aspyx 1.6.0__py3-none-any.whl → 1.6.1__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.

Potentially problematic release.


This version of aspyx might be problematic. Click here for more details.

@@ -106,9 +106,6 @@ class ConfigurationSource(ABC):
106
106
 
107
107
  __slots__ = []
108
108
 
109
- def __init__(self):
110
- pass
111
-
112
109
  @inject()
113
110
  def set_manager(self, manager: ConfigurationManager):
114
111
  manager._register(self)
@@ -14,11 +14,6 @@ class EnvConfigurationSource(ConfigurationSource):
14
14
 
15
15
  __slots__ = []
16
16
 
17
- # constructor
18
-
19
- def __init__(self):
20
- super().__init__()
21
-
22
17
  # implement
23
18
 
24
19
  def load(self) -> dict:
@@ -15,8 +15,6 @@ class YamlConfigurationSource(ConfigurationSource):
15
15
  # constructor
16
16
 
17
17
  def __init__(self, file: str):
18
- super().__init__()
19
-
20
18
  self.file = file
21
19
 
22
20
  # implement
aspyx/di/di.py CHANGED
@@ -8,6 +8,7 @@ import logging
8
8
  import importlib
9
9
  import pkgutil
10
10
  import sys
11
+ import time
11
12
 
12
13
  from abc import abstractmethod, ABC
13
14
  from enum import Enum
@@ -405,12 +406,10 @@ class ClassInstanceProvider(InstanceProvider):
405
406
  # check constructor
406
407
 
407
408
  init = TypeDescriptor.for_type(self.type).get_method("__init__")
408
- if init is None:
409
- raise DIRegistrationException(f"{self.type.__name__} does not implement __init__")
410
-
411
- self.params = len(init.param_types)
412
- for param in init.param_types:
413
- types.append(param)
409
+ if init is not None:
410
+ self.params = len(init.param_types)
411
+ for param in init.param_types:
412
+ types.append(param)
414
413
 
415
414
  # check @inject
416
415
 
@@ -976,7 +975,7 @@ class Environment:
976
975
  """
977
976
 
978
977
  def add_provider(type: Type, provider: AbstractInstanceProvider):
979
- Environment.logger.debug("\tadd provider %s for %s", provider, type)
978
+ Environment.logger.info("\tadd provider %s for %s", provider, type)
980
979
 
981
980
  self.providers[type] = provider
982
981
 
@@ -989,6 +988,8 @@ class Environment:
989
988
  if self.parent is None and env is not Boot:
990
989
  self.parent = Boot.get_environment() # inherit environment including its manged instances!
991
990
 
991
+ start = time.perf_counter()
992
+
992
993
  self.features = features
993
994
  self.providers: Dict[Type, AbstractInstanceProvider] = {}
994
995
  self.instances = []
@@ -1138,6 +1139,13 @@ class Environment:
1138
1139
  for instance in self.instances:
1139
1140
  self.execute_processors(Lifecycle.ON_RUNNING, instance)
1140
1141
 
1142
+ # done
1143
+
1144
+ end = time.perf_counter()
1145
+
1146
+ Environment.logger.info("created environment for class %s in %s ms, created %s instances", env.__qualname__, 1000 * (end - start), len(self.instances))
1147
+
1148
+
1141
1149
  def is_registered_type(self, type: Type) -> bool:
1142
1150
  provider = self.providers.get(type, None)
1143
1151
  return provider is not None and not isinstance(provider, AmbiguousProvider)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: aspyx
3
- Version: 1.6.0
3
+ Version: 1.6.1
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
@@ -117,9 +117,6 @@ from aspyx.di import injectable, on_init, on_destroy, module, Environment
117
117
 
118
118
  @injectable()
119
119
  class Foo:
120
- def __init__(self):
121
- pass
122
-
123
120
  def hello(self, msg: str):
124
121
  print(f"hello {msg}")
125
122
 
@@ -138,9 +135,7 @@ class Bar:
138
135
 
139
136
  @module()
140
137
  class SampleModule:
141
- def __init__(self):
142
- pass
143
-
138
+ pass
144
139
 
145
140
  # create environment
146
141
 
@@ -148,7 +143,7 @@ environment = Environment(SampleModule)
148
143
 
149
144
  # fetch an instance
150
145
 
151
- bar = env.read(Bar)
146
+ bar = environment.get(Bar)
152
147
 
153
148
  bar.foo.hello("world")
154
149
  ```
@@ -206,10 +201,7 @@ class Foo:
206
201
  def __init__(self):
207
202
  pass
208
203
  ```
209
- ⚠️ **Attention:** Please make sure, that the class defines a local constructor, as this is _required_ to determine injected instances.
210
- All referenced types will be injected by the environment.
211
-
212
- Only eligible types are allowed, of course!
204
+ If the class defines a constructor, all parameters - which are expected to be registered as well - will be injected automatically.
213
205
 
214
206
  The decorator accepts the keyword arguments
215
207
  - `eager : boolean`
@@ -235,9 +227,6 @@ Classes that implement the `Factory` base class and are annotated with `@factory
235
227
  ```python
236
228
  @factory()
237
229
  class TestFactory(Factory[Foo]):
238
- def __init__(self):
239
- pass
240
-
241
230
  def create(self) -> Foo:
242
231
  return Foo()
243
232
  ```
@@ -252,9 +241,6 @@ Any `injectable` can define methods decorated with `@create()`, that will create
252
241
  ```python
253
242
  @injectable()
254
243
  class Foo:
255
- def __init__(self):
256
- pass
257
-
258
244
  @create(scope="request")
259
245
  def create(self) -> Baz:
260
246
  return Baz()
@@ -290,8 +276,7 @@ constructor type argument called `module`.
290
276
  ```python
291
277
  @module()
292
278
  class SampleModule:
293
- def __init__(self):
294
- pass
279
+ pass
295
280
  ```
296
281
 
297
282
  A module is a regular injectable class decorated with `@module` that controls the discovery of injectable classes, by filtering classes according to their module location relative to this class.
@@ -311,13 +296,11 @@ By adding the parameter `features: list[str]`, it is possible to filter injectab
311
296
  @injectable()
312
297
  @conditional(requires_feature("dev"))
313
298
  class DevOnly:
314
- def __init__(self):
315
- pass
299
+ pass
316
300
 
317
301
  @module()
318
302
  class SampleModule():
319
- def __init__(self):
320
- pass
303
+ pass
321
304
 
322
305
  environment = Environment(SampleModule, features=["dev"])
323
306
  ```
@@ -329,8 +312,7 @@ By adding an `imports: list[Type]` parameter, specifying other module types, it
329
312
  ```python
330
313
  @module()
331
314
  class SampleModule(imports=[OtherModule]):
332
- def __init__(self):
333
- pass
315
+ pass
334
316
  ```
335
317
 
336
318
  Another possibility is to add a parent environment as an `Environment` constructor parameter
@@ -392,11 +374,8 @@ Different decorators are implemented, that call methods with computed values
392
374
  ```python
393
375
  @injectable()
394
376
  class Foo:
395
- def __init__(self):
396
- pass
397
-
398
377
  @inject_environment()
399
- def initEnvironment(self, env: Environment):
378
+ def set_environment(self, env: Environment):
400
379
  ...
401
380
 
402
381
  @inject()
@@ -586,9 +565,6 @@ A handy decorator `@synchronized` in combination with the respective advice is i
586
565
  ```python
587
566
  @injectable()
588
567
  class Foo:
589
- def __init__(self):
590
- pass
591
-
592
568
  @synchronized()
593
569
  def execute_synchronized(self):
594
570
  ...
@@ -601,9 +577,6 @@ It is possible to inject configuration values, by decorating methods with `@inje
601
577
  ```python
602
578
  @injectable()
603
579
  class Foo:
604
- def __init__(self):
605
- pass
606
-
607
580
  @inject_value("HOME")
608
581
  def inject_home(self, os: str):
609
582
  ...
@@ -615,13 +588,13 @@ Configuration values are managed centrally using a `ConfigurationManager`, which
615
588
 
616
589
  ```python
617
590
  class ConfigurationSource(ABC):
618
- def __init__(self):
619
- pass
620
-
621
- ...
591
+ @inject()
592
+ def set_manager(self, manager: ConfigurationManager):
593
+ manager._register(self)
622
594
 
623
595
  @abstractmethod
624
596
  def load(self) -> dict:
597
+ pass
625
598
  ```
626
599
 
627
600
  The `load` method is able to return a tree-like structure by returning a `dict`.
@@ -670,11 +643,6 @@ Typically you create the required configuration sources in an environment class,
670
643
  ```python
671
644
  @module()
672
645
  class SampleModule:
673
- # constructor
674
-
675
- def __init__(self):
676
- pass
677
-
678
646
  @create()
679
647
  def create_env_source(self) -> EnvConfigurationSource:
680
648
  return EnvConfigurationSource()
@@ -733,7 +701,7 @@ def transactional(scope):
733
701
  The class `ExceptionManager` is used to collect dynamic handlers for specific exceptions and is able to dispatch to the concrete functions
734
702
  given a specific exception.
735
703
 
736
- The handlers are declared by annoting a class with `@exception_handler` and decorating specific methods with `@handle`
704
+ The handlers are declared by annoting a class with `@exception_handler` and decorating specific methods with `@catch`
737
705
 
738
706
  **Example**:
739
707
 
@@ -745,11 +713,6 @@ class DerivedException(Exception):
745
713
 
746
714
  @module()
747
715
  class SampleModule:
748
- # constructor
749
-
750
- def __init__(self):
751
- pass
752
-
753
716
  @create()
754
717
  def create_exception_manager(self) -> ExceptionManager:
755
718
  return ExceptionManager()
@@ -758,19 +721,16 @@ class SampleModule:
758
721
  @injectable()
759
722
  @exception_handler()
760
723
  class TestExceptionHandler:
761
- def __init__(self):
762
- pass
763
-
764
- @handle()
765
- def handle_derived_exception(self, exception: DerivedException):
724
+ @catch()
725
+ def catch_derived_exception(self, exception: DerivedException):
766
726
  ExceptionManager.proceed()
767
727
 
768
- @handle()
769
- def handle_exception(self, exception: Exception):
728
+ @catch()
729
+ def catch_exception(self, exception: Exception):
770
730
  pass
771
731
 
772
- @handle()
773
- def handle_base_exception(self, exception: BaseException):
732
+ @catch()
733
+ def catch_base_exception(self, exception: BaseException):
774
734
  pass
775
735
 
776
736
 
@@ -798,9 +758,6 @@ Together with a simple around advice we can now add exception handling to any me
798
758
  ```python
799
759
  @injectable()
800
760
  class Service:
801
- def __init__(self):
802
- pass
803
-
804
761
  def throw(self):
805
762
  raise DerivedException()
806
763
 
@@ -843,3 +800,7 @@ class ExceptionAdvice:
843
800
  **1.4.1**
844
801
 
845
802
  - mkdocs
803
+
804
+ **1.6.1**
805
+
806
+ - default constructors not requires anymore
@@ -1,12 +1,12 @@
1
1
  aspyx/__init__.py,sha256=MsSFjiLMLJZ7QhUPpVBWKiyDnCzryquRyr329NoCACI,2
2
2
  aspyx/di/__init__.py,sha256=AGVU2VBWQyBxSssvbk_GOKrYWIYtcmSoIlupz-Oqxi4,1138
3
- aspyx/di/di.py,sha256=V_BAV6DmFCoepPqAXhBz2GW6NwYaKokHb03HMz6A5Sw,44639
3
+ aspyx/di/di.py,sha256=HgmLl84s3FLKUs6UO5ULzLcwuyDIzo0Ev8WrPQm3INg,44821
4
4
  aspyx/di/aop/__init__.py,sha256=rn6LSpzFtUOlgaBATyhLRWBzFmZ6XoVKA9B8SgQzYEI,746
5
5
  aspyx/di/aop/aop.py,sha256=y300DG713Gcn97CdTKuBdFL2jaS5ouW6J0azZk0Byws,19181
6
6
  aspyx/di/configuration/__init__.py,sha256=flM9A79J2wfA5I8goQbxs4tTqYustR9tn_9s0YO2WJQ,484
7
- aspyx/di/configuration/configuration.py,sha256=cXW40bPXiUZ9hUtBoZkSATT3nLrDPWsSqxtgASIBQaM,4375
8
- aspyx/di/configuration/env_configuration_source.py,sha256=FXPvREzq2ZER6_GG5xdpx154TQQDxZVf7LW7cvaylAk,1446
9
- aspyx/di/configuration/yaml_configuration_source.py,sha256=NDl3SeoLMNVlzHgfP-Ysvhco1tRew_zFnBL5gGy2WRk,550
7
+ aspyx/di/configuration/configuration.py,sha256=GVk_oGi7H0COBD_q__ZydIXyl7PgxvwW2Lplr-t44ck,4337
8
+ aspyx/di/configuration/env_configuration_source.py,sha256=mVZXRTBn-zbkqGMV9Yn5EZsae4MlpAzc8nVozXaVwnE,1375
9
+ aspyx/di/configuration/yaml_configuration_source.py,sha256=FmtM3-Xi1waxurdI5NVWUNTCcrv6q_azk5XniOL0Pg0,522
10
10
  aspyx/di/threading/__init__.py,sha256=qrWdaq7MewQ2UmZy4J0Dn6BhY-ahfiG3xsv-EHqoqSE,191
11
11
  aspyx/di/threading/synchronized.py,sha256=6JOg5BXWrRIS5nRPH9iWR7T-kUglO4qWBQpLwhy99pI,1325
12
12
  aspyx/exception/__init__.py,sha256=HfK0kk1Tcw9QaUYgIyMeBFDAIE83pkTrIGYUnoKJXPE,231
@@ -21,7 +21,7 @@ aspyx/util/__init__.py,sha256=B7QK3alguZqExBFGzx-OpHpYeoIc3ZGAL7pJnq8NNvI,352
21
21
  aspyx/util/logger.py,sha256=Hti5JyajdPXlf_1jvVT3e6Gf9eLyAsIVJRdNBMahbJs,608
22
22
  aspyx/util/serialization.py,sha256=BRsg-2S7E3IukJqxZGm7FvjTvV5d6rcyrpJT3aKoVmM,4252
23
23
  aspyx/util/stringbuilder.py,sha256=a-0T4YEXSJFUuQ3ztKN1ZPARkh8dIGMSkNEEJHRN7dc,856
24
- aspyx-1.6.0.dist-info/METADATA,sha256=fYorC9QmB3Yo6sQwu4TfMpJOI9eQk02P3Tmz6UCBrgo,26562
25
- aspyx-1.6.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
26
- aspyx-1.6.0.dist-info/licenses/LICENSE,sha256=n4jfx_MNj7cBtPhhI7MCoB_K35cj1icP9yJ4Rh4vlvY,1070
27
- aspyx-1.6.0.dist-info/RECORD,,
24
+ aspyx-1.6.1.dist-info/METADATA,sha256=H7d-mtHxb57xtVyxbvcz2385TvqslMxGHXzCtbDxdk8,26017
25
+ aspyx-1.6.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
26
+ aspyx-1.6.1.dist-info/licenses/LICENSE,sha256=n4jfx_MNj7cBtPhhI7MCoB_K35cj1icP9yJ4Rh4vlvY,1070
27
+ aspyx-1.6.1.dist-info/RECORD,,
File without changes