pycinante 0.0.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Chisheng Chen
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,10 @@
1
+ Metadata-Version: 2.1
2
+ Name: pycinante
3
+ Version: 0.0.1
4
+ Summary: Python's Rocinante for easily programming.
5
+ Home-page: https://github.com/gndlwch2w/pycinante
6
+ Author: Chisheng Chen
7
+ Author-email: chishengchen@126.com
8
+ License: MIT-0
9
+ Requires-Python: >=3.8
10
+ License-File: LICENSE
@@ -0,0 +1,2 @@
1
+ ## Pycinante
2
+ Python's Rocinante for easily programming.
@@ -0,0 +1,3 @@
1
+ from .validator import *
2
+
3
+ __version__ = '0.0.1'
@@ -0,0 +1,124 @@
1
+ from typing import Callable, Any, Union, List, Type, Tuple, Iterator
2
+ from functools import wraps
3
+ from validator import (
4
+ where,
5
+ require_not_empty as _require_not_empty,
6
+ require_gt as _require_gt,
7
+ require_gt_0 as _require_gt_0,
8
+ require_ge as _require_ge,
9
+ require_lt as _require_lt,
10
+ require_le as _require_le,
11
+ require_eq as _require_eq,
12
+ require_between as _require_in_range,
13
+ require_probability as _require_probability,
14
+ require_not_none as _require_not_none,
15
+ require_not_none_else as _require_not_none_else,
16
+ require_not_empty_else as _require_not_empty_else,
17
+ require_type as _require_type,
18
+ require_variable_name as _require_variable_name)
19
+
20
+ __all__ = [
21
+ 'require_not_empty',
22
+ 'require_gt',
23
+ 'require_gt_0',
24
+ 'require_ge',
25
+ 'require_lt',
26
+ 'require_le',
27
+ 'require_eq',
28
+ 'require_in_range',
29
+ 'require_probability',
30
+ 'require_variable_name',
31
+ 'require_not_none',
32
+ 'require_not_none_else',
33
+ 'require_not_empty_else',
34
+ 'require_type',
35
+ ]
36
+
37
+ def to_list(obj):
38
+ if isinstance(obj, List):
39
+ return obj
40
+ if isinstance(obj, (Tuple, Iterator)):
41
+ return list(obj)
42
+ return [obj]
43
+
44
+ def check_positional_arguments(validator: Callable, index: Union[int, List[int], Callable], **params) -> Callable:
45
+ """Check whether an argument at specified position on the function list is valid.
46
+
47
+ Args:
48
+ index (int, List[int], Callable): specifies the index of the argument being checked when the
49
+ type of the index is int or List[int]; Otherwise it represents the decorated function and in
50
+ which case the default index of the argument being checked is 0.
51
+ params (dict): the parameters of the validator to be called.
52
+ """
53
+ # the default index of the argument being checked is 0
54
+ index = _require_not_none_else(index, [0])
55
+ indexes = where(isinstance(index, Callable), [0], to_list(index))
56
+
57
+ def decorator(func: Callable) -> Callable:
58
+ @wraps(func)
59
+ def wrapper(*args, **kwargs) -> Any:
60
+ for i in indexes:
61
+ validator(args[i], **params)
62
+ return func(*args, **kwargs)
63
+ return wrapper
64
+
65
+ if isinstance(index, Callable):
66
+ # for annotation without arguments
67
+ return decorator(index)
68
+ return decorator
69
+
70
+ def require_not_empty(index: Union[int, List[int], Callable] = None, msg: str = None) -> Callable:
71
+ """Check whether the arguments args[index] is not empty."""
72
+ return check_positional_arguments(_require_not_empty, index, msg=msg)
73
+
74
+ def require_gt(min_val: int, index: Union[int, List[int], Callable] = None, msg: str = None) -> Callable:
75
+ """Check whether the args[index] is greater than the value `min_val`."""
76
+ return check_positional_arguments(_require_gt, index, min_val=min_val, msg=msg)
77
+
78
+ def require_gt_0(index: Union[int, List[int]] = None, msg: str = None) -> Callable:
79
+ """Check whether the argument args[index] is greater than the value 0."""
80
+ return check_positional_arguments(_require_gt_0, index, msg=msg)
81
+
82
+ def require_ge(min_val: int, index: Union[int, List[int], Callable] = None, msg: str = None) -> Callable:
83
+ """Check whether the args[index] is greater than or equal to the value `min_val`."""
84
+ return check_positional_arguments(_require_ge, index, min_val=min_val, msg=msg)
85
+
86
+ def require_lt(max_val: int, index: Union[int, List[int], Callable] = None, msg: str = None) -> Callable:
87
+ """Check whether the args[index] is less than the value `max_val`."""
88
+ return check_positional_arguments(_require_lt, index, max_val=max_val, msg=msg)
89
+
90
+ def require_le(max_val: int, index: Union[int, List[int], Callable] = None, msg: str = None) -> Callable:
91
+ """Check whether the args[index] is less than or equal to the value `max_val`."""
92
+ return check_positional_arguments(_require_le, index, max_val=max_val, msg=msg)
93
+
94
+ def require_eq(eq_val: int, index: Union[int, List[int], Callable] = None, msg: str = None) -> Callable:
95
+ """Check whether the args[index] is equal to the value `eq_val`."""
96
+ return check_positional_arguments(_require_eq, index, eq_val=eq_val, msg=msg)
97
+
98
+ def require_in_range(min_val: int, max_val: int, index: Union[int, List[int], Callable] = None, msg: str = None) -> Callable:
99
+ """Check whether the value args[index] is in the range `min_val` and `max_val`."""
100
+ return check_positional_arguments(_require_in_range, index, min_val=min_val, max_val=max_val, msg=msg)
101
+
102
+ def require_probability(index: Union[int, List[int]] = None, msg: str = None) -> Callable:
103
+ """Check whether the argument args[index] is between 0. and 1."""
104
+ return check_positional_arguments(_require_probability, index, msg=msg)
105
+
106
+ def require_variable_name(index: Union[int, List[int], Callable] = None, msg: str = None) -> Callable:
107
+ """Check whether the arguments args[index] is a valid variable name."""
108
+ return check_positional_arguments(_require_variable_name, index, msg=msg)
109
+
110
+ def require_not_none(index: Union[int, List[int], Callable] = None, msg: str = None) -> Callable:
111
+ """Check whether the argument args[index] is not None."""
112
+ return check_positional_arguments(_require_not_none, index, msg=msg)
113
+
114
+ def require_not_none_else(other: int, index: Union[int, List[int], Callable] = None, msg: str = None) -> Callable:
115
+ """Return the args[index] if the args[index] is not None otherwise return the `other`."""
116
+ return check_positional_arguments(_require_not_none_else, index, other=other, msg=msg)
117
+
118
+ def require_not_empty_else(other: int, index: Union[int, List[int], Callable] = None, msg: str = None) -> Callable:
119
+ """Return the args[index] if the args[index] is not empty otherwise return the `other`."""
120
+ return check_positional_arguments(_require_not_empty_else, index, other=other, msg=msg)
121
+
122
+ def require_type(types: Union[Type, Tuple[Type]], index: Union[int, List[int], Callable] = None, msg: str = None) -> Callable:
123
+ """Check whether the args[index] is an instance of the `types` type."""
124
+ return check_positional_arguments(_require_type, index, types=types, msg=msg)
@@ -0,0 +1,137 @@
1
+ import re
2
+ import numpy as np
3
+ from typing import Sized, TypeVar, Union, Type, Tuple, Any
4
+
5
+ T = TypeVar('T')
6
+ U = TypeVar('U')
7
+ Number = Union[int, float]
8
+
9
+ __all__ = [
10
+ 'is_equal',
11
+ 'is_empty',
12
+ 'is_not_empty',
13
+ 'where',
14
+ 'require_not_empty',
15
+ 'require_gt',
16
+ 'require_gt_0',
17
+ 'require_ge',
18
+ 'require_lt',
19
+ 'require_le',
20
+ 'require_eq',
21
+ 'require_between',
22
+ 'require_probability',
23
+ 'require_regex',
24
+ 'require_variable_name',
25
+ 'require_not_none',
26
+ 'require_not_none_else',
27
+ 'require_not_empty_else',
28
+ 'require_type',
29
+ ]
30
+
31
+ def is_equal(obj: Any, other: Any, epsilon=1e-6) -> bool:
32
+ """Return whether the object `obj` is equal to the `other`."""
33
+ if isinstance(obj, (int, float)) and isinstance(other, (int, float)):
34
+ return np.abs(obj - other) < epsilon
35
+ return obj == other
36
+
37
+ def is_empty(obj: Any) -> bool:
38
+ """Return whether the object `obj` is empty."""
39
+ if obj is None:
40
+ return True
41
+ if isinstance(obj, Sized):
42
+ return len(obj) == 0
43
+ if getattr(obj, 'is_empty', None) is not None:
44
+ return getattr(obj, 'is_empty')()
45
+ return False
46
+
47
+ def is_not_empty(obj: Any) -> bool:
48
+ """Return whether the object `obj` is not empty."""
49
+ return not is_empty(obj)
50
+
51
+ def where(condition: bool, obj: T, other: U) -> Union[T, U]:
52
+ """Return the first object if the condition is True otherwise return the second."""
53
+ return obj if condition else other
54
+
55
+ def require_not_empty(obj: T, msg: str = None) -> T:
56
+ """Check whether the object `obj` is not empty."""
57
+ msg = require_not_none_else(msg, 'the obj must be not empty')
58
+ assert is_not_empty(obj), msg
59
+ return obj
60
+
61
+ def require_gt(val: Number, min_val: Number, msg: str = None) -> Number:
62
+ """Check whether the `val` is greater than the value `min_val`."""
63
+ msg = require_not_none_else(msg, f'the value {val} must be greater than {min_val}')
64
+ assert val > min_val, msg
65
+ return val
66
+
67
+ def require_gt_0(val: Number, msg: str = None) -> Number:
68
+ """Check whether the `val` is greater than the value 0."""
69
+ msg = require_not_none_else(msg, f'the value {val} must be greater than 0')
70
+ assert val > 0., msg
71
+ return val
72
+
73
+ def require_ge(val: Number, min_val: Number, msg: str = None) -> Number:
74
+ """Check whether the `val` is greater than or equal to the value `min_val`."""
75
+ msg = require_not_none_else(msg, f'the value {val} must be greater than or equal to {min_val}')
76
+ assert val > min_val or is_equal(val, min_val), msg
77
+ return val
78
+
79
+ def require_lt(val: Number, max_val: Number, msg: str = None) -> Number:
80
+ """Check whether the `val` is less than the value `max_val`."""
81
+ msg = require_not_none_else(msg, f'the value {val} must be less than {max_val}')
82
+ assert val < max_val, msg
83
+ return val
84
+
85
+ def require_le(val: Number, max_val: Number, msg: str = None) -> Number:
86
+ """Check whether the `val` is less than or equal to the value `max_val`."""
87
+ msg = require_not_none_else(msg, f'the value {val} must be less than or equal to {max_val}')
88
+ assert val < max_val or is_equal(val, max_val), msg
89
+ return val
90
+
91
+ def require_eq(val: Number, eq_val: Number, msg: str = None) -> Number:
92
+ """Check whether the `val` is equal to the value `eq_val`."""
93
+ msg = require_not_none_else(msg, f'the value {val} must be equal to {eq_val}')
94
+ assert is_equal(val, eq_val), msg
95
+ return val
96
+
97
+ def require_between(val: Number, min_val: Number = -np.inf, max_val: Number = np.inf, msg: str = None) -> Number:
98
+ """Check whether the value `val` is in the range `min_val` (included) and `max_val` (included)."""
99
+ msg = require_not_none_else(msg, f'the value {val} must be between {min_val} and {max_val}')
100
+ assert min_val < val < max_val or is_equal(val, min_val) or is_equal(val, max_val), msg
101
+ return val
102
+
103
+ def require_probability(val: Number, msg: str = None) -> Number:
104
+ """Check whether the value `val` is between 0. and 1."""
105
+ msg = require_not_none_else(msg, f'the probability value {val} must be between 0. and 1.')
106
+ return require_between(val, 0, 1, msg)
107
+
108
+ def require_regex(val: str, pattern: str, msg: str = None) -> str:
109
+ """Check whether the string `val` matches the regular expression."""
110
+ msg = require_not_none_else(msg, f'the string {val} is not matching the regular expression {pattern}')
111
+ assert re.match(pattern, val), msg
112
+ return val
113
+
114
+ def require_variable_name(val: str, msg: str = None) -> str:
115
+ """Check whether the variable name `val` is a valid variable name."""
116
+ msg = require_not_none_else(msg, f'the variable {val} is not a valid variable name')
117
+ return require_regex(val, r'^[a-zA-Z_][a-zA-Z0-9_]*$', msg)
118
+
119
+ def require_not_none(obj: T, msg: str = None) -> T:
120
+ """Check whether the `obj` is not none."""
121
+ msg = require_not_none_else(msg, f'the obj must be not None')
122
+ assert obj is not None, msg
123
+ return obj
124
+
125
+ def require_not_none_else(obj: T, other: U) -> Union[T, U]:
126
+ """Return the `obj` if the `obj` is not None otherwise return the `other`."""
127
+ return obj if obj is not None else other
128
+
129
+ def require_not_empty_else(obj: T, other: U) -> Union[T, U]:
130
+ """Return the `obj` if the `obj` is not empty otherwise return the `other`."""
131
+ return obj if is_not_empty(obj) else other
132
+
133
+ def require_type(obj: T, types: Union[Type, Tuple[Type]], msg: str = None) -> T:
134
+ """Check whether the `obj` is an instance of the `types` type."""
135
+ msg = require_not_none_else(msg, f'the type of `obj` must be the type {types}')
136
+ assert isinstance(obj, types), msg
137
+ return obj
@@ -0,0 +1,10 @@
1
+ Metadata-Version: 2.1
2
+ Name: pycinante
3
+ Version: 0.0.1
4
+ Summary: Python's Rocinante for easily programming.
5
+ Home-page: https://github.com/gndlwch2w/pycinante
6
+ Author: Chisheng Chen
7
+ Author-email: chishengchen@126.com
8
+ License: MIT-0
9
+ Requires-Python: >=3.8
10
+ License-File: LICENSE
@@ -0,0 +1,12 @@
1
+ LICENSE
2
+ README.md
3
+ setup.py
4
+ pycinante/__init__.py
5
+ pycinante/annotation.py
6
+ pycinante/validator.py
7
+ pycinante.egg-info/PKG-INFO
8
+ pycinante.egg-info/SOURCES.txt
9
+ pycinante.egg-info/dependency_links.txt
10
+ pycinante.egg-info/requires.txt
11
+ pycinante.egg-info/top_level.txt
12
+ pycinante.egg-info/zip-safe
@@ -0,0 +1 @@
1
+ numpy
@@ -0,0 +1 @@
1
+ pycinante
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,19 @@
1
+ from setuptools import setup, find_packages
2
+ import pycinante
3
+
4
+ requirements = [
5
+ 'numpy',
6
+ ]
7
+
8
+ setup(
9
+ name='pycinante',
10
+ version=pycinante.__version__,
11
+ python_requires='>=3.8',
12
+ author='Chisheng Chen',
13
+ author_email='chishengchen@126.com',
14
+ url='https://github.com/gndlwch2w/pycinante',
15
+ description='Python\'s Rocinante for easily programming.',
16
+ license='MIT-0',
17
+ packages=find_packages(),
18
+ zip_safe=True,
19
+ install_requires=requirements, )