Skip to content

Commit

Permalink
add implicit type mark
Browse files Browse the repository at this point in the history
  • Loading branch information
Nanguage committed Sep 13, 2022
1 parent 0a0ba8d commit 1c5adc9
Show file tree
Hide file tree
Showing 11 changed files with 71 additions and 36 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@ oneFace is an easy way to create interfaces in Python, just decorate your functi
from oneface import one, Arg

@one
def bmi(name: Arg(str),
height: Arg(float, [100, 250]) = 160,
weight: Arg(float, [0, 300]) = 50.0):
def bmi(name: str,
height: Arg[float, [100, 250]] = 160,
weight: Arg[float, [0, 300]] = 50.0):
BMI = weight / (height / 100) ** 2
print(f"Hi {name}. Your BMI is: {BMI}")
return BMI
Expand Down
15 changes: 12 additions & 3 deletions docs/basic_usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,16 @@ Using `one` decorate the function, and use `Arg` mark type and range of the argu
from oneface import one, Arg

@one
def print_person(name: Arg(str), age: Arg(int, [0, 120])):
def print_person(name: str, age: Arg[int, [0, 120]]):
return f"{name} is {age} years old."
```

**Note**: `Arg(type, range)` is same to `Arg[type, range]`.

```Python
# This is same to the previous defination
@one
def print_person(name: str, age: Arg(int, [0, 120])):
return f"{name} is {age} years old."
```

Expand Down Expand Up @@ -51,7 +60,7 @@ By default, oneface will pretty print the input arguments with a table. It can b

```Python
@one(print_args=False)
def print_person(name: Arg(str), age: Arg(int, [0, 120])):
def print_person(name: str, age: Arg[int, [0, 120]]):
return f"{name} is {age} years old."

>>> print_person("Tom", 20)
Expand All @@ -66,7 +75,7 @@ Create a python module `print_person.py`:
from oneface import one, Arg

@one
def print_person(name: Arg(str), age: Arg(int, [0, 120])):
def print_person(name: str, age: Arg[int, [0, 120]]):
return f"{name} is {age} years old."

print_person.cli()
Expand Down
16 changes: 8 additions & 8 deletions docs/builtin_types.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,14 @@ from oneface.core import one, Arg
from oneface.types import (Selection, SubSet, InputPath, OutputPath)

@one
def func(in_path: Arg(InputPath),
out_path: Arg(OutputPath) = "./test",
a: Arg(int, [0, 10], text="parameter (a)") = 10,
b: Arg(float, [0, 1]) = 0.1,
c: Arg(str) = "aaaa",
d: Arg(bool) = False,
e: Arg(Selection, ["a", "b", "c"]) = "a",
f: Arg(SubSet, ["a", "b", "c"]) = ["a"]):
def func(in_path: InputPath,
out_path: OutputPath = "./test",
a: Arg[int, [0, 10], text="parameter (a)"] = 10,
b: Arg[float, [0, 1]] = 0.1,
c: Arg[str] = "aaaa",
d: Arg[bool] = False,
e: Arg[Selection, ["a", "b", "c"]] = "a",
f: Arg[SubSet, ["a", "b", "c"]] = ["a"]):
print(in_path, out_path)
print(a, b, c, d, e, f)
return a + b
Expand Down
6 changes: 3 additions & 3 deletions docs/dash_confs.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ The `show_console` parameter is used to control whether it is displayed.
from oneface import one, Arg

@one
def bmi(name: Arg(str) = "Tom",
height: Arg(float, [100, 250]) = 160,
weight: Arg(float, [0, 300]) = 50.0):
def bmi(name: str = "Tom",
height: Arg[float, [100, 250]] = 160,
weight: Arg[float, [0, 300]] = 50.0):
BMI = weight / (height / 100) ** 2
print(f"Hi {name}. Your BMI is: {BMI}")
return BMI
Expand Down
9 changes: 5 additions & 4 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,16 @@ $ pip install "oneface[pyside2]" # for example

## Example

oneFace is an easy way to create interfaces in Python, just decorate your function and mark the type and range of the arguments:
oneFace is an easy way to create interfaces in Python,
just decorate your function and mark the **type** and **range** of the arguments:

```Python
from oneface import one, Arg

@one
def bmi(name: Arg(str),
height: Arg(float, [100, 250]) = 160,
weight: Arg(float, [0, 300]) = 50.0):
def bmi(name: str,
height: Arg[float, [100, 250]] = 160,
weight: Arg[float, [0, 300]] = 50.0):
BMI = weight / (height / 100) ** 2
print(f"Hi {name}. Your BMI is: {BMI}")
return BMI
Expand Down
10 changes: 5 additions & 5 deletions docs/qt_confs.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ By default the window name is the name of the function, but it can be changed by
from oneface import one, Arg

@one
def bmi(name: Arg(str),
height: Arg(float, [100, 250]) = 160,
weight: Arg(float, [0, 300]) = 50.0):
def bmi(name: str,
height: Arg[float, [100, 250]] = 160,
weight: Arg[float, [0, 300]] = 50.0):
BMI = weight / (height / 100) ** 2
print(f"Hi {name}. Your BMI is: {BMI}")
return BMI
Expand All @@ -27,8 +27,8 @@ By default, argument label is the variable name. But it can be explicitly set by
```Python
@one
def bmi(name: Arg(str, text="NAME"), # explicitly label setting
height: Arg(float, [100, 250]) = 160,
weight: Arg(float, [0, 300]) = 50.0):
height: Arg[float, [100, 250]] = 160,
weight: Arg[float, [0, 300]] = 50.0):
BMI = weight / (height / 100) ** 2
print(f"Hi {name}. Your BMI is: {BMI}")
return BMI
Expand Down
4 changes: 2 additions & 2 deletions docs/type_extension.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ This will allow oneface to check the type of the input parameter to make sure it

```Python
@one
def print_person(person: Arg(Person)):
def print_person(person: Person):
print(f"{person.name} is {person.age} years old.")

>>> print_person(["Tom", 10]) # Incorrect input type
Expand Down Expand Up @@ -83,7 +83,7 @@ Mark the range in argument annotation:

```Python
@one
def print_person(person: Arg(Person, [0, 100])):
def print_person(person: Arg[Person, [0, 100]]):
print(f"{person.name} is {person.age} years old.")
```

Expand Down
2 changes: 1 addition & 1 deletion oneface/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from .core import one, Arg

__version__ = '0.0.2'
__version__ = '0.1.0'

__all__ = [one, Arg]
12 changes: 9 additions & 3 deletions oneface/arg.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,15 @@ class Empty:
pass


class Arg():
class ArgMeta(type):
def __getitem__(self, args):
if isinstance(args, tuple):
return Arg(*args)
else:
return Arg(args)


class Arg(metaclass=ArgMeta):
type_to_range_checker = {}
type_to_type_checker = {}

Expand All @@ -34,7 +41,7 @@ def check(self, val):
if not self.type_checker(val, self.type):
raise TypeError(
f"Input value {val} is not in valid type({self.type})")
if self.range_checker is not None:
if (self.range is not None) and (self.range_checker is not None):
if (not self.range_checker(val, self.range)):
raise ValueError(f"Input value {val} is not in a valid range.")

Expand Down Expand Up @@ -75,4 +82,3 @@ def get_func_argobjs(func: T.Callable) -> T.OrderedDict[str, Arg]:
arg.default = p.default
args[n] = arg
return args

4 changes: 2 additions & 2 deletions oneface/dash_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -285,15 +285,15 @@ class DropdownInputItem(InputItem):
def get_input(self):
return dcc.Dropdown(
self.range,
value=(self.default or range[0])
value=(self.default or self.range[0])
)


class MultiDropdownInputItem(InputItem):
def get_input(self):
return dcc.Dropdown(
self.range,
value=(self.default or range[0]), multi=True
value=(self.default or self.range[0]), multi=True
)


Expand Down
23 changes: 21 additions & 2 deletions tests/test_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ def func(a: Arg(bool)):
pass
with pytest.raises(ArgsCheckError) as e:
func(1)
@one(print_args=False)
def func(a: Arg(int)):
return a
with pytest.raises(ArgsCheckError) as e:
func(1.0)
assert isinstance(e.value.args[0][0], TypeError)


Expand Down Expand Up @@ -62,7 +67,7 @@ class A():
def __init__(self, a):
self.a = a

@one
@one(print_args=False)
def mth1(self, b: Arg(float, [0, 1])):
return self.a + b

Expand Down Expand Up @@ -99,8 +104,22 @@ def func1():
assert func1.__doc__ == "test"


def test_implicit():
@one(print_args=False)
def func(a: int):
return a + 1
assert func(1) == 2
with pytest.raises(ArgsCheckError):
func(1.0)
@one(print_args=False)
def func(a: Arg[int, [0, 10]], b: Arg[int, [0, 10]]):
return a + b
assert func(10, 10) == 20


if __name__ == "__main__":
test_arg_check()
#test_arg_check()
#test_arg_register()
#test_print_args()
#test_class_method_arg_check()
test_implicit()

0 comments on commit 1c5adc9

Please sign in to comment.