Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions .changeset/fix_bad_code_generation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
default: patch
---

# Fix bad code generation

#1360 by @EricAtORS

This fixes:
- missing parenthesis in to_multipart
#1338 #1318
- missing imports in the lazy eval in to_multipart:
#931 and #1051
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,10 @@ def to_dict(self) -> dict[str, Any]:
return field_dict

def to_multipart(self) -> types.RequestFiles:
from ..models.body_upload_file_tests_upload_post_some_nullable_object import (
BodyUploadFileTestsUploadPostSomeNullableObject,
)

files: types.RequestFiles = []

files.append(("some_file", self.some_file.to_tuple()))
Expand Down
3 changes: 3 additions & 0 deletions openapi_python_client/templates/model.py.jinja
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,9 @@ return field_dict

{% if model.is_multipart_body %}
def to_multipart(self) -> types.RequestFiles:
{% for lazy_import in model.lazy_imports %}
{{ lazy_import }}
{% endfor %}
files: types.RequestFiles = []

{% for property in model.required_properties + model.optional_properties %}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,5 @@ if not isinstance({{ source }}, Unset):
{% endmacro %}

{% macro multipart(property, source, name) %}
files.append(({{ name }}, (None, str({{ source }}), "text/plain"))
files.append(({{ name }}, (None, str({{ source }}), "text/plain")))
{% endmacro %}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""Tests for UUID property templates."""
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
"""Tests for UUID property multipart macro functionality."""

from pathlib import Path
from typing import Any
from uuid import UUID

import jinja2
import pytest

from openapi_python_client.parser.properties import UuidProperty
from openapi_python_client.utils import PythonIdentifier


def uuid_property(required: bool = True, default: Any = None) -> UuidProperty:
"""Helper to create a UuidProperty for testing."""
return UuidProperty(
name="test_uuid",
required=required,
default=default,
python_name=PythonIdentifier(value="test_uuid", prefix=""),
description="A test UUID property",
example="550e8400-e29b-41d4-a716-446655440000",
)


@pytest.fixture
def jinja_env() -> jinja2.Environment:
"""Create a Jinja2 environment with the property templates loaded."""
templates_dir = Path(__file__).parent.parent.parent.parent.parent / "openapi_python_client" / "templates"
env = jinja2.Environment(
loader=jinja2.FileSystemLoader(templates_dir),
trim_blocks=True,
lstrip_blocks=True,
)
return env


def test_multipart_macro_generates_syntactically_correct_code_for_required_uuid(jinja_env: jinja2.Environment) -> None:
"""Test that the multipart macro generates syntactically correct Python code for required UUID properties."""
prop = uuid_property(required=True)

template = jinja_env.get_template("property_templates/uuid_property.py.jinja")

# Render the multipart macro
multipart_code = template.module.multipart(prop, "test_uuid", '"test_uuid"') # type: ignore[attr-defined]

# Verify the generated code is syntactically correct
expected = 'files.append(("test_uuid", (None, str(test_uuid), "text/plain")))'
assert multipart_code.strip() == expected

# Verify it compiles as valid Python
compile(multipart_code, "<string>", "exec")


def test_multipart_macro_generates_syntactically_correct_code_for_optional_uuid(jinja_env: jinja2.Environment) -> None:
"""Test that the multipart macro generates syntactically correct Python code for optional UUID properties."""
prop = uuid_property(required=False)

template = jinja_env.get_template("property_templates/uuid_property.py.jinja")

# Render the multipart macro
multipart_code = template.module.multipart(prop, "test_uuid", '"test_uuid"') # type: ignore[attr-defined]

# Verify the generated code is syntactically correct
expected = 'files.append(("test_uuid", (None, str(test_uuid), "text/plain")))'
assert multipart_code.strip() == expected

# Verify it compiles as valid Python
compile(multipart_code, "<string>", "exec")