python-argtools 0.0.1__py3-none-any.whl → 0.0.3__py3-none-any.whl
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.
- argtools/__init__.py +120 -69
- {python_argtools-0.0.1.dist-info → python_argtools-0.0.3.dist-info}/METADATA +9 -8
- python_argtools-0.0.3.dist-info/RECORD +6 -0
- {python_argtools-0.0.1.dist-info → python_argtools-0.0.3.dist-info}/WHEEL +1 -1
- python_argtools-0.0.1.dist-info/LICENSE +0 -21
- python_argtools-0.0.1.dist-info/RECORD +0 -7
- /LICENSE → /python_argtools-0.0.3.dist-info/licenses/LICENSE +0 -0
argtools/__init__.py
CHANGED
|
@@ -6,68 +6,88 @@ some arguments at one time and then use them repeatedly later.
|
|
|
6
6
|
"""
|
|
7
7
|
|
|
8
8
|
__author__ = "ChenyangGao <https://chenyanggao.github.io>"
|
|
9
|
-
__version__ = (0, 0,
|
|
10
|
-
__all__ = ["argcount", "Args", "UpdativeArgs"]
|
|
9
|
+
__version__ = (0, 0, 3)
|
|
10
|
+
__all__ = ["argcount", "Args", "UpdativeArgs", "Call"]
|
|
11
11
|
|
|
12
12
|
from collections.abc import Callable
|
|
13
13
|
from copy import copy
|
|
14
|
+
from functools import partial, update_wrapper
|
|
14
15
|
from inspect import getfullargspec
|
|
15
|
-
from
|
|
16
|
+
from types import MethodType, MethodWrapperType
|
|
17
|
+
from typing import Any
|
|
16
18
|
|
|
17
19
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
def argcount(func: Callable) -> int:
|
|
20
|
+
def argcount(func: Callable, /) -> int:
|
|
21
|
+
if isinstance(func, partial):
|
|
22
|
+
return max(0, argcount(func.func) - len(func.args))
|
|
23
|
+
is_method = isinstance(func, (MethodType, MethodWrapperType))
|
|
23
24
|
try:
|
|
24
|
-
return func.__code__.co_argcount
|
|
25
|
+
return func.__code__.co_argcount - is_method
|
|
25
26
|
except AttributeError:
|
|
26
|
-
return len(getfullargspec(func).args)
|
|
27
|
+
return len(getfullargspec(func).args) - is_method
|
|
27
28
|
|
|
28
29
|
|
|
29
|
-
class Args
|
|
30
|
+
class Args:
|
|
30
31
|
"""Takes some positional arguments and keyword arguments,
|
|
31
32
|
and put them into an instance, which can be used repeatedly
|
|
32
33
|
every next time.
|
|
33
34
|
|
|
34
35
|
Fields::
|
|
35
|
-
self.
|
|
36
|
-
self.
|
|
36
|
+
self.args: the collected positional arguments
|
|
37
|
+
self.kwargs: the collected keyword arguments
|
|
37
38
|
"""
|
|
38
|
-
__slots__ = ("
|
|
39
|
+
__slots__ = ("args", "kwargs")
|
|
39
40
|
|
|
40
|
-
def __init__(self, /, *
|
|
41
|
-
self.
|
|
42
|
-
self.
|
|
41
|
+
def __init__(self, /, *args, **kwargs):
|
|
42
|
+
self.args = args
|
|
43
|
+
self.kwargs = kwargs
|
|
43
44
|
|
|
44
|
-
def __call__(self, /, func: Callable[..., T]) -> T:
|
|
45
|
+
def __call__[T](self, /, func: Callable[..., T]) -> T:
|
|
45
46
|
"""Pass in the collected positional arguments and keyword
|
|
46
47
|
arguments when calling the callable `func`."""
|
|
47
|
-
return func(*self.
|
|
48
|
+
return func(*self.args, **self.kwargs)
|
|
48
49
|
|
|
49
50
|
def __copy__(self, /):
|
|
50
|
-
return type(self)(*self.
|
|
51
|
+
return type(self)(*self.args, **self.kwargs)
|
|
51
52
|
|
|
52
53
|
def __eq__(self, other):
|
|
53
54
|
if isinstance(other, Args):
|
|
54
|
-
return self.
|
|
55
|
+
return self.args == other.args and self.kwargs == other.kwargs
|
|
55
56
|
return False
|
|
56
57
|
|
|
58
|
+
def __getitem__(self, idx: int | slice | str | tuple[int | slice | str, ...], /):
|
|
59
|
+
cls = type(self)
|
|
60
|
+
pget = self.args.__getitem__
|
|
61
|
+
if isinstance(idx, (int, slice)):
|
|
62
|
+
return cls(pget(idx))
|
|
63
|
+
kget = self.kwargs.__getitem__
|
|
64
|
+
if isinstance(idx, str):
|
|
65
|
+
return cls(idx=kget(idx))
|
|
66
|
+
else:
|
|
67
|
+
pargs: list = []
|
|
68
|
+
kargs: dict = {}
|
|
69
|
+
add_parg = pargs.append
|
|
70
|
+
for idx_ in idx:
|
|
71
|
+
if isinstance(idx_, (int, slice)):
|
|
72
|
+
add_parg(pget(idx_))
|
|
73
|
+
else:
|
|
74
|
+
kargs[idx_] = kget(idx_)
|
|
75
|
+
return cls(*pargs, **kargs)
|
|
76
|
+
|
|
57
77
|
def __iter__(self, /):
|
|
58
|
-
return iter((self.
|
|
78
|
+
return iter((self.args, self.kwargs))
|
|
59
79
|
|
|
60
80
|
def __repr__(self):
|
|
61
81
|
return "%s(%s)" % (
|
|
62
82
|
type(self).__qualname__,
|
|
63
83
|
", ".join((
|
|
64
|
-
*map(repr, self.
|
|
65
|
-
*("%s=%r" % e for e in self.
|
|
84
|
+
*map(repr, self.args),
|
|
85
|
+
*("%s=%r" % e for e in self.kwargs.items()),
|
|
66
86
|
)),
|
|
67
87
|
)
|
|
68
88
|
|
|
69
89
|
@classmethod
|
|
70
|
-
def call(cls, /, func: Callable[..., T], args: Any = ()) -> T:
|
|
90
|
+
def call[T](cls, /, func: Callable[..., T], args: Any = ()) -> T:
|
|
71
91
|
"""Call the callable `func` and pass in the arguments `args`.
|
|
72
92
|
|
|
73
93
|
The actual behavior as below:
|
|
@@ -81,12 +101,13 @@ class Args(Generic[T, P]):
|
|
|
81
101
|
"""
|
|
82
102
|
if isinstance(args, Args):
|
|
83
103
|
return args(func)
|
|
84
|
-
|
|
85
|
-
if
|
|
104
|
+
args_type = type(args)
|
|
105
|
+
if args_type == tuple:
|
|
86
106
|
return func(*args)
|
|
87
|
-
elif
|
|
107
|
+
elif args_type == dict:
|
|
88
108
|
return func(**args)
|
|
89
|
-
|
|
109
|
+
else:
|
|
110
|
+
return func(args)
|
|
90
111
|
|
|
91
112
|
|
|
92
113
|
class UpdativeArgs(Args):
|
|
@@ -97,12 +118,12 @@ class UpdativeArgs(Args):
|
|
|
97
118
|
collected arguments.
|
|
98
119
|
|
|
99
120
|
Fields::
|
|
100
|
-
self.
|
|
101
|
-
self.
|
|
121
|
+
self.args: the collected positional arguments
|
|
122
|
+
self.kwargs: the collected keyword arguments
|
|
102
123
|
"""
|
|
103
|
-
__slots__ = ("
|
|
124
|
+
__slots__ = ("args", "kwargs")
|
|
104
125
|
|
|
105
|
-
def extend(self, /, *
|
|
126
|
+
def extend(self, /, *args, **kwargs):
|
|
106
127
|
"""Extend the collected arguments.
|
|
107
128
|
|
|
108
129
|
Examples::
|
|
@@ -113,17 +134,17 @@ class UpdativeArgs(Args):
|
|
|
113
134
|
>>> args is args2
|
|
114
135
|
True
|
|
115
136
|
"""
|
|
116
|
-
if
|
|
117
|
-
self.
|
|
118
|
-
if
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
(k,
|
|
122
|
-
for k in
|
|
137
|
+
if args:
|
|
138
|
+
self.args += args
|
|
139
|
+
if kwargs:
|
|
140
|
+
kwargs0 = self.kwargs
|
|
141
|
+
kwargs0.update(
|
|
142
|
+
(k, kwargs[k])
|
|
143
|
+
for k in kwargs.keys() - kwargs0.keys()
|
|
123
144
|
)
|
|
124
145
|
return self
|
|
125
146
|
|
|
126
|
-
def copy_extend(self, /, *
|
|
147
|
+
def copy_extend(self, /, *args, **kwargs):
|
|
127
148
|
"""Extend the collected arguments in a copied instance.
|
|
128
149
|
|
|
129
150
|
Examples::
|
|
@@ -134,9 +155,9 @@ class UpdativeArgs(Args):
|
|
|
134
155
|
>>> args is args2
|
|
135
156
|
False
|
|
136
157
|
"""
|
|
137
|
-
return copy(self).extend(*
|
|
158
|
+
return copy(self).extend(*args, **kwargs)
|
|
138
159
|
|
|
139
|
-
def prepend(self, /, *
|
|
160
|
+
def prepend(self, /, *args, **kwargs):
|
|
140
161
|
"""Prepend the collected arguments.
|
|
141
162
|
|
|
142
163
|
Examples::
|
|
@@ -147,13 +168,13 @@ class UpdativeArgs(Args):
|
|
|
147
168
|
>>> args is args2
|
|
148
169
|
True
|
|
149
170
|
"""
|
|
150
|
-
if
|
|
151
|
-
self.
|
|
152
|
-
if
|
|
153
|
-
self.
|
|
171
|
+
if args:
|
|
172
|
+
self.args = args + self.args
|
|
173
|
+
if kwargs:
|
|
174
|
+
self.kwargs.update(kwargs)
|
|
154
175
|
return self
|
|
155
176
|
|
|
156
|
-
def copy_prepend(self, /, *
|
|
177
|
+
def copy_prepend(self, /, *args, **kwargs):
|
|
157
178
|
"""Prepend the collected arguments in a copied instance.
|
|
158
179
|
|
|
159
180
|
Examples::
|
|
@@ -164,9 +185,9 @@ class UpdativeArgs(Args):
|
|
|
164
185
|
>>> args is args2
|
|
165
186
|
False
|
|
166
187
|
"""
|
|
167
|
-
return copy(self).prepend(*
|
|
188
|
+
return copy(self).prepend(*args, **kwargs)
|
|
168
189
|
|
|
169
|
-
def update(self, /, *
|
|
190
|
+
def update(self, /, *args, **kwargs):
|
|
170
191
|
"""Update the collected arguments.
|
|
171
192
|
|
|
172
193
|
Examples::
|
|
@@ -180,17 +201,17 @@ class UpdativeArgs(Args):
|
|
|
180
201
|
>>> args.update(7, 8, 10, 11, x=9, r=0)
|
|
181
202
|
UpdativeArgs(7, 8, 10, 11, x=9, y=5, z=6, r=0)
|
|
182
203
|
"""
|
|
183
|
-
if
|
|
184
|
-
n = len(
|
|
204
|
+
if args:
|
|
205
|
+
n = len(args) - len(self.args)
|
|
185
206
|
if n >= 0:
|
|
186
|
-
self.
|
|
207
|
+
self.args = args
|
|
187
208
|
else:
|
|
188
|
-
self.
|
|
189
|
-
if
|
|
190
|
-
self.
|
|
209
|
+
self.args = args + self.args[n:]
|
|
210
|
+
if kwargs:
|
|
211
|
+
self.kwargs.update(kwargs)
|
|
191
212
|
return self
|
|
192
213
|
|
|
193
|
-
def copy_update(self, /, *
|
|
214
|
+
def copy_update(self, /, *args, **kwargs):
|
|
194
215
|
"""Update the collected arguments in a copied instance.
|
|
195
216
|
|
|
196
217
|
Examples::
|
|
@@ -213,9 +234,9 @@ class UpdativeArgs(Args):
|
|
|
213
234
|
>>> args2 == args3
|
|
214
235
|
True
|
|
215
236
|
"""
|
|
216
|
-
return copy(self).update(*
|
|
237
|
+
return copy(self).update(*args, **kwargs)
|
|
217
238
|
|
|
218
|
-
def update_extend(self, /, *
|
|
239
|
+
def update_extend(self, /, *args, **kwargs):
|
|
219
240
|
"""Update and entend the collected arguments.
|
|
220
241
|
|
|
221
242
|
Examples::
|
|
@@ -229,19 +250,19 @@ class UpdativeArgs(Args):
|
|
|
229
250
|
>>> args.update_extend(7, 8, x=9, r=0)
|
|
230
251
|
UpdativeArgs(1, 2, 3, x=4, y=5, z=6, r=0)
|
|
231
252
|
"""
|
|
232
|
-
if
|
|
233
|
-
n = len(self.
|
|
253
|
+
if args:
|
|
254
|
+
n = len(self.args) - len(args)
|
|
234
255
|
if n < 0:
|
|
235
|
-
self.
|
|
236
|
-
if
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
(k,
|
|
240
|
-
for k in
|
|
256
|
+
self.args += args[n:]
|
|
257
|
+
if kwargs:
|
|
258
|
+
kwargs0 = self.kwargs
|
|
259
|
+
kwargs0.update(
|
|
260
|
+
(k, kwargs[k])
|
|
261
|
+
for k in kwargs.keys() - kwargs0.keys()
|
|
241
262
|
)
|
|
242
263
|
return self
|
|
243
264
|
|
|
244
|
-
def copy_update_extend(self, /, *
|
|
265
|
+
def copy_update_extend(self, /, *args, **kwargs):
|
|
245
266
|
"""Update and extend the collected arguments in
|
|
246
267
|
a copied instance.
|
|
247
268
|
|
|
@@ -267,7 +288,37 @@ class UpdativeArgs(Args):
|
|
|
267
288
|
>>> args2 == args3
|
|
268
289
|
True
|
|
269
290
|
"""
|
|
270
|
-
return copy(self).update_extend(*
|
|
291
|
+
return copy(self).update_extend(*args, **kwargs)
|
|
292
|
+
|
|
293
|
+
|
|
294
|
+
class Call[**Params, R](partial):
|
|
295
|
+
"""
|
|
296
|
+
"""
|
|
297
|
+
def __new__(
|
|
298
|
+
cls,
|
|
299
|
+
func: Callable[Params, R],
|
|
300
|
+
/,
|
|
301
|
+
*args: Params.args,
|
|
302
|
+
**kwds: Params.kwargs,
|
|
303
|
+
):
|
|
304
|
+
if hasattr(func, "func"):
|
|
305
|
+
args = getattr(func, "args", ()) + args # type: ignore
|
|
306
|
+
kwargs: None | dict = None
|
|
307
|
+
try:
|
|
308
|
+
kwargs = getattr(func, "kwargs")
|
|
309
|
+
except AttributeError:
|
|
310
|
+
kwargs = getattr(func, "keywords", None)
|
|
311
|
+
if kwargs:
|
|
312
|
+
kwds = {**kwargs, **kwds} # type: ignore
|
|
313
|
+
func = func.func
|
|
314
|
+
return update_wrapper(super().__new__(cls, func, *args, **kwds), func)
|
|
315
|
+
|
|
316
|
+
@property
|
|
317
|
+
def kwargs(self, /) -> dict:
|
|
318
|
+
return self.keywords
|
|
319
|
+
|
|
320
|
+
def __call__(self, /) -> R:
|
|
321
|
+
return self.func(*self.args, **self.kwargs)
|
|
271
322
|
|
|
272
323
|
|
|
273
324
|
if __name__ == "__main__":
|
|
@@ -1,27 +1,28 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: python-argtools
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.3
|
|
4
4
|
Summary: Python argument tools.
|
|
5
|
-
Home-page: https://github.com/ChenyangGao/web-mount-packs/tree/main/python-module/python-argtools
|
|
6
5
|
License: MIT
|
|
6
|
+
License-File: LICENSE
|
|
7
7
|
Keywords: argument,tools
|
|
8
8
|
Author: ChenyangGao
|
|
9
9
|
Author-email: wosiwujm@gmail.com
|
|
10
|
-
Requires-Python: >=3.
|
|
10
|
+
Requires-Python: >=3.12,<4.0
|
|
11
11
|
Classifier: Development Status :: 5 - Production/Stable
|
|
12
12
|
Classifier: Intended Audience :: Developers
|
|
13
13
|
Classifier: License :: OSI Approved :: MIT License
|
|
14
14
|
Classifier: Operating System :: OS Independent
|
|
15
15
|
Classifier: Programming Language :: Python
|
|
16
16
|
Classifier: Programming Language :: Python :: 3
|
|
17
|
-
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
-
Classifier: Programming Language :: Python :: 3.11
|
|
19
17
|
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
20
20
|
Classifier: Programming Language :: Python :: 3 :: Only
|
|
21
21
|
Classifier: Topic :: Software Development
|
|
22
22
|
Classifier: Topic :: Software Development :: Libraries
|
|
23
23
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
24
|
-
Project-URL:
|
|
24
|
+
Project-URL: Homepage, https://github.com/ChenyangGao/python-modules/tree/main/python-argtools
|
|
25
|
+
Project-URL: Repository, https://github.com/ChenyangGao/python-modules/tree/main/python-argtools
|
|
25
26
|
Description-Content-Type: text/markdown
|
|
26
27
|
|
|
27
28
|
# Python argument tools.
|
|
@@ -31,7 +32,7 @@ Description-Content-Type: text/markdown
|
|
|
31
32
|
You can install from [pypi](https://pypi.org/project/python-argtools/)
|
|
32
33
|
|
|
33
34
|
```console
|
|
34
|
-
pip install -U argtools
|
|
35
|
+
pip install -U python-argtools
|
|
35
36
|
```
|
|
36
37
|
|
|
37
38
|
## Usage
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
argtools/__init__.py,sha256=oArhrfmUaHGKFhWNb14tPHvSDasSAmqE6qRYVTYlaoo,10303
|
|
2
|
+
argtools/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
3
|
+
python_argtools-0.0.3.dist-info/METADATA,sha256=LTRTe-O69PSnxOyCw4O5LZVfel2qrZ2HQPAqHF1CmQw,1337
|
|
4
|
+
python_argtools-0.0.3.dist-info/WHEEL,sha256=EGEvSphFYqXKs23-kQBeyNoJP1nrT8ZJKQoi5p5DYL8,88
|
|
5
|
+
python_argtools-0.0.3.dist-info/licenses/LICENSE,sha256=o5242_N2TgDsWwFhPn7yr8YJNF7XsJM5NxUMtcT97bc,1100
|
|
6
|
+
python_argtools-0.0.3.dist-info/RECORD,,
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2024 ChenyangGao <https://github.com/ChenyangGao>
|
|
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.
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
LICENSE,sha256=o5242_N2TgDsWwFhPn7yr8YJNF7XsJM5NxUMtcT97bc,1100
|
|
2
|
-
argtools/__init__.py,sha256=t6sGhWh2ph0jYQausPJr-j8ALV59ketr2qOA2Gj0w8k,8519
|
|
3
|
-
argtools/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
|
-
python_argtools-0.0.1.dist-info/LICENSE,sha256=o5242_N2TgDsWwFhPn7yr8YJNF7XsJM5NxUMtcT97bc,1100
|
|
5
|
-
python_argtools-0.0.1.dist-info/METADATA,sha256=_VNtcqlH_kfeQ-0VipJlg2xPsVbUZOdk4z0lc8UssmQ,1326
|
|
6
|
-
python_argtools-0.0.1.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
|
|
7
|
-
python_argtools-0.0.1.dist-info/RECORD,,
|
|
File without changes
|