pyopenapi-gen 0.9.0__tar.gz → 0.10.2__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.
Files changed (326) hide show
  1. pyopenapi_gen-0.10.2/.bandit +22 -0
  2. pyopenapi_gen-0.10.2/.cursor/mcp.json +10 -0
  3. pyopenapi_gen-0.10.2/.cursor/rules/architecture.mdc +86 -0
  4. pyopenapi_gen-0.10.2/.cursor/rules/coding-conventions.mdc +190 -0
  5. pyopenapi_gen-0.10.2/.cursor/rules/project-goal.mdc +84 -0
  6. pyopenapi_gen-0.10.2/.cursor/rules/testing.mdc +185 -0
  7. pyopenapi_gen-0.10.2/.github/BRANCH_PROTECTION.md +168 -0
  8. pyopenapi_gen-0.10.2/.github/CLAUDE_CONFIGURATION.md +88 -0
  9. pyopenapi_gen-0.10.2/.github/CODEOWNERS +30 -0
  10. pyopenapi_gen-0.10.2/.github/ISSUE_TEMPLATE/bug_report.md +50 -0
  11. pyopenapi_gen-0.10.2/.github/ISSUE_TEMPLATE/feature_request.md +31 -0
  12. pyopenapi_gen-0.10.2/.github/dependabot.yml +38 -0
  13. pyopenapi_gen-0.10.2/.github/workflows/ci.yml +23 -0
  14. pyopenapi_gen-0.10.2/.github/workflows/claude-auto-approve.yml +153 -0
  15. pyopenapi_gen-0.10.2/.github/workflows/claude-review-trigger.yml +71 -0
  16. pyopenapi_gen-0.10.2/.github/workflows/claude.yml +60 -0
  17. pyopenapi_gen-0.10.2/.github/workflows/pr-checks.yml +141 -0
  18. pyopenapi_gen-0.10.2/.github/workflows/production-release.yml.backup +170 -0
  19. pyopenapi_gen-0.10.2/.github/workflows/promote-to-staging.yml +65 -0
  20. pyopenapi_gen-0.10.2/.github/workflows/semantic-release.yml +304 -0
  21. pyopenapi_gen-0.10.2/.github/workflows/staging-publish.yml +110 -0
  22. pyopenapi_gen-0.10.2/.github/workflows/testpypi-publish.yml +45 -0
  23. pyopenapi_gen-0.10.2/.gitignore +192 -0
  24. pyopenapi_gen-0.10.2/.python-version +1 -0
  25. pyopenapi_gen-0.10.2/.vscode/settings.json +16 -0
  26. pyopenapi_gen-0.10.2/CHANGELOG.md +1291 -0
  27. pyopenapi_gen-0.10.2/CLAUDE.md +790 -0
  28. pyopenapi_gen-0.10.2/CONTRIBUTING.md +602 -0
  29. pyopenapi_gen-0.10.2/Makefile +188 -0
  30. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/PKG-INFO +37 -39
  31. pyopenapi_gen-0.10.2/coverage.xml +6690 -0
  32. pyopenapi_gen-0.10.2/docs/README.md +79 -0
  33. pyopenapi_gen-0.10.2/docs/architecture.md +219 -0
  34. pyopenapi_gen-0.10.2/docs/endpoint_visitor.md +12 -0
  35. pyopenapi_gen-0.10.2/docs/helpers.md +50 -0
  36. pyopenapi_gen-0.10.2/docs/ir_models.md +90 -0
  37. pyopenapi_gen-0.10.2/docs/line_writer.md +206 -0
  38. pyopenapi_gen-0.10.2/docs/loader.md +11 -0
  39. pyopenapi_gen-0.10.2/docs/model_visitor.md +12 -0
  40. pyopenapi_gen-0.10.2/docs/render_context.md +11 -0
  41. pyopenapi_gen-0.10.2/docs/unified_type_resolution.md +206 -0
  42. pyopenapi_gen-0.10.2/input/business_swagger.json +11723 -0
  43. pyopenapi_gen-0.10.2/input/minimal_swagger.json +49 -0
  44. pyopenapi_gen-0.10.2/input/minimal_syntax_test.json +120 -0
  45. pyopenapi_gen-0.10.2/input/test_name_collision_spec.json +121 -0
  46. pyopenapi_gen-0.10.2/mkdocs.yml +22 -0
  47. pyopenapi_gen-0.10.2/poetry.lock +2915 -0
  48. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/pyproject.toml +5 -4
  49. pyopenapi_gen-0.10.2/tests/__init__.py +1 -0
  50. pyopenapi_gen-0.10.2/tests/auth/auth_analysis.md +22 -0
  51. pyopenapi_gen-0.10.2/tests/auth/test_auth_base.py +116 -0
  52. pyopenapi_gen-0.10.2/tests/auth/test_auth_plugins.py +133 -0
  53. pyopenapi_gen-0.10.2/tests/cli/cli_analysis.md +64 -0
  54. pyopenapi_gen-0.10.2/tests/cli/test_cli_backup_diff.py +60 -0
  55. pyopenapi_gen-0.10.2/tests/cli/test_cli_edge_cases.py +100 -0
  56. pyopenapi_gen-0.10.2/tests/cli/test_cli_edge_cases_comprehensive.py +647 -0
  57. pyopenapi_gen-0.10.2/tests/cli/test_cli_internal_utils.py +29 -0
  58. pyopenapi_gen-0.10.2/tests/cli/test_http_pagination_cli.py +166 -0
  59. pyopenapi_gen-0.10.2/tests/context/context_analysis.md +75 -0
  60. pyopenapi_gen-0.10.2/tests/context/test_file_manager.py +176 -0
  61. pyopenapi_gen-0.10.2/tests/context/test_import_collector.py +791 -0
  62. pyopenapi_gen-0.10.2/tests/context/test_render_context.py +446 -0
  63. pyopenapi_gen-0.10.2/tests/context/test_render_context_imports.py +38 -0
  64. pyopenapi_gen-0.10.2/tests/context/test_render_context_relative_paths.py +103 -0
  65. pyopenapi_gen-0.10.2/tests/core/core_analysis.md +341 -0
  66. pyopenapi_gen-0.10.2/tests/core/loader/test_extractor.py +900 -0
  67. pyopenapi_gen-0.10.2/tests/core/parsing/common/ref_resolution/helpers/helpers_analysis.md +196 -0
  68. pyopenapi_gen-0.10.2/tests/core/parsing/common/ref_resolution/helpers/test_cyclic_properties.py +132 -0
  69. pyopenapi_gen-0.10.2/tests/core/parsing/common/ref_resolution/helpers/test_direct_cycle.py +78 -0
  70. pyopenapi_gen-0.10.2/tests/core/parsing/common/ref_resolution/helpers/test_existing_schema.py +74 -0
  71. pyopenapi_gen-0.10.2/tests/core/parsing/common/ref_resolution/helpers/test_list_response.py +125 -0
  72. pyopenapi_gen-0.10.2/tests/core/parsing/common/ref_resolution/helpers/test_missing_ref.py +145 -0
  73. pyopenapi_gen-0.10.2/tests/core/parsing/common/ref_resolution/helpers/test_new_schema.py +142 -0
  74. pyopenapi_gen-0.10.2/tests/core/parsing/common/ref_resolution/helpers/test_stripped_suffix.py +156 -0
  75. pyopenapi_gen-0.10.2/tests/core/parsing/keywords/__init__.py +1 -0
  76. pyopenapi_gen-0.10.2/tests/core/parsing/keywords/keywords_analysis.md +182 -0
  77. pyopenapi_gen-0.10.2/tests/core/parsing/keywords/test_all_of_parser.py +641 -0
  78. pyopenapi_gen-0.10.2/tests/core/parsing/keywords/test_any_of_parser.py +306 -0
  79. pyopenapi_gen-0.10.2/tests/core/parsing/keywords/test_array_items_parser.py +197 -0
  80. pyopenapi_gen-0.10.2/tests/core/parsing/keywords/test_one_of_parser.py +242 -0
  81. pyopenapi_gen-0.10.2/tests/core/parsing/keywords/test_properties_parser.py +453 -0
  82. pyopenapi_gen-0.10.2/tests/core/parsing/parsing_analysis.md +221 -0
  83. pyopenapi_gen-0.10.2/tests/core/parsing/test_context.py +269 -0
  84. pyopenapi_gen-0.10.2/tests/core/parsing/test_cycle_detection.py +615 -0
  85. pyopenapi_gen-0.10.2/tests/core/parsing/test_cycle_helpers.py +195 -0
  86. pyopenapi_gen-0.10.2/tests/core/parsing/test_improved_schema_naming.py +330 -0
  87. pyopenapi_gen-0.10.2/tests/core/parsing/test_inline_enum_extractor.py +436 -0
  88. pyopenapi_gen-0.10.2/tests/core/parsing/test_inline_object_promoter.py +160 -0
  89. pyopenapi_gen-0.10.2/tests/core/parsing/test_logging.py +281 -0
  90. pyopenapi_gen-0.10.2/tests/core/parsing/test_ref_resolver.py +150 -0
  91. pyopenapi_gen-0.10.2/tests/core/parsing/test_schema_finalizer.py +283 -0
  92. pyopenapi_gen-0.10.2/tests/core/parsing/test_schema_parser.py +852 -0
  93. pyopenapi_gen-0.10.2/tests/core/parsing/test_schema_parser_list_response.py +202 -0
  94. pyopenapi_gen-0.10.2/tests/core/parsing/test_type_parser.py +216 -0
  95. pyopenapi_gen-0.10.2/tests/core/test_dataclass_serialization.py +351 -0
  96. pyopenapi_gen-0.10.2/tests/core/test_detect_circular_imports.py +99 -0
  97. pyopenapi_gen-0.10.2/tests/core/test_edge_cases_integration.py +762 -0
  98. pyopenapi_gen-0.10.2/tests/core/test_edge_cases_systematic.py +603 -0
  99. pyopenapi_gen-0.10.2/tests/core/test_exceptions_module.py +45 -0
  100. pyopenapi_gen-0.10.2/tests/core/test_forward_references.py +78 -0
  101. pyopenapi_gen-0.10.2/tests/core/test_http_transport.py +75 -0
  102. pyopenapi_gen-0.10.2/tests/core/test_import_resolution.py +63 -0
  103. pyopenapi_gen-0.10.2/tests/core/test_ir.py +153 -0
  104. pyopenapi_gen-0.10.2/tests/core/test_ir_schema.py +22 -0
  105. pyopenapi_gen-0.10.2/tests/core/test_loader.py +595 -0
  106. pyopenapi_gen-0.10.2/tests/core/test_loader_extensive.py +173 -0
  107. pyopenapi_gen-0.10.2/tests/core/test_loader_invalid_refs.py +105 -0
  108. pyopenapi_gen-0.10.2/tests/core/test_loader_malformed.py +24 -0
  109. pyopenapi_gen-0.10.2/tests/core/test_loader_media_types.py +65 -0
  110. pyopenapi_gen-0.10.2/tests/core/test_pagination.py +209 -0
  111. pyopenapi_gen-0.10.2/tests/core/test_parsing_context.py +22 -0
  112. pyopenapi_gen-0.10.2/tests/core/test_protocol_defaults.py +28 -0
  113. pyopenapi_gen-0.10.2/tests/core/test_schema_parser_specific_case.py +40 -0
  114. pyopenapi_gen-0.10.2/tests/core/test_schemas.py +773 -0
  115. pyopenapi_gen-0.10.2/tests/core/test_simple_self_ref_check.py +142 -0
  116. pyopenapi_gen-0.10.2/tests/core/test_streaming_helpers.py +154 -0
  117. pyopenapi_gen-0.10.2/tests/core/test_telemetry.py +60 -0
  118. pyopenapi_gen-0.10.2/tests/core/test_telemetry_client.py +66 -0
  119. pyopenapi_gen-0.10.2/tests/core/test_utils.py +359 -0
  120. pyopenapi_gen-0.10.2/tests/core/test_warning_collector.py +49 -0
  121. pyopenapi_gen-0.10.2/tests/core/writers/test_code_writer.py +98 -0
  122. pyopenapi_gen-0.10.2/tests/core/writers/test_documentation_writer.py +480 -0
  123. pyopenapi_gen-0.10.2/tests/core/writers/test_line_writer.py +600 -0
  124. pyopenapi_gen-0.10.2/tests/core/writers/test_python_construct_renderer_json_wizard.py +213 -0
  125. pyopenapi_gen-0.10.2/tests/core/writers/writers_analysis.md +49 -0
  126. pyopenapi_gen-0.10.2/tests/emitters/emitters_analysis.md +162 -0
  127. pyopenapi_gen-0.10.2/tests/emitters/test_client_emitter.py +62 -0
  128. pyopenapi_gen-0.10.2/tests/emitters/test_docs_emitter.py +110 -0
  129. pyopenapi_gen-0.10.2/tests/emitters/test_duplicate_operations.py +110 -0
  130. pyopenapi_gen-0.10.2/tests/emitters/test_endpoints_emitter.py +881 -0
  131. pyopenapi_gen-0.10.2/tests/emitters/test_exceptions_emitter.py +54 -0
  132. pyopenapi_gen-0.10.2/tests/emitters/test_list_response_generation.py +163 -0
  133. pyopenapi_gen-0.10.2/tests/emitters/test_models_emitter.py +716 -0
  134. pyopenapi_gen-0.10.2/tests/end_to_end/test_dataclass_serialization_e2e.py +170 -0
  135. pyopenapi_gen-0.10.2/tests/examples/test_developer_experience_demo.py +221 -0
  136. pyopenapi_gen-0.10.2/tests/generation/generation_analysis.md +71 -0
  137. pyopenapi_gen-0.10.2/tests/generation/test_external_core_package.py +312 -0
  138. pyopenapi_gen-0.10.2/tests/generation_issues/specs/minimal_addmessage_like.json +112 -0
  139. pyopenapi_gen-0.10.2/tests/generation_issues/test_addmessage_like_issues.py +185 -0
  140. pyopenapi_gen-0.10.2/tests/generation_issues/test_agent_include_parameter_typing.py +126 -0
  141. pyopenapi_gen-0.10.2/tests/generation_issues/test_message_batch_response_issue.py +173 -0
  142. pyopenapi_gen-0.10.2/tests/helpers/helpers_analysis.md +247 -0
  143. pyopenapi_gen-0.10.2/tests/helpers/test_array_resolver.py +189 -0
  144. pyopenapi_gen-0.10.2/tests/helpers/test_endpoint_utils.py +722 -0
  145. pyopenapi_gen-0.10.2/tests/helpers/test_endpoint_utils_extended.py +1469 -0
  146. pyopenapi_gen-0.10.2/tests/helpers/test_get_endpoint_return_types.py +164 -0
  147. pyopenapi_gen-0.10.2/tests/helpers/test_named_resolver.py +531 -0
  148. pyopenapi_gen-0.10.2/tests/helpers/test_named_type_resolver.py +82 -0
  149. pyopenapi_gen-0.10.2/tests/helpers/test_object_resolver.py +643 -0
  150. pyopenapi_gen-0.10.2/tests/helpers/test_put_endpoint_return_types.py +207 -0
  151. pyopenapi_gen-0.10.2/tests/helpers/test_type_cleaner.py +481 -0
  152. pyopenapi_gen-0.10.2/tests/helpers/test_type_helper.py +1581 -0
  153. pyopenapi_gen-0.10.2/tests/helpers/test_url_utils.py +69 -0
  154. pyopenapi_gen-0.10.2/tests/helpers/test_utils_helpers.py +235 -0
  155. pyopenapi_gen-0.10.2/tests/integration/test_generated_code_structure.py +56 -0
  156. pyopenapi_gen-0.10.2/tests/integrations/integrations_analysis.md +64 -0
  157. pyopenapi_gen-0.10.2/tests/integrations/test_business_swagger_message_type.py +100 -0
  158. pyopenapi_gen-0.10.2/tests/integrations/test_end_to_end_business_swagger.py +221 -0
  159. pyopenapi_gen-0.10.2/tests/integrations/test_end_to_end_petstore.py +134 -0
  160. pyopenapi_gen-0.10.2/tests/integrations/test_name_collisions.py +163 -0
  161. pyopenapi_gen-0.10.2/tests/specs/response_unwrapping_spec.yaml +91 -0
  162. pyopenapi_gen-0.10.2/tests/test_analysis_overview.md +153 -0
  163. pyopenapi_gen-0.10.2/tests/test_init.py +112 -0
  164. pyopenapi_gen-0.10.2/tests/types/__init__.py +1 -0
  165. pyopenapi_gen-0.10.2/tests/types/test_business_swagger_integration.py +166 -0
  166. pyopenapi_gen-0.10.2/tests/types/test_contracts_types.py +114 -0
  167. pyopenapi_gen-0.10.2/tests/types/test_reference_resolver.py +94 -0
  168. pyopenapi_gen-0.10.2/tests/types/test_response_resolver.py +388 -0
  169. pyopenapi_gen-0.10.2/tests/types/test_response_strategy.py +450 -0
  170. pyopenapi_gen-0.10.2/tests/types/test_response_strategy_simplified.py +328 -0
  171. pyopenapi_gen-0.10.2/tests/types/test_schema_resolver.py +643 -0
  172. pyopenapi_gen-0.10.2/tests/types/test_type_service.py +180 -0
  173. pyopenapi_gen-0.10.2/tests/visit/__init__.py +1 -0
  174. pyopenapi_gen-0.10.2/tests/visit/endpoint/__init__.py +1 -0
  175. pyopenapi_gen-0.10.2/tests/visit/endpoint/generators/__init__.py +1 -0
  176. pyopenapi_gen-0.10.2/tests/visit/endpoint/generators/generators_analysis.md +106 -0
  177. pyopenapi_gen-0.10.2/tests/visit/endpoint/generators/test_dataclass_integration.py +331 -0
  178. pyopenapi_gen-0.10.2/tests/visit/endpoint/generators/test_docstring_generator.py +222 -0
  179. pyopenapi_gen-0.10.2/tests/visit/endpoint/generators/test_endpoint_method_generator.py +243 -0
  180. pyopenapi_gen-0.10.2/tests/visit/endpoint/generators/test_match_case_response.py +241 -0
  181. pyopenapi_gen-0.10.2/tests/visit/endpoint/generators/test_request_generator.py +85 -0
  182. pyopenapi_gen-0.10.2/tests/visit/endpoint/generators/test_response_handler_generator.py +736 -0
  183. pyopenapi_gen-0.10.2/tests/visit/endpoint/generators/test_response_handler_generator_strategy.py +429 -0
  184. pyopenapi_gen-0.10.2/tests/visit/endpoint/generators/test_signature_generator.py +158 -0
  185. pyopenapi_gen-0.10.2/tests/visit/endpoint/generators/test_url_args_generator.py +603 -0
  186. pyopenapi_gen-0.10.2/tests/visit/endpoint/processors/__init__.py +1 -0
  187. pyopenapi_gen-0.10.2/tests/visit/endpoint/processors/test_import_analyzer.py +446 -0
  188. pyopenapi_gen-0.10.2/tests/visit/endpoint/processors/test_import_analyzer.py.bak +450 -0
  189. pyopenapi_gen-0.10.2/tests/visit/endpoint/processors/test_parameter_processor.py +429 -0
  190. pyopenapi_gen-0.10.2/tests/visit/endpoint/test_endpoint_visitor.py +144 -0
  191. pyopenapi_gen-0.10.2/tests/visit/model/__init__.py +0 -0
  192. pyopenapi_gen-0.10.2/tests/visit/model/test_alias_generator.py +0 -0
  193. pyopenapi_gen-0.10.2/tests/visit/model/test_dataclass_generator.py +0 -0
  194. pyopenapi_gen-0.10.2/tests/visit/model/test_dataclass_generator_json_wizard.py +248 -0
  195. pyopenapi_gen-0.10.2/tests/visit/model/test_enum_generator.py +774 -0
  196. pyopenapi_gen-0.10.2/tests/visit/test_client_visitor.py +362 -0
  197. pyopenapi_gen-0.10.2/tests/visit/test_model_visitor.py +643 -0
  198. pyopenapi_gen-0.10.2/tests/visit/test_visitor.py +193 -0
  199. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/LICENSE +0 -0
  200. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/README.md +0 -0
  201. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/__init__.py +0 -0
  202. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/__main__.py +0 -0
  203. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/cli.py +0 -0
  204. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/context/CLAUDE.md +0 -0
  205. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/context/file_manager.py +0 -0
  206. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/context/import_collector.py +0 -0
  207. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/context/render_context.py +0 -0
  208. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/core/CLAUDE.md +0 -0
  209. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/core/__init__.py +0 -0
  210. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/core/auth/base.py +0 -0
  211. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/core/auth/plugins.py +0 -0
  212. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/core/exceptions.py +0 -0
  213. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/core/http_transport.py +0 -0
  214. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/core/loader/__init__.py +0 -0
  215. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/core/loader/loader.py +0 -0
  216. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/core/loader/operations/__init__.py +0 -0
  217. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/core/loader/operations/parser.py +0 -0
  218. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/core/loader/operations/post_processor.py +0 -0
  219. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/core/loader/operations/request_body.py +0 -0
  220. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/core/loader/parameters/__init__.py +0 -0
  221. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/core/loader/parameters/parser.py +0 -0
  222. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/core/loader/responses/__init__.py +0 -0
  223. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/core/loader/responses/parser.py +0 -0
  224. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/core/loader/schemas/__init__.py +0 -0
  225. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/core/loader/schemas/extractor.py +0 -0
  226. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/core/pagination.py +0 -0
  227. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/core/parsing/__init__.py +0 -0
  228. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/core/parsing/common/__init__.py +0 -0
  229. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/core/parsing/common/ref_resolution/__init__.py +0 -0
  230. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/core/parsing/common/ref_resolution/helpers/__init__.py +0 -0
  231. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/core/parsing/common/ref_resolution/helpers/cyclic_properties.py +0 -0
  232. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/core/parsing/common/ref_resolution/helpers/direct_cycle.py +0 -0
  233. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/core/parsing/common/ref_resolution/helpers/existing_schema.py +0 -0
  234. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/core/parsing/common/ref_resolution/helpers/list_response.py +0 -0
  235. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/core/parsing/common/ref_resolution/helpers/missing_ref.py +0 -0
  236. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/core/parsing/common/ref_resolution/helpers/new_schema.py +0 -0
  237. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/core/parsing/common/ref_resolution/helpers/stripped_suffix.py +0 -0
  238. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/core/parsing/common/ref_resolution/resolve_schema_ref.py +0 -0
  239. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/core/parsing/common/type_parser.py +0 -0
  240. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/core/parsing/context.py +0 -0
  241. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/core/parsing/cycle_helpers.py +0 -0
  242. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/core/parsing/keywords/__init__.py +0 -0
  243. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/core/parsing/keywords/all_of_parser.py +0 -0
  244. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/core/parsing/keywords/any_of_parser.py +0 -0
  245. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/core/parsing/keywords/array_items_parser.py +0 -0
  246. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/core/parsing/keywords/one_of_parser.py +0 -0
  247. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/core/parsing/keywords/properties_parser.py +0 -0
  248. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/core/parsing/schema_finalizer.py +0 -0
  249. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/core/parsing/schema_parser.py +0 -0
  250. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/core/parsing/transformers/__init__.py +0 -0
  251. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/core/parsing/transformers/inline_enum_extractor.py +0 -0
  252. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/core/parsing/transformers/inline_object_promoter.py +0 -0
  253. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/core/parsing/unified_cycle_detection.py +0 -0
  254. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/core/postprocess_manager.py +0 -0
  255. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/core/schemas.py +0 -0
  256. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/core/streaming_helpers.py +0 -0
  257. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/core/telemetry.py +0 -0
  258. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/core/utils.py +0 -0
  259. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/core/warning_collector.py +0 -0
  260. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/core/writers/code_writer.py +0 -0
  261. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/core/writers/documentation_writer.py +0 -0
  262. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/core/writers/line_writer.py +0 -0
  263. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/core/writers/python_construct_renderer.py +0 -0
  264. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/core_package_template/README.md +0 -0
  265. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/emit/models_emitter.py +0 -0
  266. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/emitters/CLAUDE.md +0 -0
  267. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/emitters/client_emitter.py +0 -0
  268. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/emitters/core_emitter.py +0 -0
  269. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/emitters/docs_emitter.py +0 -0
  270. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/emitters/endpoints_emitter.py +0 -0
  271. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/emitters/exceptions_emitter.py +0 -0
  272. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/emitters/models_emitter.py +0 -0
  273. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/generator/CLAUDE.md +0 -0
  274. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/generator/client_generator.py +0 -0
  275. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/helpers/CLAUDE.md +0 -0
  276. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/helpers/__init__.py +0 -0
  277. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/helpers/endpoint_utils.py +0 -0
  278. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/helpers/type_cleaner.py +0 -0
  279. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/helpers/type_helper.py +0 -0
  280. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/helpers/type_resolution/__init__.py +0 -0
  281. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/helpers/type_resolution/array_resolver.py +0 -0
  282. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/helpers/type_resolution/composition_resolver.py +0 -0
  283. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/helpers/type_resolution/finalizer.py +0 -0
  284. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/helpers/type_resolution/named_resolver.py +0 -0
  285. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/helpers/type_resolution/object_resolver.py +0 -0
  286. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/helpers/type_resolution/primitive_resolver.py +0 -0
  287. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/helpers/type_resolution/resolver.py +0 -0
  288. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/helpers/url_utils.py +0 -0
  289. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/http_types.py +0 -0
  290. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/ir.py +0 -0
  291. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/py.typed +0 -0
  292. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/types/CLAUDE.md +0 -0
  293. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/types/__init__.py +0 -0
  294. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/types/contracts/__init__.py +0 -0
  295. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/types/contracts/protocols.py +0 -0
  296. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/types/contracts/types.py +0 -0
  297. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/types/resolvers/__init__.py +0 -0
  298. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/types/resolvers/reference_resolver.py +0 -0
  299. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/types/resolvers/response_resolver.py +0 -0
  300. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/types/resolvers/schema_resolver.py +0 -0
  301. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/types/services/__init__.py +0 -0
  302. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/types/services/type_service.py +0 -0
  303. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/types/strategies/__init__.py +0 -0
  304. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/types/strategies/response_strategy.py +0 -0
  305. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/visit/CLAUDE.md +0 -0
  306. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/visit/client_visitor.py +0 -0
  307. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/visit/docs_visitor.py +0 -0
  308. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/visit/endpoint/__init__.py +0 -0
  309. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/visit/endpoint/endpoint_visitor.py +0 -0
  310. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/visit/endpoint/generators/__init__.py +0 -0
  311. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/visit/endpoint/generators/docstring_generator.py +0 -0
  312. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/visit/endpoint/generators/endpoint_method_generator.py +0 -0
  313. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/visit/endpoint/generators/request_generator.py +0 -0
  314. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/visit/endpoint/generators/response_handler_generator.py +0 -0
  315. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/visit/endpoint/generators/signature_generator.py +0 -0
  316. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/visit/endpoint/generators/url_args_generator.py +0 -0
  317. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/visit/endpoint/processors/__init__.py +0 -0
  318. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/visit/endpoint/processors/import_analyzer.py +0 -0
  319. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/visit/endpoint/processors/parameter_processor.py +0 -0
  320. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/visit/exception_visitor.py +0 -0
  321. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/visit/model/__init__.py +0 -0
  322. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/visit/model/alias_generator.py +0 -0
  323. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/visit/model/dataclass_generator.py +0 -0
  324. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/visit/model/enum_generator.py +0 -0
  325. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/visit/model/model_visitor.py +0 -0
  326. {pyopenapi_gen-0.9.0 → pyopenapi_gen-0.10.2}/src/pyopenapi_gen/visit/visitor.py +0 -0
@@ -0,0 +1,22 @@
1
+ # Bandit configuration for pyopenapi-gen
2
+
3
+ # Skip these specific checks that are acceptable for this project:
4
+ # B101: assert_used - We use assertions for Design by Contract (DbC) as documented
5
+ # B404: import_subprocess - We need subprocess for post-processing (ruff, mypy)
6
+ # B603: subprocess_without_shell_equals_true - We use controlled subprocess calls to trusted tools
7
+ # B110: try_except_pass - Acceptable for telemetry error handling
8
+ skips:
9
+ - B101
10
+ - B404
11
+ - B603
12
+ - B110
13
+
14
+ # Only scan source code, not tests (tests may have different security requirements)
15
+ exclude_dirs:
16
+ - tests/
17
+ - _process/
18
+ - venv/
19
+ - .venv/
20
+
21
+ # Set confidence level to only report medium and high confidence issues
22
+ confidence: MEDIUM
@@ -0,0 +1,10 @@
1
+ {
2
+ "mcpServers": {
3
+ "nodejs-debugger": {
4
+ "command": "npx",
5
+ "args": [
6
+ "@hyperdrive-eng/mcp-nodejs-debugger"
7
+ ]
8
+ }
9
+ }
10
+ }
@@ -0,0 +1,86 @@
1
+ ---
2
+ description:
3
+ globs:
4
+ alwaysApply: true
5
+ ---
6
+ # Cursor Rule: architecture
7
+
8
+ ## Purpose
9
+ This rule introduces the crucial classes and the overall architecture of the Python OpenAPI client generator. It is intended to provide a high-level mental model for developers and AI agents working on the codebase.
10
+
11
+ ---
12
+
13
+ ## Core Architectural Concepts
14
+
15
+ ### 1. **Intermediate Representation (IR)**
16
+ - **IRSpec, IROperation, IRParameter, IRRequestBody, IRResponse, IRSchema**
17
+ - These dataclasses represent the parsed and normalized OpenAPI spec.
18
+ - All code generation is based on this IR, not the raw OpenAPI dict.
19
+
20
+ ### 1.5. **Parsing and Loading Architecture**
21
+ - **Loader (core/loader/)**
22
+ - `loader.py` - Main loader orchestration
23
+ - `operations/` - Operation parsing (parser.py, post_processor.py, request_body.py)
24
+ - `parameters/` - Parameter parsing (parser.py)
25
+ - `responses/` - Response parsing (parser.py)
26
+ - `schemas/` - Schema extraction (extractor.py)
27
+ - **Schema Parsing (core/parsing/)**
28
+ - `schema_parser.py` - Core schema parsing logic
29
+ - `unified_cycle_detection.py` - Comprehensive cycle detection system
30
+ - `context.py` - ParsingContext for state management
31
+ - `ref_resolution/` - Reference resolution helpers
32
+ - `keywords/` - Keyword-specific parsers (allOf, oneOf, etc.)
33
+ - `transformers/` - Schema transformation utilities
34
+
35
+ ### 2. **Visitors**
36
+ - **Visitor (base class)**
37
+ - Generic base for all code generation visitors. Uses the visitor pattern to traverse IR nodes.
38
+ - **EndpointVisitor**
39
+ - Renders Python code for endpoint client classes and methods from IROperation nodes.
40
+ - **ModelVisitor**
41
+ - Renders Python dataclasses or enums from IRSchema nodes.
42
+ - **ClientVisitor**
43
+ - Renders the main APIClient class, which aggregates tag clients and manages transport.
44
+ - **ExceptionVisitor**
45
+ - Renders exception alias classes for HTTP error codes.
46
+ - **DocsVisitor**
47
+ - Renders Markdown documentation from the IR.
48
+
49
+ ### 3. **Emitters**
50
+ - **Emitters (e.g., EndpointsEmitter, ModelsEmitter, ClientEmitter, ExceptionsEmitter, DocsEmitter)**
51
+ - Orchestrate the code generation process for each major output (endpoints, models, client, exceptions, docs).
52
+ - Use the corresponding visitor to render code, then write files to disk.
53
+
54
+ ### 4. **Helpers and Utilities**
55
+ - **CodeWriter**
56
+ - Utility for building Python code with correct indentation and formatting.
57
+ - **NameSanitizer**
58
+ - Ensures all generated names are valid Python identifiers.
59
+ - **RenderContext**
60
+ - Tracks imports, file paths, and other state during code generation.
61
+
62
+ ### 5. **Authentication and Transport**
63
+ - **HttpTransport (protocol), HttpxTransport (default implementation)**
64
+ - Abstract and concrete classes for HTTP communication, supporting pluggable authentication.
65
+ - **BaseAuth and plugins**
66
+ - Protocol and implementations for authentication schemes (Bearer, API key, OAuth2, etc.).
67
+
68
+ ---
69
+
70
+ ## Architectural Flow
71
+ 1. **Spec Loading**: The OpenAPI spec is loaded and validated by the loader module.
72
+ 2. **Schema Parsing**: Raw schema dictionaries are parsed into IR dataclasses using the parsing module, with unified cycle detection handling circular references.
73
+ 3. **IR Construction**: Complete IRSpec object is built with all operations, parameters, responses, and schemas.
74
+ 4. **Code Generation**: Emitters use visitors to traverse the IR and generate code for models, endpoints, client, exceptions, and docs.
75
+ 5. **Helpers**: Utilities like CodeWriter and NameSanitizer ensure code quality and correctness.
76
+ 6. **Output**: Generated code is written to disk as a ready-to-use Python package.
77
+
78
+ ---
79
+
80
+ ## Key Principles
81
+ - **Single Responsibility**: Each class/module has a focused purpose.
82
+ - **Extensibility**: New emitters, visitors, or plugins can be added without modifying core logic.
83
+ - **Strong Typing**: All IR and generated code is strongly typed.
84
+ - **Separation of Concerns**: Parsing, code generation, and file I/O are clearly separated.
85
+ - **Unified Cycle Detection**: A single, comprehensive system handles all circular reference scenarios consistently.
86
+ - **Modular Parsing**: Schema parsing is broken into focused, testable components.
@@ -0,0 +1,190 @@
1
+ ---
2
+ description: >-
3
+ Python Coding Conventions — enforce Design-by-Contract without
4
+ external libraries, ensure Separation of Concerns, Test-Driven
5
+ Development, high coverage & first-class documentation.
6
+ globs: ["**/*.py"]
7
+ alwaysApply: true
8
+ ---
9
+
10
+ # Python Coding Conventions
11
+
12
+ > **Purpose**
13
+ > Guarantee that every line of Python in this repository is **clear,
14
+ > maintainable, testable and rigorously specified by contract & tests**.
15
+
16
+ ---
17
+
18
+ ## 1. Core Principles
19
+
20
+ 1. **Design by Contract (DbC)** — every public function/method *must*
21
+ declare and enforce **pre-conditions**, **post-conditions** &
22
+ **invariants**.
23
+ 2. **Separation of Concerns** — single responsibility per module, class
24
+ and function; avoid God classes & long functions.
25
+ 3. **Clarity & Readability** — code is read far more than written;
26
+ prefer explicitness over cleverness.
27
+ 4. **Maintainability & Extensibility** — design for change; prefer
28
+ composition to inheritance; follow SOLID (esp. SRP, OCP, LSP, DIP).
29
+ 5. **Test-Driven Development** — write the failing test first; tests are
30
+ executable specifications; aim for ≥ 90 % **branch** coverage.
31
+ 6. **Comprehensive Documentation** — docstrings & type hints are
32
+ mandatory; docs express the contract.
33
+
34
+ ---
35
+
36
+ ## 2. Design by Contract Without External Libraries
37
+
38
+ ### 2.1 Contract Enforcement
39
+
40
+ * Use **plain `assert` statements** to guard pre-conditions at the top
41
+ of the function and post-conditions at the end. Use
42
+ `__post_init__` (dataclasses) or property setters to maintain
43
+ invariants.
44
+ * Never disable contract `assert`s in production; they are part of
45
+ behaviour. Configure the runtime to **never run with `-O`/`PYTHONOPTIMIZE`**.
46
+ * Assertions must be **side-effect-free** and cheap.
47
+
48
+ ```python
49
+ from dataclasses import dataclass
50
+
51
+ @dataclass
52
+ class Account:
53
+ total: int
54
+
55
+ def __post_init__(self) -> None:
56
+ # Class invariant
57
+ assert self.total >= 0, "total must be non-negative"
58
+
59
+ def deposit(self, amount: int) -> None:
60
+ """Deposit money.
61
+
62
+ Contracts:
63
+ Pre-conditions:
64
+ - ``amount`` > 0
65
+ Post-conditions:
66
+ - ``self.total`` increased by exactly ``amount``
67
+ """
68
+ # Pre-condition
69
+ assert amount > 0, "amount must be positive"
70
+
71
+ old_total = self.total
72
+ self.total += amount
73
+
74
+ # Post-condition
75
+ assert self.total == old_total + amount, "balance unchanged"
76
+ ```
77
+
78
+ ### 2.2 Contract Documentation
79
+
80
+ Extend docstrings with a **Contracts** section using the following
81
+ markers (Google style or reST is accepted):
82
+
83
+ ```
84
+ Contracts:
85
+ Preconditions:
86
+ - <condition>
87
+ Postconditions:
88
+ - <condition>
89
+ Invariants:
90
+ - <condition>
91
+ ```
92
+
93
+ Write conditions in **business vocabulary**, not implementation detail.
94
+
95
+ ### 2.3 Contract Testing
96
+
97
+ * Unit tests **duplicate the contract** so failures show friendly
98
+ messages rather than bare AssertionErrors.
99
+ * When a contract fails, the test should describe the violated
100
+ assumption in its name.
101
+
102
+ ---
103
+
104
+ ## 3. Separation of Concerns & Structure
105
+
106
+ * **Modules**: logically cohesive; avoid mixed concerns.
107
+ * **Functions**: ≤ 40 logical lines; prefer pure functions.
108
+ * **Classes**: ≤ 400 logical lines & ≤ 7 public methods.
109
+ * **Layers**: domain → application/service → infrastructure. Enforce via
110
+ package structure: `domain/*`, `services/*`, `infra/*`.
111
+ * **Dependency Direction**: higher layers must not import lower layers.
112
+
113
+ ---
114
+
115
+ ## 4. Code Style & Readability
116
+
117
+ | Aspect | Rule |
118
+ | -------------- | ------------------------------------------------------ |
119
+ | **Formatting** | `black` (line length 120) + `ruff format` |
120
+ | **Linting** | `ruff check` for linting and import sorting |
121
+ | **Typing** | `mypy --strict` is CI-blocking |
122
+ | **Naming** | PEP 8: classes `PascalCase`, funcs `snake_case` |
123
+ | **Patterns** | Prefer **dataclasses** & **enums** over raw tuples/str |
124
+ | **Globals** | No mutable module-level state |
125
+
126
+ ---
127
+
128
+ ## 5. Testing Conventions
129
+
130
+ * Use **pytest** with `pytest-cov` & **hypothesis** for property tests.
131
+ * Directory: mirror package structure under `tests/`.
132
+ * Every bug fix requires a *regression test*.
133
+ * **Coverage gate**: branches ≥ 90 % enforced by CI.
134
+ * Tests are *specifications* — structure names as
135
+ **Given\_When\_Then**.
136
+ * Keep tests **fast & deterministic** (< 200 ms each).
137
+
138
+ ```python
139
+ def test_deposit_increases_balance():
140
+ # Given
141
+ acc = Account(total=0)
142
+ # When
143
+ acc.deposit(50)
144
+ # Then
145
+ assert acc.total == 50
146
+ ```
147
+
148
+ ---
149
+
150
+ ## 6. Documentation Standards
151
+
152
+ * **Docstrings**: PEP 257; include **Contracts** block where relevant.
153
+ * Use **reST** or **Google style**, but be consistent project-wide.
154
+ * Provide runnable examples (`doctest`).
155
+ * Generate API docs with **Sphinx + autodoc**; CI fails on warnings.
156
+
157
+ ---
158
+
159
+ ## 7. Tooling & Continuous Integration
160
+
161
+ 1. **Pre-commit hooks**: `black`, `isort`, `flake8`, `mypy`.
162
+ 2. **CI stages** (GitHub Actions):
163
+
164
+ 1. *Static Analysis* – format, lint, type checks.
165
+ 2. *Unit Tests* – `pytest -q --cov`.
166
+ 3. *Docs* – `sphinx-build -n -W . ./_build`.
167
+ 3. **Fail-fast** – pipeline stops on first violation.
168
+
169
+ ---
170
+
171
+ ## 8. Prohibited / Discouraged Patterns
172
+
173
+ * Catching broad `Exception` or using bare `except`.
174
+ * Hidden side-effects or implicit I/O in domain logic.
175
+ * Monolithic script files; always package code.
176
+ * Circular imports — resolve with adapter modules.
177
+ * Premature optimisation; measure before optimising.
178
+
179
+ ---
180
+
181
+ ## 9. AI / Agent Instructions
182
+
183
+ * Generated code **should include asserts and Contracts docstrings** where appropriate.
184
+ * When editing legacy code lacking contracts/tests, suggest refactor + tests as a separate task.
185
+ * Prefer clear names & explicit types over brevity.
186
+ * **Note**: The current codebase is transitioning to full Design by Contract compliance. Focus on critical business logic for contract enforcement.
187
+
188
+ ---
189
+
190
+ ### End of Rule
@@ -0,0 +1,84 @@
1
+ ---
2
+ description:
3
+ globs:
4
+ alwaysApply: true
5
+ ---
6
+ # PROJECT GOAL
7
+
8
+ The Python OpenAPI client generator must produce client code that:
9
+
10
+ ## 1. Direct API Communication
11
+ - Communicates directly with the API as defined by the provided OpenAPI spec.
12
+ - Accepts strongly typed input parameters (matching the OpenAPI schema).
13
+ - Returns strongly typed responses (matching the OpenAPI schema).
14
+
15
+ ## 2. Authentication & Transport
16
+ - Supports authentication and lazy loading.
17
+ - Uses a system default HTTP implementation by default, but allows the user to inject a custom HTTP class for communication.
18
+
19
+ ## 3. Out-of-the-Box Functionality
20
+ - The generated code is fully functional out of the box—no stubs, placeholders, or manual implementation required for basic API communication.
21
+
22
+ ## 4. IDE Support
23
+ - The generated client must support code completion and type hints in IDEs (such as PyCharm, VSCode, etc.), leveraging Python's type annotations and docstrings for maximum developer productivity.
24
+
25
+ ## 5. Error Handling
26
+ - All errors that the client receives from the API must be handled by raising an exception; only successful responses are returned as response types.
27
+
28
+ ---
29
+
30
+ ## 6. Client Independence & Core Module
31
+
32
+ **The generated client code must be fully independent and must not require any runtime dependency on `pyopenapi_gen` itself.**
33
+
34
+ - All runtime dependencies (e.g., base transport, authentication protocols, exceptions, utility classes) must be generated into a `core` module/folder within the output package.
35
+ - The generator must provide an option to customize the name and location of this `core` folder, to support scenarios where multiple clients are generated for the same system and can share a single core implementation.
36
+ - All imports in the generated client code must be relative (e.g., `from .core.http_transport import HttpTransport`) or from the standard library/allowed third-party packages.
37
+ - No `from pyopenapi_gen...` imports should appear in the generated output.
38
+
39
+ ### Example Output Structure
40
+
41
+ ```
42
+ my_generated_client/
43
+ core/
44
+ http_transport.py
45
+ auth.py
46
+ exceptions.py
47
+ ...
48
+ models/
49
+ ...
50
+ endpoints/
51
+ ...
52
+ __init__.py
53
+ py.typed
54
+ README.md
55
+ ```
56
+
57
+ Or, with a shared core:
58
+
59
+ ```
60
+ shared_core/
61
+ http_transport.py
62
+ auth.py
63
+ exceptions.py
64
+ ...
65
+ client_a/
66
+ models/
67
+ endpoints/
68
+ ...
69
+ client_b/
70
+ models/
71
+ endpoints/
72
+ ...
73
+ ```
74
+ *(Clients can import from the shared core as configured.)*
75
+
76
+ ---
77
+
78
+ ## 7. Documentation
79
+ - The generated client’s README must clearly state that it is independent and does not require `pyopenapi_gen` at runtime.
80
+ - If the core module is shared, document how to set up the import path.
81
+
82
+ ---
83
+
84
+ **This ensures that the generated client is robust, portable, and easy to integrate into any Python project without extra dependencies.**
@@ -0,0 +1,185 @@
1
+ ---
2
+ description:
3
+ globs: tests/**/*.py
4
+ alwaysApply: false
5
+ ---
6
+ 1. 🎯 Purpose
7
+
8
+ To ensure all tests — both unit and integration — are:
9
+
10
+ - Precise in intent
11
+ - Fully verifying the contract of the component under test
12
+ - Isolated from unrelated dependencies
13
+ - Described clearly for human readability and maintainability
14
+
15
+ This cursor rule must be followed both by human developers and any AI writing tests.
16
+
17
+ 2. ✅ Scope of Tests
18
+
19
+ 2.1 Unit Tests
20
+
21
+ Must test the smallest testable part of the application in isolation.
22
+
23
+ - Only one unit (e.g., function, class method) should be tested per test case.
24
+ - External dependencies (DBs, APIs, services, time, randomness, etc.) must be mocked or stubbed.
25
+
26
+ 2.2 Integration Tests
27
+
28
+ Should test cooperation between units (e.g., service layer + repository).
29
+
30
+ - Can include real implementations of multiple components, but external system boundaries must still be mocked unless explicitly testing integrations.
31
+ - Only use real I/O for designated "integration" or "e2e" test environments, never in unit tests.
32
+
33
+ 3. 📋 Test Case Structure
34
+
35
+ All tests must follow this standard format:
36
+
37
+ ```python
38
+ def test_<unit_of_work>__<condition>__<expected_outcome>():
39
+ """
40
+ Scenario:
41
+ - Description of the test scenario in 2–4 lines of natural language.
42
+ - Describe what is being tested and why it's important.
43
+
44
+ Expected Outcome:
45
+ - Explicitly state what the correct result should be (including side effects).
46
+ """
47
+ # Arrange
48
+ # Setup necessary inputs and mocks
49
+
50
+ # Act
51
+ # Run the function or method being tested
52
+
53
+ # Assert
54
+ # Check for correct result and side effects
55
+ ```
56
+
57
+ 4. 🧠 AI Agent Testing Rules
58
+
59
+ When AI is tasked to write tests, it must:
60
+
61
+ - Use the above structure.
62
+ - Generate a clear, natural-language docstring summarizing the scenario and expected result.
63
+ - Mock all dependencies not directly under test.
64
+ - Avoid redundant assertions or low-value "happy path only" testing — focus on variation in input and edge cases.
65
+ - Ensure high coverage of:
66
+ - Control flow (if/else, error branches)
67
+ - Contract fidelity (input/output invariants, exceptions)
68
+ - State changes (data updates, method calls)
69
+ - Do not test third-party libraries (assume their correctness).
70
+
71
+ 5. 🔬 Coverage Requirements
72
+
73
+ - All public methods and functions must be tested with 100% logical branch coverage.
74
+ - Edge cases must be included (e.g. empty list, None, 0, large inputs).
75
+ - For integration tests, ensure interface expectations between units are fully verified.
76
+ - Use pytest-cov or equivalent to enforce and review coverage.
77
+
78
+ 6. 🔄 Isolation Rule
79
+
80
+ - Only the unit or flow under test may contain logic.
81
+ - Everything else (e.g., repositories, downstream APIs, services, clocks, logging, randomness) must be mocked using unittest.mock, pytest-mock, or equivalent.
82
+ - Use fixtures where applicable, but avoid overly abstract or reused test setups that reduce test clarity.
83
+
84
+ 7. 🏷️ Naming & File Structure
85
+
86
+ Test files mirror the code structure: foo.py → test_foo.py
87
+
88
+ Use descriptive function names:
89
+
90
+ - ✅ test_user_creation__invalid_email__raises_error
91
+ - ❌ test_invalid_email
92
+
93
+ 8. 📚 Example
94
+
95
+ ```python
96
+ def test_calculate_discount__vip_customer__applies_20_percent():
97
+ """
98
+ Scenario:
99
+ A VIP customer is eligible for a 20% discount. We want to verify that
100
+ the discount logic applies the correct rate based on the customer tier.
101
+
102
+ Expected Outcome:
103
+ The function should return the original price multiplied by 0.8.
104
+ """
105
+ # Arrange
106
+ price = 100.0
107
+ customer = Customer(tier="VIP")
108
+
109
+ # Act
110
+ result = calculate_discount(price, customer)
111
+
112
+ # Assert
113
+ assert result == 80.0
114
+ ```
115
+
116
+ 9. 🧵 Integration Test Example
117
+
118
+ ```python
119
+ def test_user_registration_flow__valid_data__creates_user_and_sends_email():
120
+ """
121
+ Scenario:
122
+ A new user registers with valid data. The service should create the user,
123
+ send a welcome email, and return a success status.
124
+
125
+ Expected Outcome:
126
+ - UserRepository.save is called with correct user
127
+ - EmailService.send_welcome_email is called
128
+ - Function returns success result
129
+ """
130
+ # Arrange
131
+ user_data = {"email": "test@example.com", "name": "Alice"}
132
+ repo = Mock()
133
+ email_service = Mock()
134
+ service = UserService(repo, email_service)
135
+
136
+ # Act
137
+ result = service.register_user(user_data)
138
+
139
+ # Assert
140
+ repo.save.assert_called_once()
141
+ email_service.send_welcome_email.assert_called_once()
142
+ assert result == {"status": "ok"}
143
+ ```
144
+ ## 10. Preferred Testing Framework & Style
145
+
146
+ **10.1. Framework Choice:**
147
+ - All new Python unit tests and integration tests written for this project **MUST** use the `pytest` framework.
148
+ - Existing tests written using `unittest.TestCase` **SHOULD** be refactored to `pytest` style when those files are being significantly modified or as a dedicated refactoring effort to improve test suite consistency and leverage `pytest` features.
149
+
150
+ **10.2. `pytest` Idiomatic Style:**
151
+ - **Assertions:** Tests **MUST** use plain `assert` statements for assertions (e.g., `assert result == expected`).
152
+ - **Fixtures:** Test setup, teardown, and dependency injection **MUST** be managed using `pytest` fixtures. Fixtures should be defined in the test file itself or in a relevant `conftest.py`.
153
+ - **Parameterization:** For testing multiple variations of inputs or conditions against the same test logic, `pytest.mark.parametrize` **MUST** be used to keep tests DRY (Don't Repeat Yourself) and data-driven.
154
+ - **Test Structure:** Test classes (if used) **SHOULD NOT** inherit from `unittest.TestCase`. They should be plain Python classes. Test functions can also be defined at the module level.
155
+ - **Exception Testing:** Testing for expected exceptions **MUST** use `pytest.raises` as a context manager (e.g., `with pytest.raises(SpecificException):`).
156
+
157
+ ## 11. Test Suite Analysis & Documentation
158
+
159
+ **11.1. Purpose:**
160
+ - To maintain a continuous understanding of the test suite's health, coverage, and adherence to conventions.
161
+ - To provide a quick reference for the status and quality of tests within different modules.
162
+
163
+ **11.2. Root Analysis Overview (`tests/test_analysis_overview.md`):**
164
+ - **Maintenance:** This document **MUST** be kept up-to-date.
165
+ - **Content:**
166
+ - It **MUST** list all test files and their current analysis status (e.g., "Analyzed", "Needs Analysis", "Analyzed - Empty").
167
+ - It **MUST** include links to per-directory detailed analysis documents.
168
+ - **Updates:** This document **SHOULD** be updated whenever:
169
+ - New test files are added.
170
+ - Existing test files are significantly refactored or moved.
171
+ - A new pass of test analysis is completed for any part of the suite.
172
+
173
+ **11.3. Per-Directory Analysis Documents (e.g., `tests/<module>/<module>_analysis.md`):**
174
+ - **Maintenance:** These documents **SHOULD** be created or updated when a significant portion of tests within a directory/module is reviewed or refactored.
175
+ - **Content:** Each document **SHOULD** summarize:
176
+ - Overall conciseness and consistency of tests within that directory.
177
+ - Alignment with these testing conventions.
178
+ - Identification of any potentially contradictory expectations or areas for improvement specific to that module's tests.
179
+ - **Trigger for Updates:**
180
+ - After a focused review or refactoring effort on the tests within that directory.
181
+ - When the `test_analysis_overview.md` indicates a need for a detailed review of a specific area.
182
+
183
+ **11.4. Responsibility for AI Agents:**
184
+ - When an AI agent is tasked with adding new test files or performing significant refactoring of existing tests, it **MUST** update the `tests/test_analysis_overview.md` to reflect the new or changed files and their status.
185
+ - If an AI agent performs an analysis pass on a directory as requested, it **MUST** contribute to or create the relevant per-directory analysis document.