python-injection 0.12.3__tar.gz → 0.13.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.
- 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,
|