Skip to content

Commit d5e71ab

Browse files
author
Abraham Murciano
committed
Improve type hints in punq stubs
- Replace object with Any where appropriate - Clarify the use of **kwargs in method signatures - Make _T default to Any and use it in more places instead of Any/object - Include _Empty as a default parameter where applicable
1 parent 9059696 commit d5e71ab

File tree

2 files changed

+39
-23
lines changed

2 files changed

+39
-23
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
punq._Empty.__init__

stubs/punq/punq/__init__.pyi

Lines changed: 38 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from collections.abc import Callable
22
from enum import Enum
3-
from typing import Any, Generic, NamedTuple, TypeVar, overload
3+
from typing import Any, Final, Generic, NamedTuple, NewType, TypeVar, overload
44

55
__version__: str
66

@@ -15,27 +15,36 @@ class Scope(Enum):
1515
transient = 0
1616
singleton = 1
1717

18-
_T = TypeVar("_T")
19-
_TOpt = TypeVar("_TOpt", default=object)
18+
_T = TypeVar("_T", default=Any)
2019

2120
class _Registration(NamedTuple, Generic[_T]):
2221
service: type[_T] | str
2322
scope: Scope
24-
builder: Callable[[], _T]
25-
needs: dict[str, object]
26-
args: dict[str, object]
23+
builder: Callable[..., _T]
24+
needs: dict[str, Any] # the type hints of the builder's parameters
25+
args: dict[str, Any] # passed to builder at instantiation time
2726

28-
empty: Any
27+
_Empty = NewType("_Empty", object) # a class at runtime
28+
empty: Final[_Empty]
2929

3030
class _Registry:
3131
def register_service_and_impl(
32-
self, service: type | str, scope: Scope, impl: Callable[..., object], resolve_args: dict[str, object]
32+
self,
33+
service: type[_T] | str,
34+
scope: Scope,
35+
impl: type[_T],
36+
resolve_args: dict[str, Any], # forwarded to _Registration.builder
3337
) -> None: ...
3438
def register_service_and_instance(self, service: type[_T] | str, instance: _T) -> None: ...
3539
def register_concrete_service(self, service: type | str, scope: Scope) -> None: ...
3640
def build_context(self, key: type | str, existing: _ResolutionContext | None = None) -> _ResolutionContext: ...
3741
def register(
38-
self, service: type[_T] | str, factory: Callable[..., _T] = ..., instance: _T = ..., scope: Scope = ..., **kwargs: object
42+
self,
43+
service: type[_T] | str,
44+
factory: Callable[..., _T] | _Empty = ...,
45+
instance: _T | _Empty = ...,
46+
scope: Scope = Scope.transient,
47+
**kwargs: Any, # forwarded to _Registration.builder
3948
) -> None: ...
4049
def __getitem__(self, service: type[_T] | str) -> list[_Registration[_T]]: ...
4150

@@ -45,38 +54,44 @@ class _ResolutionTarget(Generic[_T]):
4554
def __init__(self, key: type[_T] | str, impls: list[_Registration[_T]]) -> None: ...
4655
def is_generic_list(self) -> bool: ...
4756
@property
48-
def generic_parameter(self) -> Any: ...
57+
def generic_parameter(self) -> Any: ... # returns the first annotated generic parameter of the service
4958
def next_impl(self) -> _Registration[_T]: ...
5059

5160
class _ResolutionContext:
52-
targets: dict[type | str, _ResolutionTarget[object]]
53-
cache: dict[type | str, object]
61+
targets: dict[type | str, _ResolutionTarget[Any]]
62+
cache: dict[type | str, Any] # resolved objects during this resolution
5463
service: type | str
55-
def __init__(self, key: type | str, impls: list[_Registration[object]]) -> None: ...
64+
def __init__(self, key: type | str, impls: list[_Registration[Any]]) -> None: ...
5665
def target(self, key: type[_T] | str) -> _ResolutionTarget[_T]: ...
5766
def has_cached(self, key: type | str) -> bool: ...
58-
def __getitem__(self, key: type | str) -> object: ...
59-
def __setitem__(self, key: type | str, value: object) -> None: ...
67+
def __getitem__(self, key: type[_T] | str) -> _T: ...
68+
def __setitem__(self, key: type[_T] | str, value: _T) -> None: ...
6069
def all_registrations(self, service: type[_T] | str) -> list[_Registration[_T]]: ...
6170

6271
class Container:
6372
registrations: _Registry
6473
def __init__(self) -> None: ...
74+
# all kwargs are forwarded to _Registration.builder
6575
@overload
66-
def register(self, service: type[_TOpt] | str, *, instance: _TOpt, **kwargs: Any) -> Container: ...
76+
def register(self, service: type[_T] | str, *, instance: _T, **kwargs: Any) -> Container: ...
6777
@overload
6878
def register(
69-
self, service: type[_TOpt] | str, factory: Callable[..., _TOpt] = ..., *, scope: Scope = ..., **kwargs: Any
79+
self,
80+
service: type[_T] | str,
81+
factory: Callable[..., _T] | _Empty = ...,
82+
*,
83+
scope: Scope = Scope.transient,
84+
**kwargs: Any,
7085
) -> Container: ...
7186
@overload
7287
def register(
7388
self,
74-
service: type[_TOpt] | str,
75-
factory: Callable[..., _TOpt] = ...,
76-
instance: _TOpt = ...,
89+
service: type[_T] | str,
90+
factory: Callable[..., _T] | _Empty = ...,
91+
instance: _T | _Empty = ...,
7792
scope: Scope = Scope.transient,
7893
**kwargs: Any,
7994
): ...
80-
def resolve_all(self, service: type[_TOpt] | str, **kwargs: Any) -> list[_TOpt]: ...
81-
def resolve(self, service_key: type[_TOpt] | str, **kwargs: Any) -> _TOpt: ...
82-
def instantiate(self, service_key: type[_TOpt] | str, **kwargs: Any) -> _TOpt: ...
95+
def resolve_all(self, service: type[_T] | str, **kwargs: Any) -> list[_T]: ...
96+
def resolve(self, service_key: type[_T] | str, **kwargs: Any) -> _T: ...
97+
def instantiate(self, service_key: type[_T] | str, **kwargs: Any) -> _T: ...

0 commit comments

Comments
 (0)