Skip to content

Commit 2ea3e9c

Browse files
committed
feat: Add typing for function_decorator
# Conflicts: # tests/test_typing.py
1 parent 4715f9b commit 2ea3e9c

File tree

2 files changed

+90
-8
lines changed

2 files changed

+90
-8
lines changed

src/decopatch/main.py

+50-8
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,63 @@
1-
from makefun import with_signature, add_signature_parameters
1+
from makefun import add_signature_parameters, with_signature
2+
3+
from decopatch.utils_calls import (call_in_appropriate_mode,
4+
no_parenthesis_usage,
5+
with_parenthesis_usage)
6+
from decopatch.utils_disambiguation import (
7+
DecoratorUsageInfo, FirstArgDisambiguation, can_arg_be_a_decorator_target,
8+
create_single_arg_callable_or_class_disambiguator, disambiguate_call)
29
from decopatch.utils_modes import SignatureInfo, make_decorator_spec
3-
from decopatch.utils_disambiguation import create_single_arg_callable_or_class_disambiguator, disambiguate_call, \
4-
DecoratorUsageInfo, can_arg_be_a_decorator_target
5-
from decopatch.utils_calls import with_parenthesis_usage, no_parenthesis_usage, call_in_appropriate_mode
610

711
try: # python 3.3+
8-
from inspect import signature, Parameter
12+
from inspect import Parameter, signature
913
except ImportError:
10-
from funcsigs import signature, Parameter
14+
from funcsigs import Parameter, signature
1115

1216
try: # python 3.5+
13-
from typing import Callable, Any, Optional
17+
from typing import Any, Callable, Optional
18+
except ImportError:
19+
pass
20+
21+
try: # Python 3.9
22+
from typing import Any, Callable, Protocol, TypeVar, Union, overload
23+
try: # Python 3.10
24+
from typing import ParamSpec
25+
except ImportError:
26+
from typing_extensions import ParamSpec
27+
28+
P = ParamSpec("P")
29+
F = TypeVar("F", bound=Callable)
30+
31+
class _Decorator(Protocol[P]):
32+
33+
@overload
34+
def __call__(self, func: F) -> F:
35+
...
36+
37+
@overload
38+
def __call__(self, *args: P.args, **kwargs: P.kwargs) -> Callable[[F], F]:
39+
...
40+
41+
@overload
42+
def function_decorator(
43+
enable_stack_introspection: Callable[P, Any],
44+
custom_disambiguator: Callable[[Any], FirstArgDisambiguation] = ...,
45+
flat_mode_decorated_name: Optional[str] = ...,
46+
) -> _Decorator[P]:
47+
...
48+
49+
@overload
50+
def function_decorator(
51+
enable_stack_introspection: bool = ...,
52+
custom_disambiguator: Callable[[Any], FirstArgDisambiguation] = ...,
53+
flat_mode_decorated_name: Optional[str] = ...,
54+
) -> Callable[[Callable[P, Any]], _Decorator[P]]:
55+
...
1456
except ImportError:
1557
pass
1658

1759

18-
def function_decorator(enable_stack_introspection=False, # type: bool
60+
def function_decorator(enable_stack_introspection=False, # type: Union[Callable, bool]
1961
custom_disambiguator=None, # type: Callable[[Any], FirstArgDisambiguation]
2062
flat_mode_decorated_name=None, # type: Optional[str]
2163
):

tests/test_typing.py

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# This is test file for typing,
2+
# No automatic testing is used at the moment. Just use your type checker and see if it works.
3+
from decopatch import DECORATED, function_decorator
4+
5+
6+
@function_decorator
7+
def decorator(scope: str = "test", f=DECORATED):
8+
pass
9+
10+
# Ok, should reveal coorect type for `enable_stack_introspection`
11+
@function_decorator(enable_stack_introspection=True)
12+
def decorator_with_params(scope: str = "test", f=DECORATED):
13+
pass
14+
15+
16+
# Error, invalid argument
17+
@function_decorator(invalid_param=True)
18+
def decorator_wint_invalid_param():
19+
pass
20+
21+
# Ok
22+
@decorator
23+
def decorated_flat():
24+
pass
25+
26+
# Error, Literal[2] is incompatible with str
27+
@decorator(scope=2)
28+
def decorated_with_invalid_options():
29+
pass
30+
31+
# Ok, should reveal coorect type for `scope`
32+
@decorator(scope="success")
33+
def decorated_with_valid_options():
34+
pass
35+
36+
37+
# Ok, should reveal coorect type for `scope`
38+
@decorator_with_params(scope="success")
39+
def decorated_with_valid_options_v2():
40+
pass

0 commit comments

Comments
 (0)