Skip to content

Commit

Permalink
Merge pull request #54 from smarie/stub_files_issue_50
Browse files Browse the repository at this point in the history
On the way to fixing #50 : created stubs for module `entry_points_annotations`
  • Loading branch information
smarie authored Jan 22, 2020
2 parents 4c921e0 + c8eb65f commit fccf6b6
Show file tree
Hide file tree
Showing 4 changed files with 173 additions and 136 deletions.
11 changes: 8 additions & 3 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,9 +137,8 @@
# If there are data files included in your packages that need to be
# installed, specify them here. If using Python 2.6 or less, then these
# have to be included in MANIFEST.in as well.
# package_data={
# 'sample': ['package_data.dat'],
# },
# Note: we use the empty string so that this also works with submodules
package_data={"": ['py.typed', '*.pyi']},

# Although 'package_data' is the preferred approach, in some case you may
# need to place data files outside of your packages. See:
Expand All @@ -155,4 +154,10 @@
# 'sample=sample:main',
# ],
# },

# explicitly setting the flag to avoid `ply` being downloaded
# see https://github.com/smarie/python-getversion/pull/5
# and to make mypy happy
# see https://mypy.readthedocs.io/en/latest/installed_packages.html
zip_safe=False,
)
156 changes: 23 additions & 133 deletions valid8/entry_points_annotations.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

try: # python 3.5+
# noinspection PyUnresolvedReferences
from typing import Callable, Any, List, Union
from typing import Callable, Any, List, Union, TypeVar
try: # python 3.5.3-
# noinspection PyUnresolvedReferences
from typing import Type
Expand All @@ -14,6 +14,10 @@
else:
# noinspection PyUnresolvedReferences
from valid8.composition import ValidationFuncs

DecoratedClass = TypeVar("DecoratedClass", bound=Type[Any])
DecoratedFunc = TypeVar("DecoratedFunc", bound=Callable)

use_typing = sys.version_info > (3, 0)
except ImportError:
use_typing = False
Expand All @@ -23,7 +27,7 @@
except ImportError:
from funcsigs import signature, Signature

from makefun import with_signature, wraps
from makefun import wraps

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


# Python 3+: load the 'more explicit api'
if use_typing:
new_sig = """(self,
validated_func: Callable,
*validation_func: ValidationFuncs,
error_type: 'Type[ValidationError]' = None,
help_msg: str = None,
none_policy: int = None,
**kw_context_args):"""
else:
new_sig = None


class FuncValidator(Validator):
"""
Represents a special kind of `Validator` responsible to validate a function input or output
"""

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

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

@with_signature(new_sig)
def __init__(self,
validated_func, # type: Callable
*validation_func, # type: ValidationFuncs
Expand Down Expand Up @@ -260,27 +248,12 @@ def assert_valid(self,
**kw_context_args)


# Python 3+: load the 'more explicit api'
if use_typing:
new_sig = """(self,
validated_class: Callable,
validated_field_name: str,
*validation_func: ValidationFuncs,
error_type: 'Type[ClassFieldValidationError]' = None,
help_msg: str = None,
none_policy: int = None,
**kw_context_args):"""
else:
new_sig = None


class ClassFieldValidator(Validator):
"""
Represents a special kind of `Validator` responsible to validate a class field.
As opposed to other validators, the name of the field is hardcoded.
"""

@with_signature(new_sig)
def __init__(self,
validated_class, # type: Callable,
validated_field_name, # type: str
Expand Down Expand Up @@ -341,26 +314,12 @@ def get_validated_class_display_name(self):
return self.validated_class.__name__


# Python 3+: load the 'more explicit api'
if use_typing:
new_sig = """(cls,
field_name,
*validation_func: ValidationFuncs,
help_msg: str = None,
error_type: 'Type[InputValidationError]' = None,
none_policy: int = None,
**kw_context_args) -> 'Type':"""
else:
new_sig = None


@class_decorator(flat_mode_decorated_name='cls')
@with_signature(new_sig)
def validate_field(cls,
def validate_field(cls, # type: DecoratedClass
field_name,
*validation_func, # type: ValidationFuncs
**kwargs):
# type: (...) -> Callable
# type: (...) -> DecoratedClass
"""
A class decorator. It goes through all class variables and for all of those that are descriptors with a __set__,
it wraps the descriptors' setter function with a `validate_arg` annotation
Expand All @@ -385,11 +344,12 @@ def validate_field(cls,


@function_decorator
def validate_io(f=DECORATED,
def validate_io(f=DECORATED, # type: DecoratedFunc
none_policy=None, # type: int
_out_=None, # type: ValidationFuncs
**kw_validation_funcs # type: ValidationFuncs
):
# type: (...) -> DecoratedFunc
"""
A function decorator to add input validation prior to the function execution. It should be called with named
arguments: for each function arg name, provide a single validation function or a list of validation functions to
Expand Down Expand Up @@ -439,27 +399,13 @@ def myfunc(a, b):
return decorate_several_with_validation(f, none_policy=none_policy, _out_=_out_, **kw_validation_funcs)


# Python 3+: load the 'more explicit api'
if use_typing:
new_sig = """(f,
arg_name,
*validation_func: ValidationFuncs,
help_msg: str = None,
error_type: 'Type[InputValidationError]' = None,
none_policy: int = None,
**kw_context_args) -> Callable:"""
else:
new_sig = None


@function_decorator(flat_mode_decorated_name='f')
@with_signature(new_sig)
def validate_arg(f,
def validate_arg(f, # type: DecoratedFunc
arg_name,
*validation_func, # type: ValidationFuncs
**kwargs
):
# type: (...) -> Callable
# type: (...) -> DecoratedFunc
"""
A decorator to apply function input validation for the given argument name, with the provided base validation
function(s). You may use several such decorators on a given function as long as they are stacked on top of each
Expand All @@ -485,21 +431,9 @@ def validate_arg(f,
return decorate_with_validation(f, arg_name, *validation_func, **kwargs)


# Python 3+: load the 'more explicit api'
if use_typing:
new_sig = """(*validation_func: ValidationFuncs,
help_msg: str = None,
error_type: 'Type[OutputValidationError]' = None,
none_policy: int = None,
**kw_context_args) -> Callable:"""
else:
new_sig = None


@with_signature(new_sig)
def validate_out(*validation_func, # type: ValidationFuncs
**kwargs):
# type: (...) -> Callable
# type: (...) -> Callable[[DecoratedFunc], DecoratedFunc]
"""
A decorator to apply function output validation to this function's output, with the provided base validation
function(s). You may use several such decorators on a given function as long as they are stacked on top of each
Expand Down Expand Up @@ -530,25 +464,11 @@ def decorate(f):
""" The reserved key for output validation """


# Python 3+: load the 'more explicit api'
if use_typing:
new_sig = """(cls,
field_name: str,
*validation_func: ValidationFuncs,
help_msg: str = None,
error_type: 'Union[Type[InputValidationError], Type[OutputValidationError]]' = None,
none_policy: int = None,
**kw_context_args) -> Callable:"""
else:
new_sig = None


@with_signature(new_sig)
def decorate_cls_with_validation(cls,
def decorate_cls_with_validation(cls, # type: DecoratedClass
field_name, # type: str
*validation_func, # type: ValidationFuncs
**kwargs):
# type: (...) -> Type[Any]
# type: (...) -> DecoratedClass
"""
This method is equivalent to decorating a class with the `@validate_field` decorator but can be used a posteriori.
Expand Down Expand Up @@ -688,12 +608,12 @@ def decorate_cls_with_validation(cls,
return cls


def decorate_several_with_validation(func,
def decorate_several_with_validation(func, # type: DecoratedFunc
_out_=None, # type: ValidationFuncs
none_policy=None, # type: int
**validation_funcs # type: ValidationFuncs
):
# type: (...) -> Callable
# type: (...) -> DecoratedFunc
"""
This method is equivalent to applying `decorate_with_validation` once for each of the provided arguments of
the function `func` as well as output `_out_`. validation_funcs keyword arguments are validation functions for each
Expand Down Expand Up @@ -721,26 +641,11 @@ def decorate_several_with_validation(func,
return func


# Python 3+: load the 'more explicit api'
if use_typing:
new_sig = """(func,
arg_name: str,
*validation_func: ValidationFuncs,
help_msg: str = None,
error_type: 'Union[Type[InputValidationError], Type[OutputValidationError]]' = None,
none_policy: int = None,
_constructor_of_cls_: 'Type'=None,
**kw_context_args) -> Callable:"""
else:
new_sig = None


@with_signature(new_sig)
def decorate_with_validation(func,
def decorate_with_validation(func, # type: DecoratedFunc
arg_name, # type: str
*validation_func, # type: ValidationFuncs
**kwargs):
# type: (...) -> Callable
# type: (...) -> DecoratedFunc
"""
This method is the inner method used in `@validate_io`, `@validate_arg` and `@validate_out`.
It can be used if you with to perform decoration manually without a decorator.
Expand Down Expand Up @@ -798,6 +703,7 @@ def decorate_with_validation(func,
def _get_final_none_policy_for_validator(is_nonable, # type: bool
none_policy # type: NoneArgPolicy
):
# type: (...) -> NoneArgPolicy
"""
Depending on none_policy and of the fact that the target parameter is nonable or not, returns a corresponding
NonePolicy
Expand Down Expand Up @@ -826,29 +732,12 @@ class fields)"""
pass


# Python 3+: load the 'more explicit api'
if use_typing:
new_sig = """(validated_func: Callable,
s: Signature,
arg_name: str,
*validation_func: ValidationFuncs,
help_msg: str = None,
error_type: 'Type[InputValidationError]' = None,
none_policy: int = None,
validated_class: 'Type'=None,
validated_class_field_name: str=None,
**kw_context_args):"""
else:
new_sig = None


@with_signature(new_sig)
def _create_function_validator(validated_func, # type: Callable
s, # type: Signature
arg_name, # type: str
*validation_func, # type: ValidationFuncs
**kwargs):

# type: (...) -> Union[ClassFieldValidator, InputValidator, OutputValidator]
error_type, help_msg, none_policy, validated_class, validated_class_field_name = \
pop_kwargs(kwargs, [('error_type', None), ('help_msg', None), ('none_policy', None),
('validated_class', None), ('validated_class_field_name', None)], allow_others=True)
Expand Down Expand Up @@ -895,10 +784,11 @@ def _create_function_validator(validated_func, # type: Callable
error_type=error_type, help_msg=help_msg, **kw_context_args)


def decorate_with_validators(func,
def decorate_with_validators(func, # type: DecoratedFunc
func_signature=None, # type: Signature
**validators # type: Union[Validator, List[Validator]]
):
# type: (...) -> DecoratedFunc
"""
Utility method to decorate the provided function with the provided input and output Validator objects. Since this
method takes Validator objects as argument, it is for advanced users.
Expand Down
Loading

0 comments on commit fccf6b6

Please sign in to comment.