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.
@@ -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(type):
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
- dct[attr_name] = mcs.wrap_with_logging(
55
- func=attr_value, class_name=name, call_times={}
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(self: object, *args: object, **kwargs: object) -> object:
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(self, *args, **kwargs)
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(type):
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
- dct: dict[str, Any],
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
- dct: The attribute dictionary
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, dct)
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.is_abstract_method(method) for method in cls.__dict__.values())
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
- return getattr(method, "__final__", False)
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, ABCMeta):
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:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: winipedia-utils
3
- Version: 0.1.12
3
+ Version: 0.1.14
4
4
  Summary: A package with many utility functions
5
5
  License: MIT
6
6
  Author: Winipedia
@@ -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=UpHags1j80OABxW4Q3QYt7A7lLIArvgUrGcWeYJaRyU,10576
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.12.dist-info/LICENSE,sha256=3PrKJ2CWNrnyyHaC_r0wPDSukVWgmjOxHr__eQVH7cw,1087
65
- winipedia_utils-0.1.12.dist-info/METADATA,sha256=u2sgf1gcfep7whVI1VvB9GMrkXyvX2rNl_FxzxIQ5Zs,12385
66
- winipedia_utils-0.1.12.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
67
- winipedia_utils-0.1.12.dist-info/RECORD,,
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,,