Skip to content

Commit f5f3b41

Browse files
Fix bad code generation (#1360)
I've had some issues with the code generation. This should fix: - missing parenthesis in to_multipart #1338 #1318 - missing imports in the lazy eval in to_multipart: #931 and #1051 --------- Co-authored-by: Eric Yen <[email protected]>
1 parent 5814739 commit f5f3b41

File tree

6 files changed

+92
-1
lines changed

6 files changed

+92
-1
lines changed
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
---
2+
default: patch
3+
---
4+
5+
# Fix bad code generation
6+
7+
#1360 by @EricAtORS
8+
9+
This fixes:
10+
- missing parenthesis in to_multipart
11+
#1338 #1318
12+
- missing imports in the lazy eval in to_multipart:
13+
#931 and #1051

end_to_end_tests/golden-record/my_test_api_client/models/body_upload_file_tests_upload_post.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,10 @@ def to_dict(self) -> dict[str, Any]:
172172
return field_dict
173173

174174
def to_multipart(self) -> types.RequestFiles:
175+
from ..models.body_upload_file_tests_upload_post_some_nullable_object import (
176+
BodyUploadFileTestsUploadPostSomeNullableObject,
177+
)
178+
175179
files: types.RequestFiles = []
176180

177181
files.append(("some_file", self.some_file.to_tuple()))

openapi_python_client/templates/model.py.jinja

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,9 @@ return field_dict
151151

152152
{% if model.is_multipart_body %}
153153
def to_multipart(self) -> types.RequestFiles:
154+
{% for lazy_import in model.lazy_imports %}
155+
{{ lazy_import }}
156+
{% endfor %}
154157
files: types.RequestFiles = []
155158

156159
{% for property in model.required_properties + model.optional_properties %}

openapi_python_client/templates/property_templates/uuid_property.py.jinja

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,5 +29,5 @@ if not isinstance({{ source }}, Unset):
2929
{% endmacro %}
3030

3131
{% macro multipart(property, source, name) %}
32-
files.append(({{ name }}, (None, str({{ source }}), "text/plain"))
32+
files.append(({{ name }}, (None, str({{ source }}), "text/plain")))
3333
{% endmacro %}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
"""Tests for UUID property templates."""
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
"""Tests for UUID property multipart macro functionality."""
2+
3+
from pathlib import Path
4+
from typing import Any
5+
from uuid import UUID
6+
7+
import jinja2
8+
import pytest
9+
10+
from openapi_python_client.parser.properties import UuidProperty
11+
from openapi_python_client.utils import PythonIdentifier
12+
13+
14+
def uuid_property(required: bool = True, default: Any = None) -> UuidProperty:
15+
"""Helper to create a UuidProperty for testing."""
16+
return UuidProperty(
17+
name="test_uuid",
18+
required=required,
19+
default=default,
20+
python_name=PythonIdentifier(value="test_uuid", prefix=""),
21+
description="A test UUID property",
22+
example="550e8400-e29b-41d4-a716-446655440000",
23+
)
24+
25+
26+
@pytest.fixture
27+
def jinja_env() -> jinja2.Environment:
28+
"""Create a Jinja2 environment with the property templates loaded."""
29+
templates_dir = Path(__file__).parent.parent.parent.parent.parent / "openapi_python_client" / "templates"
30+
env = jinja2.Environment(
31+
loader=jinja2.FileSystemLoader(templates_dir),
32+
trim_blocks=True,
33+
lstrip_blocks=True,
34+
)
35+
return env
36+
37+
38+
def test_multipart_macro_generates_syntactically_correct_code_for_required_uuid(jinja_env: jinja2.Environment) -> None:
39+
"""Test that the multipart macro generates syntactically correct Python code for required UUID properties."""
40+
prop = uuid_property(required=True)
41+
42+
template = jinja_env.get_template("property_templates/uuid_property.py.jinja")
43+
44+
# Render the multipart macro
45+
multipart_code = template.module.multipart(prop, "test_uuid", '"test_uuid"') # type: ignore[attr-defined]
46+
47+
# Verify the generated code is syntactically correct
48+
expected = 'files.append(("test_uuid", (None, str(test_uuid), "text/plain")))'
49+
assert multipart_code.strip() == expected
50+
51+
# Verify it compiles as valid Python
52+
compile(multipart_code, "<string>", "exec")
53+
54+
55+
def test_multipart_macro_generates_syntactically_correct_code_for_optional_uuid(jinja_env: jinja2.Environment) -> None:
56+
"""Test that the multipart macro generates syntactically correct Python code for optional UUID properties."""
57+
prop = uuid_property(required=False)
58+
59+
template = jinja_env.get_template("property_templates/uuid_property.py.jinja")
60+
61+
# Render the multipart macro
62+
multipart_code = template.module.multipart(prop, "test_uuid", '"test_uuid"') # type: ignore[attr-defined]
63+
64+
# Verify the generated code is syntactically correct
65+
expected = 'files.append(("test_uuid", (None, str(test_uuid), "text/plain")))'
66+
assert multipart_code.strip() == expected
67+
68+
# Verify it compiles as valid Python
69+
compile(multipart_code, "<string>", "exec")
70+

0 commit comments

Comments
 (0)