python-injection 0.5.0__tar.gz → 0.5.1__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 python-injection might be problematic. Click here for more details.

@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: python-injection
3
- Version: 0.5.0
3
+ Version: 0.5.1
4
4
  Summary: Fast and easy dependency injection framework.
5
5
  Home-page: https://github.com/simplysquare/python-injection
6
6
  License: MIT
@@ -48,12 +48,12 @@ Events
48
48
  """
49
49
 
50
50
 
51
- @dataclass(slots=True)
51
+ @dataclass(frozen=True, slots=True)
52
52
  class ContainerEvent(Event, ABC):
53
53
  on_container: Container
54
54
 
55
55
 
56
- @dataclass(slots=True)
56
+ @dataclass(frozen=True, slots=True)
57
57
  class ContainerDependenciesUpdated(ContainerEvent):
58
58
  references: set[type]
59
59
 
@@ -68,27 +68,39 @@ class ContainerDependenciesUpdated(ContainerEvent):
68
68
  )
69
69
 
70
70
 
71
- @dataclass(slots=True)
71
+ @dataclass(frozen=True, slots=True)
72
72
  class ModuleEvent(Event, ABC):
73
73
  on_module: Module
74
74
 
75
75
 
76
- @dataclass(slots=True)
76
+ @dataclass(frozen=True)
77
77
  class ModuleEventProxy(ModuleEvent):
78
78
  event: Event
79
79
 
80
80
  def __str__(self) -> str:
81
81
  return f"`{self.on_module}` has propagated an event: {self.origin}"
82
82
 
83
- @property
83
+ @cached_property
84
84
  def origin(self) -> Event:
85
85
  if isinstance(self.event, ModuleEventProxy):
86
86
  return self.event.origin
87
87
 
88
88
  return self.event
89
89
 
90
+ @property
91
+ def is_circular(self) -> bool:
92
+ origin = self.origin
93
+ return isinstance(origin, ModuleEvent) and origin.on_module is self.on_module
94
+
95
+ @property
96
+ def previous_module(self) -> Module | None:
97
+ if isinstance(self.event, ModuleEvent):
98
+ return self.event.on_module
90
99
 
91
- @dataclass(slots=True)
100
+ return None
101
+
102
+
103
+ @dataclass(frozen=True, slots=True)
92
104
  class ModuleAdded(ModuleEvent):
93
105
  module_added: Module
94
106
 
@@ -96,7 +108,7 @@ class ModuleAdded(ModuleEvent):
96
108
  return f"`{self.on_module}` now uses `{self.module_added}`."
97
109
 
98
110
 
99
- @dataclass(slots=True)
111
+ @dataclass(frozen=True, slots=True)
100
112
  class ModuleRemoved(ModuleEvent):
101
113
  module_removed: Module
102
114
 
@@ -104,7 +116,7 @@ class ModuleRemoved(ModuleEvent):
104
116
  return f"`{self.on_module}` no longer uses `{self.module_removed}`."
105
117
 
106
118
 
107
- @dataclass(slots=True)
119
+ @dataclass(frozen=True, slots=True)
108
120
  class ModulePriorityUpdated(ModuleEvent):
109
121
  module_updated: Module
110
122
  priority: ModulePriorities
@@ -352,10 +364,9 @@ class Module(EventListener):
352
364
  * **HIGH**: The module concerned becomes the most important of the modules used.
353
365
  """
354
366
 
355
- if self.__move_module(module, priority):
356
- event = ModulePriorityUpdated(self, module, priority)
357
- self.notify(event)
358
-
367
+ self.__move_module(module, priority)
368
+ event = ModulePriorityUpdated(self, module, priority)
369
+ self.notify(event)
359
370
  return self
360
371
 
361
372
  def add_listener(self, listener: EventListener):
@@ -368,6 +379,13 @@ class Module(EventListener):
368
379
 
369
380
  def on_event(self, event: Event, /):
370
381
  self_event = ModuleEventProxy(self, event)
382
+
383
+ if self_event.is_circular:
384
+ raise ModuleError(
385
+ "Circular dependency between two modules: "
386
+ f"`{self_event.previous_module}` and `{self}`."
387
+ )
388
+
371
389
  self.notify(self_event)
372
390
 
373
391
  def notify(self, event: Event):
@@ -375,15 +393,15 @@ class Module(EventListener):
375
393
  self.__channel.dispatch(event)
376
394
  return self
377
395
 
378
- def __move_module(self, module: Module, priority: ModulePriorities) -> bool:
396
+ def __move_module(self, module: Module, priority: ModulePriorities):
379
397
  last = priority == ModulePriorities.LOW
380
398
 
381
399
  try:
382
400
  self.__modules.move_to_end(module, last=last)
383
- except KeyError:
384
- return False
385
-
386
- return True
401
+ except KeyError as exc:
402
+ raise ModuleError(
403
+ f"`{module}` can't be found in the modules used by `{self}`."
404
+ ) from exc
387
405
 
388
406
 
389
407
  """
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "python-injection"
3
- version = "0.5.0"
3
+ version = "0.5.1"
4
4
  description = "Fast and easy dependency injection framework."
5
5
  authors = ["remimd"]
6
6
  keywords = ["dependencies", "inject", "injection"]