ddutils 0.2.1__tar.gz → 0.2.2__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ddutils
3
- Version: 0.2.1
3
+ Version: 0.2.2
4
4
  Summary: Domain Driven Utils Library
5
5
  Keywords: python,ddutils
6
6
  Author: davyddd
@@ -191,6 +191,31 @@ get_origin_class_of_method(C, 'method') # <class 'C'>
191
191
  get_origin_class_of_method(B, 'method') # <class 'A'>
192
192
  ```
193
193
 
194
+ ### get_generic_base_argument
195
+
196
+ Returns the type argument a class bound to a generic base when subclassing it. `None` when the base was not
197
+ subscripted, the `TypeVar` itself when the subclass is still generic.
198
+
199
+ ```python
200
+ from typing import Generic, TypeVar
201
+
202
+ from ddutils.class_helpers import get_generic_base_argument
203
+
204
+ T = TypeVar('T')
205
+
206
+
207
+ class Repository(Generic[T]):
208
+ pass
209
+
210
+
211
+ class UserRepository(Repository[User]):
212
+ pass
213
+
214
+
215
+ get_generic_base_argument(UserRepository, Repository) # <class 'User'>
216
+ get_generic_base_argument(Repository, Repository) # None
217
+ ```
218
+
194
219
  ## Function Helpers
195
220
 
196
221
  Tools for creating and modifying Python functions at runtime.
@@ -173,6 +173,31 @@ get_origin_class_of_method(C, 'method') # <class 'C'>
173
173
  get_origin_class_of_method(B, 'method') # <class 'A'>
174
174
  ```
175
175
 
176
+ ### get_generic_base_argument
177
+
178
+ Returns the type argument a class bound to a generic base when subclassing it. `None` when the base was not
179
+ subscripted, the `TypeVar` itself when the subclass is still generic.
180
+
181
+ ```python
182
+ from typing import Generic, TypeVar
183
+
184
+ from ddutils.class_helpers import get_generic_base_argument
185
+
186
+ T = TypeVar('T')
187
+
188
+
189
+ class Repository(Generic[T]):
190
+ pass
191
+
192
+
193
+ class UserRepository(Repository[User]):
194
+ pass
195
+
196
+
197
+ get_generic_base_argument(UserRepository, Repository) # <class 'User'>
198
+ get_generic_base_argument(Repository, Repository) # None
199
+ ```
200
+
176
201
  ## Function Helpers
177
202
 
178
203
  Tools for creating and modifying Python functions at runtime.
@@ -1,6 +1,6 @@
1
1
  import inspect
2
2
  from collections.abc import Callable
3
- from typing import Any, TypeVar
3
+ from typing import Any, TypeVar, get_args, get_origin
4
4
 
5
5
  _T = TypeVar('_T', bound=Any)
6
6
 
@@ -25,6 +25,26 @@ def get_origin_class_of_method(cls: Any, method_name: str) -> type | None:
25
25
  return None
26
26
 
27
27
 
28
+ def get_generic_base_argument(cls: type, generic_base: type, position: int = 0) -> Any | None:
29
+ """
30
+ Return the type argument that `cls` bound to `generic_base` when subclassing it.
31
+
32
+ For `class ProfileCache(GenericCache[Profile])` this is `Profile`. Returns `None` when `cls` does not
33
+ subscript `generic_base` (`class Cache(GenericCache)`), and a `TypeVar` when the subclass is still
34
+ generic (`class Base[T](GenericCache[T])`), so callers can reject both cases in `__init_subclass__`.
35
+
36
+ Args:
37
+ cls: The class to inspect.
38
+ generic_base: The generic base class whose argument to look up.
39
+ position: Index of the argument for bases with several type parameters.
40
+ """
41
+ for base in getattr(cls, '__orig_bases__', ()):
42
+ if get_origin(base) is generic_base:
43
+ arguments = get_args(base)
44
+ return arguments[position] if position < len(arguments) else None
45
+ return None
46
+
47
+
28
48
  class classproperty: # noqa: N801
29
49
  """
30
50
  A descriptor that defines a read-only property at the class level.
@@ -1,7 +1,7 @@
1
1
  [project]
2
2
  name = "ddutils"
3
3
  description = "Domain Driven Utils Library"
4
- version = "0.2.1"
4
+ version = "0.2.2"
5
5
  license = "MIT"
6
6
  license-files = ["LICENSE"]
7
7
  readme = "README.md"
@@ -1,7 +1,7 @@
1
1
  [project]
2
2
  name = "ddutils"
3
3
  description = "Domain Driven Utils Library"
4
- version = "0.2.1"
4
+ version = "0.2.2"
5
5
  authors = [{ name = "davyddd" }]
6
6
  license = "MIT"
7
7
  license-files = ["LICENSE"]
File without changes
File without changes
File without changes
File without changes