Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,11 @@ jobs:
os: [ubuntu-latest]
python-version:
[
3.8,
3.9,
"3.10",
"3.11",
"3.12",
"3.13",
"3.14",
"pypy3.8",
"pypy3.9",
"pypy3.10",
"pypy3.11",
]
Expand Down
5 changes: 5 additions & 0 deletions CHANGES
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
Injector Change Log
===================

0.25.0
------

- Dropped support for Python 3.8 and 3.9. Python 3.10+ is now required.

0.24.0
------

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ The core values of Injector are:
* Documentation: https://injector.readthedocs.org
* Change log: https://injector.readthedocs.io/en/latest/changelog.html

Injector works with CPython 3.8+ and PyPy 3 implementing Python 3.8+.
Injector works with CPython 3.10+ and PyPy 3 implementing Python 3.10+.

A Quick Example
---------------
Expand Down
2 changes: 1 addition & 1 deletion docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ PyPI (installable, stable distributions): https://pypi.org/project/injector. You

pip install injector

Injector works with CPython 3.6+ and PyPy 3 implementing Python 3.6+.
Injector works with CPython 3.10+ and PyPy 3 implementing Python 3.10+.

Introduction
------------
Expand Down
38 changes: 6 additions & 32 deletions injector/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
from abc import ABCMeta, abstractmethod
from dataclasses import dataclass
from typing import (
TYPE_CHECKING,
Any,
Callable,
Collection,
Expand All @@ -45,24 +44,7 @@
overload,
)

try:
from typing import NoReturn
except ImportError:
from typing_extensions import NoReturn

# This is a messy, type-wise, because we not only have two potentially conflicting imports here
# The easiest way to make mypy happy here is to tell it the versions from typing_extensions are
# canonical. Since this typing_extensions import is only for mypy it'll work even without
# typing_extensions actually installed so all's good.
if TYPE_CHECKING:
from typing_extensions import Annotated, _AnnotatedAlias, get_type_hints
else:
# Ignoring errors here as typing_extensions stub doesn't know about those things yet
try:
from typing import Annotated, _AnnotatedAlias, get_type_hints
except ImportError:
from typing_extensions import Annotated, _AnnotatedAlias, get_type_hints

from typing import Annotated, NoReturn, _AnnotatedAlias, get_type_hints # type: ignore[attr-defined]

__author__ = 'Alec Thomas <alec@swapoff.org>'
__version__ = '0.24.0'
Expand Down Expand Up @@ -108,7 +90,7 @@ def wrapper(*args: Any, **kwargs: Any) -> Any:
InjectT = TypeVar('InjectT')
Inject = Annotated[InjectT, _inject_marker]
"""An experimental way to declare injectable dependencies utilizing a `PEP 593`_ implementation
in Python 3.9 and backported to Python 3.7+ in `typing_extensions`.
in Python 3.9.

Those two declarations are equivalent::

Expand Down Expand Up @@ -136,19 +118,18 @@ def fun(t: Inject[SomeType], s: SomeOtherType) -> None:
A way to inspect how various injection declarations interact with each other.

.. versionadded:: 0.18.0
.. note:: Requires Python 3.7+.
.. note:: Requires Python 3.9+.
.. note::

If you're using mypy you need the version 0.750 or newer to fully type-check code using this
construct.

.. _PEP 593: https://www.python.org/dev/peps/pep-0593/
.. _typing_extensions: https://pypi.org/project/typing-extensions/
"""

NoInject = Annotated[InjectT, _noinject_marker]
"""An experimental way to declare noninjectable dependencies utilizing a `PEP 593`_ implementation
in Python 3.9 and backported to Python 3.7+ in `typing_extensions`.
in Python 3.9.

Since :func:`inject` declares all function's parameters to be injectable there needs to be a way
to opt out of it. This has been provided by :func:`noninjectable` but `noninjectable` suffers from
Expand All @@ -175,14 +156,13 @@ def fun(a: TypeA, b: NoInject[TypeB]) -> None:
A way to inspect how various injection declarations interact with each other.

.. versionadded:: 0.18.0
.. note:: Requires Python 3.7+.
.. note:: Requires Python 3.9+.
.. note::

If you're using mypy you need the version 0.750 or newer to fully type-check code using this
construct.

.. _PEP 593: https://www.python.org/dev/peps/pep-0593/
.. _typing_extensions: https://pypi.org/project/typing-extensions/
"""


Expand Down Expand Up @@ -791,13 +771,7 @@ def _ensure_iterable(item_or_list: Union[T, List[T]]) -> List[T]:


def _punch_through_alias(type_: Any) -> type:
if (
sys.version_info < (3, 10)
and getattr(type_, '__qualname__', '') == 'NewType.<locals>.new_type'
or sys.version_info >= (3, 10)
and type(type_).__module__ == 'typing'
and type(type_).__name__ == 'NewType'
):
if type(type_).__module__ == 'typing' and type(type_).__name__ == 'NewType':
return type_.__supertype__
elif isinstance(type_, _AnnotatedAlias) and getattr(type_, '__metadata__', None) is not None:
return type_.__origin__
Expand Down
8 changes: 1 addition & 7 deletions injector_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,14 @@
"""Functional tests for the "Injector" dependency injection framework."""

import abc
import sys
import threading
import traceback
import warnings
from contextlib import contextmanager
from dataclasses import dataclass
from typing import Any, Literal, NewType, Optional, Union

if sys.version_info >= (3, 9):
from typing import Annotated
else:
from typing_extensions import Annotated
from typing import Annotated

from typing import Dict, List, NewType

Expand Down Expand Up @@ -2031,7 +2027,6 @@ def function(a: Inject[Inject[int]]) -> None:


# Tests https://github.com/alecthomas/injector/issues/202
@pytest.mark.skipif(sys.version_info < (3, 10), reason="Requires Python 3.10+")
def test_get_bindings_for_pep_604():
@inject
def function1(a: int | None) -> None:
Expand Down Expand Up @@ -2255,7 +2250,6 @@ def provide_second(self) -> Annotated[str, 'second']:


# Test for https://github.com/alecthomas/injector/issues/303
@pytest.mark.skipif(sys.version_info < (3, 10), reason="Requires Python 3.10+")
def test_can_inject_dataclass_with_literal_value():
@dataclass(slots=True)
class ServiceConfig:
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[tool.black]
line-length = 110
target_version = ['py36', 'py37']
target_version = ['py310']
skip_string_normalization = true
1 change: 0 additions & 1 deletion requirements-dev.in
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,3 @@ pytest-cov>=2.5.1
mypy;implementation_name=="cpython"
black;implementation_name=="cpython"
check-manifest
typing_extensions>=3.7.4;python_version<"3.9"
43 changes: 34 additions & 9 deletions requirements-dev.txt
Original file line number Diff line number Diff line change
@@ -1,20 +1,45 @@
black==24.3.0 ; implementation_name == "cpython"
# This file was autogenerated by uv via the following command:
# uv pip compile requirements-dev.in --output-file requirements-dev.txt
black==26.3.1
# via -r requirements-dev.in
build==1.0.3
# via check-manifest
check-manifest==0.49
# via -r requirements-dev.in
click==8.1.7
coverage[toml]==7.3.2
exceptiongroup==1.2.0
importlib-metadata==7.0.0
# via black
coverage==7.3.2
# via pytest-cov
iniconfig==2.0.0
mypy==1.7.1 ; implementation_name == "cpython"
# via pytest
mypy==1.7.1
# via -r requirements-dev.in
mypy-extensions==1.0.0
# via
# black
# mypy
packaging==25.0
pathspec==0.12.1
# via
# black
# build
# pytest
pathspec==1.0.4
# via black
platformdirs==4.1.0
# via black
pluggy==1.3.0
# via pytest
pyproject-hooks==1.0.0
# via build
pytest==7.4.3
# via
# -r requirements-dev.in
# pytest-cov
pytest-cov==4.1.0
tomli==2.0.1
typing-extensions==4.9.0 ; python_version < "3.9"
zipp==3.19.1
# via -r requirements-dev.in
pytokens==0.4.1
# via black
setuptools==82.0.1
# via check-manifest
typing-extensions==4.15.0
# via mypy
1 change: 0 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1 +0,0 @@
typing_extensions>=3.7.4;python_version<"3.9"
1 change: 0 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import sys
import warnings


warnings.filterwarnings("always", module=__name__)


Expand Down
Loading