pyopenapi-gen 0.20.0__tar.gz → 0.20.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of pyopenapi-gen might be problematic. Click here for more details.

Files changed (341) hide show
  1. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/CHANGELOG.md +47 -0
  2. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/PKG-INFO +1 -1
  3. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/coverage.xml +56 -54
  4. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/pyproject.toml +2 -2
  5. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/__init__.py +1 -1
  6. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/visit/endpoint/generators/endpoint_method_generator.py +2 -2
  7. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/visit/endpoint/generators/overload_generator.py +9 -2
  8. pyopenapi_gen-0.20.1/tests/generation_issues/test_overload_naming_issues.py +203 -0
  9. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/visit/endpoint/generators/test_endpoint_method_generator.py +61 -0
  10. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/visit/endpoint/generators/test_overload_generator.py +84 -0
  11. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/.bandit +0 -0
  12. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/.cursor/mcp.json +0 -0
  13. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/.cursor/rules/architecture.mdc +0 -0
  14. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/.cursor/rules/coding-conventions.mdc +0 -0
  15. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/.cursor/rules/project-goal.mdc +0 -0
  16. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/.cursor/rules/testing.mdc +0 -0
  17. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/.github/BRANCH_PROTECTION.md +0 -0
  18. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/.github/CLAUDE_CONFIGURATION.md +0 -0
  19. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/.github/CODEOWNERS +0 -0
  20. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  21. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  22. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/.github/dependabot.yml +0 -0
  23. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/.github/workflows/ci.yml +0 -0
  24. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/.github/workflows/claude-auto-approve.yml +0 -0
  25. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/.github/workflows/claude-review-trigger.yml +0 -0
  26. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/.github/workflows/claude.yml +0 -0
  27. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/.github/workflows/pr-checks.yml +0 -0
  28. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/.github/workflows/production-release.yml.backup +0 -0
  29. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/.github/workflows/promote-to-staging.yml +0 -0
  30. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/.github/workflows/semantic-release.yml +0 -0
  31. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/.github/workflows/staging-publish.yml +0 -0
  32. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/.github/workflows/testpypi-publish.yml +0 -0
  33. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/.gitignore +0 -0
  34. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/.python-version +0 -0
  35. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/.vscode/settings.json +0 -0
  36. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/CLAUDE.md +0 -0
  37. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/CONTRIBUTING.md +0 -0
  38. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/LICENSE +0 -0
  39. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/Makefile +0 -0
  40. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/README.md +0 -0
  41. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/docs/README.md +0 -0
  42. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/docs/architecture.md +0 -0
  43. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/docs/endpoint_visitor.md +0 -0
  44. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/docs/helpers.md +0 -0
  45. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/docs/ir_models.md +0 -0
  46. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/docs/line_writer.md +0 -0
  47. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/docs/loader.md +0 -0
  48. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/docs/model_visitor.md +0 -0
  49. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/docs/release-automation.md +0 -0
  50. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/docs/render_context.md +0 -0
  51. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/docs/unified_type_resolution.md +0 -0
  52. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/input/business_swagger.json +0 -0
  53. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/input/minimal_swagger.json +0 -0
  54. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/input/minimal_syntax_test.json +0 -0
  55. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/input/test_name_collision_spec.json +0 -0
  56. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/mkdocs.yml +0 -0
  57. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/poetry.lock +0 -0
  58. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/scripts/sync_version_to_init.py +0 -0
  59. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/scripts/validate_version_sync.py +0 -0
  60. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/__main__.py +0 -0
  61. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/cli.py +0 -0
  62. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/context/CLAUDE.md +0 -0
  63. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/context/file_manager.py +0 -0
  64. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/context/import_collector.py +0 -0
  65. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/context/render_context.py +0 -0
  66. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/core/CLAUDE.md +0 -0
  67. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/core/__init__.py +0 -0
  68. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/core/auth/base.py +0 -0
  69. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/core/auth/plugins.py +0 -0
  70. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/core/exceptions.py +0 -0
  71. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/core/http_status_codes.py +0 -0
  72. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/core/http_transport.py +0 -0
  73. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/core/loader/__init__.py +0 -0
  74. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/core/loader/loader.py +0 -0
  75. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/core/loader/operations/__init__.py +0 -0
  76. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/core/loader/operations/parser.py +0 -0
  77. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/core/loader/operations/post_processor.py +0 -0
  78. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/core/loader/operations/request_body.py +0 -0
  79. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/core/loader/parameters/__init__.py +0 -0
  80. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/core/loader/parameters/parser.py +0 -0
  81. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/core/loader/responses/__init__.py +0 -0
  82. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/core/loader/responses/parser.py +0 -0
  83. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/core/loader/schemas/__init__.py +0 -0
  84. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/core/loader/schemas/extractor.py +0 -0
  85. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/core/pagination.py +0 -0
  86. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/core/parsing/__init__.py +0 -0
  87. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/core/parsing/common/__init__.py +0 -0
  88. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/core/parsing/common/ref_resolution/__init__.py +0 -0
  89. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/core/parsing/common/ref_resolution/helpers/__init__.py +0 -0
  90. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/core/parsing/common/ref_resolution/helpers/cyclic_properties.py +0 -0
  91. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/core/parsing/common/ref_resolution/helpers/direct_cycle.py +0 -0
  92. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/core/parsing/common/ref_resolution/helpers/existing_schema.py +0 -0
  93. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/core/parsing/common/ref_resolution/helpers/list_response.py +0 -0
  94. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/core/parsing/common/ref_resolution/helpers/missing_ref.py +0 -0
  95. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/core/parsing/common/ref_resolution/helpers/new_schema.py +0 -0
  96. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/core/parsing/common/ref_resolution/helpers/stripped_suffix.py +0 -0
  97. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/core/parsing/common/ref_resolution/resolve_schema_ref.py +0 -0
  98. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/core/parsing/common/type_parser.py +0 -0
  99. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/core/parsing/context.py +0 -0
  100. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/core/parsing/cycle_helpers.py +0 -0
  101. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/core/parsing/keywords/__init__.py +0 -0
  102. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/core/parsing/keywords/all_of_parser.py +0 -0
  103. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/core/parsing/keywords/any_of_parser.py +0 -0
  104. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/core/parsing/keywords/array_items_parser.py +0 -0
  105. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/core/parsing/keywords/one_of_parser.py +0 -0
  106. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/core/parsing/keywords/properties_parser.py +0 -0
  107. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/core/parsing/schema_finalizer.py +0 -0
  108. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/core/parsing/schema_parser.py +0 -0
  109. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/core/parsing/transformers/__init__.py +0 -0
  110. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/core/parsing/transformers/inline_enum_extractor.py +0 -0
  111. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/core/parsing/transformers/inline_object_promoter.py +0 -0
  112. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/core/parsing/unified_cycle_detection.py +0 -0
  113. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/core/postprocess_manager.py +0 -0
  114. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/core/schemas.py +0 -0
  115. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/core/streaming_helpers.py +0 -0
  116. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/core/telemetry.py +0 -0
  117. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/core/utils.py +0 -0
  118. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/core/warning_collector.py +0 -0
  119. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/core/writers/code_writer.py +0 -0
  120. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/core/writers/documentation_writer.py +0 -0
  121. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/core/writers/line_writer.py +0 -0
  122. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/core/writers/python_construct_renderer.py +0 -0
  123. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/core_package_template/README.md +0 -0
  124. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/emit/models_emitter.py +0 -0
  125. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/emitters/CLAUDE.md +0 -0
  126. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/emitters/client_emitter.py +0 -0
  127. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/emitters/core_emitter.py +0 -0
  128. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/emitters/docs_emitter.py +0 -0
  129. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/emitters/endpoints_emitter.py +0 -0
  130. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/emitters/exceptions_emitter.py +0 -0
  131. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/emitters/models_emitter.py +0 -0
  132. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/generator/CLAUDE.md +0 -0
  133. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/generator/client_generator.py +0 -0
  134. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/helpers/CLAUDE.md +0 -0
  135. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/helpers/__init__.py +0 -0
  136. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/helpers/endpoint_utils.py +0 -0
  137. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/helpers/type_cleaner.py +0 -0
  138. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/helpers/type_helper.py +0 -0
  139. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/helpers/type_resolution/__init__.py +0 -0
  140. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/helpers/type_resolution/array_resolver.py +0 -0
  141. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/helpers/type_resolution/composition_resolver.py +0 -0
  142. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/helpers/type_resolution/finalizer.py +0 -0
  143. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/helpers/type_resolution/named_resolver.py +0 -0
  144. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/helpers/type_resolution/object_resolver.py +0 -0
  145. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/helpers/type_resolution/primitive_resolver.py +0 -0
  146. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/helpers/type_resolution/resolver.py +0 -0
  147. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/helpers/url_utils.py +0 -0
  148. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/http_types.py +0 -0
  149. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/ir.py +0 -0
  150. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/py.typed +0 -0
  151. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/types/CLAUDE.md +0 -0
  152. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/types/__init__.py +0 -0
  153. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/types/contracts/__init__.py +0 -0
  154. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/types/contracts/protocols.py +0 -0
  155. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/types/contracts/types.py +0 -0
  156. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/types/resolvers/__init__.py +0 -0
  157. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/types/resolvers/reference_resolver.py +0 -0
  158. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/types/resolvers/response_resolver.py +0 -0
  159. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/types/resolvers/schema_resolver.py +0 -0
  160. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/types/services/__init__.py +0 -0
  161. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/types/services/type_service.py +0 -0
  162. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/types/strategies/__init__.py +0 -0
  163. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/types/strategies/response_strategy.py +0 -0
  164. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/visit/CLAUDE.md +0 -0
  165. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/visit/client_visitor.py +0 -0
  166. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/visit/docs_visitor.py +0 -0
  167. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/visit/endpoint/__init__.py +0 -0
  168. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/visit/endpoint/endpoint_visitor.py +0 -0
  169. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/visit/endpoint/generators/__init__.py +0 -0
  170. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/visit/endpoint/generators/docstring_generator.py +0 -0
  171. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/visit/endpoint/generators/request_generator.py +0 -0
  172. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/visit/endpoint/generators/response_handler_generator.py +0 -0
  173. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/visit/endpoint/generators/signature_generator.py +0 -0
  174. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/visit/endpoint/generators/url_args_generator.py +0 -0
  175. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/visit/endpoint/processors/__init__.py +0 -0
  176. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/visit/endpoint/processors/import_analyzer.py +0 -0
  177. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/visit/endpoint/processors/parameter_processor.py +0 -0
  178. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/visit/exception_visitor.py +0 -0
  179. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/visit/model/__init__.py +0 -0
  180. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/visit/model/alias_generator.py +0 -0
  181. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/visit/model/dataclass_generator.py +0 -0
  182. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/visit/model/enum_generator.py +0 -0
  183. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/visit/model/model_visitor.py +0 -0
  184. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/src/pyopenapi_gen/visit/visitor.py +0 -0
  185. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/__init__.py +0 -0
  186. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/api/test_programmatic_api.py +0 -0
  187. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/auth/auth_analysis.md +0 -0
  188. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/auth/test_auth_base.py +0 -0
  189. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/auth/test_auth_plugins.py +0 -0
  190. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/cli/cli_analysis.md +0 -0
  191. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/cli/test_cli_backup_diff.py +0 -0
  192. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/cli/test_cli_edge_cases.py +0 -0
  193. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/cli/test_cli_edge_cases_comprehensive.py +0 -0
  194. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/cli/test_cli_internal_utils.py +0 -0
  195. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/cli/test_http_pagination_cli.py +0 -0
  196. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/context/context_analysis.md +0 -0
  197. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/context/test_core_import_path.py +0 -0
  198. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/context/test_file_manager.py +0 -0
  199. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/context/test_import_collector.py +0 -0
  200. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/context/test_render_context.py +0 -0
  201. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/context/test_render_context_imports.py +0 -0
  202. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/context/test_render_context_relative_paths.py +0 -0
  203. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/core/core_analysis.md +0 -0
  204. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/core/loader/parameters/test_inline_enum_array_params.py +0 -0
  205. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/core/loader/test_extractor.py +0 -0
  206. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/core/loader/test_top_level_enum_extraction.py +0 -0
  207. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/core/parsing/common/ref_resolution/helpers/helpers_analysis.md +0 -0
  208. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/core/parsing/common/ref_resolution/helpers/test_cyclic_properties.py +0 -0
  209. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/core/parsing/common/ref_resolution/helpers/test_direct_cycle.py +0 -0
  210. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/core/parsing/common/ref_resolution/helpers/test_existing_schema.py +0 -0
  211. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/core/parsing/common/ref_resolution/helpers/test_list_response.py +0 -0
  212. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/core/parsing/common/ref_resolution/helpers/test_missing_ref.py +0 -0
  213. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/core/parsing/common/ref_resolution/helpers/test_new_schema.py +0 -0
  214. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/core/parsing/common/ref_resolution/helpers/test_stripped_suffix.py +0 -0
  215. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/core/parsing/keywords/__init__.py +0 -0
  216. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/core/parsing/keywords/keywords_analysis.md +0 -0
  217. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/core/parsing/keywords/test_all_of_parser.py +0 -0
  218. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/core/parsing/keywords/test_any_of_parser.py +0 -0
  219. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/core/parsing/keywords/test_array_items_parser.py +0 -0
  220. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/core/parsing/keywords/test_one_of_parser.py +0 -0
  221. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/core/parsing/keywords/test_properties_parser.py +0 -0
  222. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/core/parsing/parsing_analysis.md +0 -0
  223. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/core/parsing/test_context.py +0 -0
  224. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/core/parsing/test_cycle_detection.py +0 -0
  225. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/core/parsing/test_cycle_helpers.py +0 -0
  226. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/core/parsing/test_improved_schema_naming.py +0 -0
  227. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/core/parsing/test_inline_enum_extractor.py +0 -0
  228. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/core/parsing/test_inline_object_promoter.py +0 -0
  229. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/core/parsing/test_logging.py +0 -0
  230. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/core/parsing/test_ref_resolver.py +0 -0
  231. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/core/parsing/test_schema_finalizer.py +0 -0
  232. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/core/parsing/test_schema_parser.py +0 -0
  233. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/core/parsing/test_schema_parser_list_response.py +0 -0
  234. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/core/parsing/test_type_parser.py +0 -0
  235. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/core/test_dataclass_serialization.py +0 -0
  236. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/core/test_detect_circular_imports.py +0 -0
  237. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/core/test_edge_cases_integration.py +0 -0
  238. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/core/test_edge_cases_systematic.py +0 -0
  239. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/core/test_exceptions_module.py +0 -0
  240. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/core/test_forward_references.py +0 -0
  241. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/core/test_http_transport.py +0 -0
  242. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/core/test_import_resolution.py +0 -0
  243. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/core/test_ir.py +0 -0
  244. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/core/test_ir_schema.py +0 -0
  245. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/core/test_loader.py +0 -0
  246. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/core/test_loader_extensive.py +0 -0
  247. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/core/test_loader_invalid_refs.py +0 -0
  248. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/core/test_loader_malformed.py +0 -0
  249. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/core/test_loader_media_types.py +0 -0
  250. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/core/test_pagination.py +0 -0
  251. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/core/test_parsing_context.py +0 -0
  252. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/core/test_protocol_defaults.py +0 -0
  253. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/core/test_schema_parser_specific_case.py +0 -0
  254. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/core/test_schemas.py +0 -0
  255. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/core/test_simple_self_ref_check.py +0 -0
  256. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/core/test_streaming_helpers.py +0 -0
  257. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/core/test_telemetry.py +0 -0
  258. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/core/test_telemetry_client.py +0 -0
  259. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/core/test_utils.py +0 -0
  260. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/core/test_warning_collector.py +0 -0
  261. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/core/writers/test_code_writer.py +0 -0
  262. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/core/writers/test_documentation_writer.py +0 -0
  263. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/core/writers/test_line_writer.py +0 -0
  264. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/core/writers/test_python_construct_renderer_json_wizard.py +0 -0
  265. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/core/writers/writers_analysis.md +0 -0
  266. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/emitters/emitters_analysis.md +0 -0
  267. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/emitters/test_client_emitter.py +0 -0
  268. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/emitters/test_docs_emitter.py +0 -0
  269. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/emitters/test_duplicate_operations.py +0 -0
  270. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/emitters/test_endpoints_emitter.py +0 -0
  271. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/emitters/test_exceptions_emitter.py +0 -0
  272. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/emitters/test_list_response_generation.py +0 -0
  273. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/emitters/test_models_emitter.py +0 -0
  274. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/end_to_end/test_dataclass_serialization_e2e.py +0 -0
  275. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/examples/test_developer_experience_demo.py +0 -0
  276. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/generation/generation_analysis.md +0 -0
  277. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/generation/test_external_core_package.py +0 -0
  278. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/generation_issues/specs/minimal_addmessage_like.json +0 -0
  279. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/generation_issues/test_addmessage_like_issues.py +0 -0
  280. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/generation_issues/test_agent_include_parameter_typing.py +0 -0
  281. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/generation_issues/test_message_batch_response_issue.py +0 -0
  282. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/helpers/helpers_analysis.md +0 -0
  283. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/helpers/test_array_resolver.py +0 -0
  284. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/helpers/test_endpoint_utils.py +0 -0
  285. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/helpers/test_endpoint_utils_extended.py +0 -0
  286. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/helpers/test_get_endpoint_return_types.py +0 -0
  287. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/helpers/test_named_resolver.py +0 -0
  288. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/helpers/test_named_type_resolver.py +0 -0
  289. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/helpers/test_object_resolver.py +0 -0
  290. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/helpers/test_put_endpoint_return_types.py +0 -0
  291. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/helpers/test_type_cleaner.py +0 -0
  292. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/helpers/test_type_helper.py +0 -0
  293. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/helpers/test_url_utils.py +0 -0
  294. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/helpers/test_utils_helpers.py +0 -0
  295. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/integration/test_generated_code_structure.py +0 -0
  296. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/integrations/integrations_analysis.md +0 -0
  297. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/integrations/test_business_swagger_message_type.py +0 -0
  298. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/integrations/test_end_to_end_business_swagger.py +0 -0
  299. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/integrations/test_end_to_end_petstore.py +0 -0
  300. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/integrations/test_name_collisions.py +0 -0
  301. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/specs/response_unwrapping_spec.yaml +0 -0
  302. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/test_analysis_overview.md +0 -0
  303. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/test_init.py +0 -0
  304. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/types/__init__.py +0 -0
  305. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/types/test_business_swagger_integration.py +0 -0
  306. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/types/test_contracts_types.py +0 -0
  307. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/types/test_missing_imports_bug.py +0 -0
  308. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/types/test_reference_resolver.py +0 -0
  309. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/types/test_response_resolver.py +0 -0
  310. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/types/test_response_strategy.py +0 -0
  311. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/types/test_response_strategy_simplified.py +0 -0
  312. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/types/test_schema_resolver.py +0 -0
  313. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/types/test_schema_resolver_enums.py +0 -0
  314. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/types/test_type_service.py +0 -0
  315. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/visit/__init__.py +0 -0
  316. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/visit/endpoint/__init__.py +0 -0
  317. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/visit/endpoint/generators/__init__.py +0 -0
  318. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/visit/endpoint/generators/generators_analysis.md +0 -0
  319. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/visit/endpoint/generators/test_dataclass_integration.py +0 -0
  320. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/visit/endpoint/generators/test_docstring_generator.py +0 -0
  321. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/visit/endpoint/generators/test_match_case_response.py +0 -0
  322. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/visit/endpoint/generators/test_request_generator.py +0 -0
  323. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/visit/endpoint/generators/test_response_handler_generator.py +0 -0
  324. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/visit/endpoint/generators/test_response_handler_generator_strategy.py +0 -0
  325. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/visit/endpoint/generators/test_signature_generator.py +0 -0
  326. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/visit/endpoint/generators/test_url_args_generator.py +0 -0
  327. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/visit/endpoint/processors/__init__.py +0 -0
  328. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/visit/endpoint/processors/test_import_analyzer.py +0 -0
  329. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/visit/endpoint/processors/test_import_analyzer.py.bak +0 -0
  330. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/visit/endpoint/processors/test_parameter_processor.py +0 -0
  331. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/visit/endpoint/test_endpoint_visitor.py +0 -0
  332. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/visit/model/__init__.py +0 -0
  333. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/visit/model/test_alias_generator.py +0 -0
  334. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/visit/model/test_dataclass_generator.py +0 -0
  335. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/visit/model/test_dataclass_generator_json_wizard.py +0 -0
  336. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/visit/model/test_enum_generator.py +0 -0
  337. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/visit/model/test_json_value_integration.py +0 -0
  338. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/visit/model/test_json_value_wrapper.py +0 -0
  339. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/visit/test_client_visitor.py +0 -0
  340. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/visit/test_model_visitor.py +0 -0
  341. {pyopenapi_gen-0.20.0 → pyopenapi_gen-0.20.1}/tests/visit/test_visitor.py +0 -0
@@ -1,6 +1,53 @@
1
1
  # CHANGELOG
2
2
 
3
3
 
4
+ ## v0.20.1 (2025-10-21)
5
+
6
+ ### Bug Fixes
7
+
8
+ - **codegen**: Resolve method naming and file handling in overloaded endpoints
9
+ ([`190e581`](https://github.com/mindhiveoy/pyopenapi_gen/commit/190e5819e99edf37d14722b075069851d03c4c3b))
10
+
11
+ This commit fixes two critical issues in code generation for operations with multiple content types
12
+ (overloaded methods):
13
+
14
+ 1. **Method Naming**: Overloaded methods were using camelCase from OpenAPI operationId instead of
15
+ converting to Python's snake_case convention. - Fixed: Added NameSanitizer.sanitize_method_name()
16
+ in overload_generator.py - Example: updateDocument -> update_document
17
+
18
+ 2. **File Upload Handling**: Multipart/form-data file uploads were incorrectly being passed through
19
+ DataclassSerializer.serialize(), which is designed for dataclass-to-dict conversion, not file I/O.
20
+ - Fixed: Pass file dict directly to httpx transport in endpoint_method_generator.py - Rationale:
21
+ httpx expects raw IO objects, not serialized data
22
+
23
+ Both issues only affected operations with multiple content types (JSON + multipart). Standard
24
+ single-content-type operations were unaffected.
25
+
26
+ Changes: - src/pyopenapi_gen/visit/endpoint/generators/overload_generator.py: Added NameSanitizer
27
+ import and method name sanitisation in two locations (overload signatures and implementation
28
+ signatures)
29
+
30
+ - src/pyopenapi_gen/visit/endpoint/generators/endpoint_method_generator.py: Removed
31
+ DataclassSerializer.serialize() for file parameters in multipart handling, passing files directly
32
+ to transport
33
+
34
+ - tests/visit/endpoint/generators/test_overload_generator.py: Added unit tests for snake_case
35
+ conversion in overload and implementation signatures
36
+
37
+ - tests/visit/endpoint/generators/test_endpoint_method_generator.py: Added test for file handling
38
+ without serialisation
39
+
40
+ - tests/generation_issues/test_overload_naming_issues.py: Added integration tests verifying both
41
+ fixes in full code generation pipeline
42
+
43
+ All tests pass (1348 tests) with full quality checks (format, lint, typecheck, security).
44
+
45
+ ### Chores
46
+
47
+ - **release**: Sync __init__.py version [skip ci]
48
+ ([`8047e53`](https://github.com/mindhiveoy/pyopenapi_gen/commit/8047e53df11d8985d95f89dbf3b36046af1e6f1a))
49
+
50
+
4
51
  ## v0.20.0 (2025-10-19)
5
52
 
6
53
  ### Bug Fixes
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyopenapi-gen
3
- Version: 0.20.0
3
+ Version: 0.20.1
4
4
  Summary: Modern, async-first Python client generator for OpenAPI specifications with advanced cycle detection and unified type resolution
5
5
  Project-URL: Homepage, https://github.com/your-org/pyopenapi-gen
6
6
  Project-URL: Documentation, https://github.com/your-org/pyopenapi-gen/blob/main/README.md
@@ -1,5 +1,5 @@
1
1
  <?xml version="1.0" ?>
2
- <coverage version="7.10.7" timestamp="1760875420300" lines-valid="6505" lines-covered="5750" line-rate="0.8839" branches-covered="0" branches-valid="0" branch-rate="0" complexity="0">
2
+ <coverage version="7.10.7" timestamp="1761058806878" lines-valid="6507" lines-covered="5752" line-rate="0.884" branches-covered="0" branches-valid="0" branch-rate="0" complexity="0">
3
3
  <!-- Generated by coverage.py: https://coverage.readthedocs.io/en/7.10.7 -->
4
4
  <!-- Based on https://raw.githubusercontent.com/cobertura/web/master/htdocs/xml/coverage-04.dtd -->
5
5
  <sources>
@@ -6008,7 +6008,7 @@
6008
6008
  </class>
6009
6009
  </classes>
6010
6010
  </package>
6011
- <package name="pyopenapi_gen.visit.endpoint.generators" line-rate="0.8881" branch-rate="0" complexity="0">
6011
+ <package name="pyopenapi_gen.visit.endpoint.generators" line-rate="0.8884" branch-rate="0" complexity="0">
6012
6012
  <classes>
6013
6013
  <class name="__init__.py" filename="pyopenapi_gen/visit/endpoint/generators/__init__.py" complexity="0" line-rate="1" branch-rate="0">
6014
6014
  <methods/>
@@ -6085,7 +6085,7 @@
6085
6085
  <line number="123" hits="1"/>
6086
6086
  </lines>
6087
6087
  </class>
6088
- <class name="endpoint_method_generator.py" filename="pyopenapi_gen/visit/endpoint/generators/endpoint_method_generator.py" complexity="0" line-rate="0.9291" branch-rate="0">
6088
+ <class name="endpoint_method_generator.py" filename="pyopenapi_gen/visit/endpoint/generators/endpoint_method_generator.py" complexity="0" line-rate="0.9286" branch-rate="0">
6089
6089
  <methods/>
6090
6090
  <lines>
6091
6091
  <line number="1" hits="1"/>
@@ -6188,7 +6188,6 @@
6188
6188
  <line number="181" hits="1"/>
6189
6189
  <line number="182" hits="1"/>
6190
6190
  <line number="183" hits="1"/>
6191
- <line number="184" hits="1"/>
6192
6191
  <line number="185" hits="1"/>
6193
6192
  <line number="186" hits="1"/>
6194
6193
  <line number="187" hits="1"/>
@@ -6228,93 +6227,96 @@
6228
6227
  <line number="10" hits="1"/>
6229
6228
  <line number="11" hits="1"/>
6230
6229
  <line number="12" hits="1"/>
6231
- <line number="14" hits="1"/>
6232
- <line number="17" hits="1"/>
6233
- <line number="26" hits="1"/>
6230
+ <line number="13" hits="1"/>
6231
+ <line number="15" hits="1"/>
6232
+ <line number="18" hits="1"/>
6234
6233
  <line number="27" hits="1"/>
6235
6234
  <line number="28" hits="1"/>
6236
6235
  <line number="29" hits="1"/>
6237
6236
  <line number="30" hits="1"/>
6238
- <line number="32" hits="1"/>
6239
- <line number="42" hits="1"/>
6237
+ <line number="31" hits="1"/>
6238
+ <line number="33" hits="1"/>
6240
6239
  <line number="43" hits="1"/>
6241
6240
  <line number="44" hits="1"/>
6242
- <line number="46" hits="1"/>
6243
- <line number="60" hits="1"/>
6241
+ <line number="45" hits="1"/>
6242
+ <line number="47" hits="1"/>
6244
6243
  <line number="61" hits="1"/>
6245
- <line number="64" hits="1"/>
6244
+ <line number="62" hits="1"/>
6246
6245
  <line number="65" hits="1"/>
6247
6246
  <line number="66" hits="1"/>
6248
6247
  <line number="67" hits="1"/>
6249
- <line number="69" hits="1"/>
6250
- <line number="72" hits="1"/>
6251
- <line number="76" hits="1"/>
6248
+ <line number="68" hits="1"/>
6249
+ <line number="70" hits="1"/>
6250
+ <line number="73" hits="1"/>
6252
6251
  <line number="77" hits="1"/>
6253
6252
  <line number="78" hits="1"/>
6254
- <line number="80" hits="1"/>
6255
- <line number="82" hits="1"/>
6256
- <line number="103" hits="1"/>
6257
- <line number="106" hits="1"/>
6258
- <line number="109" hits="1"/>
6259
- <line number="112" hits="1"/>
6260
- <line number="115" hits="1"/>
6253
+ <line number="79" hits="1"/>
6254
+ <line number="81" hits="1"/>
6255
+ <line number="83" hits="1"/>
6256
+ <line number="104" hits="1"/>
6257
+ <line number="107" hits="1"/>
6258
+ <line number="110" hits="1"/>
6259
+ <line number="113" hits="1"/>
6261
6260
  <line number="116" hits="1"/>
6262
- <line number="118" hits="1"/>
6263
- <line number="120" hits="1"/>
6261
+ <line number="117" hits="1"/>
6262
+ <line number="119" hits="1"/>
6264
6263
  <line number="121" hits="1"/>
6265
6264
  <line number="122" hits="1"/>
6266
6265
  <line number="123" hits="1"/>
6267
- <line number="126" hits="1"/>
6268
- <line number="129" hits="1"/>
6269
- <line number="132" hits="1"/>
6270
- <line number="135" hits="1"/>
6271
- <line number="138" hits="1"/>
6266
+ <line number="124" hits="1"/>
6267
+ <line number="127" hits="1"/>
6268
+ <line number="130" hits="1"/>
6269
+ <line number="133" hits="1"/>
6270
+ <line number="136" hits="1"/>
6272
6271
  <line number="139" hits="1"/>
6273
- <line number="140" hits="1"/>
6274
- <line number="141" hits="1"/>
6275
6272
  <line number="142" hits="1"/>
6276
6273
  <line number="143" hits="1"/>
6274
+ <line number="144" hits="1"/>
6277
6275
  <line number="145" hits="1"/>
6276
+ <line number="146" hits="1"/>
6278
6277
  <line number="147" hits="1"/>
6279
- <line number="159" hits="1"/>
6280
- <line number="161" hits="1"/>
6281
- <line number="164" hits="1"/>
6282
- <line number="166" hits="1"/>
6283
- <line number="167" hits="1"/>
6284
- <line number="169" hits="1"/>
6278
+ <line number="149" hits="1"/>
6279
+ <line number="151" hits="1"/>
6280
+ <line number="163" hits="1"/>
6281
+ <line number="165" hits="1"/>
6282
+ <line number="168" hits="1"/>
6283
+ <line number="170" hits="1"/>
6285
6284
  <line number="171" hits="1"/>
6286
6285
  <line number="173" hits="1"/>
6287
6286
  <line number="175" hits="1"/>
6287
+ <line number="177" hits="1"/>
6288
6288
  <line number="179" hits="1"/>
6289
- <line number="180" hits="1"/>
6290
- <line number="182" hits="1"/>
6291
- <line number="197" hits="1"/>
6292
- <line number="200" hits="1"/>
6293
- <line number="203" hits="1"/>
6289
+ <line number="183" hits="1"/>
6290
+ <line number="184" hits="1"/>
6291
+ <line number="186" hits="1"/>
6292
+ <line number="201" hits="1"/>
6294
6293
  <line number="204" hits="1"/>
6295
- <line number="206" hits="1"/>
6294
+ <line number="207" hits="1"/>
6296
6295
  <line number="208" hits="1"/>
6297
- <line number="209" hits="1"/>
6298
6296
  <line number="210" hits="1"/>
6299
- <line number="211" hits="1"/>
6297
+ <line number="212" hits="1"/>
6298
+ <line number="213" hits="1"/>
6300
6299
  <line number="214" hits="1"/>
6301
- <line number="217" hits="1"/>
6300
+ <line number="215" hits="1"/>
6302
6301
  <line number="218" hits="1"/>
6303
- <line number="220" hits="1"/>
6304
6302
  <line number="221" hits="1"/>
6303
+ <line number="222" hits="1"/>
6305
6304
  <line number="224" hits="1"/>
6306
6305
  <line number="225" hits="1"/>
6307
- <line number="226" hits="1"/>
6308
- <line number="227" hits="1"/>
6306
+ <line number="228" hits="1"/>
6307
+ <line number="229" hits="1"/>
6309
6308
  <line number="230" hits="1"/>
6310
- <line number="233" hits="1"/>
6311
- <line number="236" hits="1"/>
6309
+ <line number="231" hits="1"/>
6310
+ <line number="234" hits="1"/>
6312
6311
  <line number="237" hits="1"/>
6313
- <line number="238" hits="1"/>
6314
- <line number="239" hits="1"/>
6315
6312
  <line number="240" hits="1"/>
6316
- <line number="241" hits="1"/>
6317
6313
  <line number="243" hits="1"/>
6314
+ <line number="244" hits="1"/>
6315
+ <line number="245" hits="1"/>
6316
+ <line number="246" hits="1"/>
6317
+ <line number="247" hits="1"/>
6318
+ <line number="248" hits="1"/>
6319
+ <line number="250" hits="1"/>
6318
6320
  </lines>
6319
6321
  </class>
6320
6322
  <class name="request_generator.py" filename="pyopenapi_gen/visit/endpoint/generators/request_generator.py" complexity="0" line-rate="0.9535" branch-rate="0">
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "pyopenapi-gen"
7
- version = "0.20.0"
7
+ version = "0.20.1"
8
8
  description = "Modern, async-first Python client generator for OpenAPI specifications with advanced cycle detection and unified type resolution"
9
9
  authors = [{ name = "Mindhive Oy", email = "contact@mindhive.fi" }]
10
10
  maintainers = [{ name = "Ville Venäläinen | Mindhive Oy", email = "ville@mindhive.fi" }]
@@ -140,7 +140,7 @@ pyopenapi-gen = "pyopenapi_gen.cli:app"
140
140
 
141
141
  [tool.commitizen]
142
142
  name = "cz_conventional_commits"
143
- version = "0.20.0"
143
+ version = "0.20.1"
144
144
  version_files = [
145
145
  "pyproject.toml:version",
146
146
  "src/pyopenapi_gen/__init__.py:__version__"
@@ -50,7 +50,7 @@ __all__ = [
50
50
  ]
51
51
 
52
52
  # Semantic version of the generator core – automatically managed by semantic-release.
53
- __version__: str = "0.20.0"
53
+ __version__: str = "0.20.1"
54
54
 
55
55
  # ---------------------------------------------------------------------------
56
56
  # Lazy-loading and autocompletion support (This part remains)
@@ -181,12 +181,12 @@ class EndpointMethodGenerator:
181
181
  writer.dedent()
182
182
  writer.write_line(")")
183
183
  elif content_type == "multipart/form-data":
184
- writer.write_line(f"files_data = DataclassSerializer.serialize({param_info['name']})")
184
+ # Files dict is already in correct format for httpx - pass directly
185
185
  writer.write_line("response = await self._transport.request(")
186
186
  writer.indent()
187
187
  writer.write_line(f'"{op.method.value.upper()}", url,')
188
188
  writer.write_line("params=None,")
189
- writer.write_line("files=files_data,")
189
+ writer.write_line(f"files={param_info['name']},")
190
190
  writer.write_line("headers=None")
191
191
  writer.dedent()
192
192
  writer.write_line(")")
@@ -6,6 +6,7 @@ from typing import Any
6
6
  from pyopenapi_gen import IROperation
7
7
 
8
8
  from ....context.render_context import RenderContext
9
+ from ....core.utils import NameSanitizer
9
10
  from ....core.writers.code_writer import CodeWriter
10
11
  from ..processors.parameter_processor import EndpointParameterProcessor
11
12
  from .docstring_generator import EndpointDocstringGenerator
@@ -134,9 +135,12 @@ class OverloadMethodGenerator:
134
135
  # Get return type from response strategy
135
136
  return_type = response_strategy.return_type
136
137
 
138
+ # Sanitize method name to snake_case
139
+ method_name = NameSanitizer.sanitize_method_name(op.operation_id)
140
+
137
141
  # Write signature
138
142
  params_str = ",\n ".join(param_parts)
139
- writer.write_line(f"async def {op.operation_id}(")
143
+ writer.write_line(f"async def {method_name}(")
140
144
  writer.indent()
141
145
  writer.write_line(params_str)
142
146
  writer.dedent()
@@ -232,9 +236,12 @@ class OverloadMethodGenerator:
232
236
  # Get return type
233
237
  return_type = response_strategy.return_type
234
238
 
239
+ # Sanitize method name to snake_case
240
+ method_name = NameSanitizer.sanitize_method_name(op.operation_id)
241
+
235
242
  # Write signature
236
243
  params_str = ",\n ".join(param_parts)
237
- writer.write_line(f"async def {op.operation_id}(")
244
+ writer.write_line(f"async def {method_name}(")
238
245
  writer.indent()
239
246
  writer.write_line(params_str)
240
247
  writer.dedent()
@@ -0,0 +1,203 @@
1
+ """
2
+ Integration tests for overload method naming and file handling issues.
3
+
4
+ These tests verify that:
5
+ 1. Methods with camelCase operationIds are converted to snake_case
6
+ 2. File uploads don't use incorrect DataclassSerializer.serialize()
7
+ 3. Multi-content-type operations generate correct code
8
+ """
9
+
10
+ import json
11
+ import tempfile
12
+ from pathlib import Path
13
+
14
+ import pytest
15
+
16
+ from pyopenapi_gen.generator.client_generator import ClientGenerator
17
+
18
+
19
+ @pytest.fixture
20
+ def minimal_spec_with_camelcase_operations() -> dict:
21
+ """Minimal OpenAPI spec with camelCase operation IDs and multi-content types."""
22
+ return {
23
+ "openapi": "3.0.0",
24
+ "info": {"title": "Test API", "version": "1.0.0"},
25
+ "paths": {
26
+ "/documents/{id}": {
27
+ "put": {
28
+ "operationId": "updateDocument", # camelCase
29
+ "summary": "Update a document",
30
+ "tags": ["documents"],
31
+ "parameters": [{"name": "id", "in": "path", "required": True, "schema": {"type": "string"}}],
32
+ "requestBody": {
33
+ "required": True,
34
+ "content": {
35
+ "application/json": {
36
+ "schema": {
37
+ "type": "object",
38
+ "properties": {"title": {"type": "string"}},
39
+ }
40
+ },
41
+ "multipart/form-data": {
42
+ "schema": {
43
+ "type": "object",
44
+ "properties": {"file": {"type": "string", "format": "binary"}},
45
+ }
46
+ },
47
+ },
48
+ },
49
+ "responses": {
50
+ "200": {
51
+ "description": "Success",
52
+ "content": {
53
+ "application/json": {
54
+ "schema": {
55
+ "type": "object",
56
+ "properties": {"id": {"type": "string"}},
57
+ }
58
+ }
59
+ },
60
+ }
61
+ },
62
+ }
63
+ },
64
+ "/documents": {
65
+ "post": {
66
+ "operationId": "createDocument", # camelCase
67
+ "summary": "Create a document",
68
+ "tags": ["documents"],
69
+ "requestBody": {
70
+ "required": True,
71
+ "content": {
72
+ "application/json": {
73
+ "schema": {
74
+ "type": "object",
75
+ "properties": {"title": {"type": "string"}},
76
+ }
77
+ },
78
+ "multipart/form-data": {
79
+ "schema": {
80
+ "type": "object",
81
+ "properties": {"file": {"type": "string", "format": "binary"}},
82
+ }
83
+ },
84
+ },
85
+ },
86
+ "responses": {
87
+ "201": {
88
+ "description": "Created",
89
+ "content": {
90
+ "application/json": {
91
+ "schema": {
92
+ "type": "object",
93
+ "properties": {"id": {"type": "string"}},
94
+ }
95
+ }
96
+ },
97
+ }
98
+ },
99
+ }
100
+ },
101
+ },
102
+ }
103
+
104
+
105
+ class TestOverloadNamingIntegration:
106
+ """Integration tests for camelCase to snake_case conversion."""
107
+
108
+ def test_generate_client__camelcase_operations__converts_to_snake_case(
109
+ self, minimal_spec_with_camelcase_operations: dict
110
+ ) -> None:
111
+ """
112
+ Scenario: Generate client from spec with camelCase operationIds
113
+ Expected Outcome: Generated methods should be snake_case
114
+ """
115
+ # Arrange
116
+ with tempfile.TemporaryDirectory() as tmpdir:
117
+ spec_path = Path(tmpdir) / "spec.json"
118
+ with open(spec_path, "w") as f:
119
+ json.dump(minimal_spec_with_camelcase_operations, f)
120
+
121
+ output_path = Path(tmpdir) / "output"
122
+ output_path.mkdir()
123
+
124
+ generator = ClientGenerator()
125
+
126
+ # Act
127
+ generated_files = generator.generate(
128
+ spec_path=str(spec_path),
129
+ project_root=output_path,
130
+ output_package="testapi",
131
+ force=True,
132
+ no_postprocess=True, # Skip formatting for faster test
133
+ )
134
+
135
+ # Assert
136
+ # Find the generated endpoint file (exclude __init__.py)
137
+ endpoint_files = [
138
+ f for f in generated_files if "endpoints" in str(f) and not str(f).endswith("__init__.py")
139
+ ]
140
+ assert len(endpoint_files) > 0, "No endpoint files generated"
141
+
142
+ # Collect all endpoint code
143
+ all_code = ""
144
+ for endpoint_file in endpoint_files:
145
+ with open(endpoint_file, "r") as f:
146
+ all_code += f.read()
147
+
148
+ # Check method names are snake_case
149
+ assert "async def update_document(" in all_code, "updateDocument should be update_document"
150
+ assert "async def create_document(" in all_code, "createDocument should be create_document"
151
+
152
+ # Check they're NOT camelCase
153
+ assert "async def updateDocument(" not in all_code, "Method name should not be camelCase updateDocument"
154
+ assert "async def createDocument(" not in all_code, "Method name should not be camelCase createDocument"
155
+
156
+
157
+ class TestFileHandlingIntegration:
158
+ """Integration tests for file upload handling."""
159
+
160
+ def test_generate_client__multipart_files__no_serialization(
161
+ self, minimal_spec_with_camelcase_operations: dict
162
+ ) -> None:
163
+ """
164
+ Scenario: Generate client with multipart/form-data operations
165
+ Expected Outcome: Files should be passed directly, not serialized
166
+ """
167
+ # Arrange
168
+ with tempfile.TemporaryDirectory() as tmpdir:
169
+ spec_path = Path(tmpdir) / "spec.json"
170
+ with open(spec_path, "w") as f:
171
+ json.dump(minimal_spec_with_camelcase_operations, f)
172
+
173
+ output_path = Path(tmpdir) / "output"
174
+ output_path.mkdir()
175
+
176
+ generator = ClientGenerator()
177
+
178
+ # Act
179
+ generated_files = generator.generate(
180
+ spec_path=str(spec_path),
181
+ project_root=output_path,
182
+ output_package="testapi",
183
+ force=True,
184
+ no_postprocess=True,
185
+ )
186
+
187
+ # Assert
188
+ endpoint_files = [f for f in generated_files if "endpoints" in str(f)]
189
+ assert len(endpoint_files) > 0
190
+
191
+ for endpoint_file in endpoint_files:
192
+ with open(endpoint_file, "r") as f:
193
+ code = f.read()
194
+
195
+ # Files should be passed directly
196
+ if "multipart/form-data" in code:
197
+ # Should NOT serialize files
198
+ assert (
199
+ "files_data = DataclassSerializer.serialize(files)" not in code
200
+ ), "Files should not be serialized"
201
+
202
+ # Should pass files directly
203
+ assert "files=files," in code or "files = files" in code, "Files should be passed directly"
@@ -241,3 +241,64 @@ class TestEndpointMethodGenerator:
241
241
  result_code
242
242
  == "def test_op():\n # Docstring here\n # Only comments or whitespace added by helpers\n pass"
243
243
  )
244
+
245
+
246
+ class TestGenerateImplementationMethod:
247
+ """Tests for _generate_implementation_method."""
248
+
249
+ def test_generate_implementation_method__multipart_files__no_serialization(
250
+ self, mock_render_context: RenderContext
251
+ ) -> None:
252
+ """
253
+ Scenario: Generating implementation method for multipart/form-data with files
254
+ Expected Outcome: Files parameter should be passed directly without DataclassSerializer
255
+ """
256
+ # Arrange
257
+ from pyopenapi_gen import IRRequestBody, IRResponse
258
+ from pyopenapi_gen.ir import IRSchema
259
+ from pyopenapi_gen.types.strategies.response_strategy import ResponseStrategy
260
+
261
+ op = IROperation(
262
+ path="/upload",
263
+ method=HTTPMethod.POST,
264
+ operation_id="uploadFile",
265
+ summary="Upload file",
266
+ description="Upload operation",
267
+ parameters=[],
268
+ request_body=IRRequestBody(
269
+ description="File upload",
270
+ required=True,
271
+ content={
272
+ "application/json": IRSchema(type="object", name="UploadRequest"),
273
+ "multipart/form-data": IRSchema(type="object", name="FileUpload"),
274
+ },
275
+ ),
276
+ responses=[
277
+ IRResponse(
278
+ status_code="201", description="Created", content={"application/json": IRSchema(type="object")}
279
+ )
280
+ ],
281
+ )
282
+
283
+ response_ir = IRResponse(
284
+ status_code="201", description="Created", content={"application/json": IRSchema(type="object")}
285
+ )
286
+ response_strategy = ResponseStrategy(
287
+ return_type="UploadResponse",
288
+ response_schema=IRSchema(type="object", name="UploadResponse"),
289
+ is_streaming=False,
290
+ response_ir=response_ir,
291
+ )
292
+
293
+ generator = EndpointMethodGenerator(schemas={})
294
+
295
+ # Act
296
+ result = generator._generate_implementation_method(op, mock_render_context, response_strategy)
297
+
298
+ # Assert - Files should be passed directly, NOT serialized
299
+ # The implementation should contain: files=files (not files_data=DataclassSerializer.serialize(files))
300
+ assert "files=files," in result or "files={param_info['name']}" in result
301
+ # Should NOT contain serialization of files
302
+ assert "DataclassSerializer.serialize(files)" not in result
303
+ # The variable assignment should be for json_body, not files_data
304
+ assert "files_data" not in result or "files_data = files" in result