aspyx 1.0.1__tar.gz → 1.1.0__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.
Potentially problematic release.
This version of aspyx might be problematic. Click here for more details.
- {aspyx-1.0.1/src/aspyx.egg-info → aspyx-1.1.0}/PKG-INFO +46 -19
- {aspyx-1.0.1 → aspyx-1.1.0}/README.md +45 -18
- {aspyx-1.0.1 → aspyx-1.1.0}/pyproject.toml +1 -1
- {aspyx-1.0.1 → aspyx-1.1.0}/src/aspyx/di/__init__.py +5 -4
- {aspyx-1.0.1 → aspyx-1.1.0}/src/aspyx/di/configuration/configuration.py +3 -3
- {aspyx-1.0.1 → aspyx-1.1.0}/src/aspyx/di/di.py +191 -67
- aspyx-1.1.0/src/aspyx/di/util/__init__.py +8 -0
- aspyx-1.1.0/src/aspyx/di/util/stringbuilder.py +31 -0
- {aspyx-1.0.1 → aspyx-1.1.0}/src/aspyx/reflection/reflection.py +11 -6
- {aspyx-1.0.1 → aspyx-1.1.0/src/aspyx.egg-info}/PKG-INFO +46 -19
- {aspyx-1.0.1 → aspyx-1.1.0}/src/aspyx.egg-info/SOURCES.txt +2 -0
- {aspyx-1.0.1 → aspyx-1.1.0}/tests/test_aop.py +14 -12
- {aspyx-1.0.1 → aspyx-1.1.0}/tests/test_configuration.py +7 -5
- {aspyx-1.0.1 → aspyx-1.1.0}/tests/test_di.py +42 -28
- {aspyx-1.0.1 → aspyx-1.1.0}/tests/test_di_cycle.py +7 -5
- {aspyx-1.0.1 → aspyx-1.1.0}/tests/test_proxy.py +4 -1
- {aspyx-1.0.1 → aspyx-1.1.0}/tests/test_reflection.py +10 -14
- {aspyx-1.0.1 → aspyx-1.1.0}/LICENSE +0 -0
- {aspyx-1.0.1 → aspyx-1.1.0}/setup.cfg +0 -0
- {aspyx-1.0.1 → aspyx-1.1.0}/src/aspyx/di/aop/__init__.py +0 -0
- {aspyx-1.0.1 → aspyx-1.1.0}/src/aspyx/di/aop/aop.py +0 -0
- {aspyx-1.0.1 → aspyx-1.1.0}/src/aspyx/di/configuration/__init__.py +0 -0
- {aspyx-1.0.1 → aspyx-1.1.0}/src/aspyx/reflection/__init__.py +0 -0
- {aspyx-1.0.1 → aspyx-1.1.0}/src/aspyx/reflection/proxy.py +0 -0
- {aspyx-1.0.1 → aspyx-1.1.0}/src/aspyx.egg-info/dependency_links.txt +0 -0
- {aspyx-1.0.1 → aspyx-1.1.0}/src/aspyx.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: aspyx
|
|
3
|
-
Version: 1.0
|
|
3
|
+
Version: 1.1.0
|
|
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
|
|
@@ -34,8 +34,9 @@ Dynamic: license-file
|
|
|
34
34
|
|
|
35
35
|

|
|
36
36
|

|
|
37
|
-

|
|
38
38
|

|
|
39
|
+

|
|
39
40
|
|
|
40
41
|
## Table of Contents
|
|
41
42
|
|
|
@@ -56,18 +57,18 @@ Dynamic: license-file
|
|
|
56
57
|
- [AOP](#aop)
|
|
57
58
|
- [Configuration](#configuration)
|
|
58
59
|
- [Reflection](#reflection)
|
|
60
|
+
- [Version History](#version-history)
|
|
59
61
|
|
|
60
62
|
# Introduction
|
|
61
63
|
|
|
62
64
|
Aspyx is a small python libary, that adds support for both dependency injection and aop.
|
|
63
65
|
|
|
64
66
|
The following features are supported
|
|
65
|
-
- constructor injection
|
|
66
|
-
- method injection
|
|
67
|
+
- constructor and setter injection
|
|
67
68
|
- post processors
|
|
68
69
|
- factory classes and methods
|
|
69
70
|
- support for eager construction
|
|
70
|
-
- support for singleton and
|
|
71
|
+
- support for singleton and request scopes
|
|
71
72
|
- possibilty to add custom scopes
|
|
72
73
|
- lifecycle events methods
|
|
73
74
|
- bundling of injectable object sets by environment classes including recursive imports and inheritance
|
|
@@ -156,7 +157,7 @@ Let's look at the details
|
|
|
156
157
|
|
|
157
158
|
`pip install aspyx`
|
|
158
159
|
|
|
159
|
-
The library is tested with Python version > 3.
|
|
160
|
+
The library is tested with all Python version > 3.9
|
|
160
161
|
|
|
161
162
|
Ready to go...
|
|
162
163
|
|
|
@@ -185,8 +186,15 @@ The decorator accepts the keyword arguments
|
|
|
185
186
|
- `eager : boolean`
|
|
186
187
|
if `True`, the container will create the instances automatically while booting the environment. This is the default.
|
|
187
188
|
- `scope: str`
|
|
188
|
-
the name of a scope which will determine how often instances will be created.
|
|
189
|
-
|
|
189
|
+
the name of a - registered - scope which will determine how often instances will be created.
|
|
190
|
+
|
|
191
|
+
The following scopes are implemented out of the box:
|
|
192
|
+
- `singleton`
|
|
193
|
+
objects are created once inside an environment and cached. This is the default.
|
|
194
|
+
- `request`
|
|
195
|
+
obejcts are created on every injection request
|
|
196
|
+
- `thread`
|
|
197
|
+
objects are cerated and cached with respect to the current thread.
|
|
190
198
|
|
|
191
199
|
Other scopes - e.g. session related scopes - can be defined dynamically. Please check the corresponding chapter.
|
|
192
200
|
|
|
@@ -304,7 +312,7 @@ Different decorators are implemented, that call methods with computed values
|
|
|
304
312
|
the method is called with all resolved parameter types ( same as the constructor call)
|
|
305
313
|
- `@inject_environment`
|
|
306
314
|
the method is called with the creating environment as a single parameter
|
|
307
|
-
- `@
|
|
315
|
+
- `@inject_value()`
|
|
308
316
|
the method is called with a resolved configuration value. Check the corresponding chapter
|
|
309
317
|
|
|
310
318
|
**Example**:
|
|
@@ -325,9 +333,11 @@ class Foo:
|
|
|
325
333
|
|
|
326
334
|
## Lifecycle methods
|
|
327
335
|
|
|
328
|
-
It is possible to mark specific
|
|
336
|
+
It is possible to mark specific lifecyle methods.
|
|
329
337
|
- `@on_init()`
|
|
330
338
|
called after the constructor and all other injections.
|
|
339
|
+
- `@on_running()`
|
|
340
|
+
called an environment has initialized all eager objects.
|
|
331
341
|
- `@on_destroy()`
|
|
332
342
|
called during shutdown of the environment
|
|
333
343
|
|
|
@@ -460,7 +470,7 @@ class TransactionAdvice:
|
|
|
460
470
|
|
|
461
471
|
# Configuration
|
|
462
472
|
|
|
463
|
-
It is possible to inject configuration values, by decorating methods with `@value(<name>)` given a configuration key.
|
|
473
|
+
It is possible to inject configuration values, by decorating methods with `@inject-value(<name>)` given a configuration key.
|
|
464
474
|
|
|
465
475
|
```python
|
|
466
476
|
@injectable()
|
|
@@ -522,16 +532,24 @@ TypeDescriptor.for_type(<type>)
|
|
|
522
532
|
```
|
|
523
533
|
|
|
524
534
|
it offers the methods
|
|
525
|
-
- `get_methods(local=False)`
|
|
526
|
-
|
|
527
|
-
- `
|
|
528
|
-
|
|
535
|
+
- `get_methods(local=False)`
|
|
536
|
+
return a list of either local or overall methods
|
|
537
|
+
- `get_method(name: str, local=False)`
|
|
538
|
+
return a single either local or overall method
|
|
539
|
+
- `has_decorator(decorator: Callable) -> bool`
|
|
540
|
+
return `True`, if the class is decorated with the specified decrator
|
|
541
|
+
- `get_decorator(decorator) -> Optional[DecoratorDescriptor]`
|
|
542
|
+
return a descriptor covering the decorator. In addition to the callable, it also stores the supplied args in the `args` property
|
|
529
543
|
|
|
530
544
|
The returned method descriptors offer:
|
|
531
|
-
- `param_types`
|
|
532
|
-
|
|
533
|
-
- `
|
|
534
|
-
|
|
545
|
+
- `param_types`
|
|
546
|
+
list of arg types
|
|
547
|
+
- `return_type`
|
|
548
|
+
the retur type
|
|
549
|
+
- `has_decorator(decorator: Callable) -> bool`
|
|
550
|
+
return `True`, if the method is decorated with the specified decrator
|
|
551
|
+
- `get_decorator(decorator: Callable) -> Optional[DecoratorDescriptor]`
|
|
552
|
+
return a descriptor covering the decorator. In addition to the callable, it also stores the supplied args in the `args` property
|
|
535
553
|
|
|
536
554
|
The management of decorators in turn relies on another utility class `Decorators` that caches decorators.
|
|
537
555
|
|
|
@@ -548,7 +566,16 @@ def transactional():
|
|
|
548
566
|
```
|
|
549
567
|
|
|
550
568
|
|
|
569
|
+
# Version History
|
|
570
|
+
|
|
571
|
+
**1.0.1**
|
|
572
|
+
|
|
573
|
+
- some internal refactorings
|
|
574
|
+
|
|
575
|
+
**1.1.0**
|
|
551
576
|
|
|
577
|
+
- added `@on_running()` callback
|
|
578
|
+
- added `thread` scope
|
|
552
579
|
|
|
553
580
|
|
|
554
581
|
|
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|

|
|
4
4
|

|
|
5
|
-

|
|
6
6
|

|
|
7
|
+

|
|
7
8
|
|
|
8
9
|
## Table of Contents
|
|
9
10
|
|
|
@@ -24,18 +25,18 @@
|
|
|
24
25
|
- [AOP](#aop)
|
|
25
26
|
- [Configuration](#configuration)
|
|
26
27
|
- [Reflection](#reflection)
|
|
28
|
+
- [Version History](#version-history)
|
|
27
29
|
|
|
28
30
|
# Introduction
|
|
29
31
|
|
|
30
32
|
Aspyx is a small python libary, that adds support for both dependency injection and aop.
|
|
31
33
|
|
|
32
34
|
The following features are supported
|
|
33
|
-
- constructor injection
|
|
34
|
-
- method injection
|
|
35
|
+
- constructor and setter injection
|
|
35
36
|
- post processors
|
|
36
37
|
- factory classes and methods
|
|
37
38
|
- support for eager construction
|
|
38
|
-
- support for singleton and
|
|
39
|
+
- support for singleton and request scopes
|
|
39
40
|
- possibilty to add custom scopes
|
|
40
41
|
- lifecycle events methods
|
|
41
42
|
- bundling of injectable object sets by environment classes including recursive imports and inheritance
|
|
@@ -124,7 +125,7 @@ Let's look at the details
|
|
|
124
125
|
|
|
125
126
|
`pip install aspyx`
|
|
126
127
|
|
|
127
|
-
The library is tested with Python version > 3.
|
|
128
|
+
The library is tested with all Python version > 3.9
|
|
128
129
|
|
|
129
130
|
Ready to go...
|
|
130
131
|
|
|
@@ -153,8 +154,15 @@ The decorator accepts the keyword arguments
|
|
|
153
154
|
- `eager : boolean`
|
|
154
155
|
if `True`, the container will create the instances automatically while booting the environment. This is the default.
|
|
155
156
|
- `scope: str`
|
|
156
|
-
the name of a scope which will determine how often instances will be created.
|
|
157
|
-
|
|
157
|
+
the name of a - registered - scope which will determine how often instances will be created.
|
|
158
|
+
|
|
159
|
+
The following scopes are implemented out of the box:
|
|
160
|
+
- `singleton`
|
|
161
|
+
objects are created once inside an environment and cached. This is the default.
|
|
162
|
+
- `request`
|
|
163
|
+
obejcts are created on every injection request
|
|
164
|
+
- `thread`
|
|
165
|
+
objects are cerated and cached with respect to the current thread.
|
|
158
166
|
|
|
159
167
|
Other scopes - e.g. session related scopes - can be defined dynamically. Please check the corresponding chapter.
|
|
160
168
|
|
|
@@ -272,7 +280,7 @@ Different decorators are implemented, that call methods with computed values
|
|
|
272
280
|
the method is called with all resolved parameter types ( same as the constructor call)
|
|
273
281
|
- `@inject_environment`
|
|
274
282
|
the method is called with the creating environment as a single parameter
|
|
275
|
-
- `@
|
|
283
|
+
- `@inject_value()`
|
|
276
284
|
the method is called with a resolved configuration value. Check the corresponding chapter
|
|
277
285
|
|
|
278
286
|
**Example**:
|
|
@@ -293,9 +301,11 @@ class Foo:
|
|
|
293
301
|
|
|
294
302
|
## Lifecycle methods
|
|
295
303
|
|
|
296
|
-
It is possible to mark specific
|
|
304
|
+
It is possible to mark specific lifecyle methods.
|
|
297
305
|
- `@on_init()`
|
|
298
306
|
called after the constructor and all other injections.
|
|
307
|
+
- `@on_running()`
|
|
308
|
+
called an environment has initialized all eager objects.
|
|
299
309
|
- `@on_destroy()`
|
|
300
310
|
called during shutdown of the environment
|
|
301
311
|
|
|
@@ -428,7 +438,7 @@ class TransactionAdvice:
|
|
|
428
438
|
|
|
429
439
|
# Configuration
|
|
430
440
|
|
|
431
|
-
It is possible to inject configuration values, by decorating methods with `@value(<name>)` given a configuration key.
|
|
441
|
+
It is possible to inject configuration values, by decorating methods with `@inject-value(<name>)` given a configuration key.
|
|
432
442
|
|
|
433
443
|
```python
|
|
434
444
|
@injectable()
|
|
@@ -490,16 +500,24 @@ TypeDescriptor.for_type(<type>)
|
|
|
490
500
|
```
|
|
491
501
|
|
|
492
502
|
it offers the methods
|
|
493
|
-
- `get_methods(local=False)`
|
|
494
|
-
|
|
495
|
-
- `
|
|
496
|
-
|
|
503
|
+
- `get_methods(local=False)`
|
|
504
|
+
return a list of either local or overall methods
|
|
505
|
+
- `get_method(name: str, local=False)`
|
|
506
|
+
return a single either local or overall method
|
|
507
|
+
- `has_decorator(decorator: Callable) -> bool`
|
|
508
|
+
return `True`, if the class is decorated with the specified decrator
|
|
509
|
+
- `get_decorator(decorator) -> Optional[DecoratorDescriptor]`
|
|
510
|
+
return a descriptor covering the decorator. In addition to the callable, it also stores the supplied args in the `args` property
|
|
497
511
|
|
|
498
512
|
The returned method descriptors offer:
|
|
499
|
-
- `param_types`
|
|
500
|
-
|
|
501
|
-
- `
|
|
502
|
-
|
|
513
|
+
- `param_types`
|
|
514
|
+
list of arg types
|
|
515
|
+
- `return_type`
|
|
516
|
+
the retur type
|
|
517
|
+
- `has_decorator(decorator: Callable) -> bool`
|
|
518
|
+
return `True`, if the method is decorated with the specified decrator
|
|
519
|
+
- `get_decorator(decorator: Callable) -> Optional[DecoratorDescriptor]`
|
|
520
|
+
return a descriptor covering the decorator. In addition to the callable, it also stores the supplied args in the `args` property
|
|
503
521
|
|
|
504
522
|
The management of decorators in turn relies on another utility class `Decorators` that caches decorators.
|
|
505
523
|
|
|
@@ -516,7 +534,16 @@ def transactional():
|
|
|
516
534
|
```
|
|
517
535
|
|
|
518
536
|
|
|
537
|
+
# Version History
|
|
538
|
+
|
|
539
|
+
**1.0.1**
|
|
540
|
+
|
|
541
|
+
- some internal refactorings
|
|
542
|
+
|
|
543
|
+
**1.1.0**
|
|
519
544
|
|
|
545
|
+
- added `@on_running()` callback
|
|
546
|
+
- added `thread` scope
|
|
520
547
|
|
|
521
548
|
|
|
522
549
|
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
"""
|
|
2
2
|
This module provides dependency injection and aop capabilities for Python applications.
|
|
3
3
|
"""
|
|
4
|
-
from .di import InjectorException,
|
|
4
|
+
from .di import InjectorException, AbstractCallableProcessor, LifecycleCallable, Lifecycle, Providers, Environment, ClassInstanceProvider, injectable, factory, environment, inject, create, on_init, on_running, on_destroy, inject_environment, Factory, PostProcessor
|
|
5
5
|
|
|
6
6
|
# import something from the subpackages, so that teh decorators are executed
|
|
7
7
|
|
|
8
|
-
from
|
|
9
|
-
from
|
|
8
|
+
from .configuration import ConfigurationManager
|
|
9
|
+
from .aop import before
|
|
10
10
|
|
|
11
11
|
imports = [ConfigurationManager, before]
|
|
12
12
|
|
|
@@ -21,11 +21,12 @@ __all__ = [
|
|
|
21
21
|
"create",
|
|
22
22
|
|
|
23
23
|
"on_init",
|
|
24
|
+
"on_running",
|
|
24
25
|
"on_destroy",
|
|
25
26
|
"inject_environment",
|
|
26
27
|
"Factory",
|
|
27
28
|
"PostProcessor",
|
|
28
|
-
"
|
|
29
|
+
"AbstractCallableProcessor",
|
|
29
30
|
"LifecycleCallable",
|
|
30
31
|
"InjectorException",
|
|
31
32
|
"Lifecycle"
|
|
@@ -8,7 +8,7 @@ import os
|
|
|
8
8
|
from typing import Optional, Type, TypeVar
|
|
9
9
|
from dotenv import load_dotenv
|
|
10
10
|
|
|
11
|
-
from aspyx.di import injectable, Environment,
|
|
11
|
+
from aspyx.di import injectable, Environment, LifecycleCallable, Lifecycle
|
|
12
12
|
from aspyx.di.di import order, inject
|
|
13
13
|
from aspyx.reflection import Decorators, DecoratorDescriptor, TypeDescriptor
|
|
14
14
|
|
|
@@ -188,8 +188,8 @@ def value(key: str, default=None):
|
|
|
188
188
|
@injectable()
|
|
189
189
|
@order(9)
|
|
190
190
|
class ConfigurationLifecycleCallable(LifecycleCallable):
|
|
191
|
-
def __init__(self,
|
|
192
|
-
super().__init__(value,
|
|
191
|
+
def __init__(self, manager: ConfigurationManager):
|
|
192
|
+
super().__init__(value, Lifecycle.ON_INJECT)
|
|
193
193
|
|
|
194
194
|
self.manager = manager
|
|
195
195
|
|