Skip to content

Commit 65d3513

Browse files
committed
Merge branch 'release/4.49.0'
2 parents 964d932 + 5f7aa1c commit 65d3513

48 files changed

Lines changed: 1544 additions & 488 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/dependabot.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
version: 2
2+
updates:
3+
- package-ecosystem: github-actions
4+
directory: "/"
5+
open-pull-requests-limit: 2
6+
schedule:
7+
interval: monthly

.github/workflows/publishing.yml

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,14 @@ jobs:
1212
name: Run tests
1313
runs-on: ubuntu-24.04
1414
steps:
15-
- uses: actions/checkout@v3
16-
- uses: actions/setup-python@v4
15+
- uses: actions/checkout@v6
16+
- uses: actions/setup-python@v6
1717
with:
18-
python-version: 3.13
18+
python-version: 3.14
1919
- run: pip install tox
2020
- run: tox
2121
env:
22-
TOXENV: 3.13
22+
TOXENV: 3.14
2323

2424
linters:
2525
name: Run linters
@@ -28,10 +28,10 @@ jobs:
2828
matrix:
2929
toxenv: [flake8, pydocstyle, mypy, pylint]
3030
steps:
31-
- uses: actions/checkout@v3
32-
- uses: actions/setup-python@v4
31+
- uses: actions/checkout@v6
32+
- uses: actions/setup-python@v6
3333
with:
34-
python-version: 3.13
34+
python-version: 3.14
3535
- run: pip install tox
3636
- run: tox
3737
env:
@@ -42,14 +42,14 @@ jobs:
4242
needs: [tests, linters]
4343
runs-on: ubuntu-24.04
4444
steps:
45-
- uses: actions/checkout@v3
46-
- uses: actions/setup-python@v4
45+
- uses: actions/checkout@v6
46+
- uses: actions/setup-python@v6
4747
with:
48-
python-version: 3.13
48+
python-version: 3.14
4949
- run: |
5050
python -m pip install --upgrade build
5151
python -m build --sdist
52-
- uses: actions/upload-artifact@v4
52+
- uses: actions/upload-artifact@v7
5353
with:
5454
name: cibw-sdist
5555
path: ./dist/*
@@ -63,15 +63,16 @@ jobs:
6363
os: [ubuntu-24.04, ubuntu-24.04-arm, windows-2022, macos-14]
6464
env:
6565
CIBW_ENABLE: pypy
66+
CIBW_SKIP: "cp3??t-*"
6667
CIBW_ENVIRONMENT: >-
6768
PIP_CONFIG_SETTINGS="build_ext=-j4"
6869
DEPENDENCY_INJECTOR_LIMITED_API="1"
6970
CFLAGS="-g0"
7071
steps:
71-
- uses: actions/checkout@v3
72+
- uses: actions/checkout@v6
7273
- name: Build wheels
73-
uses: pypa/cibuildwheel@v3.0.0
74-
- uses: actions/upload-artifact@v4
74+
uses: pypa/cibuildwheel@v3.4.0
75+
- uses: actions/upload-artifact@v7
7576
with:
7677
name: cibw-wheels-${{ matrix.os }}-${{ strategy.job-index }}
7778
path: ./wheelhouse/*.whl
@@ -84,7 +85,7 @@ jobs:
8485
permissions:
8586
id-token: write
8687
steps:
87-
- uses: actions/download-artifact@v4
88+
- uses: actions/download-artifact@v8
8889
with:
8990
pattern: cibw-*
9091
path: dist
@@ -101,7 +102,7 @@ jobs:
101102
permissions:
102103
id-token: write
103104
steps:
104-
- uses: actions/download-artifact@v4
105+
- uses: actions/download-artifact@v8
105106
with:
106107
pattern: cibw-*
107108
path: dist
@@ -113,10 +114,10 @@ jobs:
113114
needs: [publish]
114115
runs-on: ubuntu-24.04
115116
steps:
116-
- uses: actions/checkout@v3
117-
- uses: actions/setup-python@v4
117+
- uses: actions/checkout@v6
118+
- uses: actions/setup-python@v6
118119
with:
119-
python-version: 3.13
120+
python-version: 3.14
120121
- run: pip install awscli
121122
- run: pip install -r requirements-doc.txt
122123
- run: pip install -e .

.github/workflows/tests-and-linters.yml

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@ jobs:
99
runs-on: ubuntu-latest
1010
strategy:
1111
matrix:
12-
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"]
12+
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13", "3.14"]
1313
steps:
14-
- uses: actions/checkout@v3
15-
- uses: actions/setup-python@v4
14+
- uses: actions/checkout@v6
15+
- uses: actions/setup-python@v6
1616
with:
1717
python-version: ${{ matrix.python-version }}
1818
- run: pip install tox
@@ -25,10 +25,10 @@ jobs:
2525
name: Run tests with different pydantic versions
2626
runs-on: ubuntu-latest
2727
steps:
28-
- uses: actions/checkout@v3
29-
- uses: actions/setup-python@v4
28+
- uses: actions/checkout@v6
29+
- uses: actions/setup-python@v6
3030
with:
31-
python-version: "3.12"
31+
python-version: "3.14"
3232
- run: pip install tox
3333
- run: tox -e pydantic-v1,pydantic-v2
3434

@@ -41,10 +41,10 @@ jobs:
4141
COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_REPO_TOKEN }}
4242
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
4343
steps:
44-
- uses: actions/checkout@v3
45-
- uses: actions/setup-python@v4
44+
- uses: actions/checkout@v6
45+
- uses: actions/setup-python@v6
4646
with:
47-
python-version: 3.12
47+
python-version: 3.14
4848
- run: pip install tox
4949
- run: tox -vv
5050
env:
@@ -57,10 +57,10 @@ jobs:
5757
matrix:
5858
toxenv: [flake8, pydocstyle, mypy, pylint]
5959
steps:
60-
- uses: actions/checkout@v3
61-
- uses: actions/setup-python@v4
60+
- uses: actions/checkout@v6
61+
- uses: actions/setup-python@v6
6262
with:
63-
python-version: 3.13
63+
python-version: 3.14
6464
- run: pip install tox
6565
- run: tox
6666
env:

docs/main/changelog.rst

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,19 @@ that were made in every particular version.
77
From version 0.7.6 *Dependency Injector* framework strictly
88
follows `Semantic versioning`_
99

10+
4.49.0
11+
------
12+
13+
- Python 3.14 support
14+
- Fix Pydantic v2 deprecation warning triggering on settings class import
15+
- Add missing warn_unresolved parameter to WiringConfiguration in ``containers.pyi``. Thanks to `@jonathandannenberg <https://github.com/jonathandannenberg>`_ for `#951 <https://github.com/ets-labs/python-dependency-injector/pull/951>`_.
16+
- Add keep_cache argument to Container.wire typings. Thanks to `@romantolkachyov <https://github.com/romantolkachyov>`_ for `#952 <https://github.com/ets-labs/python-dependency-injector/pull/952>`_.
17+
- Use assert_type for type-stub checks. Thanks to `@leonarduschen <https://github.com/leonarduschen>`_ for `#934 <https://github.com/ets-labs/python-dependency-injector/issues/934>`_, `#953 <https://github.com/ets-labs/python-dependency-injector/issues/953>`_.
18+
- Add provided()<func>.call ``*args``, ``**kwargs`` arguments. Thanks to `@pavalso <https://github.com/pavalso>`_ for `#946 <https://github.com/ets-labs/python-dependency-injector/pull/946>`_.
19+
- Add context local resource. Thanks to `@elina-israyelyan <https://github.com/elina-israyelyan>`_ for `#931 <https://github.com/ets-labs/python-dependency-injector/pull/931>`_.
20+
- Update CI/CD to ``actions/checkout@v6``, ``actions/setup-python@v6``, ``actions/download-artifact@v8``, ``actions/upload-artifact@v7`` and ``pypa/[email protected]``.
21+
- Add dependabot config for GitHub Actions
22+
1023
4.48.3
1124
------
1225

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
.. _context-local-resource-provider:
2+
3+
Context Local Resource provider
4+
================================
5+
6+
.. meta::
7+
:keywords: Python,DI,Dependency injection,IoC,Inversion of Control,Resource,Context Local,
8+
Context Variables,Singleton,Per-context
9+
:description: Context Local Resource provider provides a component with initialization and shutdown
10+
that is scoped to execution context using contextvars. This page demonstrates how to
11+
use context local resource provider.
12+
13+
.. currentmodule:: dependency_injector.providers
14+
15+
``ContextLocalResource`` inherits from :ref:`resource-provider` and uses the same initialization and shutdown logic
16+
as the standard ``Resource`` provider.
17+
It extends it with context-local storage using Python's ``contextvars`` module.
18+
This means that objects are context local singletons - the same context will
19+
receive the same instance, but different execution contexts will have their own separate instances.
20+
21+
This is particularly useful in asynchronous applications where you need per-request resource instances
22+
(such as database sessions) that are automatically cleaned up when the request context ends.
23+
Example:
24+
25+
.. literalinclude:: ../../examples/providers/context_local_resource.py
26+
:language: python
27+
:lines: 3-
28+
29+
30+
31+
.. disqus::
32+

docs/providers/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ Providers module API docs - :py:mod:`dependency_injector.providers`
4646
dict
4747
configuration
4848
resource
49+
context_local_resource
4950
aggregate
5051
selector
5152
dependency

docs/providers/resource.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ Resource provider
2121
Resource providers help to initialize and configure logging, event loop, thread or process pool, etc.
2222

2323
Resource provider is similar to ``Singleton``. Resource initialization happens only once.
24+
If you need a context local singleton (where each execution context has its own instance),
25+
see :ref:`context-local-resource-provider`.
26+
2427
You can make injections and use provided instance the same way like you do with any other provider.
2528

2629
.. code-block:: python
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
from uuid import uuid4
2+
3+
from fastapi import Depends, FastAPI
4+
5+
from dependency_injector import containers, providers
6+
from dependency_injector.wiring import Closing, Provide, inject
7+
8+
global_list = []
9+
10+
11+
class AsyncSessionLocal:
12+
def __init__(self):
13+
self.id = uuid4()
14+
15+
async def __aenter__(self):
16+
print("Entering session !")
17+
return self
18+
19+
async def __aexit__(self, exc_type, exc_val, exc_tb):
20+
print("Closing session !")
21+
22+
async def execute(self, user_input):
23+
return f"Executing {user_input} in session {self.id}"
24+
25+
26+
app = FastAPI()
27+
28+
29+
class Container(containers.DeclarativeContainer):
30+
db_session = providers.ContextLocalResource(AsyncSessionLocal)
31+
32+
33+
@app.get("/")
34+
@inject
35+
async def index(db: AsyncSessionLocal = Depends(Closing[Provide["db_session"]])):
36+
if db.id in global_list:
37+
raise Exception("The db session was already used") # never reaches here
38+
global_list.append(db.id)
39+
res = await db.execute("SELECT 1")
40+
return str(res)
41+
42+
43+
if __name__ == "__main__":
44+
import uvicorn
45+
46+
container = Container()
47+
container.wire(modules=["__main__"])
48+
uvicorn.run(app, host="localhost", port=8000)
49+
container.unwire()

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ classifiers = [
3737
"Programming Language :: Python :: 3.11",
3838
"Programming Language :: Python :: 3.12",
3939
"Programming Language :: Python :: 3.13",
40+
"Programming Language :: Python :: 3.14",
4041
"Programming Language :: Python :: Implementation :: CPython",
4142
"Programming Language :: Python :: Implementation :: PyPy",
4243
"Framework :: AsyncIO",

src/dependency_injector/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"""Top-level package."""
22

3-
__version__ = "4.48.3"
3+
__version__ = "4.49.0"
44
"""Version number.
55
66
:type: str

0 commit comments

Comments
 (0)