python-argtools 0.0.1__py3-none-any.whl → 0.0.2__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 CHANGED
@@ -6,68 +6,67 @@ 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, 1)
10
- __all__ = ["argcount", "Args", "UpdativeArgs"]
9
+ __version__ = (0, 0, 2)
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 typing import Any, Callable, Generic, ParamSpec, TypeVar
16
+ from typing import cast, Any
16
17
 
17
18
 
18
- T = TypeVar("T")
19
- P = ParamSpec("P")
20
-
21
-
22
- def argcount(func: Callable) -> int:
19
+ def argcount(func: Callable, /) -> int:
20
+ if isinstance(func, partial):
21
+ return max(0, argcount(func.func) - len(func.args))
23
22
  try:
24
23
  return func.__code__.co_argcount
25
24
  except AttributeError:
26
25
  return len(getfullargspec(func).args)
27
26
 
28
27
 
29
- class Args(Generic[T, P]):
28
+ class Args:
30
29
  """Takes some positional arguments and keyword arguments,
31
30
  and put them into an instance, which can be used repeatedly
32
31
  every next time.
33
32
 
34
33
  Fields::
35
- self.pargs: the collected positional arguments
36
- self.kargs: the collected keyword arguments
34
+ self.args: the collected positional arguments
35
+ self.kwargs: the collected keyword arguments
37
36
  """
38
- __slots__ = ("pargs", "kargs")
37
+ __slots__ = ("args", "kwargs")
39
38
 
40
- def __init__(self, /, *pargs, **kargs):
41
- self.pargs: P.args = pargs
42
- self.kargs: P.kwargs = kargs
39
+ def __init__(self, /, *args, **kwargs):
40
+ self.args = args
41
+ self.kwargs = kwargs
43
42
 
44
- def __call__(self, /, func: Callable[..., T]) -> T:
43
+ def __call__[T](self, /, func: Callable[..., T]) -> T:
45
44
  """Pass in the collected positional arguments and keyword
46
45
  arguments when calling the callable `func`."""
47
- return func(*self.pargs, **self.kargs)
46
+ return func(*self.args, **self.kwargs)
48
47
 
49
48
  def __copy__(self, /):
50
- return type(self)(*self.pargs, **self.kargs)
49
+ return type(self)(*self.args, **self.kwargs)
51
50
 
52
51
  def __eq__(self, other):
53
52
  if isinstance(other, Args):
54
- return self.pargs == other.pargs and self.kargs == other.kargs
53
+ return self.args == other.args and self.kwargs == other.kwargs
55
54
  return False
56
55
 
57
56
  def __iter__(self, /):
58
- return iter((self.pargs, self.kargs))
57
+ return iter((self.args, self.kwargs))
59
58
 
60
59
  def __repr__(self):
61
60
  return "%s(%s)" % (
62
61
  type(self).__qualname__,
63
62
  ", ".join((
64
- *map(repr, self.pargs),
65
- *("%s=%r" % e for e in self.kargs.items()),
63
+ *map(repr, self.args),
64
+ *("%s=%r" % e for e in self.kwargs.items()),
66
65
  )),
67
66
  )
68
67
 
69
68
  @classmethod
70
- def call(cls, /, func: Callable[..., T], args: Any = ()) -> T:
69
+ def call[T](cls, /, func: Callable[..., T], args: Any = ()) -> T:
71
70
  """Call the callable `func` and pass in the arguments `args`.
72
71
 
73
72
  The actual behavior as below:
@@ -81,12 +80,13 @@ class Args(Generic[T, P]):
81
80
  """
82
81
  if isinstance(args, Args):
83
82
  return args(func)
84
- type_ = type(args)
85
- if type_ is tuple:
83
+ args_type = type(args)
84
+ if args_type == tuple:
86
85
  return func(*args)
87
- elif type_ is dict:
86
+ elif args_type == dict:
88
87
  return func(**args)
89
- return func(args)
88
+ else:
89
+ return func(args)
90
90
 
91
91
 
92
92
  class UpdativeArgs(Args):
@@ -97,12 +97,12 @@ class UpdativeArgs(Args):
97
97
  collected arguments.
98
98
 
99
99
  Fields::
100
- self.pargs: the collected positional arguments
101
- self.kargs: the collected keyword arguments
100
+ self.args: the collected positional arguments
101
+ self.kwargs: the collected keyword arguments
102
102
  """
103
- __slots__ = ("pargs", "kargs")
103
+ __slots__ = ("args", "kwargs")
104
104
 
105
- def extend(self, /, *pargs, **kargs):
105
+ def extend(self, /, *args, **kwargs):
106
106
  """Extend the collected arguments.
107
107
 
108
108
  Examples::
@@ -113,17 +113,17 @@ class UpdativeArgs(Args):
113
113
  >>> args is args2
114
114
  True
115
115
  """
116
- if pargs:
117
- self.pargs += pargs
118
- if kargs:
119
- kargs0 = self.kargs
120
- kargs0.update(
121
- (k, kargs[k])
122
- for k in kargs.keys() - kargs0.keys()
116
+ if args:
117
+ self.args += args
118
+ if kwargs:
119
+ kwargs0 = self.kwargs
120
+ kwargs0.update(
121
+ (k, kwargs[k])
122
+ for k in kwargs.keys() - kwargs0.keys()
123
123
  )
124
124
  return self
125
125
 
126
- def copy_extend(self, /, *pargs, **kargs):
126
+ def copy_extend(self, /, *args, **kwargs):
127
127
  """Extend the collected arguments in a copied instance.
128
128
 
129
129
  Examples::
@@ -134,9 +134,9 @@ class UpdativeArgs(Args):
134
134
  >>> args is args2
135
135
  False
136
136
  """
137
- return copy(self).extend(*pargs, **kargs)
137
+ return copy(self).extend(*args, **kwargs)
138
138
 
139
- def prepend(self, /, *pargs, **kargs):
139
+ def prepend(self, /, *args, **kwargs):
140
140
  """Prepend the collected arguments.
141
141
 
142
142
  Examples::
@@ -147,13 +147,13 @@ class UpdativeArgs(Args):
147
147
  >>> args is args2
148
148
  True
149
149
  """
150
- if pargs:
151
- self.pargs = pargs + self.pargs
152
- if kargs:
153
- self.kargs.update(kargs)
150
+ if args:
151
+ self.args = args + self.args
152
+ if kwargs:
153
+ self.kwargs.update(kwargs)
154
154
  return self
155
155
 
156
- def copy_prepend(self, /, *pargs, **kargs):
156
+ def copy_prepend(self, /, *args, **kwargs):
157
157
  """Prepend the collected arguments in a copied instance.
158
158
 
159
159
  Examples::
@@ -164,9 +164,9 @@ class UpdativeArgs(Args):
164
164
  >>> args is args2
165
165
  False
166
166
  """
167
- return copy(self).prepend(*pargs, **kargs)
167
+ return copy(self).prepend(*args, **kwargs)
168
168
 
169
- def update(self, /, *pargs, **kargs):
169
+ def update(self, /, *args, **kwargs):
170
170
  """Update the collected arguments.
171
171
 
172
172
  Examples::
@@ -180,17 +180,17 @@ class UpdativeArgs(Args):
180
180
  >>> args.update(7, 8, 10, 11, x=9, r=0)
181
181
  UpdativeArgs(7, 8, 10, 11, x=9, y=5, z=6, r=0)
182
182
  """
183
- if pargs:
184
- n = len(pargs) - len(self.pargs)
183
+ if args:
184
+ n = len(args) - len(self.args)
185
185
  if n >= 0:
186
- self.pargs = pargs
186
+ self.args = args
187
187
  else:
188
- self.pargs = pargs + self.pargs[n:]
189
- if kargs:
190
- self.kargs.update(kargs)
188
+ self.args = args + self.args[n:]
189
+ if kwargs:
190
+ self.kwargs.update(kwargs)
191
191
  return self
192
192
 
193
- def copy_update(self, /, *pargs, **kargs):
193
+ def copy_update(self, /, *args, **kwargs):
194
194
  """Update the collected arguments in a copied instance.
195
195
 
196
196
  Examples::
@@ -213,9 +213,9 @@ class UpdativeArgs(Args):
213
213
  >>> args2 == args3
214
214
  True
215
215
  """
216
- return copy(self).update(*pargs, **kargs)
216
+ return copy(self).update(*args, **kwargs)
217
217
 
218
- def update_extend(self, /, *pargs, **kargs):
218
+ def update_extend(self, /, *args, **kwargs):
219
219
  """Update and entend the collected arguments.
220
220
 
221
221
  Examples::
@@ -229,19 +229,19 @@ class UpdativeArgs(Args):
229
229
  >>> args.update_extend(7, 8, x=9, r=0)
230
230
  UpdativeArgs(1, 2, 3, x=4, y=5, z=6, r=0)
231
231
  """
232
- if pargs:
233
- n = len(self.pargs) - len(pargs)
232
+ if args:
233
+ n = len(self.args) - len(args)
234
234
  if n < 0:
235
- self.pargs += pargs[n:]
236
- if kargs:
237
- kargs0 = self.kargs
238
- kargs0.update(
239
- (k, kargs[k])
240
- for k in kargs.keys() - kargs0.keys()
235
+ self.args += args[n:]
236
+ if kwargs:
237
+ kwargs0 = self.kwargs
238
+ kwargs0.update(
239
+ (k, kwargs[k])
240
+ for k in kwargs.keys() - kwargs0.keys()
241
241
  )
242
242
  return self
243
243
 
244
- def copy_update_extend(self, /, *pargs, **kargs):
244
+ def copy_update_extend(self, /, *args, **kwargs):
245
245
  """Update and extend the collected arguments in
246
246
  a copied instance.
247
247
 
@@ -267,7 +267,37 @@ class UpdativeArgs(Args):
267
267
  >>> args2 == args3
268
268
  True
269
269
  """
270
- return copy(self).update_extend(*pargs, **kargs)
270
+ return copy(self).update_extend(*args, **kwargs)
271
+
272
+
273
+ class Call[**Params, R](partial):
274
+ """
275
+ """
276
+ def __new__(
277
+ cls,
278
+ func: Callable[Params, R],
279
+ /,
280
+ *args: Params.args,
281
+ **kwds: Params.kwargs,
282
+ ):
283
+ if hasattr(func, "func"):
284
+ args = cast(Params.args, getattr(func, "args", ()) + args)
285
+ kwargs: None | dict = None
286
+ try:
287
+ kwargs = getattr(func, "kwargs")
288
+ except AttributeError:
289
+ kwargs = getattr(func, "keywords", None)
290
+ if kwargs:
291
+ kwds = cast(Params.kwargs, {**kwargs, **kwds})
292
+ func = func.func
293
+ return update_wrapper(super().__new__(cls, func, *args, **kwds), func)
294
+
295
+ @property
296
+ def kwargs(self, /) -> Params.kwargs:
297
+ return self.keywords
298
+
299
+ def __call__(self, /) -> R:
300
+ return self.func(*self.args, **self.kwargs)
271
301
 
272
302
 
273
303
  if __name__ == "__main__":
@@ -1,22 +1,21 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: python-argtools
3
- Version: 0.0.1
3
+ Version: 0.0.2
4
4
  Summary: Python argument tools.
5
5
  Home-page: https://github.com/ChenyangGao/web-mount-packs/tree/main/python-module/python-argtools
6
6
  License: MIT
7
7
  Keywords: argument,tools
8
8
  Author: ChenyangGao
9
9
  Author-email: wosiwujm@gmail.com
10
- Requires-Python: >=3.10,<4.0
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
20
19
  Classifier: Programming Language :: Python :: 3 :: Only
21
20
  Classifier: Topic :: Software Development
22
21
  Classifier: Topic :: Software Development :: Libraries
@@ -0,0 +1,7 @@
1
+ LICENSE,sha256=o5242_N2TgDsWwFhPn7yr8YJNF7XsJM5NxUMtcT97bc,1100
2
+ argtools/__init__.py,sha256=VnzRDtsySC_7s0mh1jypHXclNG-bh_42xdICRmnDLaw,9498
3
+ argtools/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
+ python_argtools-0.0.2.dist-info/LICENSE,sha256=o5242_N2TgDsWwFhPn7yr8YJNF7XsJM5NxUMtcT97bc,1100
5
+ python_argtools-0.0.2.dist-info/METADATA,sha256=m36i3M9ThbvirkRV19D2rDu45N4Te9EmrXVPfbYRTQI,1275
6
+ python_argtools-0.0.2.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
7
+ python_argtools-0.0.2.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: poetry-core 1.8.1
2
+ Generator: poetry-core 1.9.1
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
@@ -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,,