Skip to content

Commit bf1f404

Browse files
πŸ› Fix imports.
1 parent 45e148f commit bf1f404

File tree

6 files changed

+58
-65
lines changed

6 files changed

+58
-65
lines changed

β€Žsrc/lapidary/render/model/python/__init__.pyβ€Ž

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -95,13 +95,13 @@ def modules(self) -> Sequence[AbstractModule]:
9595
def _modules(self) -> Iterable[AbstractModule]:
9696
known_modules = set()
9797
for mod in itertools.chain(self.schemas, self._response_envelopes):
98-
assert mod.path not in known_modules
98+
assert mod.path not in known_modules, mod.path
9999
known_modules.add(mod.path)
100100
yield mod
101101

102102
for package in self.packages():
103-
assert package not in known_modules
104-
yield EmptyModule(path=package, body=None)
103+
if package not in known_modules:
104+
yield EmptyModule(path=package, body=None)
105105

106106
def add_response_envelope_module(self, mod: ResponseEnvelopeModule):
107107
self._response_envelopes.append(mod)

β€Žsrc/lapidary/render/model/python/model.pyβ€Ž

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,6 @@ class Field:
3535
deprecated: bool = False
3636
"""Currently not used"""
3737

38-
@property
39-
def dependencies(self) -> Iterable[TypeHint]:
40-
return [self.annotation.type]
41-
4238

4339
@dc.dataclass
4440
class Auth:
@@ -119,11 +115,10 @@ class OperationFunction:
119115
responses: ResponseMap
120116
security: SecurityRequirements | None
121117

122-
@property
123118
def dependencies(self) -> Iterable[TypeHint]:
124119
yield self.request_body_type
125120
for param in self.params:
126-
yield from param.dependencies
121+
yield from param.dependencies()
127122
yield self.response_body_type
128123

129124
@property
@@ -164,7 +159,6 @@ class Parameter:
164159
style: ParamStyle | None
165160
explode: bool | None
166161

167-
@property
168162
def dependencies(self) -> Iterable[TypeHint]:
169163
yield self.type
170164

@@ -184,11 +178,10 @@ class SchemaClass:
184178
fields: list[Field] = dc.field(default_factory=list)
185179
model_type: ModelType = ModelType.model
186180

187-
@property
188181
def dependencies(self) -> Iterable[TypeHint]:
189182
yield self.base_type
190183
for prop in self.fields:
191-
yield from prop.dependencies
184+
yield prop.annotation.type
192185

193186

194187
@dc.dataclass
@@ -200,7 +193,6 @@ class ClientInit:
200193
response_map: ResponseMap = dc.field(default_factory=dict)
201194
security: SecurityRequirements | None = None
202195

203-
@property
204196
def dependencies(self) -> Iterable[TypeHint]:
205197
for mime_map in self.response_map.values():
206198
yield from mime_map.values()
@@ -211,11 +203,10 @@ class ClientClass:
211203
init_method: ClientInit
212204
methods: list[OperationFunction] = dc.field(default_factory=list)
213205

214-
@property
215206
def dependencies(self) -> Iterable[TypeHint]:
216-
yield from self.init_method.dependencies
207+
yield from self.init_method.dependencies()
217208
for fn in self.methods:
218-
yield from fn.dependencies
209+
yield from fn.dependencies()
219210

220211

221212
@dc.dataclass(frozen=True)
@@ -225,7 +216,6 @@ class ResponseHeader:
225216
type: TypeHint
226217
annotation: Literal['Cookie', 'Header', 'Link']
227218

228-
@property
229219
def dependencies(self) -> Iterable[TypeHint]:
230220
yield self.type
231221

@@ -236,8 +226,7 @@ class ResponseEnvelopeModel:
236226
headers: Iterable[ResponseHeader]
237227
body_type: TypeHint
238228

239-
@property
240229
def dependencies(self) -> Iterable[TypeHint]:
241230
yield self.body_type
242231
for header in self.headers:
243-
yield from header.dependencies
232+
yield from header.dependencies()

β€Žsrc/lapidary/render/model/python/module.pyβ€Ž

Lines changed: 26 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,13 @@
44

55
from .model import ClientClass, ResponseEnvelopeModel, SchemaClass
66
from .module_path import ModulePath
7-
from .type_hint import GenericTypeHint, TypeHint
7+
from .type_hint import NONE, TypeHint, flatten
88

99
template_imports = [
1010
'builtins',
1111
'typing',
1212
'typing_extensions',
13+
'lapidary.runtime',
1314
]
1415

1516

@@ -19,13 +20,23 @@ class AbstractModule[Body](abc.ABC):
1920
module_type: str
2021
body: Body = dc.field()
2122

22-
@property
2323
@abc.abstractmethod
24-
def imports(self) -> Iterable[str]:
24+
def dependencies(self) -> Iterable[TypeHint]:
2525
pass
2626

2727
@property
28-
def rel_path(self) -> str:
28+
def imports(self) -> Iterable[str]:
29+
dependencies = flatten(self.dependencies())
30+
return sorted(
31+
{
32+
dep.module
33+
for dep in dependencies
34+
if dep.module not in template_imports and dep != NONE and dep.module != str(self.path)
35+
}
36+
)
37+
38+
@property
39+
def file_path(self) -> str:
2940
return self.path.to_path()
3041

3142

@@ -34,20 +45,16 @@ class AuthModule(AbstractModule[Mapping[str, TypeHint]]):
3445
module_type = 'auth'
3546

3647
@property
37-
def imports(self) -> Iterable[str]:
38-
yield from ()
48+
def dependencies(self) -> Iterable[TypeHint]:
49+
return self.body.values()
3950

4051

4152
@dc.dataclass(frozen=True, kw_only=True)
4253
class ClientModule(AbstractModule[ClientClass]):
4354
module_type: str = dc.field(default='client')
4455

45-
@property
46-
def imports(self) -> Iterable[str]:
47-
dependencies = GenericTypeHint.union_of(*self.body.dependencies).args # flatten unions
48-
imports = sorted({imp for dep in dependencies if dep for imp in dep.imports() if imp not in template_imports})
49-
50-
return imports
56+
def dependencies(self) -> Iterable[TypeHint]:
57+
return self.body.dependencies()
5158

5259

5360
@dc.dataclass(frozen=True, kw_only=True)
@@ -57,18 +64,16 @@ class EmptyModule(AbstractModule[None]):
5764
module_type: str = dc.field(default='empty')
5865
body: None = None
5966

60-
@property
61-
def imports(self) -> Iterable[str]:
62-
yield from ()
67+
def dependencies(self) -> Iterable[TypeHint]:
68+
return ()
6369

6470

6571
@dc.dataclass(frozen=True, kw_only=True)
6672
class ResponseEnvelopeModule(AbstractModule[ResponseEnvelopeModel]):
6773
module_type: str = dc.field(default='response')
6874

69-
@property
70-
def imports(self) -> Iterable[str]:
71-
yield from self.body.dependencies
75+
def dependencies(self) -> Iterable[TypeHint]:
76+
return self.body.dependencies()
7277

7378

7479
@dc.dataclass(frozen=True, kw_only=True)
@@ -80,14 +85,6 @@ class SchemaModule(AbstractModule[Iterable[SchemaClass]]):
8085

8186
module_type: str = 'schema'
8287

83-
@property
84-
def imports(self) -> Iterable[str]:
85-
dependencies = GenericTypeHint.union_of(
86-
*[dep for cls in self.body for dep in cls.dependencies]
87-
).args # flatten unions
88-
imports = sorted({imp for dep in dependencies if dep for imp in dep.imports() if imp not in template_imports})
89-
path_str = str(self.path)
90-
if path_str in imports:
91-
imports.remove(path_str)
92-
93-
return imports
88+
def dependencies(self) -> Iterable[TypeHint]:
89+
for schema in self.body:
90+
yield from schema.dependencies()

β€Žsrc/lapidary/render/model/python/type_hint.pyβ€Ž

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import dataclasses as dc
2-
from collections.abc import Collection, Iterable
2+
from collections.abc import Collection, Iterable, MutableSet
33
from typing import cast
44

55

@@ -39,8 +39,8 @@ def is_union(self) -> bool:
3939
def is_none(self) -> bool:
4040
return False
4141

42-
def _types(self) -> 'Iterable[TypeHint]':
43-
return [self]
42+
def dependencies(self) -> 'Iterable[TypeHint]':
43+
return ()
4444

4545
def __eq__(self, other) -> bool:
4646
return isinstance(other, TypeHint) and self.module == other.module and self.name == other.name
@@ -57,12 +57,9 @@ def __repr__(self):
5757
return self.full_name()
5858

5959
@staticmethod
60-
def from_str(name: str) -> 'BuiltinTypeHint':
60+
def from_str(name: str) -> TypeHint:
6161
return BuiltinTypeHint(name=name)
6262

63-
def imports(self) -> list[str]:
64-
return []
65-
6663
def full_name(self):
6764
return self.name
6865

@@ -84,11 +81,8 @@ def union_of(*types: TypeHint) -> 'GenericTypeHint':
8481
def is_union(self) -> bool:
8582
return self.module == 'typing' and self.name == 'Union'
8683

87-
def imports(self) -> list[str]:
88-
return [imp for typ in self._types() for imp in TypeHint.imports(typ) if imp != 'builtins']
89-
90-
def _types(self) -> Iterable[TypeHint]:
91-
return [self, *[typ for arg in self.args for typ in arg._types()]]
84+
def dependencies(self) -> Iterable[TypeHint]:
85+
yield from self.args
9286

9387
def __repr__(self) -> str:
9488
return self.full_name()
@@ -118,7 +112,7 @@ def __hash__(self) -> int:
118112

119113
class NoneTypeHint(TypeHint):
120114
def __init__(self):
121-
super().__init__(module=None, name=None)
115+
super().__init__(module='types', name='NoneType')
122116

123117
def full_name(self):
124118
return 'None'
@@ -146,3 +140,15 @@ def type_hint_or_union(types: Collection[TypeHint]) -> TypeHint:
146140
return next(iter(types))
147141
else:
148142
return GenericTypeHint.union_of(*types)
143+
144+
145+
def flatten(types: Iterable[TypeHint]) -> Iterable[TypeHint]:
146+
all_types = set()
147+
_flatten(types, all_types)
148+
return GenericTypeHint.union_of(*all_types).args
149+
150+
151+
def _flatten(types: Iterable[TypeHint], target: MutableSet[TypeHint]) -> None:
152+
for typ in types:
153+
target.add(typ)
154+
_flatten(typ.dependencies(), target)

β€Žsrc/lapidary/render/templates/render/includes/module/response.py.jinjaβ€Ž

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
{% import 'includes/type_hint.py.jinja' as th -%}
22

33
from __future__ import annotations
4-
import typing_extensions as typing
54

5+
import typing_extensions as typing
66
from lapidary.runtime import *
7+
{%- for imp in item.imports %}
8+
import {{ imp }}
9+
{%- endfor %}
710

811

912
class {{item.body.name}}(ResponseEnvelope):

β€Žsrc/lapidary/render/templates/render/includes/module/schema.py.jinjaβ€Ž

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
from __future__ import annotations
22

3-
import typing
4-
53
import lapidary.runtime
64
import pydantic
7-
import typing_extensions
5+
import typing_extensions as typing
86

97
{%- for imp in item.imports %}
108
import {{ imp }}

0 commit comments

Comments
Β (0)