python-injection 0.12.3__tar.gz → 0.13.0__tar.gz
Sign up to get free protection for your applications and to get access to all the features.
- python_injection-0.13.0/.gitignore +322 -0
- {python_injection-0.12.3 → python_injection-0.13.0}/PKG-INFO +14 -15
- {python_injection-0.12.3 → python_injection-0.13.0}/README.md +3 -2
- {python_injection-0.12.3 → python_injection-0.13.0}/injection/__init__.py +5 -0
- {python_injection-0.12.3 → python_injection-0.13.0}/injection/__init__.pyi +59 -48
- {python_injection-0.12.3 → python_injection-0.13.0}/injection/_core/common/asynchronous.py +12 -11
- {python_injection-0.12.3 → python_injection-0.13.0}/injection/_core/common/event.py +1 -1
- python_injection-0.13.0/injection/_core/common/key.py +5 -0
- {python_injection-0.12.3 → python_injection-0.13.0}/injection/_core/common/type.py +33 -2
- python_injection-0.13.0/injection/_core/injectables.py +179 -0
- {python_injection-0.12.3 → python_injection-0.13.0}/injection/_core/module.py +109 -46
- python_injection-0.13.0/injection/_core/scope.py +215 -0
- {python_injection-0.12.3 → python_injection-0.13.0}/injection/exceptions.py +12 -0
- python_injection-0.13.0/injection/integrations/fastapi.py +38 -0
- {python_injection-0.12.3 → python_injection-0.13.0}/injection/testing/__init__.py +2 -0
- python_injection-0.13.0/injection/testing/__init__.pyi +17 -0
- {python_injection-0.12.3 → python_injection-0.13.0}/injection/utils.py +7 -2
- {python_injection-0.12.3 → python_injection-0.13.0}/pyproject.toml +39 -32
- python_injection-0.12.3/injection/_core/common/threading.py +0 -11
- python_injection-0.12.3/injection/_core/injectables.py +0 -98
- python_injection-0.12.3/injection/integrations/fastapi.py +0 -63
- python_injection-0.12.3/injection/testing/__init__.pyi +0 -14
- {python_injection-0.12.3 → python_injection-0.13.0}/injection/_core/__init__.py +0 -0
- {python_injection-0.12.3 → python_injection-0.13.0}/injection/_core/common/__init__.py +0 -0
- {python_injection-0.12.3 → python_injection-0.13.0}/injection/_core/common/invertible.py +0 -0
- {python_injection-0.12.3 → python_injection-0.13.0}/injection/_core/common/lazy.py +0 -0
- {python_injection-0.12.3 → python_injection-0.13.0}/injection/_core/descriptors.py +0 -0
- {python_injection-0.12.3 → python_injection-0.13.0}/injection/_core/hook.py +0 -0
- {python_injection-0.12.3 → python_injection-0.13.0}/injection/integrations/__init__.py +0 -0
- {python_injection-0.12.3 → python_injection-0.13.0}/injection/py.typed +0 -0
@@ -0,0 +1,322 @@
|
|
1
|
+
# Created by https://www.toptal.com/developers/gitignore/api/python,pycharm,dotenv,macos
|
2
|
+
# Edit at https://www.toptal.com/developers/gitignore?templates=python,pycharm,dotenv,macos
|
3
|
+
|
4
|
+
### dotenv ###
|
5
|
+
.env
|
6
|
+
|
7
|
+
### macOS ###
|
8
|
+
# General
|
9
|
+
.DS_Store
|
10
|
+
.AppleDouble
|
11
|
+
.LSOverride
|
12
|
+
|
13
|
+
# Icon must end with two \r
|
14
|
+
Icon
|
15
|
+
|
16
|
+
|
17
|
+
# Thumbnails
|
18
|
+
._*
|
19
|
+
|
20
|
+
# Files that might appear in the root of a volume
|
21
|
+
.DocumentRevisions-V100
|
22
|
+
.fseventsd
|
23
|
+
.Spotlight-V100
|
24
|
+
.TemporaryItems
|
25
|
+
.Trashes
|
26
|
+
.VolumeIcon.icns
|
27
|
+
.com.apple.timemachine.donotpresent
|
28
|
+
|
29
|
+
# Directories potentially created on remote AFP share
|
30
|
+
.AppleDB
|
31
|
+
.AppleDesktop
|
32
|
+
Network Trash Folder
|
33
|
+
Temporary Items
|
34
|
+
.apdisk
|
35
|
+
|
36
|
+
### macOS Patch ###
|
37
|
+
# iCloud generated files
|
38
|
+
*.icloud
|
39
|
+
|
40
|
+
### PyCharm ###
|
41
|
+
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
|
42
|
+
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
43
|
+
|
44
|
+
# User-specific stuff
|
45
|
+
.idea/**/workspace.xml
|
46
|
+
.idea/**/tasks.xml
|
47
|
+
.idea/**/usage.statistics.xml
|
48
|
+
.idea/**/dictionaries
|
49
|
+
.idea/**/shelf
|
50
|
+
|
51
|
+
# AWS User-specific
|
52
|
+
.idea/**/aws.xml
|
53
|
+
|
54
|
+
# Generated files
|
55
|
+
.idea/**/contentModel.xml
|
56
|
+
|
57
|
+
# Sensitive or high-churn files
|
58
|
+
.idea/**/dataSources/
|
59
|
+
.idea/**/dataSources.ids
|
60
|
+
.idea/**/dataSources.local.xml
|
61
|
+
.idea/**/sqlDataSources.xml
|
62
|
+
.idea/**/dynamic.xml
|
63
|
+
.idea/**/uiDesigner.xml
|
64
|
+
.idea/**/dbnavigator.xml
|
65
|
+
|
66
|
+
# Gradle
|
67
|
+
.idea/**/gradle.xml
|
68
|
+
.idea/**/libraries
|
69
|
+
|
70
|
+
# Gradle and Maven with auto-import
|
71
|
+
# When using Gradle or Maven with auto-import, you should exclude module files,
|
72
|
+
# since they will be recreated, and may cause churn. Uncomment if using
|
73
|
+
# auto-import.
|
74
|
+
# .idea/artifacts
|
75
|
+
# .idea/compiler.xml
|
76
|
+
# .idea/jarRepositories.xml
|
77
|
+
# .idea/modules.xml
|
78
|
+
# .idea/*.iml
|
79
|
+
# .idea/modules
|
80
|
+
# *.iml
|
81
|
+
# *.ipr
|
82
|
+
|
83
|
+
# CMake
|
84
|
+
cmake-build-*/
|
85
|
+
|
86
|
+
# Mongo Explorer plugin
|
87
|
+
.idea/**/mongoSettings.xml
|
88
|
+
|
89
|
+
# File-based project format
|
90
|
+
*.iws
|
91
|
+
|
92
|
+
# IntelliJ
|
93
|
+
out/
|
94
|
+
|
95
|
+
# mpeltonen/sbt-idea plugin
|
96
|
+
.idea_modules/
|
97
|
+
|
98
|
+
# JIRA plugin
|
99
|
+
atlassian-ide-plugin.xml
|
100
|
+
|
101
|
+
# Cursive Clojure plugin
|
102
|
+
.idea/replstate.xml
|
103
|
+
|
104
|
+
# SonarLint plugin
|
105
|
+
.idea/sonarlint/
|
106
|
+
|
107
|
+
# Crashlytics plugin (for Android Studio and IntelliJ)
|
108
|
+
com_crashlytics_export_strings.xml
|
109
|
+
crashlytics.properties
|
110
|
+
crashlytics-build.properties
|
111
|
+
fabric.properties
|
112
|
+
|
113
|
+
# Editor-based Rest Client
|
114
|
+
.idea/httpRequests
|
115
|
+
|
116
|
+
# Android studio 3.1+ serialized cache file
|
117
|
+
.idea/caches/build_file_checksums.ser
|
118
|
+
|
119
|
+
### PyCharm Patch ###
|
120
|
+
# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721
|
121
|
+
|
122
|
+
# *.iml
|
123
|
+
# modules.xml
|
124
|
+
# .idea/misc.xml
|
125
|
+
# *.ipr
|
126
|
+
|
127
|
+
# Sonarlint plugin
|
128
|
+
# https://plugins.jetbrains.com/plugin/7973-sonarlint
|
129
|
+
.idea/**/sonarlint/
|
130
|
+
|
131
|
+
# SonarQube Plugin
|
132
|
+
# https://plugins.jetbrains.com/plugin/7238-sonarqube-community-plugin
|
133
|
+
.idea/**/sonarIssues.xml
|
134
|
+
|
135
|
+
# Markdown Navigator plugin
|
136
|
+
# https://plugins.jetbrains.com/plugin/7896-markdown-navigator-enhanced
|
137
|
+
.idea/**/markdown-navigator.xml
|
138
|
+
.idea/**/markdown-navigator-enh.xml
|
139
|
+
.idea/**/markdown-navigator/
|
140
|
+
|
141
|
+
# Cache file creation bug
|
142
|
+
# See https://youtrack.jetbrains.com/issue/JBR-2257
|
143
|
+
.idea/$CACHE_FILE$
|
144
|
+
|
145
|
+
# CodeStream plugin
|
146
|
+
# https://plugins.jetbrains.com/plugin/12206-codestream
|
147
|
+
.idea/codestream.xml
|
148
|
+
|
149
|
+
# Azure Toolkit for IntelliJ plugin
|
150
|
+
# https://plugins.jetbrains.com/plugin/8053-azure-toolkit-for-intellij
|
151
|
+
.idea/**/azureSettings.xml
|
152
|
+
|
153
|
+
### Python ###
|
154
|
+
# Byte-compiled / optimized / DLL files
|
155
|
+
__pycache__/
|
156
|
+
*.py[cod]
|
157
|
+
*$py.class
|
158
|
+
|
159
|
+
# C extensions
|
160
|
+
*.so
|
161
|
+
|
162
|
+
# Distribution / packaging
|
163
|
+
.Python
|
164
|
+
build/
|
165
|
+
develop-eggs/
|
166
|
+
dist/
|
167
|
+
downloads/
|
168
|
+
eggs/
|
169
|
+
.eggs/
|
170
|
+
lib/
|
171
|
+
lib64/
|
172
|
+
parts/
|
173
|
+
sdist/
|
174
|
+
var/
|
175
|
+
wheels/
|
176
|
+
share/python-wheels/
|
177
|
+
*.egg-info/
|
178
|
+
.installed.cfg
|
179
|
+
*.egg
|
180
|
+
MANIFEST
|
181
|
+
|
182
|
+
# PyInstaller
|
183
|
+
# Usually these files are written by a python script from a template
|
184
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
185
|
+
*.manifest
|
186
|
+
*.spec
|
187
|
+
|
188
|
+
# Installer logs
|
189
|
+
pip-log.txt
|
190
|
+
pip-delete-this-directory.txt
|
191
|
+
|
192
|
+
# Unit test / coverage reports
|
193
|
+
htmlcov/
|
194
|
+
.tox/
|
195
|
+
.nox/
|
196
|
+
.coverage
|
197
|
+
.coverage.*
|
198
|
+
.cache
|
199
|
+
nosetests.xml
|
200
|
+
coverage.xml
|
201
|
+
*.cover
|
202
|
+
*.py,cover
|
203
|
+
.hypothesis/
|
204
|
+
.pytest_cache/
|
205
|
+
cover/
|
206
|
+
|
207
|
+
# Translations
|
208
|
+
*.mo
|
209
|
+
*.pot
|
210
|
+
|
211
|
+
# Django stuff:
|
212
|
+
*.log
|
213
|
+
local_settings.py
|
214
|
+
db.sqlite3
|
215
|
+
db.sqlite3-journal
|
216
|
+
|
217
|
+
# Flask stuff:
|
218
|
+
instance/
|
219
|
+
.webassets-cache
|
220
|
+
|
221
|
+
# Scrapy stuff:
|
222
|
+
.scrapy
|
223
|
+
|
224
|
+
# Sphinx documentation
|
225
|
+
docs/_build/
|
226
|
+
|
227
|
+
# PyBuilder
|
228
|
+
.pybuilder/
|
229
|
+
target/
|
230
|
+
|
231
|
+
# Jupyter Notebook
|
232
|
+
.ipynb_checkpoints
|
233
|
+
|
234
|
+
# IPython
|
235
|
+
profile_default/
|
236
|
+
ipython_config.py
|
237
|
+
|
238
|
+
# pyenv
|
239
|
+
# For a library or package, you might want to ignore these files since the code is
|
240
|
+
# intended to run in multiple environments; otherwise, check them in:
|
241
|
+
# .python-version
|
242
|
+
|
243
|
+
# pipenv
|
244
|
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
245
|
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
246
|
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
247
|
+
# install all needed dependencies.
|
248
|
+
#Pipfile.lock
|
249
|
+
|
250
|
+
# poetry
|
251
|
+
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
252
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
253
|
+
# commonly ignored for libraries.
|
254
|
+
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
255
|
+
#poetry.lock
|
256
|
+
|
257
|
+
# pdm
|
258
|
+
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
259
|
+
#pdm.lock
|
260
|
+
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
|
261
|
+
# in version control.
|
262
|
+
# https://pdm.fming.dev/#use-with-ide
|
263
|
+
.pdm.toml
|
264
|
+
|
265
|
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
266
|
+
__pypackages__/
|
267
|
+
|
268
|
+
# Celery stuff
|
269
|
+
celerybeat-schedule
|
270
|
+
celerybeat.pid
|
271
|
+
|
272
|
+
# SageMath parsed files
|
273
|
+
*.sage.py
|
274
|
+
|
275
|
+
# Environments
|
276
|
+
.venv
|
277
|
+
env/
|
278
|
+
venv/
|
279
|
+
ENV/
|
280
|
+
env.bak/
|
281
|
+
venv.bak/
|
282
|
+
|
283
|
+
# Spyder project settings
|
284
|
+
.spyderproject
|
285
|
+
.spyproject
|
286
|
+
|
287
|
+
# Rope project settings
|
288
|
+
.ropeproject
|
289
|
+
|
290
|
+
# mkdocs documentation
|
291
|
+
/site
|
292
|
+
|
293
|
+
# mypy
|
294
|
+
.mypy_cache/
|
295
|
+
.dmypy.json
|
296
|
+
dmypy.json
|
297
|
+
|
298
|
+
# Pyre type checker
|
299
|
+
.pyre/
|
300
|
+
|
301
|
+
# pytype static type analyzer
|
302
|
+
.pytype/
|
303
|
+
|
304
|
+
# Cython debug symbols
|
305
|
+
cython_debug/
|
306
|
+
|
307
|
+
# PyCharm
|
308
|
+
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
309
|
+
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
310
|
+
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
311
|
+
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
312
|
+
#.idea/
|
313
|
+
|
314
|
+
# End of https://www.toptal.com/developers/gitignore/api/python,pycharm,dotenv,macos
|
315
|
+
|
316
|
+
# Pyenv
|
317
|
+
.python-version
|
318
|
+
|
319
|
+
# Code editors
|
320
|
+
.fleet/
|
321
|
+
.idea/
|
322
|
+
.vscode/
|
@@ -1,31 +1,30 @@
|
|
1
|
-
Metadata-Version: 2.
|
1
|
+
Metadata-Version: 2.4
|
2
2
|
Name: python-injection
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.13.0
|
4
4
|
Summary: Fast and easy dependency injection framework.
|
5
|
-
|
5
|
+
Project-URL: Repository, https://github.com/100nm/python-injection
|
6
|
+
Author: remimd
|
6
7
|
License: MIT
|
7
8
|
Keywords: dependencies,dependency,inject,injection
|
8
|
-
Author: remimd
|
9
|
-
Requires-Python: >=3.12, <4
|
10
9
|
Classifier: Development Status :: 4 - Beta
|
10
|
+
Classifier: Intended Audience :: Developers
|
11
|
+
Classifier: Natural Language :: English
|
12
|
+
Classifier: Operating System :: OS Independent
|
13
|
+
Classifier: Programming Language :: Python
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
15
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
11
16
|
Classifier: Topic :: Software Development :: Libraries
|
12
17
|
Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
|
13
18
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
14
19
|
Classifier: Topic :: Software Development :: Testing
|
15
|
-
Classifier: Programming Language :: Python
|
16
|
-
Classifier: Programming Language :: Python :: 3
|
17
|
-
Classifier: Programming Language :: Python :: 3 :: Only
|
18
|
-
Classifier: Operating System :: OS Independent
|
19
|
-
Classifier: Intended Audience :: Developers
|
20
|
-
Classifier: Natural Language :: English
|
21
20
|
Classifier: Typing :: Typed
|
22
|
-
|
21
|
+
Requires-Python: <4,>=3.12
|
23
22
|
Description-Content-Type: text/markdown
|
24
23
|
|
25
24
|
# python-injection
|
26
25
|
|
27
26
|
[](https://github.com/100nm/python-injection)
|
28
|
-
[](https://pypi.org/project/python-injection
|
27
|
+
[](https://pypi.org/project/python-injection)
|
29
28
|
[](https://github.com/astral-sh/ruff)
|
30
29
|
|
31
30
|
Fast and easy dependency injection framework.
|
@@ -80,9 +79,9 @@ if __name__ == "__main__":
|
|
80
79
|
## Resources
|
81
80
|
|
82
81
|
* [**Basic usage**](https://github.com/100nm/python-injection/tree/prod/documentation/basic-usage.md)
|
82
|
+
* [**Scoped dependencies**](https://github.com/100nm/python-injection/tree/prod/documentation/scoped-dependencies.md)
|
83
83
|
* [**Testing**](https://github.com/100nm/python-injection/tree/prod/documentation/testing.md)
|
84
84
|
* [**Advanced usage**](https://github.com/100nm/python-injection/tree/prod/documentation/advanced-usage.md)
|
85
85
|
* [**Utils**](https://github.com/100nm/python-injection/tree/prod/documentation/utils.md)
|
86
86
|
* [**Integrations**](https://github.com/100nm/python-injection/tree/prod/documentation/integrations.md)
|
87
|
-
* [**Concrete example**](https://github.com/100nm/python-injection
|
88
|
-
|
87
|
+
* [**Concrete example**](https://github.com/100nm/python-injection-example)
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# python-injection
|
2
2
|
|
3
3
|
[](https://github.com/100nm/python-injection)
|
4
|
-
[](https://pypi.org/project/python-injection
|
4
|
+
[](https://pypi.org/project/python-injection)
|
5
5
|
[](https://github.com/astral-sh/ruff)
|
6
6
|
|
7
7
|
Fast and easy dependency injection framework.
|
@@ -56,8 +56,9 @@ if __name__ == "__main__":
|
|
56
56
|
## Resources
|
57
57
|
|
58
58
|
* [**Basic usage**](https://github.com/100nm/python-injection/tree/prod/documentation/basic-usage.md)
|
59
|
+
* [**Scoped dependencies**](https://github.com/100nm/python-injection/tree/prod/documentation/scoped-dependencies.md)
|
59
60
|
* [**Testing**](https://github.com/100nm/python-injection/tree/prod/documentation/testing.md)
|
60
61
|
* [**Advanced usage**](https://github.com/100nm/python-injection/tree/prod/documentation/advanced-usage.md)
|
61
62
|
* [**Utils**](https://github.com/100nm/python-injection/tree/prod/documentation/utils.md)
|
62
63
|
* [**Integrations**](https://github.com/100nm/python-injection/tree/prod/documentation/integrations.md)
|
63
|
-
* [**Concrete example**](https://github.com/100nm/python-injection
|
64
|
+
* [**Concrete example**](https://github.com/100nm/python-injection-example)
|
@@ -1,6 +1,7 @@
|
|
1
1
|
from ._core.descriptors import LazyInstance
|
2
2
|
from ._core.injectables import Injectable
|
3
3
|
from ._core.module import Mode, Module, Priority, mod
|
4
|
+
from ._core.scope import adefine_scope, define_scope
|
4
5
|
|
5
6
|
__all__ = (
|
6
7
|
"Injectable",
|
@@ -8,16 +9,19 @@ __all__ = (
|
|
8
9
|
"Mode",
|
9
10
|
"Module",
|
10
11
|
"Priority",
|
12
|
+
"adefine_scope",
|
11
13
|
"afind_instance",
|
12
14
|
"aget_instance",
|
13
15
|
"aget_lazy_instance",
|
14
16
|
"constant",
|
17
|
+
"define_scope",
|
15
18
|
"find_instance",
|
16
19
|
"get_instance",
|
17
20
|
"get_lazy_instance",
|
18
21
|
"inject",
|
19
22
|
"injectable",
|
20
23
|
"mod",
|
24
|
+
"scoped",
|
21
25
|
"set_constant",
|
22
26
|
"should_be_injectable",
|
23
27
|
"singleton",
|
@@ -32,6 +36,7 @@ get_instance = mod().get_instance
|
|
32
36
|
get_lazy_instance = mod().get_lazy_instance
|
33
37
|
inject = mod().inject
|
34
38
|
injectable = mod().injectable
|
39
|
+
scoped = mod().scoped
|
35
40
|
set_constant = mod().set_constant
|
36
41
|
should_be_injectable = mod().should_be_injectable
|
37
42
|
singleton = mod().singleton
|
@@ -1,17 +1,9 @@
|
|
1
1
|
from abc import abstractmethod
|
2
|
-
from collections.abc import Awaitable, Callable
|
3
|
-
from contextlib import
|
2
|
+
from collections.abc import AsyncIterator, Awaitable, Callable, Iterator
|
3
|
+
from contextlib import asynccontextmanager, contextmanager
|
4
4
|
from enum import Enum
|
5
5
|
from logging import Logger
|
6
|
-
from typing import
|
7
|
-
Any,
|
8
|
-
ContextManager,
|
9
|
-
Protocol,
|
10
|
-
Self,
|
11
|
-
final,
|
12
|
-
overload,
|
13
|
-
runtime_checkable,
|
14
|
-
)
|
6
|
+
from typing import Any, Final, Protocol, Self, final, overload, runtime_checkable
|
15
7
|
|
16
8
|
from ._core.common.invertible import Invertible as _Invertible
|
17
9
|
from ._core.common.type import InputType as _InputType
|
@@ -19,27 +11,47 @@ from ._core.common.type import TypeInfo as _TypeInfo
|
|
19
11
|
from ._core.module import InjectableFactory as _InjectableFactory
|
20
12
|
from ._core.module import ModeStr, PriorityStr
|
21
13
|
|
22
|
-
|
14
|
+
__MODULE: Final[Module] = ...
|
23
15
|
|
24
|
-
afind_instance =
|
25
|
-
aget_instance =
|
26
|
-
aget_lazy_instance =
|
27
|
-
constant =
|
28
|
-
find_instance =
|
29
|
-
get_instance =
|
30
|
-
get_lazy_instance =
|
31
|
-
inject =
|
32
|
-
injectable =
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
del _
|
16
|
+
afind_instance = __MODULE.afind_instance
|
17
|
+
aget_instance = __MODULE.aget_instance
|
18
|
+
aget_lazy_instance = __MODULE.aget_lazy_instance
|
19
|
+
constant = __MODULE.constant
|
20
|
+
find_instance = __MODULE.find_instance
|
21
|
+
get_instance = __MODULE.get_instance
|
22
|
+
get_lazy_instance = __MODULE.get_lazy_instance
|
23
|
+
inject = __MODULE.inject
|
24
|
+
injectable = __MODULE.injectable
|
25
|
+
scoped = __MODULE.scoped
|
26
|
+
set_constant = __MODULE.set_constant
|
27
|
+
should_be_injectable = __MODULE.should_be_injectable
|
28
|
+
singleton = __MODULE.singleton
|
38
29
|
|
30
|
+
@asynccontextmanager
|
31
|
+
def adefine_scope(name: str, *, shared: bool = ...) -> AsyncIterator[None]: ...
|
32
|
+
@contextmanager
|
33
|
+
def define_scope(name: str, *, shared: bool = ...) -> Iterator[None]: ...
|
39
34
|
def mod(name: str = ..., /) -> Module:
|
40
35
|
"""
|
41
36
|
Short syntax for `Module.from_name`.
|
42
37
|
"""
|
38
|
+
@runtime_checkable
|
39
|
+
class Injectable[T](Protocol):
|
40
|
+
@property
|
41
|
+
def is_locked(self) -> bool: ...
|
42
|
+
def unlock(self) -> None: ...
|
43
|
+
@abstractmethod
|
44
|
+
async def aget_instance(self) -> T: ...
|
45
|
+
@abstractmethod
|
46
|
+
def get_instance(self) -> T: ...
|
47
|
+
|
48
|
+
class LazyInstance[T]:
|
49
|
+
def __init__(self, cls: _InputType[T], module: Module = ...) -> None: ...
|
50
|
+
@overload
|
51
|
+
def __get__(self, instance: object, owner: type | None = ...) -> T: ...
|
52
|
+
@overload
|
53
|
+
def __get__(self, instance: None = ..., owner: type | None = ...) -> Self: ...
|
54
|
+
|
43
55
|
@final
|
44
56
|
class Module:
|
45
57
|
"""
|
@@ -94,6 +106,21 @@ class Module:
|
|
94
106
|
always be the same.
|
95
107
|
"""
|
96
108
|
|
109
|
+
def scoped[**P, T](
|
110
|
+
self,
|
111
|
+
scope_name: str,
|
112
|
+
/,
|
113
|
+
*,
|
114
|
+
inject: bool = ...,
|
115
|
+
on: _TypeInfo[T] = (),
|
116
|
+
mode: Mode | ModeStr = ...,
|
117
|
+
) -> Any:
|
118
|
+
"""
|
119
|
+
Decorator applicable to a class or function or generator function. It is used
|
120
|
+
to indicate how the scoped instance will be constructed. At injection time, the
|
121
|
+
injected instance is retrieved from the scope.
|
122
|
+
"""
|
123
|
+
|
97
124
|
def should_be_injectable[T](self, wrapped: type[T] = ..., /) -> Any:
|
98
125
|
"""
|
99
126
|
Decorator applicable to a class. It is used to specify whether an injectable
|
@@ -233,12 +260,13 @@ class Module:
|
|
233
260
|
Function to remove a module in use.
|
234
261
|
"""
|
235
262
|
|
263
|
+
@contextmanager
|
236
264
|
def use_temporarily(
|
237
265
|
self,
|
238
266
|
module: Module,
|
239
267
|
*,
|
240
268
|
priority: Priority | PriorityStr = ...,
|
241
|
-
) ->
|
269
|
+
) -> Iterator[None]:
|
242
270
|
"""
|
243
271
|
Context manager or decorator for temporary use of a module.
|
244
272
|
"""
|
@@ -275,30 +303,13 @@ class Module:
|
|
275
303
|
Class method for getting the default module.
|
276
304
|
"""
|
277
305
|
|
278
|
-
@final
|
279
|
-
class Priority(Enum):
|
280
|
-
LOW = ...
|
281
|
-
HIGH = ...
|
282
|
-
|
283
|
-
@runtime_checkable
|
284
|
-
class Injectable[T](Protocol):
|
285
|
-
@property
|
286
|
-
def is_locked(self) -> bool: ...
|
287
|
-
def unlock(self) -> None: ...
|
288
|
-
@abstractmethod
|
289
|
-
async def aget_instance(self) -> T: ...
|
290
|
-
@abstractmethod
|
291
|
-
def get_instance(self) -> T: ...
|
292
|
-
|
293
306
|
@final
|
294
307
|
class Mode(Enum):
|
295
308
|
FALLBACK = ...
|
296
309
|
NORMAL = ...
|
297
310
|
OVERRIDE = ...
|
298
311
|
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
@overload
|
304
|
-
def __get__(self, instance: None = ..., owner: type | None = ...) -> Self: ...
|
312
|
+
@final
|
313
|
+
class Priority(Enum):
|
314
|
+
LOW = ...
|
315
|
+
HIGH = ...
|
@@ -1,10 +1,19 @@
|
|
1
1
|
import asyncio
|
2
2
|
from abc import abstractmethod
|
3
|
-
from collections.abc import Awaitable, Callable, Generator
|
3
|
+
from collections.abc import Awaitable, Callable, Coroutine, Generator
|
4
4
|
from dataclasses import dataclass
|
5
5
|
from typing import Any, Protocol, runtime_checkable
|
6
6
|
|
7
7
|
|
8
|
+
def run_sync[T](coroutine: Coroutine[Any, Any, T]) -> T:
|
9
|
+
loop = asyncio.get_event_loop()
|
10
|
+
|
11
|
+
try:
|
12
|
+
return loop.run_until_complete(coroutine)
|
13
|
+
finally:
|
14
|
+
coroutine.close()
|
15
|
+
|
16
|
+
|
8
17
|
@dataclass(repr=False, eq=False, frozen=True, slots=True)
|
9
18
|
class SimpleAwaitable[T](Awaitable[T]):
|
10
19
|
callable: Callable[..., Awaitable[T]]
|
@@ -28,21 +37,13 @@ class Caller[**P, T](Protocol):
|
|
28
37
|
|
29
38
|
@dataclass(repr=False, eq=False, frozen=True, slots=True)
|
30
39
|
class AsyncCaller[**P, T](Caller[P, T]):
|
31
|
-
callable: Callable[P,
|
40
|
+
callable: Callable[P, Coroutine[Any, Any, T]]
|
32
41
|
|
33
42
|
async def acall(self, /, *args: P.args, **kwargs: P.kwargs) -> T:
|
34
43
|
return await self.callable(*args, **kwargs)
|
35
44
|
|
36
45
|
def call(self, /, *args: P.args, **kwargs: P.kwargs) -> T:
|
37
|
-
|
38
|
-
|
39
|
-
if loop.is_running():
|
40
|
-
raise RuntimeError(
|
41
|
-
"Can't call an asynchronous function in a synchronous context."
|
42
|
-
)
|
43
|
-
|
44
|
-
coroutine = self.callable(*args, **kwargs)
|
45
|
-
return loop.run_until_complete(coroutine)
|
46
|
+
return run_sync(self.callable(*args, **kwargs))
|
46
47
|
|
47
48
|
|
48
49
|
@dataclass(repr=False, eq=False, frozen=True, slots=True)
|
@@ -25,7 +25,7 @@ class EventChannel:
|
|
25
25
|
@contextmanager
|
26
26
|
def dispatch(self, event: Event) -> Iterator[None]:
|
27
27
|
with ExitStack() as stack:
|
28
|
-
for listener in
|
28
|
+
for listener in self.__listeners:
|
29
29
|
context_manager = listener.on_event(event)
|
30
30
|
|
31
31
|
if context_manager is None:
|
@@ -1,4 +1,12 @@
|
|
1
|
-
from collections.abc import
|
1
|
+
from collections.abc import (
|
2
|
+
AsyncGenerator,
|
3
|
+
AsyncIterable,
|
4
|
+
AsyncIterator,
|
5
|
+
Callable,
|
6
|
+
Generator,
|
7
|
+
Iterable,
|
8
|
+
Iterator,
|
9
|
+
)
|
2
10
|
from inspect import isfunction
|
3
11
|
from types import GenericAlias, UnionType
|
4
12
|
from typing import (
|
@@ -23,7 +31,7 @@ def get_return_types(*args: TypeInfo[Any]) -> Iterator[InputType[Any]]:
|
|
23
31
|
):
|
24
32
|
inner_args = arg
|
25
33
|
|
26
|
-
elif isfunction(arg) and (return_type :=
|
34
|
+
elif isfunction(arg) and (return_type := get_return_hint(arg)):
|
27
35
|
inner_args = (return_type,)
|
28
36
|
|
29
37
|
else:
|
@@ -33,6 +41,29 @@ def get_return_types(*args: TypeInfo[Any]) -> Iterator[InputType[Any]]:
|
|
33
41
|
yield from get_return_types(*inner_args)
|
34
42
|
|
35
43
|
|
44
|
+
def get_return_hint[T](function: Callable[..., T]) -> InputType[T] | None:
|
45
|
+
return get_type_hints(function).get("return")
|
46
|
+
|
47
|
+
|
48
|
+
def get_yield_hint[T](
|
49
|
+
function: Callable[..., Iterator[T]] | Callable[..., AsyncIterator[T]],
|
50
|
+
) -> InputType[T] | None:
|
51
|
+
return_type = get_return_hint(function)
|
52
|
+
|
53
|
+
if get_origin(return_type) not in {
|
54
|
+
AsyncGenerator,
|
55
|
+
AsyncIterable,
|
56
|
+
AsyncIterator,
|
57
|
+
Generator,
|
58
|
+
Iterable,
|
59
|
+
Iterator,
|
60
|
+
}:
|
61
|
+
return None
|
62
|
+
|
63
|
+
args = get_args(return_type)
|
64
|
+
return next(iter(args), None)
|
65
|
+
|
66
|
+
|
36
67
|
def standardize_types(
|
37
68
|
*types: InputType[Any],
|
38
69
|
with_origin: bool = False,
|