Library to overload function and methods like C++. This library tries to match type annotations.
Project description
# Overload Function
This allows python to overload functions like C++. It uses function argument type annotations to do this.
## Example - Simple
```python
import overload_function
class Test(object):
def __init__(self, x=0):
self.x = x
self.int_test = None
self.bool_test = None
@overload_function
def set_x(self, x: int):
self.int_test = True
self.x = x
@set_x.overload
def set_x(self, x: bool):
self.bool_test = True
self.x = 0
t = Test()
assert t.x == 0
value = 2
t.set_x(value)
assert t.x == value
assert t.int_test
value = False
t.set_x(value)
assert t.x == 0
assert t.bool_test
```
## Example - advanced
```python
from overload_function import overload_function
class Point(object):
def __init__(self, x=0, y=0):
self.x = x
self.y = y
def __eq__(self, obj):
try:
return self.x == obj.x and self.y == obj.y
except:
return False
class Test(object):
@overload_function
def __init__(self, s: str="", x: int=0, b: bool=False, p: Point=Point()):
self.s = s
self.x = x
self.b = b
self.p = p
@__init__.overload
def __init__(self, x: int=0, b: bool=False, s: str="", p: Point=Point()):
self.s = s
self.x = x
self.b = b
self.p = p
@__init__.overload
def __init__(self, p: Point=Point(), x: int=0, b: bool=False, s: str=""):
self.s = s
self.x = x
self.b = b
self.p = p
t1 = Test("Hello World!", 1, True, Point(1, 1))
assert t1.s == "Hello World!"
assert t1.x == 1
assert t1.b is True
assert t1.p == Point(1, 1)
# Overload x first
t2 = Test(1, True, "Hello World!", Point(1, 1))
assert t2.s == "Hello World!"
assert t2.x == 1
assert t2.b is True
assert t2.p == Point(1, 1)
# Overload p first
t3 = Test(Point(1, 1), 1, True, "Hello World!")
assert t3.s == "Hello World!"
assert t3.x == 1
assert t3.b is True
assert t3.p == Point(1, 1)
```
## Example - function
```python
import overload_function
t1 = []
t2 = []
@overload_function
def run1(x: int=0, y: int=0):
t1.append((x, y))
@run1.overload
def run1(x: str="1", y: str="1"):
t2.append((int(x), int(y)))
run1(2, 2)
assert t1 == [(2, 2)]
run1("3", "3")
assert t2 == [(3, 3)]
```
## Example - custom match function
```python
import overload_function
def match_on_overloader(given_args, given_kwargs, func, spec_arg_names, spec_annotations, spec_defaults):
"""Compare arguments and return a weight for how much you want to use this function.
Args:
given_args (tuple): Arguments given to the function call.
given_kwargs (dict): Keyword arguments given to the function call.
func (function): Function that you are checking arguments for
spec_arg_names (list): List of argument names in order found with inspect.getfullargspec.
spec_annotations (dict): Dictionary of spec argument names and type annotations to try and match.
spec_defaults (tuple): Default values that match the spec_arg_names.
Returns:
weight (int): Integer that dictates how likely this function is to be the correct function. The highest
number will be used in deciding which function should be called.
"""
try:
idx = spec_arg_names.index("overloader")
overloader_val = spec_defaults[idx]
if overloader_val == given_kwargs["overloader"]:
return float("inf")
except:
pass
return 0
# return overload_function.match(given_args, given_kwargs,
# func, spec_arg_names, spec_annotations, spec_defaults)
class Test(object):
@overload_function(match_func=match_on_overloader)
def __init__(self, s:str="", x:int=0, b:bool=False, overloader:None="first"):
self.s = s
self.x = x
self.b = b
print("overloader", overloader)
@__init__.overload
def __init__(self, x:int=0, b:bool=False, s:str="", overloader:None="second"):
self.s = s
self.x = x
self.b = b
print("overloader", overloader)
@__init__.overload
def __init__(self, b:bool=False, x:int=0, s:str="", overloader:None="third"):
self.s = s
self.x = x
self.b = b
print("overloader", overloader)
t = Test(1, 2, 3, overloader="third")
assert t.s == 3
assert t.x == 2
assert t.b == 1
t = Test(1, 2, 3, overloader="first")
assert t.s == 1
assert t.x == 2
assert t.b == 3
t = Test(1, 2, 3, overloader="second")
assert t.s == 3
assert t.x == 1
assert t.b == 2
t = Test(1, 2, 3) # Will used the first function set (overloader=="first")
assert t.s == 1
assert t.x == 2
assert t.b == 3
```
This allows python to overload functions like C++. It uses function argument type annotations to do this.
## Example - Simple
```python
import overload_function
class Test(object):
def __init__(self, x=0):
self.x = x
self.int_test = None
self.bool_test = None
@overload_function
def set_x(self, x: int):
self.int_test = True
self.x = x
@set_x.overload
def set_x(self, x: bool):
self.bool_test = True
self.x = 0
t = Test()
assert t.x == 0
value = 2
t.set_x(value)
assert t.x == value
assert t.int_test
value = False
t.set_x(value)
assert t.x == 0
assert t.bool_test
```
## Example - advanced
```python
from overload_function import overload_function
class Point(object):
def __init__(self, x=0, y=0):
self.x = x
self.y = y
def __eq__(self, obj):
try:
return self.x == obj.x and self.y == obj.y
except:
return False
class Test(object):
@overload_function
def __init__(self, s: str="", x: int=0, b: bool=False, p: Point=Point()):
self.s = s
self.x = x
self.b = b
self.p = p
@__init__.overload
def __init__(self, x: int=0, b: bool=False, s: str="", p: Point=Point()):
self.s = s
self.x = x
self.b = b
self.p = p
@__init__.overload
def __init__(self, p: Point=Point(), x: int=0, b: bool=False, s: str=""):
self.s = s
self.x = x
self.b = b
self.p = p
t1 = Test("Hello World!", 1, True, Point(1, 1))
assert t1.s == "Hello World!"
assert t1.x == 1
assert t1.b is True
assert t1.p == Point(1, 1)
# Overload x first
t2 = Test(1, True, "Hello World!", Point(1, 1))
assert t2.s == "Hello World!"
assert t2.x == 1
assert t2.b is True
assert t2.p == Point(1, 1)
# Overload p first
t3 = Test(Point(1, 1), 1, True, "Hello World!")
assert t3.s == "Hello World!"
assert t3.x == 1
assert t3.b is True
assert t3.p == Point(1, 1)
```
## Example - function
```python
import overload_function
t1 = []
t2 = []
@overload_function
def run1(x: int=0, y: int=0):
t1.append((x, y))
@run1.overload
def run1(x: str="1", y: str="1"):
t2.append((int(x), int(y)))
run1(2, 2)
assert t1 == [(2, 2)]
run1("3", "3")
assert t2 == [(3, 3)]
```
## Example - custom match function
```python
import overload_function
def match_on_overloader(given_args, given_kwargs, func, spec_arg_names, spec_annotations, spec_defaults):
"""Compare arguments and return a weight for how much you want to use this function.
Args:
given_args (tuple): Arguments given to the function call.
given_kwargs (dict): Keyword arguments given to the function call.
func (function): Function that you are checking arguments for
spec_arg_names (list): List of argument names in order found with inspect.getfullargspec.
spec_annotations (dict): Dictionary of spec argument names and type annotations to try and match.
spec_defaults (tuple): Default values that match the spec_arg_names.
Returns:
weight (int): Integer that dictates how likely this function is to be the correct function. The highest
number will be used in deciding which function should be called.
"""
try:
idx = spec_arg_names.index("overloader")
overloader_val = spec_defaults[idx]
if overloader_val == given_kwargs["overloader"]:
return float("inf")
except:
pass
return 0
# return overload_function.match(given_args, given_kwargs,
# func, spec_arg_names, spec_annotations, spec_defaults)
class Test(object):
@overload_function(match_func=match_on_overloader)
def __init__(self, s:str="", x:int=0, b:bool=False, overloader:None="first"):
self.s = s
self.x = x
self.b = b
print("overloader", overloader)
@__init__.overload
def __init__(self, x:int=0, b:bool=False, s:str="", overloader:None="second"):
self.s = s
self.x = x
self.b = b
print("overloader", overloader)
@__init__.overload
def __init__(self, b:bool=False, x:int=0, s:str="", overloader:None="third"):
self.s = s
self.x = x
self.b = b
print("overloader", overloader)
t = Test(1, 2, 3, overloader="third")
assert t.s == 3
assert t.x == 2
assert t.b == 1
t = Test(1, 2, 3, overloader="first")
assert t.s == 1
assert t.x == 2
assert t.b == 3
t = Test(1, 2, 3, overloader="second")
assert t.s == 3
assert t.x == 1
assert t.b == 2
t = Test(1, 2, 3) # Will used the first function set (overloader=="first")
assert t.s == 1
assert t.x == 2
assert t.b == 3
```
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
File details
Details for the file overload_function-1.2.3.tar.gz
.
File metadata
- Download URL: overload_function-1.2.3.tar.gz
- Upload date:
- Size: 5.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | c04f66d52fd9a37a1e55188e04869c52c3bceca72a185182fb01814af516ed6e |
|
MD5 | 048b668ac2b44c05652d3f2c7b3d76e6 |
|
BLAKE2b-256 | 7e03ccc1cfad29649e005a4e1d95197c1045758f81bc38e35331ca345544a36d |