🌐 AI搜索 & 代理 主页
Skip to content

Commit 6f555f3

Browse files
committed
add newtype support
1 parent 726ff34 commit 6f555f3

File tree

6 files changed

+110
-0
lines changed

6 files changed

+110
-0
lines changed
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
from typing import (
2+
NewType,
3+
)
4+
5+
6+
UserId = NewType('UserId', int)
7+
8+
9+
def name_by_id(user_id: UserId) -> str:
10+
return str(user_id)
11+
12+
13+
class SomeClass:
14+
a: int
15+
16+
17+
SomeClassInNewType = NewType('SomeClassInNewType', SomeClass)
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
from py_codegen.test_fixtures.new_type import (
2+
name_by_id,
3+
SomeClassInNewType,
4+
)
5+
from py_codegen.type_extractor.__tests__.utils import traverse, cleanup
6+
from py_codegen.type_extractor.nodes.ClassFound import ClassFound
7+
from py_codegen.type_extractor.nodes.FunctionFound import FunctionFound
8+
from py_codegen.type_extractor.nodes.NewType import NewTypeFound
9+
from py_codegen.type_extractor.nodes.TypeVarFound import TypeVarFound
10+
from py_codegen.type_extractor.type_extractor import TypeExtractor
11+
12+
13+
def test_newtype():
14+
type_extractor = TypeExtractor()
15+
type_extractor.add()(name_by_id)
16+
type_extractor.add()(SomeClassInNewType)
17+
cleaned_up = {
18+
key: traverse(value, cleanup)
19+
for (key, value) in type_extractor.collected_types.items()
20+
}
21+
user_id_newtype = NewTypeFound(
22+
name='UserId',
23+
actual=int,
24+
)
25+
some_class = ClassFound(
26+
name='SomeClass',
27+
fields={
28+
'a': int,
29+
}
30+
)
31+
assert cleaned_up == {
32+
'UserId': user_id_newtype,
33+
'name_by_id': FunctionFound(
34+
name='name_by_id',
35+
params={
36+
'user_id': user_id_newtype,
37+
},
38+
return_type=str,
39+
),
40+
'SomeClass': some_class,
41+
'SomeClassInNewType': NewTypeFound(
42+
name='SomeClassInNewType',
43+
actual=some_class,
44+
),
45+
}
46+
print(1)

py_codegen/type_extractor/__tests__/utils.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
from py_codegen.type_extractor.nodes.BaseNodeType import NodeType
66
from py_codegen.type_extractor.nodes.FixedGenericFound import FixedGenericFound
7+
from py_codegen.type_extractor.nodes.NewType import NewTypeFound
78
from py_codegen.type_extractor.nodes.TypeVarFound import TypeVarFound
89
from py_codegen.type_extractor.nodes.TypedDictFound import TypedDictFound
910
from py_codegen.type_extractor.nodes.ClassFound import ClassFound
@@ -67,6 +68,12 @@ def traverse(node: NodeType, func: traverse_func_type):
6768
node.original, func
6869
)
6970
return func(typevar_node)
71+
if isinstance(node, NewTypeFound):
72+
newtype_found = copy(node)
73+
newtype_found.actual = traverse(
74+
node.actual, func
75+
)
76+
return func(newtype_found)
7077
return node
7178

7279

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import inspect
2+
3+
from typing import Set
4+
from py_codegen.type_extractor.__base__ import BaseTypeExtractor
5+
6+
from py_codegen.type_extractor.nodes.BaseNodeType import BaseOption
7+
from py_codegen.type_extractor.nodes.NewType import NewTypeFound
8+
9+
10+
def newtype_found_middleware(
11+
typ,
12+
type_extractor: BaseTypeExtractor,
13+
options: Set[BaseOption],
14+
):
15+
if not inspect.isfunction(typ):
16+
return None
17+
if typ.__module__ is not 'typing':
18+
return None
19+
if typ.__code__.co_name is not 'new_type':
20+
return None
21+
22+
newtype_found = NewTypeFound(
23+
name=typ.__name__,
24+
actual=type_extractor.rawtype_to_node(typ.__supertype__),
25+
)
26+
27+
type_extractor.collected_types[newtype_found.name] = newtype_found
28+
return newtype_found
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
from dataclasses import dataclass
2+
from typing import List
3+
4+
from py_codegen.type_extractor.nodes.BaseNodeType import BaseNodeType, NodeType
5+
6+
7+
@dataclass
8+
class NewTypeFound(BaseNodeType):
9+
name: str
10+
actual: NodeType

py_codegen/type_extractor/type_extractor.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
from py_codegen.type_extractor.middlewares.list_found import list_found_middleware
2020
from py_codegen.type_extractor.middlewares.literal_found import literal_found_middleware
2121
from py_codegen.type_extractor.middlewares.mapping_found import mapping_found_middleware
22+
from py_codegen.type_extractor.middlewares.newtype_found import newtype_found_middleware
2223
from py_codegen.type_extractor.middlewares.tuple_found import tuple_found_middleware
2324
from py_codegen.type_extractor.middlewares.type_or import typeor_middleware
2425
from py_codegen.type_extractor.nodes.BaseNodeType import NodeType, BaseNodeType, BaseOption
@@ -54,6 +55,7 @@ class TypeExtractor(BaseTypeExtractor):
5455
typevar_found_middleware,
5556
fixed_generic_found_middleware,
5657
class_found_middleware,
58+
newtype_found_middleware,
5759
func_found_middleware,
5860
none_node_middleware,
5961
builtin_middleware,

0 commit comments

Comments
 (0)