aspyx 1.5.2__tar.gz → 1.5.3__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.
Files changed (39) hide show
  1. {aspyx-1.5.2 → aspyx-1.5.3}/PKG-INFO +1 -1
  2. {aspyx-1.5.2 → aspyx-1.5.3}/pyproject.toml +1 -1
  3. {aspyx-1.5.2 → aspyx-1.5.3}/src/aspyx/di/aop/aop.py +13 -13
  4. {aspyx-1.5.2 → aspyx-1.5.3}/src/aspyx/exception/exception_manager.py +1 -1
  5. {aspyx-1.5.2 → aspyx-1.5.3}/src/aspyx/threading/__init__.py +2 -0
  6. aspyx-1.5.3/src/aspyx/threading/context_local.py +48 -0
  7. {aspyx-1.5.2 → aspyx-1.5.3}/src/aspyx/util/__init__.py +2 -0
  8. aspyx-1.5.3/src/aspyx/util/logger.py +15 -0
  9. {aspyx-1.5.2 → aspyx-1.5.3}/tests/test_decorator.py +1 -1
  10. {aspyx-1.5.2 → aspyx-1.5.3}/tests/test_di.py +0 -1
  11. {aspyx-1.5.2 → aspyx-1.5.3}/.gitignore +0 -0
  12. {aspyx-1.5.2 → aspyx-1.5.3}/LICENSE +0 -0
  13. {aspyx-1.5.2 → aspyx-1.5.3}/README.md +0 -0
  14. {aspyx-1.5.2 → aspyx-1.5.3}/src/aspyx/__init__.py +0 -0
  15. {aspyx-1.5.2 → aspyx-1.5.3}/src/aspyx/di/__init__.py +0 -0
  16. {aspyx-1.5.2 → aspyx-1.5.3}/src/aspyx/di/aop/__init__.py +0 -0
  17. {aspyx-1.5.2 → aspyx-1.5.3}/src/aspyx/di/configuration/__init__.py +0 -0
  18. {aspyx-1.5.2 → aspyx-1.5.3}/src/aspyx/di/configuration/configuration.py +0 -0
  19. {aspyx-1.5.2 → aspyx-1.5.3}/src/aspyx/di/configuration/env_configuration_source.py +0 -0
  20. {aspyx-1.5.2 → aspyx-1.5.3}/src/aspyx/di/configuration/yaml_configuration_source.py +0 -0
  21. {aspyx-1.5.2 → aspyx-1.5.3}/src/aspyx/di/di.py +0 -0
  22. {aspyx-1.5.2 → aspyx-1.5.3}/src/aspyx/di/threading/__init__.py +0 -0
  23. {aspyx-1.5.2 → aspyx-1.5.3}/src/aspyx/di/threading/synchronized.py +0 -0
  24. {aspyx-1.5.2 → aspyx-1.5.3}/src/aspyx/exception/__init__.py +0 -0
  25. {aspyx-1.5.2 → aspyx-1.5.3}/src/aspyx/reflection/__init__.py +0 -0
  26. {aspyx-1.5.2 → aspyx-1.5.3}/src/aspyx/reflection/proxy.py +0 -0
  27. {aspyx-1.5.2 → aspyx-1.5.3}/src/aspyx/reflection/reflection.py +0 -0
  28. {aspyx-1.5.2 → aspyx-1.5.3}/src/aspyx/threading/thread_local.py +0 -0
  29. {aspyx-1.5.2 → aspyx-1.5.3}/src/aspyx/util/stringbuilder.py +0 -0
  30. {aspyx-1.5.2 → aspyx-1.5.3}/tests/config.yaml +0 -0
  31. {aspyx-1.5.2 → aspyx-1.5.3}/tests/config1.yaml +0 -0
  32. {aspyx-1.5.2 → aspyx-1.5.3}/tests/di_import.py +0 -0
  33. {aspyx-1.5.2 → aspyx-1.5.3}/tests/sub_import.py +0 -0
  34. {aspyx-1.5.2 → aspyx-1.5.3}/tests/test_aop.py +0 -0
  35. {aspyx-1.5.2 → aspyx-1.5.3}/tests/test_configuration.py +0 -0
  36. {aspyx-1.5.2 → aspyx-1.5.3}/tests/test_cycle.py +0 -0
  37. {aspyx-1.5.2 → aspyx-1.5.3}/tests/test_exception_manager.py +0 -0
  38. {aspyx-1.5.2 → aspyx-1.5.3}/tests/test_proxy.py +0 -0
  39. {aspyx-1.5.2 → aspyx-1.5.3}/tests/test_reflection.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: aspyx
3
- Version: 1.5.2
3
+ Version: 1.5.3
4
4
  Summary: A DI and AOP library for Python
5
5
  Author-email: Andreas Ernst <andreas.ernst7@gmail.com>
6
6
  License: MIT License
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "aspyx"
3
- version = "1.5.2"
3
+ version = "1.5.3"
4
4
  description = "A DI and AOP library for Python"
5
5
  authors = [{ name = "Andreas Ernst", email = "andreas.ernst7@gmail.com" }]
6
6
  readme = "README.md"
@@ -14,7 +14,7 @@ from enum import auto, Enum
14
14
  from typing import Optional, Dict, Type, Callable
15
15
 
16
16
  from aspyx.reflection import Decorators, TypeDescriptor
17
- from aspyx.di import injectable, order, Providers, ClassInstanceProvider, Environment, PostProcessor
17
+ from aspyx.di import injectable, order, Environment, PostProcessor
18
18
 
19
19
  class AOPException(Exception):
20
20
  """
@@ -197,25 +197,25 @@ class ClassAspectTarget(AspectTarget):
197
197
  #descriptor = TypeDescriptor.for_type(func)
198
198
  # type
199
199
 
200
- if len(self.types) > 0:
200
+ if self.types:
201
201
  if next((type for type in self.types if issubclass(clazz, type)), None) is None:
202
202
  return False
203
203
 
204
204
  # decorators
205
205
 
206
- if len(self.decorators) > 0:
206
+ if self.decorators:
207
207
  if next((decorator for decorator in self.decorators if class_descriptor.has_decorator(decorator)), None) is None:
208
208
  return False
209
209
 
210
210
  # names
211
211
 
212
- if len(self.names) > 0:
212
+ if self.names:
213
213
  if next((name for name in self.names if name == clazz.__name__), None) is None:
214
214
  return False
215
215
 
216
216
  # patterns
217
217
 
218
- if len(self.patterns) > 0:
218
+ if self.patterns:
219
219
  if next((pattern for pattern in self.patterns if re.fullmatch(pattern, clazz.__name__) is not None), None) is None:
220
220
  return False
221
221
 
@@ -245,7 +245,7 @@ class MethodAspectTarget(AspectTarget):
245
245
 
246
246
  # classes
247
247
 
248
- if len(self.belonging_to) > 0:
248
+ if self.belonging_to:
249
249
  match = False
250
250
  for classes in self.belonging_to:
251
251
  if classes._matches(clazz, func):
@@ -262,25 +262,25 @@ class MethodAspectTarget(AspectTarget):
262
262
 
263
263
  # type
264
264
 
265
- if len(self.types) > 0:
265
+ if self.types:
266
266
  if next((type for type in self.types if issubclass(clazz, type)), None) is None:
267
267
  return False
268
268
 
269
269
  # decorators
270
270
 
271
- if len(self.decorators) > 0:
271
+ if self.decorators:
272
272
  if next((decorator for decorator in self.decorators if method_descriptor.has_decorator(decorator)), None) is None:
273
273
  return False
274
274
 
275
275
  # names
276
276
 
277
- if len(self.names) > 0:
277
+ if self.names:
278
278
  if next((name for name in self.names if name == func.__name__), None) is None:
279
279
  return False
280
280
 
281
281
  # patterns
282
282
 
283
- if len(self.patterns) > 0:
283
+ if self.patterns:
284
284
  if next((pattern for pattern in self.patterns if re.fullmatch(pattern, func.__name__) is not None), None) is None:
285
285
  return False
286
286
 
@@ -474,7 +474,7 @@ class Invocation:
474
474
  """
475
475
  Proceed to the next aspect in the around chain up to the original method.
476
476
  """
477
- if len(args) > 0 or len(kwargs) > 0: # as soon as we have args, we replace the current ones
477
+ if args or kwargs: # as soon as we have args, we replace the current ones
478
478
  self.args = args
479
479
  self.kwargs = kwargs
480
480
 
@@ -486,7 +486,7 @@ class Invocation:
486
486
  """
487
487
  Proceed to the next aspect in the around chain up to the original method.
488
488
  """
489
- if len(args) > 0 or len(kwargs) > 0: # as soon as we have args, we replace the current ones
489
+ if args or kwargs: # as soon as we have args, we replace the current ones
490
490
  self.args = args
491
491
  self.kwargs = kwargs
492
492
 
@@ -575,7 +575,7 @@ class Advices:
575
575
  afters = cls.collect(clazz, member, AspectType.AFTER, environment)
576
576
  errors = cls.collect(clazz, member, AspectType.ERROR, environment)
577
577
 
578
- if len(befores) > 0 or len(arounds) > 0 or len(afters) > 0 or len(errors) > 0:
578
+ if befores or arounds or afters or errors:
579
579
  return Aspects(
580
580
  before=befores,
581
581
  around=arounds,
@@ -160,7 +160,7 @@ class ExceptionManager:
160
160
  for i in range(0, len(chain) - 1):
161
161
  chain[i].next = chain[i + 1]
162
162
 
163
- if len(chain) > 0:
163
+ if chain:
164
164
  return chain[0]
165
165
  else:
166
166
  return None
@@ -2,9 +2,11 @@
2
2
  A module with threading related utilities
3
3
  """
4
4
  from .thread_local import ThreadLocal
5
+ from .context_local import ContextLocal
5
6
 
6
7
  imports = [ThreadLocal]
7
8
 
8
9
  __all__ = [
9
10
  "ThreadLocal",
11
+ "ContextLocal",
10
12
  ]
@@ -0,0 +1,48 @@
1
+ import contextvars
2
+ from contextlib import contextmanager
3
+ from typing import Generic, Optional, TypeVar, Any
4
+
5
+ T = TypeVar("T")
6
+
7
+ class ContextLocal(Generic[T]):
8
+ """
9
+ A context local value holder
10
+ """
11
+ # constructor
12
+
13
+ def __init__(self, name: str, default: Optional[T] = None):
14
+ self.var = contextvars.ContextVar(name, default=default)
15
+
16
+ # public
17
+
18
+ def get(self) -> Optional[T]:
19
+ """
20
+ return the current value or invoke the optional factory to compute one
21
+
22
+ Returns:
23
+ Optional[T]: the value associated with the current thread
24
+ """
25
+ return self.var.get()
26
+
27
+ def set(self, value: Optional[T]) -> Any:
28
+ """
29
+ set a value in the current thread
30
+
31
+ Args:
32
+ value: the value
33
+ """
34
+ return self.var.set(value)
35
+
36
+ def reset(self, token) -> None:
37
+ """
38
+ clear the value in the current thread
39
+ """
40
+ self.var.reset(token)
41
+
42
+ @contextmanager
43
+ def use(self, value):
44
+ token = self.set(value)
45
+ try:
46
+ yield
47
+ finally:
48
+ self.reset(token)
@@ -2,7 +2,9 @@
2
2
  This module provides utility functions.
3
3
  """
4
4
  from .stringbuilder import StringBuilder
5
+ from .logger import Logger
5
6
 
6
7
  __all__ = [
7
8
  "StringBuilder",
9
+ "Logger"
8
10
  ]
@@ -0,0 +1,15 @@
1
+ import logging
2
+ from typing import Optional, Dict
3
+
4
+ class Logger:
5
+ """just syntactic sugar"""
6
+
7
+ @classmethod
8
+ def configure(cls,
9
+ default_level: int = logging.INFO,
10
+ format: str = "[%(asctime)s] %(levelname)s in %(filename)s:%(lineno)d - %(message)s",
11
+ levels: Optional[Dict[str, int]] = None):
12
+ logging.basicConfig(level=default_level, format=format)
13
+ if levels is not None:
14
+ for name, level in levels.items():
15
+ logging.getLogger(name).setLevel(level)
@@ -5,7 +5,7 @@ from __future__ import annotations
5
5
 
6
6
  import unittest
7
7
 
8
- from aspyx.reflection import TypeDescriptor, Decorators
8
+ from aspyx.reflection import Decorators
9
9
 
10
10
  def decorate_1(arg=""):
11
11
  def decorator(cls_or_func):
@@ -262,7 +262,6 @@ class TestDI(unittest.TestCase):
262
262
  no_feature_environment = prod_environment.get(RequiresBase)
263
263
  self.fail("should not return conditional class")
264
264
  except Exception as e:
265
- print(e)
266
265
  pass
267
266
 
268
267
  def test_process_factory_instances(self):
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes