Skip to content

Commit fccf6b6

Browse files
authored
Merge pull request #54 from smarie/stub_files_issue_50
On the way to fixing #50 : created stubs for module `entry_points_annotations`
2 parents 4c921e0 + c8eb65f commit fccf6b6

File tree

4 files changed

+173
-136
lines changed

4 files changed

+173
-136
lines changed

setup.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -137,9 +137,8 @@
137137
# If there are data files included in your packages that need to be
138138
# installed, specify them here. If using Python 2.6 or less, then these
139139
# have to be included in MANIFEST.in as well.
140-
# package_data={
141-
# 'sample': ['package_data.dat'],
142-
# },
140+
# Note: we use the empty string so that this also works with submodules
141+
package_data={"": ['py.typed', '*.pyi']},
143142

144143
# Although 'package_data' is the preferred approach, in some case you may
145144
# need to place data files outside of your packages. See:
@@ -155,4 +154,10 @@
155154
# 'sample=sample:main',
156155
# ],
157156
# },
157+
158+
# explicitly setting the flag to avoid `ply` being downloaded
159+
# see https://github.com/smarie/python-getversion/pull/5
160+
# and to make mypy happy
161+
# see https://mypy.readthedocs.io/en/latest/installed_packages.html
162+
zip_safe=False,
158163
)

valid8/entry_points_annotations.py

Lines changed: 23 additions & 133 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
try: # python 3.5+
77
# noinspection PyUnresolvedReferences
8-
from typing import Callable, Any, List, Union
8+
from typing import Callable, Any, List, Union, TypeVar
99
try: # python 3.5.3-
1010
# noinspection PyUnresolvedReferences
1111
from typing import Type
@@ -14,6 +14,10 @@
1414
else:
1515
# noinspection PyUnresolvedReferences
1616
from valid8.composition import ValidationFuncs
17+
18+
DecoratedClass = TypeVar("DecoratedClass", bound=Type[Any])
19+
DecoratedFunc = TypeVar("DecoratedFunc", bound=Callable)
20+
1721
use_typing = sys.version_info > (3, 0)
1822
except ImportError:
1923
use_typing = False
@@ -23,7 +27,7 @@
2327
except ImportError:
2428
from funcsigs import signature, Signature
2529

26-
from makefun import with_signature, wraps
30+
from makefun import wraps
2731

2832
from valid8.utils.decoration_tools import apply_on_each_func_args_sig
2933
from valid8.utils.typing_tools import is_pep484_nonable
@@ -93,25 +97,11 @@ def get_variable_str(self):
9397
return self.validator.validated_field_name + '=' + str(self.var_value)
9498

9599

96-
# Python 3+: load the 'more explicit api'
97-
if use_typing:
98-
new_sig = """(self,
99-
validated_func: Callable,
100-
*validation_func: ValidationFuncs,
101-
error_type: 'Type[ValidationError]' = None,
102-
help_msg: str = None,
103-
none_policy: int = None,
104-
**kw_context_args):"""
105-
else:
106-
new_sig = None
107-
108-
109100
class FuncValidator(Validator):
110101
"""
111102
Represents a special kind of `Validator` responsible to validate a function input or output
112103
"""
113104

114-
@with_signature(new_sig)
115105
def __init__(self,
116106
validated_func, # type: Callable
117107
*validation_func, # type: ValidationFuncs
@@ -162,7 +152,6 @@ class InputValidator(FuncValidator):
162152
Represents a special kind of `Validator` responsible to validate a function input.
163153
"""
164154

165-
@with_signature(new_sig)
166155
def __init__(self,
167156
validated_func, # type: Callable,
168157
*validation_func, # type: ValidationFuncs
@@ -203,7 +192,6 @@ def __init__(self,
203192
class OutputValidator(FuncValidator):
204193
""" Represents a special kind of `Validator` responsible to validate a function output. """
205194

206-
@with_signature(new_sig)
207195
def __init__(self,
208196
validated_func, # type: Callable
209197
*validation_func, # type: ValidationFuncs
@@ -260,27 +248,12 @@ def assert_valid(self,
260248
**kw_context_args)
261249

262250

263-
# Python 3+: load the 'more explicit api'
264-
if use_typing:
265-
new_sig = """(self,
266-
validated_class: Callable,
267-
validated_field_name: str,
268-
*validation_func: ValidationFuncs,
269-
error_type: 'Type[ClassFieldValidationError]' = None,
270-
help_msg: str = None,
271-
none_policy: int = None,
272-
**kw_context_args):"""
273-
else:
274-
new_sig = None
275-
276-
277251
class ClassFieldValidator(Validator):
278252
"""
279253
Represents a special kind of `Validator` responsible to validate a class field.
280254
As opposed to other validators, the name of the field is hardcoded.
281255
"""
282256

283-
@with_signature(new_sig)
284257
def __init__(self,
285258
validated_class, # type: Callable,
286259
validated_field_name, # type: str
@@ -341,26 +314,12 @@ def get_validated_class_display_name(self):
341314
return self.validated_class.__name__
342315

343316

344-
# Python 3+: load the 'more explicit api'
345-
if use_typing:
346-
new_sig = """(cls,
347-
field_name,
348-
*validation_func: ValidationFuncs,
349-
help_msg: str = None,
350-
error_type: 'Type[InputValidationError]' = None,
351-
none_policy: int = None,
352-
**kw_context_args) -> 'Type':"""
353-
else:
354-
new_sig = None
355-
356-
357317
@class_decorator(flat_mode_decorated_name='cls')
358-
@with_signature(new_sig)
359-
def validate_field(cls,
318+
def validate_field(cls, # type: DecoratedClass
360319
field_name,
361320
*validation_func, # type: ValidationFuncs
362321
**kwargs):
363-
# type: (...) -> Callable
322+
# type: (...) -> DecoratedClass
364323
"""
365324
A class decorator. It goes through all class variables and for all of those that are descriptors with a __set__,
366325
it wraps the descriptors' setter function with a `validate_arg` annotation
@@ -385,11 +344,12 @@ def validate_field(cls,
385344

386345

387346
@function_decorator
388-
def validate_io(f=DECORATED,
347+
def validate_io(f=DECORATED, # type: DecoratedFunc
389348
none_policy=None, # type: int
390349
_out_=None, # type: ValidationFuncs
391350
**kw_validation_funcs # type: ValidationFuncs
392351
):
352+
# type: (...) -> DecoratedFunc
393353
"""
394354
A function decorator to add input validation prior to the function execution. It should be called with named
395355
arguments: for each function arg name, provide a single validation function or a list of validation functions to
@@ -439,27 +399,13 @@ def myfunc(a, b):
439399
return decorate_several_with_validation(f, none_policy=none_policy, _out_=_out_, **kw_validation_funcs)
440400

441401

442-
# Python 3+: load the 'more explicit api'
443-
if use_typing:
444-
new_sig = """(f,
445-
arg_name,
446-
*validation_func: ValidationFuncs,
447-
help_msg: str = None,
448-
error_type: 'Type[InputValidationError]' = None,
449-
none_policy: int = None,
450-
**kw_context_args) -> Callable:"""
451-
else:
452-
new_sig = None
453-
454-
455402
@function_decorator(flat_mode_decorated_name='f')
456-
@with_signature(new_sig)
457-
def validate_arg(f,
403+
def validate_arg(f, # type: DecoratedFunc
458404
arg_name,
459405
*validation_func, # type: ValidationFuncs
460406
**kwargs
461407
):
462-
# type: (...) -> Callable
408+
# type: (...) -> DecoratedFunc
463409
"""
464410
A decorator to apply function input validation for the given argument name, with the provided base validation
465411
function(s). You may use several such decorators on a given function as long as they are stacked on top of each
@@ -485,21 +431,9 @@ def validate_arg(f,
485431
return decorate_with_validation(f, arg_name, *validation_func, **kwargs)
486432

487433

488-
# Python 3+: load the 'more explicit api'
489-
if use_typing:
490-
new_sig = """(*validation_func: ValidationFuncs,
491-
help_msg: str = None,
492-
error_type: 'Type[OutputValidationError]' = None,
493-
none_policy: int = None,
494-
**kw_context_args) -> Callable:"""
495-
else:
496-
new_sig = None
497-
498-
499-
@with_signature(new_sig)
500434
def validate_out(*validation_func, # type: ValidationFuncs
501435
**kwargs):
502-
# type: (...) -> Callable
436+
# type: (...) -> Callable[[DecoratedFunc], DecoratedFunc]
503437
"""
504438
A decorator to apply function output validation to this function's output, with the provided base validation
505439
function(s). You may use several such decorators on a given function as long as they are stacked on top of each
@@ -530,25 +464,11 @@ def decorate(f):
530464
""" The reserved key for output validation """
531465

532466

533-
# Python 3+: load the 'more explicit api'
534-
if use_typing:
535-
new_sig = """(cls,
536-
field_name: str,
537-
*validation_func: ValidationFuncs,
538-
help_msg: str = None,
539-
error_type: 'Union[Type[InputValidationError], Type[OutputValidationError]]' = None,
540-
none_policy: int = None,
541-
**kw_context_args) -> Callable:"""
542-
else:
543-
new_sig = None
544-
545-
546-
@with_signature(new_sig)
547-
def decorate_cls_with_validation(cls,
467+
def decorate_cls_with_validation(cls, # type: DecoratedClass
548468
field_name, # type: str
549469
*validation_func, # type: ValidationFuncs
550470
**kwargs):
551-
# type: (...) -> Type[Any]
471+
# type: (...) -> DecoratedClass
552472
"""
553473
This method is equivalent to decorating a class with the `@validate_field` decorator but can be used a posteriori.
554474
@@ -688,12 +608,12 @@ def decorate_cls_with_validation(cls,
688608
return cls
689609

690610

691-
def decorate_several_with_validation(func,
611+
def decorate_several_with_validation(func, # type: DecoratedFunc
692612
_out_=None, # type: ValidationFuncs
693613
none_policy=None, # type: int
694614
**validation_funcs # type: ValidationFuncs
695615
):
696-
# type: (...) -> Callable
616+
# type: (...) -> DecoratedFunc
697617
"""
698618
This method is equivalent to applying `decorate_with_validation` once for each of the provided arguments of
699619
the function `func` as well as output `_out_`. validation_funcs keyword arguments are validation functions for each
@@ -721,26 +641,11 @@ def decorate_several_with_validation(func,
721641
return func
722642

723643

724-
# Python 3+: load the 'more explicit api'
725-
if use_typing:
726-
new_sig = """(func,
727-
arg_name: str,
728-
*validation_func: ValidationFuncs,
729-
help_msg: str = None,
730-
error_type: 'Union[Type[InputValidationError], Type[OutputValidationError]]' = None,
731-
none_policy: int = None,
732-
_constructor_of_cls_: 'Type'=None,
733-
**kw_context_args) -> Callable:"""
734-
else:
735-
new_sig = None
736-
737-
738-
@with_signature(new_sig)
739-
def decorate_with_validation(func,
644+
def decorate_with_validation(func, # type: DecoratedFunc
740645
arg_name, # type: str
741646
*validation_func, # type: ValidationFuncs
742647
**kwargs):
743-
# type: (...) -> Callable
648+
# type: (...) -> DecoratedFunc
744649
"""
745650
This method is the inner method used in `@validate_io`, `@validate_arg` and `@validate_out`.
746651
It can be used if you with to perform decoration manually without a decorator.
@@ -798,6 +703,7 @@ def decorate_with_validation(func,
798703
def _get_final_none_policy_for_validator(is_nonable, # type: bool
799704
none_policy # type: NoneArgPolicy
800705
):
706+
# type: (...) -> NoneArgPolicy
801707
"""
802708
Depending on none_policy and of the fact that the target parameter is nonable or not, returns a corresponding
803709
NonePolicy
@@ -826,29 +732,12 @@ class fields)"""
826732
pass
827733

828734

829-
# Python 3+: load the 'more explicit api'
830-
if use_typing:
831-
new_sig = """(validated_func: Callable,
832-
s: Signature,
833-
arg_name: str,
834-
*validation_func: ValidationFuncs,
835-
help_msg: str = None,
836-
error_type: 'Type[InputValidationError]' = None,
837-
none_policy: int = None,
838-
validated_class: 'Type'=None,
839-
validated_class_field_name: str=None,
840-
**kw_context_args):"""
841-
else:
842-
new_sig = None
843-
844-
845-
@with_signature(new_sig)
846735
def _create_function_validator(validated_func, # type: Callable
847736
s, # type: Signature
848737
arg_name, # type: str
849738
*validation_func, # type: ValidationFuncs
850739
**kwargs):
851-
740+
# type: (...) -> Union[ClassFieldValidator, InputValidator, OutputValidator]
852741
error_type, help_msg, none_policy, validated_class, validated_class_field_name = \
853742
pop_kwargs(kwargs, [('error_type', None), ('help_msg', None), ('none_policy', None),
854743
('validated_class', None), ('validated_class_field_name', None)], allow_others=True)
@@ -895,10 +784,11 @@ def _create_function_validator(validated_func, # type: Callable
895784
error_type=error_type, help_msg=help_msg, **kw_context_args)
896785

897786

898-
def decorate_with_validators(func,
787+
def decorate_with_validators(func, # type: DecoratedFunc
899788
func_signature=None, # type: Signature
900789
**validators # type: Union[Validator, List[Validator]]
901790
):
791+
# type: (...) -> DecoratedFunc
902792
"""
903793
Utility method to decorate the provided function with the provided input and output Validator objects. Since this
904794
method takes Validator objects as argument, it is for advanced users.

0 commit comments

Comments
 (0)