Skip to content

Commit 4f8ced8

Browse files
committed
Сделать порядок импортов одинаковым
1 parent 1a67310 commit 4f8ced8

3 files changed

Lines changed: 87 additions & 6 deletions

File tree

openapi_python_client/templates/endpoint_module.py.jinja

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ from ...client import AuthenticatedClient, Client
77
from ...types import Response, UNSET
88
from ... import errors
99

10-
{% for relative in endpoint.relative_imports %}
10+
{% for relative in endpoint.relative_imports | sort %}
1111
{{ relative }}
1212
{% endfor %}
1313

openapi_python_client/templates/model.py.jinja

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,11 @@ import json
1313

1414
from ..types import UNSET, Unset
1515

16-
{% for relative in model.relative_imports %}
16+
{% for relative in model.relative_imports | sort %}
1717
{{ relative }}
1818
{% endfor %}
1919

20-
{% for lazy_import in model.lazy_imports %}
20+
{% for lazy_import in model.lazy_imports | sort %}
2121
{{ lazy_import }}
2222
{% endfor %}
2323

@@ -121,7 +121,7 @@ return field_dict
121121
{% endmacro %}
122122

123123
def to_dict(self) -> Dict[str, Any]:
124-
{% for lazy_import in model.lazy_imports %}
124+
{% for lazy_import in model.lazy_imports | sort %}
125125
{{ lazy_import }}
126126
{% endfor %}
127127
{{ _to_dict() | indent(8) }}
@@ -133,7 +133,7 @@ return field_dict
133133

134134
@classmethod
135135
def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T:
136-
{% for lazy_import in model.lazy_imports %}
136+
{% for lazy_import in model.lazy_imports | sort %}
137137
{{ lazy_import }}
138138
{% endfor %}
139139
d = src_dict.copy()
@@ -162,7 +162,7 @@ return field_dict
162162
{% import "property_templates/" + model.additional_properties.template as prop_template %}
163163

164164
{% if model.additional_properties.lazy_imports %}
165-
{% for lazy_import in model.additional_properties.lazy_imports %}
165+
{% for lazy_import in model.additional_properties.lazy_imports | sort %}
166166
{{ lazy_import }}
167167
{% endfor %}
168168
{% endif %}
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
"""Проверка, что импорты в сгенерированных файлах отсортированы одинаково."""
2+
3+
from types import SimpleNamespace
4+
5+
6+
def _build_fake_model(*, relative_imports, lazy_imports):
7+
return SimpleNamespace(
8+
relative_imports=relative_imports,
9+
lazy_imports=lazy_imports,
10+
additional_properties=None,
11+
is_multipart_body=False,
12+
class_info=SimpleNamespace(name="MyClass", module_name="my_module"),
13+
title=None,
14+
description=None,
15+
example=None,
16+
required_properties=[],
17+
optional_properties=[],
18+
)
19+
20+
21+
def _ordered_indices(output: str, items):
22+
"""Return the index of the first occurrence of each item in ``output``."""
23+
return [output.index(item) for item in items]
24+
25+
26+
def test_model_template_renders_relative_imports_sorted(env):
27+
relative_imports = [
28+
"from ..models.charlie import Charlie",
29+
"from ..models.alpha import Alpha",
30+
"from ..models.bravo import Bravo",
31+
]
32+
fake_model = _build_fake_model(relative_imports=relative_imports, lazy_imports=[])
33+
34+
output = env.get_template("model.py.jinja").render(model=fake_model)
35+
36+
sorted_imports = sorted(relative_imports)
37+
indices = _ordered_indices(output, sorted_imports)
38+
assert indices == sorted(indices), (
39+
"relative_imports must be rendered in sorted order, got order: "
40+
f"{[imp for _, imp in sorted(zip(indices, sorted_imports))]}"
41+
)
42+
43+
44+
def test_model_template_renders_lazy_imports_sorted(env):
45+
lazy_imports = [
46+
"from ..models.echo import Echo",
47+
"from ..models.delta import Delta",
48+
"from ..models.foxtrot import Foxtrot",
49+
]
50+
fake_model = _build_fake_model(relative_imports=[], lazy_imports=lazy_imports)
51+
52+
output = env.get_template("model.py.jinja").render(model=fake_model)
53+
54+
sorted_imports = sorted(lazy_imports)
55+
# lazy_imports appear at the top of the file *and* inside to_dict / from_dict.
56+
# We only assert ordering on the first occurrence of each import.
57+
indices = _ordered_indices(output, sorted_imports)
58+
assert indices == sorted(indices), (
59+
"lazy_imports must be rendered in sorted order, got order: "
60+
f"{[imp for _, imp in sorted(zip(indices, sorted_imports))]}"
61+
)
62+
63+
64+
def test_model_template_render_is_deterministic_across_input_order(env):
65+
"""Rendering with the same imports in different input order produces the
66+
same file - the bug being fixed."""
67+
imports_a = [
68+
"from ..models.alpha import Alpha",
69+
"from ..models.beta import Beta",
70+
"from ..models.gamma import Gamma",
71+
]
72+
imports_b = list(reversed(imports_a))
73+
74+
out_a = env.get_template("model.py.jinja").render(
75+
model=_build_fake_model(relative_imports=imports_a, lazy_imports=[])
76+
)
77+
out_b = env.get_template("model.py.jinja").render(
78+
model=_build_fake_model(relative_imports=imports_b, lazy_imports=[])
79+
)
80+
81+
assert out_a == out_b, "model.py.jinja output depends on import iteration order"

0 commit comments

Comments
 (0)