Skip to content

Commit

Permalink
Fix: Protocol support (#54)
Browse files Browse the repository at this point in the history
* fix: support protocols

support protocols

* chore: expand scope of test

expand scope of test by also testing protocols

* chore: upgrade action version and expand python check support

upgrade action version and expand python check support

* chore: drop 3.11 and 3.12 support

drop 3.11 and 3.12 support

* chore: update dependencies and address typing

update dependencies and address typing

* fix: add missing httpx package

add missing httpx package

* fix: removed outdated timeout arg for pytest, arranged typing

arranged typing and removed outdated pytest arg

* chore: reinclude support for python 3.11 and 3.12 tests

reinclude support for python 3.11 and 3.12 tests

* chore: drop support for python 3.7

drop support for python 3.7

Co-authored-by: Capi Etheriel <[email protected]>

---------

Co-authored-by: Capi Etheriel <[email protected]>
  • Loading branch information
jarey and barraponto authored Apr 15, 2024
1 parent ad7b2cd commit 68dc8ba
Show file tree
Hide file tree
Showing 7 changed files with 433 additions and 439 deletions.
10 changes: 5 additions & 5 deletions .github/workflows/main.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up Python 3.7
- name: Set up Python 3.8
uses: actions/setup-python@v2
with:
python-version: 3.7
python-version: 3.8
- name: Install dependencies
run: |
python -m pip install --upgrade pip
Expand All @@ -25,19 +25,19 @@ jobs:
- name: Linting
run: |
poetry run isort -c setup.cfg
poetry run black --line-length=120 --target-version py37 kink
poetry run black --line-length=120 --target-version py38 kink
poetry run mypy kink
tests:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [ 3.7, 3.8, 3.9 ]
python-version: [ "3.8", "3.9", "3.10", "3.11", "3.12" ]

steps:
- uses: actions/checkout@v2
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
Expand Down
6 changes: 2 additions & 4 deletions kink/container.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,10 @@ def add_alias(self, name: Union[str, Type], target: Union[str, Type]):
self._aliases[name].append(target)

@overload
def __getitem__(self, key: str) -> Any:
...
def __getitem__(self, key: str) -> Any: ...

@overload
def __getitem__(self, key: Type[T]) -> T:
...
def __getitem__(self, key: Type[T]) -> T: ...

def __getitem__(self, key):
if key in self._factories:
Expand Down
15 changes: 8 additions & 7 deletions kink/inject.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from abc import ABC
from functools import wraps
from inspect import Parameter as InspectParameter, isclass, signature
from typing import Any, Callable, Dict, NewType, Tuple, Type, TypeVar, Union, ForwardRef # type: ignore
from typing import Any, Callable, Dict, NewType, Tuple, Type, TypeVar, Union, ForwardRef, Optional # type: ignore

from typing_extensions import Protocol

Expand Down Expand Up @@ -101,9 +101,10 @@ def _resolve_function_kwargs(
def _decorate(binding: Dict[str, Any], service: ServiceDefinition, container: Container) -> ServiceResult:

# ignore abstract class initialiser and protocol initialisers
if (
service in [ABC.__init__, _no_init] or service.__name__ == "_no_init"
): # FIXME: fix this when typing_extensions library gets fixed
if service in [ABC.__init__, _no_init] or service.__name__ in [
"_no_init",
"_no_init_or_replace_init",
]: # FIXME: fix this when typing_extensions library gets fixed
return service

# Add class definition to dependency injection
Expand Down Expand Up @@ -166,9 +167,9 @@ async def _async_decorated(*args, **kwargs):


def inject(
_service: ServiceDefinition = None,
alias: Any = None,
bind: Dict[str, Any] = None,
_service: Optional[ServiceDefinition] = None,
alias: Optional[Any] = None,
bind: Optional[Dict[str, Any]] = None,
container: Container = di,
use_factory: bool = False,
) -> Union[ServiceResult, Callable[[ServiceDefinition], ServiceResult]]:
Expand Down
781 changes: 375 additions & 406 deletions poetry.lock

Large diffs are not rendered by default.

19 changes: 10 additions & 9 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,18 @@ include = ["kink/py.typed"]

# Requirements
[tool.poetry.dependencies]
python = "^3.7"
typing_extensions = "^4.1.1"
python = "^3.8"
typing_extensions = "^4.9.0"


[tool.poetry.dev-dependencies]
isort = "^5.7.0"
pytest = "^5.4.3"
pytest-asyncio = "^0.14.0"
pytest-cov = "^2.5"
isort = "^5.13.2"
pytest = "^8.0.0"
pytest-asyncio = "^0.23.5"
pytest-cov = "^4.1.0"
requests = "^2.31.0"
starlette = "^0.13.4"
black = "^22.3.0"
mypy = "^0.961"
starlette = "^0.37.1"
httpx = "^0.26.0"
black = "^24.2.0"
mypy = "^1.8.0"

1 change: 0 additions & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
[tool:pytest]
testpaths = tests
timeout = 10

[black]
line_length=120
Expand Down
40 changes: 33 additions & 7 deletions tests/test_issue_aliased_factory.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,42 @@
from abc import ABC
from typing import Protocol, List

from kink import inject, di

class Repository:
pass

class Repository(Protocol):
def __init__(self) -> None:
pass


@inject(alias=Repository, use_factory=True)
class PerInstanceRepository(Repository):
pass
pass


@inject(alias=Repository)
class Repository1(Repository):
pass


@inject(alias=Repository)
class Repository2(Repository):
repo: Repository1 = di[Repository1]


@inject
class Service:
def __init__(self, repository: Repository):
pass

def __init__(self, repositories: List[Repository]):
self._repositories = repositories


def test_can_inject_aliased_factory_services():
di[Service]
service: Service = di[Service]
assert service is not None
assert service._repositories is not None
assert len(service._repositories) == 3
repository: Repository = di[Repository2]
assert repository.repo is not None
repositories: List[Repository] = di[List[Repository]]
assert repositories is not None
assert len(repositories) == 3

0 comments on commit 68dc8ba

Please sign in to comment.