diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 437f61a..01b08f6 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -7,6 +7,6 @@ repos: language: system files: ^minject/.* - repo: https://github.com/duolingo/pre-commit-hooks.git - rev: 1.7.3 + rev: 1.8.0 hooks: - id: duolingo diff --git a/minject/inject.py b/minject/inject.py index aea9d75..ebf9766 100644 --- a/minject/inject.py +++ b/minject/inject.py @@ -55,8 +55,7 @@ def __bool__(self): # Overload for when we _cannot_ infer what `T` will be from a call to bind @overload -def bind(_close: None = None, **bindings: DeferredAny) -> Callable[[Type[T]], Type[T]]: - ... +def bind(_close: None = None, **bindings: DeferredAny) -> Callable[[Type[T]], Type[T]]: ... # Overload for when we _can_ infer what `T` will be from a call to bind. @@ -64,8 +63,7 @@ def bind(_close: None = None, **bindings: DeferredAny) -> Callable[[Type[T]], Ty def bind( _close: Optional[Callable[[T], None]] = None, **bindings: DeferredAny, -) -> Callable[[Type[T]], Type[T]]: - ... +) -> Callable[[Type[T]], Type[T]]: ... def bind( @@ -198,18 +196,15 @@ def __repr__(self) -> str: @overload -def reference(key: RegistryMetadata[T]) -> _RegistryReference[T]: - ... +def reference(key: RegistryMetadata[T]) -> _RegistryReference[T]: ... @overload -def reference(key: str) -> _RegistryReference: - ... +def reference(key: str) -> _RegistryReference: ... @overload -def reference(key: Type[T], **bindings: DeferredAny) -> _RegistryReference[T]: - ... +def reference(key: Type[T], **bindings: DeferredAny) -> _RegistryReference[T]: ... def reference(key, **bindings): diff --git a/minject/inject_attrs.py b/minject/inject_attrs.py index c3388fa..d859cdb 100644 --- a/minject/inject_attrs.py +++ b/minject/inject_attrs.py @@ -92,7 +92,7 @@ class _BindingKey: class_lineno: int # The line containing the "class" keyword. -_key_binding_mapping: DefaultDict[_BindingKey, dict] = defaultdict(lambda: {}) +_key_binding_mapping: DefaultDict[_BindingKey, dict] = defaultdict(dict) def inject_field(binding=_T, **attr_field_kwargs) -> Any: diff --git a/minject/model.py b/minject/model.py index 16bcca3..6bfc888 100644 --- a/minject/model.py +++ b/minject/model.py @@ -31,8 +31,7 @@ class Resolver(abc.ABC): """ @abc.abstractmethod - def resolve(self, key: "RegistryKey[T]") -> T: - ... + def resolve(self, key: "RegistryKey[T]") -> T: ... async def _aresolve(self, key: "RegistryKey[T]") -> T: """ @@ -51,8 +50,7 @@ async def _push_async_context(self, key: Any) -> Any: @property @abc.abstractmethod - def config(self) -> RegistryConfigWrapper: - ... + def config(self) -> RegistryConfigWrapper: ... MockingFunction: TypeAlias = Callable[[Arg], Any] @@ -64,8 +62,7 @@ class Deferred(abc.ABC, Generic[T_co]): """ @abc.abstractmethod - def resolve(self, registry_impl: Resolver) -> T_co: - ... + def resolve(self, registry_impl: Resolver) -> T_co: ... @abc.abstractmethod async def aresolve(self, registry_impl: Resolver) -> T_co: diff --git a/minject/registry.py b/minject/registry.py index bc800a5..3c7a927 100644 --- a/minject/registry.py +++ b/minject/registry.py @@ -1,4 +1,5 @@ """The Registry itself is a runtime collection of initialized classes.""" + import functools import logging from contextlib import AsyncExitStack @@ -57,7 +58,7 @@ def close(self) -> None: def _synchronized( - func: Callable[Concatenate["Registry", P], R] + func: Callable[Concatenate["Registry", P], R], ) -> Callable[Concatenate["Registry", P], R]: """Decorator to synchronize method access with a reentrant lock.""" diff --git a/minject/types.py b/minject/types.py index ac568a9..dbd72a5 100644 --- a/minject/types.py +++ b/minject/types.py @@ -18,11 +18,9 @@ class _MinimalMappingProtocol(Protocol[K_contra, V_co]): Defines the minimum methods needed for the dict-like objects acceptable to RegistryNestedConfig. """ - def __getitem__(self, key: K_contra) -> V_co: - ... + def __getitem__(self, key: K_contra) -> V_co: ... - def __contains__(self, key: K_contra) -> bool: - ... + def __contains__(self, key: K_contra) -> bool: ... class _AsyncContext(Protocol): @@ -32,10 +30,8 @@ class _AsyncContext(Protocol): it's __aenter__ method. """ - async def __aenter__(self: Self) -> Self: - ... + async def __aenter__(self: Self) -> Self: ... async def __aexit__( self, exc_type: Type[BaseException], exc_value: BaseException, traceback: TracebackType - ) -> None: - ... + ) -> None: ... diff --git a/pyproject.toml b/pyproject.toml index 803e32e..42881b1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,60 +1,61 @@ [project] -name = "minject" -description = "A small dependency injection library for Python." +authors = [ + { name = "Matt McHenry", email = "mmchenry@duolingo.com" }, + { name = "Alek Binion", email = "alek@duolingo.com" }, + { name = "Xiyan Shao", email = "xiyan@duolingo.com" }, + { name = "Service Framework Team", email = "service-framework-team@duolingo.com" }, +] classifiers = ['Development Status :: 5 - Production/Stable'] +description = "A small dependency injection library for Python." dynamic = ["version"] -authors = [{ name = "Matt McHenry", email = "mmchenry@duolingo.com" }, { name = "Alek Binion", email = "alek@duolingo.com" }, { name = "Xiyan Shao", email = "xiyan@duolingo.com"}, { name = "Service Framework Team", email = "service-framework-team@duolingo.com" }] -requires-python = ">=3.7" license = { file = "LICENSE" } +name = "minject" +requires-python = ">=3.7" -dependencies = [ - "attrs>=17.4", - "typing_extensions>=4.1", -] +dependencies = ["attrs>=17.4", "typing_extensions>=4.1"] [build-system] -requires = ["hatchling >= 1.10.0"] build-backend = "hatchling.build" +requires = ["hatchling >= 1.10.0"] [tool.hatch.version] path = "minject/__init__.py" [tool.hatch.envs.default] dependencies = [ - # Developer dependencies. E.g. for testing, building, packaging, etc. - "coverage", - "mypy", - "pre-commit", - "pylint", - "pytest", - "pytest-asyncio", - "pytest-cov", - "pytest-mock", - "pytest-xdist", - 'pytest-asyncio', - "typing", + # Developer dependencies. E.g. for testing, building, packaging, etc. + "coverage", + "mypy", + "pre-commit", + "pylint", + "pytest", + "pytest-asyncio", + "pytest-cov", + "pytest-mock", + "pytest-xdist", + 'pytest-asyncio', + "typing", ] [tool.hatch.envs.hatch-test] dependencies = [ - # The default hatch-test dependencies are not compatible with Python 3.7, a version we want to test against. Hence - # we need to specify our own dependencies here. - # https://github.com/pypa/hatch/blob/3adae6c0dfd5c20dfe9bf6bae19b44a696c22a43/src/hatch/env/internal/test.py - "coverage[toml]", - 'coverage-enable-subprocess', - 'pytest', - 'pytest-asyncio', - 'pytest-mock', - 'pytest-randomly', - 'pytest-asyncio', - 'pytest-rerunfailures', - 'pytest-xdist[psutil]', + # The default hatch-test dependencies are not compatible with Python 3.7, a version we want to test against. Hence + # we need to specify our own dependencies here. + # https://github.com/pypa/hatch/blob/3adae6c0dfd5c20dfe9bf6bae19b44a696c22a43/src/hatch/env/internal/test.py + "coverage[toml]", + 'coverage-enable-subprocess', + 'pytest', + 'pytest-asyncio', + 'pytest-mock', + 'pytest-randomly', + 'pytest-asyncio', + 'pytest-rerunfailures', + 'pytest-xdist[psutil]', ] [[tool.hatch.envs.hatch-test.matrix]] python = ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12", "3.13"] - [tool.hatch.envs.types.scripts] check = "mypy --install-types --non-interactive minject" diff --git a/tests/test_registry.py b/tests/test_registry.py index e7515d8..0981ce9 100644 --- a/tests/test_registry.py +++ b/tests/test_registry.py @@ -376,8 +376,7 @@ def close(base: Base): base.closed = True @bind(_close=close) - class Sub(Base): - ... + class Sub(Base): ... # Registry starts on initial lookup as part of the initiation process instance = self.registry[Sub] @@ -492,8 +491,7 @@ def check_registry_interface_variance_convenience_methods() -> None: # Test that variance is bound to the type (RegistryMetadata) and not the method. DefinedSub = define(_Sub) - def check_covariance(_: RegistryMetadata[_Super]) -> None: - ... + def check_covariance(_: RegistryMetadata[_Super]) -> None: ... check_covariance(DefinedSub) diff --git a/tests/test_registry_attrs.py b/tests/test_registry_attrs.py index 963d9a6..cd767d2 100644 --- a/tests/test_registry_attrs.py +++ b/tests/test_registry_attrs.py @@ -129,12 +129,10 @@ def test_attr_defaults() -> None: """ @inject_define - class TestClassOne: - ... + class TestClassOne: ... @inject_define(define_kwargs={}) - class TestClassTwo: - ... + class TestClassTwo: ... assert TestClassOne() != TestClassOne() assert TestClassTwo() == TestClassTwo()