winipedia-utils 0.1.12__py3-none-any.whl → 0.1.14__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.
- winipedia_utils/oop/mixins/meta.py +30 -14
- {winipedia_utils-0.1.12.dist-info → winipedia_utils-0.1.14.dist-info}/METADATA +1 -1
- {winipedia_utils-0.1.12.dist-info → winipedia_utils-0.1.14.dist-info}/RECORD +5 -5
- {winipedia_utils-0.1.12.dist-info → winipedia_utils-0.1.14.dist-info}/LICENSE +0 -0
- {winipedia_utils-0.1.12.dist-info → winipedia_utils-0.1.14.dist-info}/WHEEL +0 -0
@@ -15,13 +15,13 @@ from typing import Any, final
|
|
15
15
|
|
16
16
|
from winipedia_utils.logging.logger import get_logger
|
17
17
|
from winipedia_utils.modules.class_ import get_all_methods_from_cls
|
18
|
-
from winipedia_utils.modules.function import is_func
|
18
|
+
from winipedia_utils.modules.function import is_func, unwrap_method
|
19
19
|
from winipedia_utils.text.string import value_to_truncated_string
|
20
20
|
|
21
21
|
logger = get_logger(__name__)
|
22
22
|
|
23
23
|
|
24
|
-
class LoggingMeta(
|
24
|
+
class LoggingMeta(ABCMeta):
|
25
25
|
"""Metaclass that automatically adds logging to class methods.
|
26
26
|
|
27
27
|
Wraps non-magic methods with a logging decorator that tracks method calls,
|
@@ -51,9 +51,20 @@ class LoggingMeta(type):
|
|
51
51
|
|
52
52
|
for attr_name, attr_value in dct.items():
|
53
53
|
if mcs.is_loggable_method(attr_value):
|
54
|
-
|
55
|
-
|
56
|
-
|
54
|
+
if isinstance(attr_value, classmethod):
|
55
|
+
wrapped_method = mcs.wrap_with_logging(
|
56
|
+
func=attr_value.__func__, class_name=name, call_times={}
|
57
|
+
)
|
58
|
+
dct[attr_name] = classmethod(wrapped_method)
|
59
|
+
elif isinstance(attr_value, staticmethod):
|
60
|
+
wrapped_method = mcs.wrap_with_logging(
|
61
|
+
func=attr_value.__func__, class_name=name, call_times={}
|
62
|
+
)
|
63
|
+
dct[attr_name] = staticmethod(wrapped_method)
|
64
|
+
else:
|
65
|
+
dct[attr_name] = mcs.wrap_with_logging(
|
66
|
+
func=attr_value, class_name=name, call_times={}
|
67
|
+
)
|
57
68
|
|
58
69
|
return super().__new__(mcs, name, bases, dct)
|
59
70
|
|
@@ -96,7 +107,7 @@ class LoggingMeta(type):
|
|
96
107
|
time_time = time.time # Cache the time.time function for performance
|
97
108
|
|
98
109
|
@wraps(func)
|
99
|
-
def wrapper(
|
110
|
+
def wrapper(*args: object, **kwargs: object) -> object:
|
100
111
|
# call_times as a dictionary to store the call times of the function
|
101
112
|
# we only log if the time since the last call is greater than the threshold
|
102
113
|
# this is to avoid spamming the logs
|
@@ -132,7 +143,7 @@ class LoggingMeta(type):
|
|
132
143
|
|
133
144
|
# Execute the function and return the result
|
134
145
|
|
135
|
-
result = func(
|
146
|
+
result = func(*args, **kwargs)
|
136
147
|
|
137
148
|
if do_logging:
|
138
149
|
duration = time_time() - current_time
|
@@ -158,7 +169,7 @@ class LoggingMeta(type):
|
|
158
169
|
return wrapper
|
159
170
|
|
160
171
|
|
161
|
-
class ImplementationMeta(
|
172
|
+
class ImplementationMeta(ABCMeta):
|
162
173
|
"""Metaclass that enforces implementation.
|
163
174
|
|
164
175
|
Ensures that concrete subclasses properly implement all required attributes
|
@@ -171,7 +182,9 @@ class ImplementationMeta(type):
|
|
171
182
|
cls: "ImplementationMeta",
|
172
183
|
name: str,
|
173
184
|
bases: tuple[type, ...],
|
174
|
-
|
185
|
+
namespace: dict[str, Any],
|
186
|
+
/,
|
187
|
+
**_kwargs: Any,
|
175
188
|
) -> None:
|
176
189
|
"""Initialize a class with implementation checking.
|
177
190
|
|
@@ -183,7 +196,7 @@ class ImplementationMeta(type):
|
|
183
196
|
cls: The class being initialized
|
184
197
|
name: The name of the class
|
185
198
|
bases: The base classes
|
186
|
-
|
199
|
+
namespace: The attribute dictionary
|
187
200
|
|
188
201
|
Raises:
|
189
202
|
NotImplementedError: If the class doesn't define __abstract__
|
@@ -192,7 +205,7 @@ class ImplementationMeta(type):
|
|
192
205
|
TypeError: If a method is neither final nor abstract
|
193
206
|
|
194
207
|
"""
|
195
|
-
super().__init__(name, bases,
|
208
|
+
super().__init__(name, bases, namespace)
|
196
209
|
|
197
210
|
# Check method decorators regardless of abstract status
|
198
211
|
|
@@ -212,7 +225,7 @@ class ImplementationMeta(type):
|
|
212
225
|
True if the class is abstract, False otherwise
|
213
226
|
|
214
227
|
"""
|
215
|
-
return any(cls.
|
228
|
+
return any(cls.__abstractmethods__)
|
216
229
|
|
217
230
|
def check_method_decorators(cls) -> None:
|
218
231
|
"""Check that all methods are properly decorated with @final or @abstractmethod.
|
@@ -249,7 +262,10 @@ class ImplementationMeta(type):
|
|
249
262
|
True if the method is marked with @final, False otherwise
|
250
263
|
|
251
264
|
"""
|
252
|
-
|
265
|
+
unwrapped_method = unwrap_method(method)
|
266
|
+
return getattr(method, "__final__", False) or getattr(
|
267
|
+
unwrapped_method, "__final__", False
|
268
|
+
)
|
253
269
|
|
254
270
|
@staticmethod
|
255
271
|
def is_abstract_method(method: Callable[..., Any]) -> bool:
|
@@ -303,7 +319,7 @@ class ImplementationMeta(type):
|
|
303
319
|
return list(attrs)
|
304
320
|
|
305
321
|
|
306
|
-
class ABCImplementationLoggingMeta(ImplementationMeta, LoggingMeta
|
322
|
+
class ABCImplementationLoggingMeta(ImplementationMeta, LoggingMeta):
|
307
323
|
"""Combined metaclass that merges implementation, logging, and ABC functionality.
|
308
324
|
|
309
325
|
This metaclass combines the features of:
|
@@ -30,7 +30,7 @@ winipedia_utils/modules/module.py,sha256=mxaAsRl02CAq_bTW2HsmzRWoyC9jKNM8Q4xdgdQ
|
|
30
30
|
winipedia_utils/modules/package.py,sha256=kCm4pXQdllafo-2dmWZTvaAqRruzh3iF4hseHlCmTlU,12605
|
31
31
|
winipedia_utils/oop/__init__.py,sha256=wGjsVwLbTVEQWOfDJvN9nlvC-3NmAi8Doc2xIrm6e78,47
|
32
32
|
winipedia_utils/oop/mixins/__init__.py,sha256=PDK-cJcdRUfDUCz36qQ5pmMW07G133WtN49OpmILGNI,54
|
33
|
-
winipedia_utils/oop/mixins/meta.py,sha256=
|
33
|
+
winipedia_utils/oop/mixins/meta.py,sha256=gV2YKo_rbJHY9xNCPHhjMmFWuTtiw3C-IGZlh52IZq8,11320
|
34
34
|
winipedia_utils/oop/mixins/mixin.py,sha256=GuYdeueiOIHoRi9ds2ztxUcLnrcsBhHAsbrO43N9AGg,1170
|
35
35
|
winipedia_utils/os/__init__.py,sha256=WSLt7tb6HqWRlCGGIEwRfVksF0sLJNeEW3iZeJhGWk0,47
|
36
36
|
winipedia_utils/os/os.py,sha256=ITuiLLfjGBV2jH8tHQfwVzsICT-jY1zUxtwu3ASJBG4,1690
|
@@ -61,7 +61,7 @@ winipedia_utils/testing/tests/base/utils/utils.py,sha256=dUPDrgAxlfREQb33zz23Mfz
|
|
61
61
|
winipedia_utils/testing/tests/conftest.py,sha256=8RounBlI8Jq1aLaLNpv84MW4ne8Qq0aavQextDOp5ng,920
|
62
62
|
winipedia_utils/text/__init__.py,sha256=j2bwtK6kyeHI6SnoBjpRju0C1W2n2paXBDlNjNtaUxA,48
|
63
63
|
winipedia_utils/text/string.py,sha256=1jbBftlgxffGgSlPnQh3aRPIr8XekEwpSenjFCW6JyM,3478
|
64
|
-
winipedia_utils-0.1.
|
65
|
-
winipedia_utils-0.1.
|
66
|
-
winipedia_utils-0.1.
|
67
|
-
winipedia_utils-0.1.
|
64
|
+
winipedia_utils-0.1.14.dist-info/LICENSE,sha256=3PrKJ2CWNrnyyHaC_r0wPDSukVWgmjOxHr__eQVH7cw,1087
|
65
|
+
winipedia_utils-0.1.14.dist-info/METADATA,sha256=F5AnrujDCkrWAfddP9zJ3Gn8uK1JnvDLQwYdow6d0bA,12385
|
66
|
+
winipedia_utils-0.1.14.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
67
|
+
winipedia_utils-0.1.14.dist-info/RECORD,,
|
File without changes
|
File without changes
|