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.
- pycinante-0.0.1/LICENSE +21 -0
- pycinante-0.0.1/PKG-INFO +10 -0
- pycinante-0.0.1/README.md +2 -0
- pycinante-0.0.1/pycinante/__init__.py +3 -0
- pycinante-0.0.1/pycinante/annotation.py +124 -0
- pycinante-0.0.1/pycinante/validator.py +137 -0
- pycinante-0.0.1/pycinante.egg-info/PKG-INFO +10 -0
- pycinante-0.0.1/pycinante.egg-info/SOURCES.txt +12 -0
- pycinante-0.0.1/pycinante.egg-info/dependency_links.txt +1 -0
- pycinante-0.0.1/pycinante.egg-info/requires.txt +1 -0
- pycinante-0.0.1/pycinante.egg-info/top_level.txt +1 -0
- pycinante-0.0.1/pycinante.egg-info/zip-safe +1 -0
- pycinante-0.0.1/setup.cfg +4 -0
- pycinante-0.0.1/setup.py +19 -0
pycinante-0.0.1/LICENSE
ADDED
|
@@ -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.
|
pycinante-0.0.1/PKG-INFO
ADDED
|
@@ -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,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
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
numpy
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
pycinante
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
pycinante-0.0.1/setup.py
ADDED
|
@@ -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, )
|