modelable 1.2.0__tar.gz → 1.2.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 modelable might be problematic. Click here for more details.

Files changed (236) hide show
  1. {modelable-1.2.0 → modelable-1.2.1}/PKG-INFO +1 -1
  2. {modelable-1.2.0 → modelable-1.2.1}/mypy-baseline.txt +20 -20
  3. {modelable-1.2.0 → modelable-1.2.1}/pyproject.toml +1 -1
  4. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/emitters/rust.py +49 -8
  5. {modelable-1.2.0 → modelable-1.2.1}/tests/test_emit_rust.py +168 -0
  6. {modelable-1.2.0 → modelable-1.2.1}/uv.lock +1 -1
  7. {modelable-1.2.0 → modelable-1.2.1}/.gitignore +0 -0
  8. {modelable-1.2.0 → modelable-1.2.1}/.python-version +0 -0
  9. {modelable-1.2.0 → modelable-1.2.1}/LICENSE +0 -0
  10. {modelable-1.2.0 → modelable-1.2.1}/README.md +0 -0
  11. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/__init__.py +0 -0
  12. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/__main__.py +0 -0
  13. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/_pydantic_py314_compat.py +0 -0
  14. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/cli.py +0 -0
  15. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/commands/__init__.py +0 -0
  16. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/commands/apicurio.py +0 -0
  17. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/commands/codegen.py +0 -0
  18. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/commands/common.py +0 -0
  19. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/commands/compile.py +0 -0
  20. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/commands/create.py +0 -0
  21. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/commands/diff.py +0 -0
  22. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/commands/graph.py +0 -0
  23. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/commands/llm.py +0 -0
  24. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/commands/lsp.py +0 -0
  25. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/commands/runtime.py +0 -0
  26. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/commands/scenario.py +0 -0
  27. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/commands/spec.py +0 -0
  28. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/commands/sync.py +0 -0
  29. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/commands/workspace.py +0 -0
  30. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/compat/__init__.py +0 -0
  31. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/compat/checker.py +0 -0
  32. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/compat/diff.py +0 -0
  33. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/compiler/__init__.py +0 -0
  34. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/compiler/compiler.py +0 -0
  35. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/compiler/workspace.py +0 -0
  36. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/diagnostics/__init__.py +0 -0
  37. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/diagnostics/model.py +0 -0
  38. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/emitters/__init__.py +0 -0
  39. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/emitters/base.py +0 -0
  40. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/emitters/csharp.py +0 -0
  41. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/emitters/dbt_yaml.py +0 -0
  42. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/emitters/diagnostics.py +0 -0
  43. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/emitters/fhir.py +0 -0
  44. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/emitters/fhir_validator.py +0 -0
  45. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/emitters/go.py +0 -0
  46. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/emitters/grpc.py +0 -0
  47. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/emitters/java.py +0 -0
  48. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/emitters/json_schema.py +0 -0
  49. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/emitters/markdown.py +0 -0
  50. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/emitters/odcs.py +0 -0
  51. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/emitters/openlineage.py +0 -0
  52. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/emitters/openmetadata.py +0 -0
  53. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/emitters/protobuf.py +0 -0
  54. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/emitters/python.py +0 -0
  55. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/emitters/shapes.py +0 -0
  56. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/emitters/sql.py +0 -0
  57. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/emitters/targets.py +0 -0
  58. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/emitters/typescript.py +0 -0
  59. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/expressions/__init__.py +0 -0
  60. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/expressions/cel.py +0 -0
  61. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/governance/__init__.py +0 -0
  62. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/governance/checker.py +0 -0
  63. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/governance/por.py +0 -0
  64. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/grammar/__init__.py +0 -0
  65. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/grammar/modelable.lark +0 -0
  66. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/graph/__init__.py +0 -0
  67. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/graph/export.py +0 -0
  68. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/llm/__init__.py +0 -0
  69. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/llm/chat.py +0 -0
  70. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/llm/config.py +0 -0
  71. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/llm/context.py +0 -0
  72. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/llm/engine.py +0 -0
  73. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/llm/importers.py +0 -0
  74. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/llm/provenance.py +0 -0
  75. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/llm/providers.py +0 -0
  76. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/llm/qa.py +0 -0
  77. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/llm/recommendations.py +0 -0
  78. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/llm/redaction.py +0 -0
  79. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/llm/render.py +0 -0
  80. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/llm/update_plan.py +0 -0
  81. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/llm/validation_help.py +0 -0
  82. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/lsp/__init__.py +0 -0
  83. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/lsp/__main__.py +0 -0
  84. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/lsp/code_actions.py +0 -0
  85. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/lsp/completion.py +0 -0
  86. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/lsp/definition.py +0 -0
  87. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/lsp/diagnostics.py +0 -0
  88. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/lsp/document_symbols.py +0 -0
  89. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/lsp/federation.py +0 -0
  90. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/lsp/folding.py +0 -0
  91. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/lsp/formatting.py +0 -0
  92. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/lsp/highlight.py +0 -0
  93. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/lsp/hover.py +0 -0
  94. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/lsp/inlay_hints.py +0 -0
  95. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/lsp/references.py +0 -0
  96. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/lsp/rename.py +0 -0
  97. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/lsp/semantic_tokens.py +0 -0
  98. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/lsp/server.py +0 -0
  99. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/lsp/workspace.py +0 -0
  100. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/lsp/workspace_symbols.py +0 -0
  101. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/parser/__init__.py +0 -0
  102. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/parser/ir.py +0 -0
  103. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/parser/parse.py +0 -0
  104. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/parser/transformer.py +0 -0
  105. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/parser/wire.py +0 -0
  106. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/planner/__init__.py +0 -0
  107. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/planner/lineage.py +0 -0
  108. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/planner/planner.py +0 -0
  109. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/planner/plans.py +0 -0
  110. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/py.typed +0 -0
  111. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/registry/__init__.py +0 -0
  112. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/registry/apicurio.py +0 -0
  113. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/registry/base.py +0 -0
  114. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/registry/factory.py +0 -0
  115. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/registry/ids.py +0 -0
  116. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/registry/index.py +0 -0
  117. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/registry/local.py +0 -0
  118. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/registry/oci.py +0 -0
  119. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/registry/openlineage.py +0 -0
  120. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/registry/resolver.py +0 -0
  121. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/registry/schema.sql +0 -0
  122. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/registry/signature.py +0 -0
  123. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/release.py +0 -0
  124. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/runtime/__init__.py +0 -0
  125. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/runtime/adapter/__init__.py +0 -0
  126. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/runtime/adapter/base.py +0 -0
  127. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/runtime/adapter/postgres.py +0 -0
  128. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/specs/__init__.py +0 -0
  129. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/specs/tracking.py +0 -0
  130. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/validation/__init__.py +0 -0
  131. {modelable-1.2.0 → modelable-1.2.1}/src/modelable/validation/semantic.py +0 -0
  132. {modelable-1.2.0 → modelable-1.2.1}/tests/conftest.py +0 -0
  133. {modelable-1.2.0 → modelable-1.2.1}/tests/fixtures/auto_projection_complex.mdl +0 -0
  134. {modelable-1.2.0 → modelable-1.2.1}/tests/fixtures/billing_projection.mdl +0 -0
  135. {modelable-1.2.0 → modelable-1.2.1}/tests/fixtures/breaking_changes.mdl +0 -0
  136. {modelable-1.2.0 → modelable-1.2.1}/tests/fixtures/cel_error_cases.mdl +0 -0
  137. {modelable-1.2.0 → modelable-1.2.1}/tests/fixtures/customer.mdl +0 -0
  138. {modelable-1.2.0 → modelable-1.2.1}/tests/fixtures/federation_multi_registry/consumer.mdl +0 -0
  139. {modelable-1.2.0 → modelable-1.2.1}/tests/fixtures/federation_multi_registry/provider.mdl +0 -0
  140. {modelable-1.2.0 → modelable-1.2.1}/tests/fixtures/federation_multi_registry/workspace.mdl +0 -0
  141. {modelable-1.2.0 → modelable-1.2.1}/tests/fixtures/fhir_patient_profile.mdl +0 -0
  142. {modelable-1.2.0 → modelable-1.2.1}/tests/fixtures/governance_export_model.mdl +0 -0
  143. {modelable-1.2.0 → modelable-1.2.1}/tests/fixtures/materialized_projection_chain.mdl +0 -0
  144. {modelable-1.2.0 → modelable-1.2.1}/tests/fixtures/missing_header.mdl +0 -0
  145. {modelable-1.2.0 → modelable-1.2.1}/tests/fixtures/multi_domain_joins.mdl +0 -0
  146. {modelable-1.2.0 → modelable-1.2.1}/tests/fixtures/multi_language_target.mdl +0 -0
  147. {modelable-1.2.0 → modelable-1.2.1}/tests/fixtures/no_owner.mdl +0 -0
  148. {modelable-1.2.0 → modelable-1.2.1}/tests/fixtures/pii_governance.mdl +0 -0
  149. {modelable-1.2.0 → modelable-1.2.1}/tests/fixtures/projection_of_projection.mdl +0 -0
  150. {modelable-1.2.0 → modelable-1.2.1}/tests/fixtures/sql_and_dbt_targets.mdl +0 -0
  151. {modelable-1.2.0 → modelable-1.2.1}/tests/fixtures/wire_golden/golden/protobuf/platform_widget_v1.proto +0 -0
  152. {modelable-1.2.0 → modelable-1.2.1}/tests/fixtures/wire_golden/golden/rust/platform_widget_v1.rs +0 -0
  153. {modelable-1.2.0 → modelable-1.2.1}/tests/fixtures/wire_golden/wire_golden.mdl +0 -0
  154. {modelable-1.2.0 → modelable-1.2.1}/tests/helpers.py +0 -0
  155. {modelable-1.2.0 → modelable-1.2.1}/tests/test_apicurio_registry.py +0 -0
  156. {modelable-1.2.0 → modelable-1.2.1}/tests/test_apicurio_testcontainers.py +0 -0
  157. {modelable-1.2.0 → modelable-1.2.1}/tests/test_auto_projection.py +0 -0
  158. {modelable-1.2.0 → modelable-1.2.1}/tests/test_cel_validation.py +0 -0
  159. {modelable-1.2.0 → modelable-1.2.1}/tests/test_cli.py +0 -0
  160. {modelable-1.2.0 → modelable-1.2.1}/tests/test_cli_compile.py +0 -0
  161. {modelable-1.2.0 → modelable-1.2.1}/tests/test_cli_create.py +0 -0
  162. {modelable-1.2.0 → modelable-1.2.1}/tests/test_cli_inspect.py +0 -0
  163. {modelable-1.2.0 → modelable-1.2.1}/tests/test_codegen_docker_smoke.py +0 -0
  164. {modelable-1.2.0 → modelable-1.2.1}/tests/test_codegen_targets.py +0 -0
  165. {modelable-1.2.0 → modelable-1.2.1}/tests/test_compatibility.py +0 -0
  166. {modelable-1.2.0 → modelable-1.2.1}/tests/test_compiler.py +0 -0
  167. {modelable-1.2.0 → modelable-1.2.1}/tests/test_conformance_fixture.py +0 -0
  168. {modelable-1.2.0 → modelable-1.2.1}/tests/test_diagnostics.py +0 -0
  169. {modelable-1.2.0 → modelable-1.2.1}/tests/test_emit_csharp.py +0 -0
  170. {modelable-1.2.0 → modelable-1.2.1}/tests/test_emit_dbt_yaml.py +0 -0
  171. {modelable-1.2.0 → modelable-1.2.1}/tests/test_emit_fhir.py +0 -0
  172. {modelable-1.2.0 → modelable-1.2.1}/tests/test_emit_go.py +0 -0
  173. {modelable-1.2.0 → modelable-1.2.1}/tests/test_emit_grpc.py +0 -0
  174. {modelable-1.2.0 → modelable-1.2.1}/tests/test_emit_java.py +0 -0
  175. {modelable-1.2.0 → modelable-1.2.1}/tests/test_emit_json_schema.py +0 -0
  176. {modelable-1.2.0 → modelable-1.2.1}/tests/test_emit_markdown.py +0 -0
  177. {modelable-1.2.0 → modelable-1.2.1}/tests/test_emit_odcs.py +0 -0
  178. {modelable-1.2.0 → modelable-1.2.1}/tests/test_emit_openlineage.py +0 -0
  179. {modelable-1.2.0 → modelable-1.2.1}/tests/test_emit_openmetadata.py +0 -0
  180. {modelable-1.2.0 → modelable-1.2.1}/tests/test_emit_protobuf.py +0 -0
  181. {modelable-1.2.0 → modelable-1.2.1}/tests/test_emit_python.py +0 -0
  182. {modelable-1.2.0 → modelable-1.2.1}/tests/test_emit_sql.py +0 -0
  183. {modelable-1.2.0 → modelable-1.2.1}/tests/test_emit_typescript.py +0 -0
  184. {modelable-1.2.0 → modelable-1.2.1}/tests/test_fhir_validator.py +0 -0
  185. {modelable-1.2.0 → modelable-1.2.1}/tests/test_fixtures_regression.py +0 -0
  186. {modelable-1.2.0 → modelable-1.2.1}/tests/test_governance.py +0 -0
  187. {modelable-1.2.0 → modelable-1.2.1}/tests/test_grammar.py +0 -0
  188. {modelable-1.2.0 → modelable-1.2.1}/tests/test_graph_export.py +0 -0
  189. {modelable-1.2.0 → modelable-1.2.1}/tests/test_impact_analysis.py +0 -0
  190. {modelable-1.2.0 → modelable-1.2.1}/tests/test_lineage.py +0 -0
  191. {modelable-1.2.0 → modelable-1.2.1}/tests/test_llm_features.py +0 -0
  192. {modelable-1.2.0 → modelable-1.2.1}/tests/test_llm_provider_integration.py +0 -0
  193. {modelable-1.2.0 → modelable-1.2.1}/tests/test_lsp_code_actions.py +0 -0
  194. {modelable-1.2.0 → modelable-1.2.1}/tests/test_lsp_completion.py +0 -0
  195. {modelable-1.2.0 → modelable-1.2.1}/tests/test_lsp_completion_mirrors.py +0 -0
  196. {modelable-1.2.0 → modelable-1.2.1}/tests/test_lsp_definition.py +0 -0
  197. {modelable-1.2.0 → modelable-1.2.1}/tests/test_lsp_diagnostics.py +0 -0
  198. {modelable-1.2.0 → modelable-1.2.1}/tests/test_lsp_document_symbols.py +0 -0
  199. {modelable-1.2.0 → modelable-1.2.1}/tests/test_lsp_features.py +0 -0
  200. {modelable-1.2.0 → modelable-1.2.1}/tests/test_lsp_federation_diagnostics.py +0 -0
  201. {modelable-1.2.0 → modelable-1.2.1}/tests/test_lsp_folding.py +0 -0
  202. {modelable-1.2.0 → modelable-1.2.1}/tests/test_lsp_formatting.py +0 -0
  203. {modelable-1.2.0 → modelable-1.2.1}/tests/test_lsp_highlight.py +0 -0
  204. {modelable-1.2.0 → modelable-1.2.1}/tests/test_lsp_hover.py +0 -0
  205. {modelable-1.2.0 → modelable-1.2.1}/tests/test_lsp_inlay_hints.py +0 -0
  206. {modelable-1.2.0 → modelable-1.2.1}/tests/test_lsp_integration.py +0 -0
  207. {modelable-1.2.0 → modelable-1.2.1}/tests/test_lsp_references.py +0 -0
  208. {modelable-1.2.0 → modelable-1.2.1}/tests/test_lsp_rename.py +0 -0
  209. {modelable-1.2.0 → modelable-1.2.1}/tests/test_lsp_semantic_tokens.py +0 -0
  210. {modelable-1.2.0 → modelable-1.2.1}/tests/test_lsp_server.py +0 -0
  211. {modelable-1.2.0 → modelable-1.2.1}/tests/test_lsp_workspace.py +0 -0
  212. {modelable-1.2.0 → modelable-1.2.1}/tests/test_lsp_workspace_symbols.py +0 -0
  213. {modelable-1.2.0 → modelable-1.2.1}/tests/test_mypy_baseline.py +0 -0
  214. {modelable-1.2.0 → modelable-1.2.1}/tests/test_openlineage_sync.py +0 -0
  215. {modelable-1.2.0 → modelable-1.2.1}/tests/test_openlineage_testcontainers.py +0 -0
  216. {modelable-1.2.0 → modelable-1.2.1}/tests/test_openmetadata_testcontainers.py +0 -0
  217. {modelable-1.2.0 → modelable-1.2.1}/tests/test_planner.py +0 -0
  218. {modelable-1.2.0 → modelable-1.2.1}/tests/test_por.py +0 -0
  219. {modelable-1.2.0 → modelable-1.2.1}/tests/test_postgres_adapter.py +0 -0
  220. {modelable-1.2.0 → modelable-1.2.1}/tests/test_py314_compat.py +0 -0
  221. {modelable-1.2.0 → modelable-1.2.1}/tests/test_registry.py +0 -0
  222. {modelable-1.2.0 → modelable-1.2.1}/tests/test_registry_ids.py +0 -0
  223. {modelable-1.2.0 → modelable-1.2.1}/tests/test_registry_index.py +0 -0
  224. {modelable-1.2.0 → modelable-1.2.1}/tests/test_release_metadata.py +0 -0
  225. {modelable-1.2.0 → modelable-1.2.1}/tests/test_release_workflow.py +0 -0
  226. {modelable-1.2.0 → modelable-1.2.1}/tests/test_repository_release.py +0 -0
  227. {modelable-1.2.0 → modelable-1.2.1}/tests/test_resolver.py +0 -0
  228. {modelable-1.2.0 → modelable-1.2.1}/tests/test_samples.py +0 -0
  229. {modelable-1.2.0 → modelable-1.2.1}/tests/test_semantic.py +0 -0
  230. {modelable-1.2.0 → modelable-1.2.1}/tests/test_serialization_hints.py +0 -0
  231. {modelable-1.2.0 → modelable-1.2.1}/tests/test_spec_tracking.py +0 -0
  232. {modelable-1.2.0 → modelable-1.2.1}/tests/test_transformer.py +0 -0
  233. {modelable-1.2.0 → modelable-1.2.1}/tests/test_validate_surface_detection.py +0 -0
  234. {modelable-1.2.0 → modelable-1.2.1}/tests/test_version_range_resolution.py +0 -0
  235. {modelable-1.2.0 → modelable-1.2.1}/tests/test_wire_golden.py +0 -0
  236. {modelable-1.2.0 → modelable-1.2.1}/tests/test_workspace.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: modelable
3
- Version: 1.2.0
3
+ Version: 1.2.1
4
4
  Summary: Compiler and language server for versioned, domain-owned data models
5
5
  Project-URL: Homepage, https://github.com/ktjn/modelable
6
6
  Project-URL: Documentation, https://ktjn.github.io/modelable/
@@ -133,35 +133,35 @@ src/modelable/emitters/python.py:279: error: Function is missing a type annotati
133
133
  src/modelable/emitters/python.py:293: error: Item "ProjectionField" of "FieldDef | ProjectionField" has no attribute "optional" [union-attr]
134
134
  src/modelable/emitters/python.py:293: error: Item "ProjectionField" of "FieldDef | ProjectionField" has no attribute "type" [union-attr]
135
135
  src/modelable/emitters/python.py:75: error: Function is missing a type annotation for one or more parameters [no-untyped-def]
136
+ src/modelable/emitters/rust.py:1001: error: Item "ProjectionField" of "FieldDef | ProjectionField" has no attribute "optional" [union-attr]
137
+ src/modelable/emitters/rust.py:1001: error: Item "ProjectionField" of "FieldDef | ProjectionField" has no attribute "type" [union-attr]
138
+ src/modelable/emitters/rust.py:1005: error: Function is missing a type annotation for one or more parameters [no-untyped-def]
139
+ src/modelable/emitters/rust.py:1005: error: Missing type arguments for generic type "dict" [type-arg]
140
+ src/modelable/emitters/rust.py:1013: error: Returning Any from function declared to return "dict[Any, Any]" [no-any-return]
141
+ src/modelable/emitters/rust.py:1018: error: Returning Any from function declared to return "dict[Any, Any]" [no-any-return]
142
+ src/modelable/emitters/rust.py:1022: error: Returning Any from function declared to return "dict[Any, Any]" [no-any-return]
136
143
  src/modelable/emitters/rust.py:116: error: Missing type arguments for generic type "dict" [type-arg]
137
144
  src/modelable/emitters/rust.py:128: error: Incompatible types in assignment (expression has type "list[ProjectionVersion]", variable has type "list[ModelVersion]") [assignment]
138
145
  src/modelable/emitters/rust.py:130: error: "ModelVersion" has no attribute "source" [attr-defined]
139
146
  src/modelable/emitters/rust.py:135: error: Argument 3 to "_emit_projection" has incompatible type "ModelVersion"; expected "ProjectionVersion" [arg-type]
140
147
  src/modelable/emitters/rust.py:190: error: Function is missing a type annotation for one or more parameters [no-untyped-def]
141
148
  src/modelable/emitters/rust.py:190: error: Missing type arguments for generic type "set" [type-arg]
142
- src/modelable/emitters/rust.py:201: error: Missing type arguments for generic type "set" [type-arg]
143
- src/modelable/emitters/rust.py:316: error: Missing type arguments for generic type "dict" [type-arg]
144
- src/modelable/emitters/rust.py:372: error: Function is missing a type annotation for one or more parameters [no-untyped-def]
145
- src/modelable/emitters/rust.py:381: error: Missing type arguments for generic type "dict" [type-arg]
149
+ src/modelable/emitters/rust.py:211: error: Missing type arguments for generic type "set" [type-arg]
150
+ src/modelable/emitters/rust.py:326: error: Missing type arguments for generic type "dict" [type-arg]
151
+ src/modelable/emitters/rust.py:387: error: Function is missing a type annotation for one or more parameters [no-untyped-def]
152
+ src/modelable/emitters/rust.py:396: error: Missing type arguments for generic type "dict" [type-arg]
146
153
  src/modelable/emitters/rust.py:41: error: Missing type arguments for generic type "dict" [type-arg]
147
- src/modelable/emitters/rust.py:467: error: Function is missing a type annotation for one or more parameters [no-untyped-def]
154
+ src/modelable/emitters/rust.py:495: error: Function is missing a type annotation for one or more parameters [no-untyped-def]
148
155
  src/modelable/emitters/rust.py:56: error: Missing type arguments for generic type "frozenset" [type-arg]
149
- src/modelable/emitters/rust.py:578: error: Missing type arguments for generic type "dict" [type-arg]
150
- src/modelable/emitters/rust.py:735: error: Function is missing a type annotation for one or more parameters [no-untyped-def]
151
- src/modelable/emitters/rust.py:782: error: Function is missing a type annotation for one or more parameters [no-untyped-def]
152
- src/modelable/emitters/rust.py:811: error: Function is missing a type annotation for one or more parameters [no-untyped-def]
153
- src/modelable/emitters/rust.py:837: error: Function is missing a type annotation for one or more parameters [no-untyped-def]
154
- src/modelable/emitters/rust.py:851: error: Returning Any from function declared to return "str" [no-any-return]
156
+ src/modelable/emitters/rust.py:609: error: Missing type arguments for generic type "dict" [type-arg]
157
+ src/modelable/emitters/rust.py:776: error: Function is missing a type annotation for one or more parameters [no-untyped-def]
158
+ src/modelable/emitters/rust.py:823: error: Function is missing a type annotation for one or more parameters [no-untyped-def]
159
+ src/modelable/emitters/rust.py:852: error: Function is missing a type annotation for one or more parameters [no-untyped-def]
160
+ src/modelable/emitters/rust.py:878: error: Function is missing a type annotation for one or more parameters [no-untyped-def]
161
+ src/modelable/emitters/rust.py:892: error: Returning Any from function declared to return "str" [no-any-return]
155
162
  src/modelable/emitters/rust.py:93: error: Item "dict[str, object]" of "dict[str, object] | str" has no attribute "rstrip" [union-attr]
156
- src/modelable/emitters/rust.py:946: error: Function is missing a return type annotation [no-untyped-def]
157
- src/modelable/emitters/rust.py:946: error: Function is missing a type annotation for one or more parameters [no-untyped-def]
158
- src/modelable/emitters/rust.py:960: error: Item "ProjectionField" of "FieldDef | ProjectionField" has no attribute "optional" [union-attr]
159
- src/modelable/emitters/rust.py:960: error: Item "ProjectionField" of "FieldDef | ProjectionField" has no attribute "type" [union-attr]
160
- src/modelable/emitters/rust.py:964: error: Function is missing a type annotation for one or more parameters [no-untyped-def]
161
- src/modelable/emitters/rust.py:964: error: Missing type arguments for generic type "dict" [type-arg]
162
- src/modelable/emitters/rust.py:972: error: Returning Any from function declared to return "dict[Any, Any]" [no-any-return]
163
- src/modelable/emitters/rust.py:977: error: Returning Any from function declared to return "dict[Any, Any]" [no-any-return]
164
- src/modelable/emitters/rust.py:981: error: Returning Any from function declared to return "dict[Any, Any]" [no-any-return]
163
+ src/modelable/emitters/rust.py:987: error: Function is missing a return type annotation [no-untyped-def]
164
+ src/modelable/emitters/rust.py:987: error: Function is missing a type annotation for one or more parameters [no-untyped-def]
165
165
  src/modelable/emitters/sql.py:196: error: Function is missing a return type annotation [no-untyped-def]
166
166
  src/modelable/emitters/sql.py:196: error: Function is missing a type annotation for one or more parameters [no-untyped-def]
167
167
  src/modelable/emitters/sql.py:211: error: Function is missing a return type annotation [no-untyped-def]
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "modelable"
7
- version = "1.2.0"
7
+ version = "1.2.1"
8
8
  description = "Compiler and language server for versioned, domain-owned data models"
9
9
  readme = "README.md"
10
10
  license = "Apache-2.0"
@@ -198,6 +198,16 @@ def _collect_named_type_refs(field_type, result: set) -> None:
198
198
  _collect_named_type_refs(field_type.value, result)
199
199
 
200
200
 
201
+ def _collect_named_type_refs_from_shape(shape: TypeShape, result: set[str]) -> None:
202
+ """Recursively collect NamedType references from a resolved TypeShape."""
203
+ if shape.kind == "named" and shape.ref:
204
+ result.add(shape.ref)
205
+ elif shape.kind == "array" and shape.element is not None:
206
+ _collect_named_type_refs_from_shape(shape.element, result)
207
+ elif shape.kind == "map" and shape.value is not None:
208
+ _collect_named_type_refs_from_shape(shape.value, result)
209
+
210
+
201
211
  def _resolve_named_type_map(named_refs: set, mdl: MdlFile | None) -> tuple[dict[str, str], list[str]]:
202
212
  """Resolve NamedType references to Rust type names from the workspace.
203
213
 
@@ -207,7 +217,7 @@ def _resolve_named_type_map(named_refs: set, mdl: MdlFile | None) -> tuple[dict[
207
217
  return {}, []
208
218
  resolved_map: dict[str, str] = {}
209
219
  use_statements: list[str] = []
210
- for name in named_refs:
220
+ for name in sorted(named_refs):
211
221
  resolved = False
212
222
  for domain in mdl.domains:
213
223
  if name in domain.models:
@@ -351,8 +361,13 @@ def _emit_model(
351
361
  needs_serde_with = _any_needs_serde_with(field_specs)
352
362
  needs_uuid = _any_needs_uuid(field_specs)
353
363
  needs_serde_json = _any_needs_serde_json(field_specs)
364
+ needs_hashmap = _any_needs_hashmap(field_specs, nested_definitions)
354
365
  lines = _header_lines(
355
- serde_with=needs_serde_with, uuid=needs_uuid, serde_json=needs_serde_json, extra_uses=use_statements
366
+ serde_with=needs_serde_with,
367
+ uuid=needs_uuid,
368
+ serde_json=needs_serde_json,
369
+ hashmap=needs_hashmap,
370
+ extra_uses=use_statements,
356
371
  )
357
372
  lines.extend(_render_struct_definition(type_name, field_specs))
358
373
  lines.extend(_render_nested_definitions(nested_definitions))
@@ -385,10 +400,19 @@ def _emit_projection(
385
400
  nested_definitions: dict[str, list[str]] = {}
386
401
  local_enum_info: dict[str, list[str]] = {}
387
402
 
403
+ field_shapes: dict[str, TypeShape | None] = {
404
+ field.name: _resolve_projection_field_shape(field, version, mdl) for field in version.fields
405
+ }
406
+ named_refs: set[str] = set()
407
+ for field_shape in field_shapes.values():
408
+ if field_shape is not None:
409
+ _collect_named_type_refs_from_shape(field_shape, named_refs)
410
+ named_type_map, use_statements = _resolve_named_type_map(named_refs, mdl)
411
+
388
412
  field_specs: list[_FieldSpec] = []
389
413
  warnings: list[str] = []
390
414
  for index, field in enumerate(version.fields):
391
- field_shape = _resolve_projection_field_shape(field, version, mdl)
415
+ field_shape = field_shapes[field.name]
392
416
  if field_shape is None:
393
417
  warnings.append(type_loss(f"{domain.name}.{projection_name}.{field.name}"))
394
418
  field_specs.append(_FieldSpec(index=index, name=field.name, annotation="String", optional=False))
@@ -407,6 +431,7 @@ def _emit_projection(
407
431
  rust_hint=wire.get("rust"),
408
432
  clickhouse_hint=wire.get("clickhouse"),
409
433
  enum_info=local_enum_info,
434
+ named_type_map=named_type_map,
410
435
  )
411
436
  optional = field_shape.optional or field_shape.nullable
412
437
  serde_attrs = _serde_attrs_for_field(wire, field_shape, clickhouse=clickhouse_row)
@@ -421,6 +446,7 @@ def _emit_projection(
421
446
  needs_serde_json = _any_needs_serde_json(field_specs) or any(
422
447
  _projection_field_is_json_passthrough_to_string(f, version, mdl) for f in version.fields
423
448
  )
449
+ needs_hashmap = _any_needs_hashmap(field_specs, nested_definitions)
424
450
  storage_gated = sqlx_fromrow or clickhouse_row
425
451
  extra_derives: list[str] = []
426
452
  if sqlx_fromrow:
@@ -433,6 +459,8 @@ def _emit_projection(
433
459
  clickhouse=clickhouse_row,
434
460
  uuid=needs_uuid,
435
461
  serde_json=needs_serde_json,
462
+ hashmap=needs_hashmap,
463
+ extra_uses=use_statements,
436
464
  )
437
465
  lines.extend(
438
466
  _render_struct_definition(type_name, field_specs, extra_derives=extra_derives, storage_gated=storage_gated)
@@ -541,6 +569,9 @@ def _emit_from_impl(
541
569
  lines.append(f"use super::{src_module}::{enum_type};")
542
570
  if storage_gated:
543
571
  lines.append('#[cfg(feature = "storage")]')
572
+ # Direct-mapped fields always go through `.into()` below, which is a no-op
573
+ # (and a clippy lint) when the source and projected field share a type.
574
+ lines.append("#[allow(clippy::useless_conversion)]")
544
575
  lines.append(f"impl From<{src_type_name}> for {proj_type_name} {{")
545
576
  lines.append(f" fn from(src: {src_type_name}) -> Self {{")
546
577
  lines.append(" Self {")
@@ -608,6 +639,16 @@ def _any_needs_serde_json(field_specs: list[_FieldSpec]) -> bool:
608
639
  return any("serde_json::Value" in spec.annotation for spec in field_specs)
609
640
 
610
641
 
642
+ def _any_needs_hashmap(field_specs: list[_FieldSpec], nested_definitions: dict[str, list[str]] | None = None) -> bool:
643
+ if any("HashMap<" in spec.annotation for spec in field_specs):
644
+ return True
645
+ if nested_definitions:
646
+ for lines in nested_definitions.values():
647
+ if any("HashMap<" in line for line in lines):
648
+ return True
649
+ return False
650
+
651
+
611
652
  def _shape_involves_object(shape: TypeShape) -> bool:
612
653
  """Return True if the shape contains an inline object type.
613
654
 
@@ -630,13 +671,13 @@ def _header_lines(
630
671
  clickhouse: bool = False,
631
672
  uuid: bool = False,
632
673
  serde_json: bool = False,
674
+ hashmap: bool = False,
633
675
  extra_uses: list[str] | None = None,
634
676
  ) -> list[str]:
635
- lines = [
636
- "// @generated by Modelable",
637
- "use std::collections::HashMap;",
638
- "",
639
- ]
677
+ lines = ["// @generated by Modelable"]
678
+ if hashmap:
679
+ lines.append("use std::collections::HashMap;")
680
+ lines.append("")
640
681
  if clickhouse:
641
682
  lines.insert(1, "// requires: clickhouse (https://docs.rs/clickhouse)")
642
683
  if sqlx:
@@ -1,4 +1,7 @@
1
1
  import hashlib
2
+ import os
3
+ import subprocess
4
+ import sys
2
5
 
3
6
  from click.testing import CliRunner
4
7
 
@@ -388,6 +391,168 @@ domain customer {
388
391
  assert "pub name: String," in proj_art.content
389
392
 
390
393
 
394
+ def test_emit_rust_projection_imports_named_type_fields(tmp_path):
395
+ mdl = tmp_path / "test.mdl"
396
+ mdl.write_text(
397
+ """
398
+ domain orders {
399
+ owner: "test-team"
400
+
401
+ semantic BuyerId : uuid(7)
402
+
403
+ value OrderLine @ 1 (additive) {
404
+ sku: string
405
+ quantity: u32
406
+ }
407
+
408
+ event OrderPlaced @ 1 (additive) {
409
+ orderId: uuid
410
+ buyerId: BuyerId
411
+ lines: array<OrderLine>
412
+ }
413
+
414
+ projection OrderHistory @ 1
415
+ from orders.OrderPlaced @ 1 as placed
416
+ {
417
+ orderId <- placed.orderId
418
+ buyerId <- placed.buyerId
419
+ lines <- placed.lines
420
+ }
421
+ }
422
+ """,
423
+ encoding="utf-8",
424
+ )
425
+ from modelable.compiler.workspace import load_workspace
426
+
427
+ workspace = load_workspace(tmp_path)
428
+ artifacts = emit_rust(workspace, tmp_path / "out")
429
+ proj_art = next(a for a in artifacts if a.ref == "orders.OrderHistory@1")
430
+ # Field types must be the generated Rust type names, not the raw .mdl names.
431
+ assert "pub buyer_id: BuyerId," in proj_art.content
432
+ assert "pub lines: Vec<OrdersOrderLineV1>," in proj_art.content
433
+ # Every named type referenced by a field must have a matching use import.
434
+ assert "use super::buyer_id::BuyerId;" in proj_art.content
435
+ assert "use super::orders_order_line_v1::OrdersOrderLineV1;" in proj_art.content
436
+
437
+
438
+ def test_emit_rust_named_type_use_statements_are_hash_seed_independent(tmp_path):
439
+ """Rust output must be byte-identical across processes/interpreters.
440
+
441
+ `use` statements for named-type fields are built by iterating a `set` of
442
+ reference names. CPython's set iteration order for strings depends on
443
+ PYTHONHASHSEED, so an unsorted iteration reorders the generated `use`
444
+ lines between runs unless the seed is pinned — breaking reproducible
445
+ builds. Run the emitter in two subprocesses with different hash seeds
446
+ and require identical output.
447
+ """
448
+ mdl = tmp_path / "test.mdl"
449
+ mdl.write_text(
450
+ """
451
+ domain orders {
452
+ owner: "test-team"
453
+
454
+ semantic BuyerId : uuid(7)
455
+ semantic CartId : uuid(7)
456
+ semantic OrderId : uuid(7)
457
+
458
+ value OrderLine @ 1 (additive) {
459
+ sku: string
460
+ }
461
+
462
+ entity Order @ 1 (additive) {
463
+ @key orderId: OrderId
464
+ cartId: CartId
465
+ buyerId: BuyerId
466
+ lines: array<OrderLine>
467
+ }
468
+
469
+ event OrderPlaced @ 1 (additive) {
470
+ orderId: OrderId
471
+ cartId: CartId
472
+ buyerId: BuyerId
473
+ lines: array<OrderLine>
474
+ }
475
+
476
+ projection OrderHistory @ 1
477
+ from orders.OrderPlaced @ 1 as placed
478
+ {
479
+ orderId <- placed.orderId
480
+ cartId <- placed.cartId
481
+ buyerId <- placed.buyerId
482
+ lines <- placed.lines
483
+ }
484
+ }
485
+ """,
486
+ encoding="utf-8",
487
+ )
488
+ script = tmp_path / "emit.py"
489
+ script.write_text(
490
+ "import sys\n"
491
+ "from pathlib import Path\n"
492
+ "from modelable.compiler.workspace import load_workspace\n"
493
+ "from modelable.emitters.rust import emit_rust\n"
494
+ "workspace = load_workspace(Path(sys.argv[1]))\n"
495
+ "artifacts = emit_rust(workspace, Path(sys.argv[1]) / 'out')\n"
496
+ "for artifact in sorted(artifacts, key=lambda a: a.ref):\n"
497
+ " print(artifact.ref)\n"
498
+ " print(artifact.content)\n",
499
+ encoding="utf-8",
500
+ )
501
+
502
+ def run_with_seed(seed: str) -> str:
503
+ env = {**os.environ, "PYTHONHASHSEED": seed}
504
+ result = subprocess.run(
505
+ [sys.executable, str(script), str(tmp_path)],
506
+ capture_output=True,
507
+ text=True,
508
+ env=env,
509
+ check=True,
510
+ )
511
+ return result.stdout
512
+
513
+ output_seed_0 = run_with_seed("0")
514
+ output_seed_1 = run_with_seed("1")
515
+ assert output_seed_0 == output_seed_1
516
+
517
+
518
+ def test_emit_rust_omits_hashmap_import_when_unused(tmp_path):
519
+ mdl = tmp_path / "test.mdl"
520
+ mdl.write_text(
521
+ """
522
+ domain orders {
523
+ owner: "test-team"
524
+ value OrderLine @ 1 (additive) {
525
+ sku: string
526
+ quantity: u32
527
+ }
528
+
529
+ entity Order @ 1 (additive) {
530
+ @key orderId: uuid
531
+ lines: array<OrderLine>
532
+ }
533
+
534
+ projection OrderView @ 1
535
+ from orders.Order @ 1 as o
536
+ {
537
+ orderId <- o.orderId
538
+ lines <- o.lines
539
+ }
540
+ }
541
+ """,
542
+ encoding="utf-8",
543
+ )
544
+ workspace = load_workspace(tmp_path)
545
+ artifacts = emit_rust(workspace, tmp_path / "out")
546
+ # Neither struct has a map field, so the HashMap import (and the unused
547
+ # import it would otherwise produce) must not appear.
548
+ line_art = next(a for a in artifacts if a.ref == "orders.OrderLine@1")
549
+ order_art = next(a for a in artifacts if a.ref == "orders.Order@1")
550
+ view_art = next(a for a in artifacts if a.ref == "orders.OrderView@1")
551
+ assert "use std::collections::HashMap;" not in line_art.content
552
+ assert "use std::collections::HashMap;" not in order_art.content
553
+ assert "use std::collections::HashMap;" not in view_art.content
554
+
555
+
391
556
  def test_emit_rust_struct_has_serde_derives(tmp_path):
392
557
  mdl = tmp_path / "test.mdl"
393
558
  mdl.write_text(
@@ -769,6 +934,9 @@ domain customer {
769
934
  assert "customer_id: src.customer_id.into()," in proj.content
770
935
  assert "display_name: src.display_name.into()," in proj.content
771
936
  assert "use super::customer_customer_v1::CustomerCustomerV1;" in proj.content
937
+ # Direct-mapped fields keep an unconditional `.into()`, which is a no-op
938
+ # when source and target share a type; silence the resulting clippy lint.
939
+ assert "#[allow(clippy::useless_conversion)]\nimpl From<CustomerCustomerV1>" in proj.content
772
940
  # Model struct itself should NOT have a From impl (no projection source)
773
941
  model = next(a for a in artifacts if a.ref == "customer.Customer@1")
774
942
  assert "impl From<" not in model.content
@@ -348,7 +348,7 @@ wheels = [
348
348
 
349
349
  [[package]]
350
350
  name = "modelable"
351
- version = "1.2.0"
351
+ version = "1.2.1"
352
352
  source = { editable = "." }
353
353
  dependencies = [
354
354
  { name = "click" },
File without changes
File without changes
File without changes
File without changes