dinkleberg 0.3.1__py3-none-any.whl → 0.3.2__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.
- dinkleberg/dependency_configurator.py +60 -34
- {dinkleberg-0.3.1.dist-info → dinkleberg-0.3.2.dist-info}/METADATA +1 -1
- {dinkleberg-0.3.1.dist-info → dinkleberg-0.3.2.dist-info}/RECORD +5 -5
- {dinkleberg-0.3.1.dist-info → dinkleberg-0.3.2.dist-info}/WHEEL +0 -0
- {dinkleberg-0.3.1.dist-info → dinkleberg-0.3.2.dist-info}/top_level.txt +0 -0
|
@@ -21,10 +21,17 @@ class DependencyConfigurator(DependencyScope):
|
|
|
21
21
|
self._descriptors: dict[type, Descriptor] = {}
|
|
22
22
|
self._singleton_instances = {}
|
|
23
23
|
self._scoped_instances = {}
|
|
24
|
+
self._configurators: dict[type, list[Callable[[object], object | None]]] = {}
|
|
24
25
|
self._active_generators = []
|
|
25
26
|
self._scopes = []
|
|
26
27
|
self._closed = False
|
|
27
28
|
|
|
29
|
+
def configure[T](self, t: type[T], configurator: Callable[[T], T | None]) -> None:
|
|
30
|
+
self._raise_if_closed()
|
|
31
|
+
if t not in self._configurators:
|
|
32
|
+
self._configurators[t] = []
|
|
33
|
+
self._configurators[t].append(configurator)
|
|
34
|
+
|
|
28
35
|
async def close(self) -> None:
|
|
29
36
|
if self._closed:
|
|
30
37
|
return
|
|
@@ -51,6 +58,7 @@ class DependencyConfigurator(DependencyScope):
|
|
|
51
58
|
self._singleton_instances.clear()
|
|
52
59
|
self._active_generators.clear()
|
|
53
60
|
self._scoped_instances.clear()
|
|
61
|
+
self._configurators.clear()
|
|
54
62
|
self._descriptors.clear()
|
|
55
63
|
self._scopes.clear()
|
|
56
64
|
|
|
@@ -58,7 +66,7 @@ class DependencyConfigurator(DependencyScope):
|
|
|
58
66
|
raise ExceptionGroup('Errors occurred during closing DependencyConfigurator', exceptions)
|
|
59
67
|
|
|
60
68
|
def _add(self, lifetime: Lifetime, *, t: type = None, i: type = None,
|
|
61
|
-
generator: Callable[..., AsyncGenerator] = None, callable: Callable = None):
|
|
69
|
+
generator: Callable[..., AsyncGenerator] = None, callable: Callable = None, override: bool = False):
|
|
62
70
|
if t is None and i is None and generator is None and callable is None:
|
|
63
71
|
raise ValueError(
|
|
64
72
|
'Invalid dependency registration. At least one of t, i, generator, or callable must be provided.')
|
|
@@ -82,7 +90,7 @@ class DependencyConfigurator(DependencyScope):
|
|
|
82
90
|
t = i
|
|
83
91
|
else:
|
|
84
92
|
t = self._infer_type(generator=generator, callable=callable)
|
|
85
|
-
elif generator is None and callable is None:
|
|
93
|
+
elif generator is None and callable is None and i is None:
|
|
86
94
|
if is_builtin_type(t):
|
|
87
95
|
raise ValueError(
|
|
88
96
|
f'Cannot register built-in type {t} without explicit implementation, generator or callable.')
|
|
@@ -95,6 +103,9 @@ class DependencyConfigurator(DependencyScope):
|
|
|
95
103
|
raise ValueError(
|
|
96
104
|
f'Cannot register abstract class {t} without explicit implementation, generator or callable.')
|
|
97
105
|
|
|
106
|
+
if t in self._descriptors and not override:
|
|
107
|
+
raise ValueError(f'Type {t} is already registered.')
|
|
108
|
+
|
|
98
109
|
self._descriptors[t] = Descriptor(implementation=i, generator=generator, callable=callable, lifetime=lifetime)
|
|
99
110
|
|
|
100
111
|
@staticmethod
|
|
@@ -118,12 +129,13 @@ class DependencyConfigurator(DependencyScope):
|
|
|
118
129
|
|
|
119
130
|
def _raise_if_closed(self):
|
|
120
131
|
if self._closed:
|
|
121
|
-
raise RuntimeError('
|
|
132
|
+
raise RuntimeError('DependencyScope is already closed.')
|
|
122
133
|
|
|
123
134
|
def scope(self) -> 'DependencyConfigurator':
|
|
124
135
|
self._raise_if_closed()
|
|
125
136
|
scope = DependencyConfigurator(self)
|
|
126
137
|
scope._descriptors = self._descriptors.copy()
|
|
138
|
+
scope._configurators = self._configurators.copy()
|
|
127
139
|
self._scopes.append(scope)
|
|
128
140
|
return scope
|
|
129
141
|
|
|
@@ -206,7 +218,7 @@ class DependencyConfigurator(DependencyScope):
|
|
|
206
218
|
finally:
|
|
207
219
|
await instance.aclose()
|
|
208
220
|
|
|
209
|
-
self._wrap_instance(instance)
|
|
221
|
+
self._wrap_instance(t, instance)
|
|
210
222
|
|
|
211
223
|
if lifetime == 'singleton':
|
|
212
224
|
self._singleton_instances[t] = instance
|
|
@@ -279,10 +291,16 @@ class DependencyConfigurator(DependencyScope):
|
|
|
279
291
|
return wrapped_func
|
|
280
292
|
|
|
281
293
|
# TODO handle __slots__
|
|
282
|
-
def _wrap_instance(self, instance):
|
|
283
|
-
if getattr(instance, '__dinkleberg__', False):
|
|
294
|
+
def _wrap_instance(self, t: type, instance: object):
|
|
295
|
+
if getattr(instance, '__dinkleberg__', False) or is_builtin_type(t):
|
|
284
296
|
return
|
|
285
297
|
|
|
298
|
+
configurators = self._configurators.get(t, [])
|
|
299
|
+
for configurator in configurators:
|
|
300
|
+
result = configurator(instance)
|
|
301
|
+
if result is not None:
|
|
302
|
+
instance = result
|
|
303
|
+
|
|
286
304
|
methods = get_public_methods(instance)
|
|
287
305
|
for name, value in methods:
|
|
288
306
|
instance_method = getattr(instance, name)
|
|
@@ -298,109 +316,117 @@ class DependencyConfigurator(DependencyScope):
|
|
|
298
316
|
pass
|
|
299
317
|
|
|
300
318
|
@overload
|
|
301
|
-
def add_singleton[I](self, *, instance: I):
|
|
319
|
+
def add_singleton[I](self, *, instance: I, override: bool = False):
|
|
302
320
|
...
|
|
303
321
|
|
|
304
322
|
@overload
|
|
305
|
-
def add_singleton[T, I](self, *, t: type[T], instance: I):
|
|
323
|
+
def add_singleton[T, I](self, *, t: type[T], instance: I, override: bool = False):
|
|
306
324
|
...
|
|
307
325
|
|
|
308
326
|
@overload
|
|
309
|
-
def add_singleton[T](self, *, t: type[T]):
|
|
327
|
+
def add_singleton[T](self, *, t: type[T], override: bool = False):
|
|
310
328
|
...
|
|
311
329
|
|
|
312
330
|
@overload
|
|
313
|
-
def add_singleton[I](self, *, i: type[I]):
|
|
331
|
+
def add_singleton[I](self, *, i: type[I], override: bool = False):
|
|
314
332
|
...
|
|
315
333
|
|
|
316
334
|
@overload
|
|
317
|
-
def add_singleton[T, I](self, *, t: type[T], i: type[I]):
|
|
335
|
+
def add_singleton[T, I](self, *, t: type[T], i: type[I], override: bool = False):
|
|
318
336
|
...
|
|
319
337
|
|
|
320
338
|
@overload
|
|
321
|
-
def add_singleton[I](self, *, callable: Callable[..., I]):
|
|
339
|
+
def add_singleton[I](self, *, callable: Callable[..., I], override: bool = False):
|
|
322
340
|
...
|
|
323
341
|
|
|
324
342
|
@overload
|
|
325
|
-
def add_singleton[T, I](self, *, t: type[T], callable: Callable[..., I]):
|
|
343
|
+
def add_singleton[T, I](self, *, t: type[T], callable: Callable[..., I], override: bool = False):
|
|
326
344
|
...
|
|
327
345
|
|
|
328
346
|
@overload
|
|
329
|
-
def add_singleton[I](self, *, generator: Callable[..., AsyncGenerator[I]]):
|
|
347
|
+
def add_singleton[I](self, *, generator: Callable[..., AsyncGenerator[I]], override: bool = False):
|
|
330
348
|
...
|
|
331
349
|
|
|
332
350
|
@overload
|
|
333
|
-
def add_singleton[T, I](self, *, t: type[T], generator: Callable[..., AsyncGenerator[I]]):
|
|
351
|
+
def add_singleton[T, I](self, *, t: type[T], generator: Callable[..., AsyncGenerator[I]], override: bool = False):
|
|
334
352
|
...
|
|
335
353
|
|
|
336
354
|
def add_singleton[T, I](self, *, t: type[T] = None, i: type[I] = None,
|
|
337
355
|
generator: Callable[..., AsyncGenerator[I]] = None,
|
|
338
|
-
callable: Callable[..., I] = None, instance: I = None):
|
|
356
|
+
callable: Callable[..., I] = None, instance: I = None, override: bool = False):
|
|
339
357
|
self._raise_if_closed()
|
|
340
358
|
|
|
341
359
|
if instance is None:
|
|
342
|
-
self._add('singleton', t=t, i=i, generator=generator, callable=callable)
|
|
360
|
+
self._add('singleton', t=t, i=i, generator=generator, callable=callable, override=override)
|
|
343
361
|
return
|
|
344
362
|
elif t is None:
|
|
345
363
|
t = type(instance)
|
|
346
364
|
|
|
347
|
-
self.
|
|
365
|
+
if t in self._descriptors:
|
|
366
|
+
raise ValueError(f'Type {t} is already registered with a descriptor. Cannot register singleton instance.')
|
|
367
|
+
|
|
368
|
+
if t in self._singleton_instances and not override:
|
|
369
|
+
raise ValueError(f'Type {t} already has a singleton instance registered.')
|
|
370
|
+
|
|
371
|
+
self._wrap_instance(t, instance)
|
|
348
372
|
|
|
349
373
|
self._singleton_instances[t] = instance
|
|
350
374
|
|
|
351
375
|
@overload
|
|
352
|
-
def add_scoped[T](self, *, t: type[T]):
|
|
376
|
+
def add_scoped[T](self, *, t: type[T], override: bool = False):
|
|
353
377
|
...
|
|
354
378
|
|
|
355
379
|
@overload
|
|
356
|
-
def add_scoped[I](self, *, i: type[I]):
|
|
380
|
+
def add_scoped[I](self, *, i: type[I], override: bool = False):
|
|
357
381
|
...
|
|
358
382
|
|
|
359
383
|
@overload
|
|
360
|
-
def add_scoped[T, I](self, *, t: type[T], i: type[I]):
|
|
384
|
+
def add_scoped[T, I](self, *, t: type[T], i: type[I], override: bool = False):
|
|
361
385
|
...
|
|
362
386
|
|
|
363
387
|
@overload
|
|
364
|
-
def add_scoped[I](self, *, callable: Callable[..., I]):
|
|
388
|
+
def add_scoped[I](self, *, callable: Callable[..., I], override: bool = False):
|
|
365
389
|
...
|
|
366
390
|
|
|
367
391
|
@overload
|
|
368
|
-
def add_scoped[T, I](self, *, t: type[T], callable: Callable[..., I]):
|
|
392
|
+
def add_scoped[T, I](self, *, t: type[T], callable: Callable[..., I], override: bool = False):
|
|
369
393
|
...
|
|
370
394
|
|
|
371
395
|
@overload
|
|
372
|
-
def add_scoped[I](self, *, generator: Callable[..., AsyncGenerator[I]]):
|
|
396
|
+
def add_scoped[I](self, *, generator: Callable[..., AsyncGenerator[I]], override: bool = False):
|
|
373
397
|
...
|
|
374
398
|
|
|
375
399
|
@overload
|
|
376
|
-
def add_scoped[T, I](self, *, t: type[T], generator: Callable[..., AsyncGenerator[I]]):
|
|
400
|
+
def add_scoped[T, I](self, *, t: type[T], generator: Callable[..., AsyncGenerator[I]], override: bool = False):
|
|
377
401
|
...
|
|
378
402
|
|
|
379
403
|
def add_scoped[T, I](self, *, t: type[T] = None, i: type[I] = None,
|
|
380
|
-
generator: Callable[..., AsyncGenerator[I]] = None, callable: Callable[..., I] = None
|
|
404
|
+
generator: Callable[..., AsyncGenerator[I]] = None, callable: Callable[..., I] = None,
|
|
405
|
+
override: bool = False):
|
|
381
406
|
self._raise_if_closed()
|
|
382
|
-
self._add('scoped', t=t, i=i, generator=generator, callable=callable)
|
|
407
|
+
self._add('scoped', t=t, i=i, generator=generator, callable=callable, override=override)
|
|
383
408
|
|
|
384
409
|
@overload
|
|
385
|
-
def add_transient[T](self, *, t: type[T]):
|
|
410
|
+
def add_transient[T](self, *, t: type[T], override: bool = False):
|
|
386
411
|
...
|
|
387
412
|
|
|
388
413
|
@overload
|
|
389
|
-
def add_transient[I](self, *, i: type[I]):
|
|
414
|
+
def add_transient[I](self, *, i: type[I], override: bool = False):
|
|
390
415
|
...
|
|
391
416
|
|
|
392
417
|
@overload
|
|
393
|
-
def add_transient[T, I](self, *, t: type[T], i: type[I]):
|
|
418
|
+
def add_transient[T, I](self, *, t: type[T], i: type[I], override: bool = False):
|
|
394
419
|
...
|
|
395
420
|
|
|
396
421
|
@overload
|
|
397
|
-
def add_transient[I](self, *, callable: Callable[..., I]):
|
|
422
|
+
def add_transient[I](self, *, callable: Callable[..., I], override: bool = False):
|
|
398
423
|
...
|
|
399
424
|
|
|
400
425
|
@overload
|
|
401
|
-
def add_transient[T, I](self, *, t: type[T], callable: Callable[..., I]):
|
|
426
|
+
def add_transient[T, I](self, *, t: type[T], callable: Callable[..., I], override: bool = False):
|
|
402
427
|
...
|
|
403
428
|
|
|
404
|
-
def add_transient[T, I](self, *, t: type[T] = None, i: type[I] = None, callable: Callable[..., I] = None
|
|
429
|
+
def add_transient[T, I](self, *, t: type[T] = None, i: type[I] = None, callable: Callable[..., I] = None,
|
|
430
|
+
override: bool = False):
|
|
405
431
|
self._raise_if_closed()
|
|
406
|
-
self._add('transient', i=i, t=t, callable=callable)
|
|
432
|
+
self._add('transient', i=i, t=t, callable=callable, override=override)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dinkleberg
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.2
|
|
4
4
|
Summary: Your friendly neighbour when it comes to dependency management.
|
|
5
5
|
Project-URL: Homepage, https://github.com/DavidVollmers/dinkleberg
|
|
6
6
|
Project-URL: Documentation, https://github.com/DavidVollmers/dinkleberg/blob/main/libs/dinkleberg/README.md
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
dinkleberg/__init__.py,sha256=6gowHoL3xTWd2iyU09upgjXKUv_WWp6Tw1iqw2uz7Vc,192
|
|
2
|
-
dinkleberg/dependency_configurator.py,sha256=
|
|
2
|
+
dinkleberg/dependency_configurator.py,sha256=lS_IPK2nLdVPQZpYOxlk6pv1fzQ9MK2PdJ9ucOrptww,16514
|
|
3
3
|
dinkleberg/descriptor.py,sha256=ZtVwJihvCLugakHx201iX7Jm4A50Z0SzPu9zeHfD320,349
|
|
4
4
|
dinkleberg/typing.py,sha256=qAdSQomntQfI4bSWc9X32DXGftuyj56WP7nG3Pia7ZE,942
|
|
5
5
|
dinkleberg/fastapi/__init__.py,sha256=boj1ywpWhuuOjHLwdUha2EPBG2f1zbc374N35k1CJxk,352
|
|
6
|
-
dinkleberg-0.3.
|
|
7
|
-
dinkleberg-0.3.
|
|
8
|
-
dinkleberg-0.3.
|
|
9
|
-
dinkleberg-0.3.
|
|
6
|
+
dinkleberg-0.3.2.dist-info/METADATA,sha256=sKUDY2mt75smvk6Em79QVJXf8kgL16M1KYDxCVUvCes,1555
|
|
7
|
+
dinkleberg-0.3.2.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
8
|
+
dinkleberg-0.3.2.dist-info/top_level.txt,sha256=6TjbaJ_eyRzoxzz2r1Eu0hgYfxBBM2bOV3u_TJ8yjjw,11
|
|
9
|
+
dinkleberg-0.3.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|