Skip to content

Commit aa9e393

Browse files
author
remimd
committed
refactor: Now analyze type hints with type-analyzer
1 parent fca940b commit aa9e393

File tree

6 files changed

+177
-201
lines changed

6 files changed

+177
-201
lines changed

injection/_core/common/type.py

Lines changed: 1 addition & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,10 @@
1010
Iterator,
1111
)
1212
from inspect import isclass, isfunction
13-
from types import GenericAlias, NoneType, UnionType
13+
from types import GenericAlias, UnionType
1414
from typing import (
15-
Annotated,
1615
Any,
1716
TypeAliasType,
18-
Union,
1917
get_args,
2018
get_origin,
2119
get_type_hints,
@@ -67,43 +65,3 @@ def get_yield_hint[T](
6765
return (arg,)
6866

6967
return ()
70-
71-
72-
def standardize_types(
73-
*types: InputType[Any],
74-
with_origin: bool = False,
75-
ignore_none_type: bool = False,
76-
) -> Iterator[TypeDef[Any]]:
77-
for tp in types:
78-
if tp is None or (ignore_none_type and tp is NoneType):
79-
continue
80-
81-
origin = get_origin(tp)
82-
83-
if origin is Union or isinstance(tp, UnionType):
84-
inner_types = get_args(tp)
85-
86-
elif origin is Annotated:
87-
inner_types = get_args(tp)[:1]
88-
89-
else:
90-
yield tp
91-
92-
if with_origin:
93-
if origin is not None:
94-
yield origin
95-
96-
for alias in (tp, origin):
97-
if isinstance(alias, TypeAliasType):
98-
yield from standardize_types(
99-
alias.__value__,
100-
with_origin=with_origin,
101-
)
102-
103-
continue
104-
105-
yield from standardize_types(
106-
*inner_types,
107-
with_origin=with_origin,
108-
ignore_none_type=ignore_none_type,
109-
)

injection/_core/descriptors.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,7 @@ def __generate_keys(
5353
if name == descriptor_name:
5454
continue
5555

56-
key = self.__module.reserve_scoped_slot(
57-
hint,
58-
scope_name=self.__name,
59-
ignore_none_type=True,
60-
)
56+
key = self.__module.reserve_scoped_slot(hint, scope_name=self.__name)
6157
yield name, key
6258

6359
def __mapping_from(self, instance: object) -> dict[SlotKey[Any], Any]:

injection/_core/module.py

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from __future__ import annotations
22

3+
import itertools
34
from abc import ABC, abstractmethod
45
from collections import OrderedDict, deque
56
from collections.abc import (
@@ -42,6 +43,8 @@
4243
runtime_checkable,
4344
)
4445

46+
from type_analyzer import MatchingTypesConfig, matching_types
47+
4548
from injection._core.common.asynchronous import (
4649
AsyncCaller,
4750
Caller,
@@ -59,7 +62,6 @@
5962
TypeInfo,
6063
get_return_types,
6164
get_yield_hint,
62-
standardize_types,
6365
)
6466
from injection._core.injectables import (
6567
AsyncCMScopedInjectable,
@@ -229,7 +231,6 @@ class Updater[T]:
229231
classes: Iterable[InputType[T]]
230232
injectable: Injectable[T]
231233
mode: Mode
232-
ignore_none_type: bool
233234

234235
def make_record(self) -> Record[T]:
235236
return Record(self.injectable, self.mode)
@@ -241,13 +242,11 @@ def with_basics(
241242
/,
242243
injectable: Injectable[T],
243244
mode: Mode | ModeStr,
244-
ignore_none_type: bool = False,
245245
) -> Self:
246246
return cls(
247247
classes=get_return_types(on),
248248
injectable=injectable,
249249
mode=Mode(mode),
250-
ignore_none_type=ignore_none_type,
251250
)
252251

253252

@@ -353,18 +352,25 @@ def __keep_new_record[T](
353352

354353
@staticmethod
355354
def __reduce_classes[T](updater: Updater[T]) -> frozenset[TypeDef[T]]:
355+
config = MatchingTypesConfig(ignore_none=True)
356356
return frozenset(
357-
standardize_types(
358-
*updater.classes,
359-
ignore_none_type=updater.ignore_none_type,
357+
itertools.chain.from_iterable(
358+
matching_types(cls, config) for cls in updater.classes
360359
)
361360
)
362361

363362
@staticmethod
364363
def __standardize_inputs[T](
365364
classes: Iterable[InputType[T]],
366365
) -> Iterator[InputType[T]]:
367-
return standardize_types(*classes, with_origin=True)
366+
config = MatchingTypesConfig(
367+
with_bases=True,
368+
with_origin=True,
369+
with_type_alias_value=True,
370+
)
371+
372+
for cls in classes:
373+
yield from matching_types(cls, config)
368374

369375

370376
"""
@@ -564,10 +570,9 @@ def reserve_scoped_slot[T](
564570
scope_name: str,
565571
*,
566572
mode: Mode | ModeStr = Mode.get_default(),
567-
ignore_none_type: bool = False,
568573
) -> SlotKey[T]:
569574
injectable = ScopedSlotInjectable(cls, scope_name)
570-
updater = Updater.with_basics(cls, injectable, mode, ignore_none_type)
575+
updater = Updater.with_basics(cls, injectable, mode)
571576
self.update(updater)
572577
return injectable.key
573578

pyproject.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,9 @@ classifiers = [
5555
"Natural Language :: English",
5656
"Typing :: Typed",
5757
]
58-
dependencies = []
58+
dependencies = [
59+
"type-analyzer",
60+
]
5961

6062
[project.optional-dependencies]
6163
async = [

tests/test_inject.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,16 +36,16 @@ def test_inject_with_annotated(self):
3636
self.assert_inject(Annotated[SomeInjectable, "metadata"])
3737

3838
def test_inject_with_union(self):
39-
self.assert_inject(Union[T, SomeInjectable])
39+
self.assert_inject(Union[str, SomeInjectable])
4040

4141
def test_inject_with_new_union(self):
42-
self.assert_inject(T | SomeInjectable)
42+
self.assert_inject(str | SomeInjectable)
4343

4444
def test_inject_with_union_and_none(self):
4545
self.assert_inject(None | SomeInjectable)
4646

4747
def test_inject_with_annotated_and_union(self):
48-
self.assert_inject(Annotated[T | SomeInjectable, "metadata"])
48+
self.assert_inject(Annotated[str | SomeInjectable, "metadata"])
4949

5050
def test_inject_with_optional(self):
5151
self.assert_inject(Optional[SomeInjectable])

0 commit comments

Comments
 (0)