metaobjects 0.19.7__tar.gz → 0.19.9__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 (393) hide show
  1. {metaobjects-0.19.7 → metaobjects-0.19.9}/PKG-INFO +1 -1
  2. {metaobjects-0.19.7 → metaobjects-0.19.9}/pyproject.toml +1 -1
  3. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/apidocs/builder.py +16 -1
  4. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/cli.py +14 -1
  5. metaobjects-0.19.9/src/metaobjects/codegen/collision_names.py +110 -0
  6. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/codegen/extract_delegate_emitter.py +109 -51
  7. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/codegen/generators/extractor_generator.py +65 -26
  8. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/codegen/generators/output_parser_generator.py +119 -19
  9. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/codegen/generators/output_prompt_generator.py +16 -1
  10. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/codegen/generators/payload_vo_generator.py +43 -62
  11. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/codegen/generators/render_helper_generator.py +23 -18
  12. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/codegen/generators/trace_helper_generator.py +19 -1
  13. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/codegen/type_map.py +8 -0
  14. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/core_types.py +9 -0
  15. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/core/field/field_constants.py +5 -0
  16. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/spec_metamodel/field.json +9 -3
  17. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_cli_verify_subverbs.py +110 -0
  18. metaobjects-0.19.9/tests/codegen/test_extract_tier_collision.py +507 -0
  19. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_payload_vo_generator.py +15 -3
  20. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_render_helper_generator.py +11 -4
  21. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_validation_conformance.py +19 -3
  22. {metaobjects-0.19.7 → metaobjects-0.19.9}/uv.lock +1 -1
  23. {metaobjects-0.19.7 → metaobjects-0.19.9}/.gitignore +0 -0
  24. {metaobjects-0.19.7 → metaobjects-0.19.9}/LICENSE +0 -0
  25. {metaobjects-0.19.7 → metaobjects-0.19.9}/README.md +0 -0
  26. {metaobjects-0.19.7 → metaobjects-0.19.9}/hatch_build.py +0 -0
  27. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/__init__.py +0 -0
  28. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/agent_context/__init__.py +0 -0
  29. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/agent_context/scaffold.py +0 -0
  30. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/apidocs/__init__.py +0 -0
  31. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/apidocs/api_model.py +0 -0
  32. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/apidocs/naming.py +0 -0
  33. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/apidocs/paths.py +0 -0
  34. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/apidocs/renderer.py +0 -0
  35. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/attr_class_map.py +0 -0
  36. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/codegen/KNOWN_GAPS.md +0 -0
  37. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/codegen/__init__.py +0 -0
  38. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/codegen/config.py +0 -0
  39. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/codegen/constants.py +0 -0
  40. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/codegen/extract_schema_emitter.py +0 -0
  41. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/codegen/format.py +0 -0
  42. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/codegen/fr010_field_mapping.py +0 -0
  43. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/codegen/generator.py +0 -0
  44. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/codegen/generator_registry.py +0 -0
  45. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/codegen/generators/__init__.py +0 -0
  46. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/codegen/generators/entity_model.py +0 -0
  47. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/codegen/generators/filter_allowlist_generator.py +0 -0
  48. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/codegen/generators/fr019_shared_enum.py +0 -0
  49. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/codegen/generators/m2m_codegen.py +0 -0
  50. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/codegen/generators/router_generator.py +0 -0
  51. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/codegen/generators/template_generator.py +0 -0
  52. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/codegen/generators/tph_plan.py +0 -0
  53. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/codegen/instance_artifacts.py +0 -0
  54. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/codegen/output_format_spec_emitter.py +0 -0
  55. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/codegen/overwrite_policy.py +0 -0
  56. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/codegen/runner.py +0 -0
  57. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/codegen/runtime/__init__.py +0 -0
  58. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/codegen/runtime/filter_parser.py +0 -0
  59. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/codegen/template_codegen/__init__.py +0 -0
  60. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/codegen/template_codegen/output_pattern.py +0 -0
  61. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/codegen/template_codegen/template_data.py +0 -0
  62. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/codegen/template_codegen/template_spec.py +0 -0
  63. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/datatype.py +0 -0
  64. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/documentation/__init__.py +0 -0
  65. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/documentation/doc_constants.py +0 -0
  66. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/documentation/doc_provider.py +0 -0
  67. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/documentation/doc_schema.py +0 -0
  68. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/errors.py +0 -0
  69. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/loader/__init__.py +0 -0
  70. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/loader/merge.py +0 -0
  71. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/loader/meta_data_loader.py +0 -0
  72. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/loader/registered_validation.py +0 -0
  73. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/loader/sources/__init__.py +0 -0
  74. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/loader/sources/directory_source.py +0 -0
  75. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/loader/sources/file_source.py +0 -0
  76. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/loader/sources/meta_data_source.py +0 -0
  77. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/loader/sources/uri_source.py +0 -0
  78. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/loader/validate_discriminator.py +0 -0
  79. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/loader/validate_field_readonly.py +0 -0
  80. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/loader/validate_source_escapes.py +0 -0
  81. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/loader/validate_source_parameter_ref.py +0 -0
  82. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/loader/validate_source_physical_names.py +0 -0
  83. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/loader/validation_passes.py +0 -0
  84. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/__init__.py +0 -0
  85. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/core/__init__.py +0 -0
  86. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/core/attr/__init__.py +0 -0
  87. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/core/attr/attr_constants.py +0 -0
  88. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/core/attr/meta_attr.py +0 -0
  89. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/core/field/__init__.py +0 -0
  90. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/core/field/meta_field.py +0 -0
  91. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/core/identity/__init__.py +0 -0
  92. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/core/identity/identity_constants.py +0 -0
  93. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/core/identity/meta_identity.py +0 -0
  94. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/core/index/__init__.py +0 -0
  95. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/core/index/index_constants.py +0 -0
  96. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/core/index/meta_index.py +0 -0
  97. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/core/object/__init__.py +0 -0
  98. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/core/object/meta_object.py +0 -0
  99. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/core/object/meta_object_aware.py +0 -0
  100. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/core/object/object_class_registry.py +0 -0
  101. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/core/object/object_constants.py +0 -0
  102. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/core/object/object_extract.py +0 -0
  103. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/core/object/value_object.py +0 -0
  104. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/core/relationship/__init__.py +0 -0
  105. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/core/relationship/derive_m2m_fields.py +0 -0
  106. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/core/relationship/meta_relationship.py +0 -0
  107. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/core/relationship/relationship_constants.py +0 -0
  108. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/core/validator/__init__.py +0 -0
  109. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/core/validator/validator_constants.py +0 -0
  110. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/meta_data.py +0 -0
  111. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/meta_root.py +0 -0
  112. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/persistence/__init__.py +0 -0
  113. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/persistence/db/__init__.py +0 -0
  114. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/persistence/db/db_constants.py +0 -0
  115. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/persistence/db/db_provider.py +0 -0
  116. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/persistence/origin/__init__.py +0 -0
  117. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/persistence/origin/meta_origin.py +0 -0
  118. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/persistence/origin/origin_constants.py +0 -0
  119. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/persistence/source/__init__.py +0 -0
  120. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/persistence/source/meta_source.py +0 -0
  121. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/persistence/source/source_constants.py +0 -0
  122. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/presentation/__init__.py +0 -0
  123. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/presentation/layout/__init__.py +0 -0
  124. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/presentation/layout/layout_constants.py +0 -0
  125. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/presentation/layout/meta_layout.py +0 -0
  126. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/presentation/ui/__init__.py +0 -0
  127. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/presentation/ui/ui_provider.py +0 -0
  128. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/presentation/view/__init__.py +0 -0
  129. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/presentation/view/meta_view.py +0 -0
  130. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/presentation/view/view_constants.py +0 -0
  131. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/provider_extends.py +0 -0
  132. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/template/__init__.py +0 -0
  133. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/template/meta_template.py +0 -0
  134. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/template/prompt_provider.py +0 -0
  135. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/template/template_constants.py +0 -0
  136. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/naming_refs.py +0 -0
  137. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/parser.py +0 -0
  138. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/parser_yaml.py +0 -0
  139. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/provider.py +0 -0
  140. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/py.typed +0 -0
  141. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/registry.py +0 -0
  142. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/registry_manifest.py +0 -0
  143. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/render/__init__.py +0 -0
  144. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/render/email_document.py +0 -0
  145. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/render/escapers.py +0 -0
  146. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/render/extract/KNOWN_GAPS.md +0 -0
  147. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/render/extract/__init__.py +0 -0
  148. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/render/extract/coerce.py +0 -0
  149. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/render/extract/extract.py +0 -0
  150. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/render/extract/extract_map.py +0 -0
  151. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/render/extract/json_forgiving_reader.py +0 -0
  152. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/render/extract/locate.py +0 -0
  153. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/render/extract/normalize.py +0 -0
  154. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/render/extract/strip.py +0 -0
  155. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/render/extract/types.py +0 -0
  156. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/render/extract/xml_forgiving_reader.py +0 -0
  157. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/render/filesystem_provider.py +0 -0
  158. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/render/prompt/__init__.py +0 -0
  159. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/render/prompt/output_format_renderer.py +0 -0
  160. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/render/prompt/output_format_spec.py +0 -0
  161. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/render/prompt/prompt_field.py +0 -0
  162. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/render/prompt/prompt_overrides.py +0 -0
  163. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/render/prompt/prompt_style.py +0 -0
  164. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/render/renderer.py +0 -0
  165. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/render/verify.py +0 -0
  166. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/runtime/__init__.py +0 -0
  167. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/runtime/llm_recorder.py +0 -0
  168. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/runtime/n2m_resolver.py +0 -0
  169. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/runtime/object_manager.py +0 -0
  170. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/runtime/tph.py +0 -0
  171. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/serializer_json.py +0 -0
  172. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/shared/__init__.py +0 -0
  173. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/shared/base_types.py +0 -0
  174. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/shared/separators.py +0 -0
  175. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/shared/structural.py +0 -0
  176. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/source/__init__.py +0 -0
  177. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/source/error_source.py +0 -0
  178. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/source/json_path.py +0 -0
  179. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/source/semantic_diff.py +0 -0
  180. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/source/yaml_positions.py +0 -0
  181. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/spec_metamodel/__init__.py +0 -0
  182. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/spec_metamodel/attr.json +0 -0
  183. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/spec_metamodel/db.json +0 -0
  184. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/spec_metamodel/documentation.json +0 -0
  185. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/spec_metamodel/identity.json +0 -0
  186. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/spec_metamodel/index.json +0 -0
  187. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/spec_metamodel/layout.json +0 -0
  188. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/spec_metamodel/object.json +0 -0
  189. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/spec_metamodel/origin.json +0 -0
  190. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/spec_metamodel/prompt.json +0 -0
  191. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/spec_metamodel/relationship.json +0 -0
  192. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/spec_metamodel/source.json +0 -0
  193. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/spec_metamodel/template.json +0 -0
  194. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/spec_metamodel/ui-web.json +0 -0
  195. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/spec_metamodel/ui.json +0 -0
  196. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/spec_metamodel/validator.json +0 -0
  197. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/spec_metamodel/view.json +0 -0
  198. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/super_resolve.py +0 -0
  199. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/validation_types.py +0 -0
  200. {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/yaml_desugar.py +0 -0
  201. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/__init__.py +0 -0
  202. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/__init__.py +0 -0
  203. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/golden/extends/expected/BaseEntity.py +0 -0
  204. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/golden/extends/expected/Program.py +0 -0
  205. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/golden/extends/meta.json +0 -0
  206. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/golden/nested-array/expected/AuthorBrief.py +0 -0
  207. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/golden/nested-array/expected/PostBrief.py +0 -0
  208. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/golden/nested-array/meta.json +0 -0
  209. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/golden/scalars/expected/Metric.py +0 -0
  210. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/golden/scalars/expected/Report.py +0 -0
  211. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/golden/scalars/meta.json +0 -0
  212. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/golden/vanilla/expected/Subscriber.py +0 -0
  213. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/golden/vanilla/meta.json +0 -0
  214. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_abstract_conformance.py +0 -0
  215. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_api_docs_builder.py +0 -0
  216. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_api_docs_paths.py +0 -0
  217. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_cli.py +0 -0
  218. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_cli_providers.py +0 -0
  219. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_cli_registry.py +0 -0
  220. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_cli_staleness_nudge.py +0 -0
  221. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_cli_verify_strict.py +0 -0
  222. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_constants_config.py +0 -0
  223. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_entity_model.py +0 -0
  224. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_enum_conformance.py +0 -0
  225. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_extends_abstract_field_inheritance.py +0 -0
  226. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_extractor_generator.py +0 -0
  227. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_filter_allowlist_generator.py +0 -0
  228. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_format.py +0 -0
  229. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_fr010_nested_object_prompt.py +0 -0
  230. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_fr010_output_codegen.py +0 -0
  231. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_fr019_shared_provided_conformance.py +0 -0
  232. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_generator.py +0 -0
  233. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_generator_extension_seams.py +0 -0
  234. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_golden.py +0 -0
  235. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_inherit_without_restate_gate.py +0 -0
  236. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_inheritance_conformance.py +0 -0
  237. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_instance_artifacts.py +0 -0
  238. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_m2m_codegen.py +0 -0
  239. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_origin_nullability.py +0 -0
  240. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_output_parser_generator.py +0 -0
  241. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_overwrite_policy.py +0 -0
  242. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_projection_compile.py +0 -0
  243. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_render_helper_conformance.py +0 -0
  244. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_reverse_finders.py +0 -0
  245. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_router_autoset.py +0 -0
  246. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_router_generator.py +0 -0
  247. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_runner.py +0 -0
  248. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_template_data.py +0 -0
  249. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_template_generator.py +0 -0
  250. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_template_output_pattern.py +0 -0
  251. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_template_scope_helpers.py +0 -0
  252. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_template_scope_walk.py +0 -0
  253. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_template_spec.py +0 -0
  254. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_tph_codegen.py +0 -0
  255. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_trace_helper_generator.py +0 -0
  256. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_type_map.py +0 -0
  257. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_write_through.py +0 -0
  258. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/conformance/__init__.py +0 -0
  259. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/conformance/capabilities.py +0 -0
  260. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/conformance/conformance-expected-failures.json +0 -0
  261. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/conformance/conformance_adapter.py +0 -0
  262. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/conformance/corpus.py +0 -0
  263. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/conformance/expected_failures.py +0 -0
  264. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/conformance/fixture_discovery.py +0 -0
  265. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/conformance/navigator.py +0 -0
  266. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/conformance/test_api_docs_cross_port_conformance.py +0 -0
  267. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/conformance/test_conformance.py +0 -0
  268. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/conformance/test_extract_conformance.py +0 -0
  269. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/conformance/test_extract_object_verdict.py +0 -0
  270. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/conformance/test_fr010_loader_attrs.py +0 -0
  271. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/conformance/test_fr011_attrs.py +0 -0
  272. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/conformance/test_generator_registry_conformance.py +0 -0
  273. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/conformance/test_object_model_conformance.py +0 -0
  274. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/conformance/test_provider_composition_conformance.py +0 -0
  275. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/conformance/test_registry_conformance.py +0 -0
  276. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/conformance/test_runner_hardfail.py +0 -0
  277. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/conformance/test_spec_metamodel_embed.py +0 -0
  278. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/conformance/test_strict_attr_load.py +0 -0
  279. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/conformance/test_template_codegen_conformance.py +0 -0
  280. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/conformance/test_template_generator_conformance.py +0 -0
  281. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/conformance/test_yaml_conformance.py +0 -0
  282. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/conformance/yaml-conformance-expected-failures.json +0 -0
  283. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/integration/__init__.py +0 -0
  284. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/integration/api_contract_assertions.py +0 -0
  285. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/integration/api_contract_jsonb_server.py +0 -0
  286. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/integration/api_contract_m2m_server.py +0 -0
  287. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/integration/api_contract_server.py +0 -0
  288. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/integration/generated_jsonb_app.py +0 -0
  289. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/integration/generated_m2m_app.py +0 -0
  290. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/integration/generated_router_app.py +0 -0
  291. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/integration/generated_tph_app.py +0 -0
  292. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/integration/meta_ai_trace.yaml +0 -0
  293. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/integration/normalization.py +0 -0
  294. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/integration/postgres_container.py +0 -0
  295. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/integration/query_runner.py +0 -0
  296. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/integration/scenarios.py +0 -0
  297. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/integration/test_api_contract.py +0 -0
  298. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/integration/test_api_contract_generated.py +0 -0
  299. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/integration/test_api_contract_jsonb.py +0 -0
  300. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/integration/test_api_contract_m2m.py +0 -0
  301. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/integration/test_api_contract_m2m_generated.py +0 -0
  302. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/integration/test_api_contract_tph_generated.py +0 -0
  303. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/integration/test_generated_router_uuid_pk.py +0 -0
  304. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/integration/test_llm_call_trace.py +0 -0
  305. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/integration/test_normalization.py +0 -0
  306. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/integration/test_query_scenarios.py +0 -0
  307. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/integration/test_runtime_return_types.py +0 -0
  308. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/open_closed_proof_test.py +0 -0
  309. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/render/__init__.py +0 -0
  310. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/render/extract/__init__.py +0 -0
  311. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/render/extract/test_coerce.py +0 -0
  312. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/render/extract/test_extract.py +0 -0
  313. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/render/extract/test_extract_map.py +0 -0
  314. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/render/extract/test_json_forgiving_reader.py +0 -0
  315. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/render/extract/test_locate.py +0 -0
  316. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/render/extract/test_model.py +0 -0
  317. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/render/extract/test_normalize.py +0 -0
  318. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/render/extract/test_strip.py +0 -0
  319. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/render/extract/test_xml_forgiving_reader.py +0 -0
  320. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/render/prompt/__init__.py +0 -0
  321. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/render/prompt/test_output_format_renderer.py +0 -0
  322. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/render/test_email_document.py +0 -0
  323. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/render/test_filesystem_provider.py +0 -0
  324. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/render/test_output_format_renderer_nested.py +0 -0
  325. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/render/test_output_prompt_conformance.py +0 -0
  326. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/render/test_render_conformance.py +0 -0
  327. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/render/test_render_max_chars.py +0 -0
  328. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/render/test_verify.py +0 -0
  329. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/render/test_verify_conformance.py +0 -0
  330. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/source/__init__.py +0 -0
  331. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/source/test_fr5c_merge_attribution.py +0 -0
  332. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/source/test_fr5d_reference_resolution.py +0 -0
  333. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/source/test_fr5e_database_source_shape.py +0 -0
  334. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/source/test_json_path.py +0 -0
  335. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/source/test_semantic_diff.py +0 -0
  336. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/source/test_source_on_node.py +0 -0
  337. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/source/test_yaml_positions.py +0 -0
  338. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/test_api_docs_accuracy.py +0 -0
  339. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/__init__.py +0 -0
  340. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_agent_context_staleness.py +0 -0
  341. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_capabilities.py +0 -0
  342. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_common_attrs.py +0 -0
  343. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_core_types.py +0 -0
  344. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_effective_package.py +0 -0
  345. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_errors.py +0 -0
  346. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_field_enum.py +0 -0
  347. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_field_map_validation.py +0 -0
  348. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_field_uuid_dbcolumntype.py +0 -0
  349. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_fr016_source_name_and_kind_aliases.py +0 -0
  350. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_index_lookup.py +0 -0
  351. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_llm_recorder.py +0 -0
  352. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_loader.py +0 -0
  353. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_loader_bom.py +0 -0
  354. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_loader_class.py +0 -0
  355. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_merge.py +0 -0
  356. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_meta_attr.py +0 -0
  357. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_meta_data.py +0 -0
  358. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_meta_source.py +0 -0
  359. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_module_shortcuts.py +0 -0
  360. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_n2m_resolver.py +0 -0
  361. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_n2m_resolver_inherited.py +0 -0
  362. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_object_manager_autoset_stamping.py +0 -0
  363. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_object_manager_uuid_coercion.py +0 -0
  364. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_object_manager_write_through.py +0 -0
  365. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_one_primary_source.py +0 -0
  366. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_parser.py +0 -0
  367. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_parser_yaml.py +0 -0
  368. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_provider.py +0 -0
  369. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_provider_extension.py +0 -0
  370. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_registry.py +0 -0
  371. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_registry_completeness.py +0 -0
  372. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_registry_extend.py +0 -0
  373. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_registry_sealed.py +0 -0
  374. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_relationship_referential_actions.py +0 -0
  375. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_resolution_key.py +0 -0
  376. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_runtime_resolution_key_binding.py +0 -0
  377. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_serializer.py +0 -0
  378. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_shared_constants.py +0 -0
  379. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_smoke.py +0 -0
  380. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_source_escapes.py +0 -0
  381. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_sources.py +0 -0
  382. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_strict_child_placement.py +0 -0
  383. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_super_resolve.py +0 -0
  384. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_template_toolcall.py +0 -0
  385. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_template_wrong_subtype_attrs.py +0 -0
  386. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_validation_attr_schema.py +0 -0
  387. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_validation_filter_values.py +0 -0
  388. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_validation_origin_195.py +0 -0
  389. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_validation_origin_paths.py +0 -0
  390. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_validation_sort_field.py +0 -0
  391. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_validation_warnings.py +0 -0
  392. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_write_coercion_arrays.py +0 -0
  393. {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_yaml_desugar.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: metaobjects
3
- Version: 0.19.7
3
+ Version: 0.19.9
4
4
  Summary: Cross-language metadata standard: declare typed entities once, generate idiomatic drift-checked code across languages — Python port.
5
5
  Project-URL: Homepage, https://metaobjects.dev
6
6
  Project-URL: Repository, https://github.com/metaobjectsdev/metaobjects
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "metaobjects"
3
- version = "0.19.7"
3
+ version = "0.19.9"
4
4
  description = "Cross-language metadata standard: declare typed entities once, generate idiomatic drift-checked code across languages — Python port."
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.11"
@@ -55,11 +55,24 @@ from metaobjects.meta.meta_data import MetaData
55
55
  from metaobjects.meta.persistence.source.source_constants import SOURCE_KIND_TABLE
56
56
  from metaobjects.meta.template import template_constants as tc
57
57
  from metaobjects.shared.base_types import TYPE_OBJECT, TYPE_TEMPLATE
58
+ from metaobjects.shared.separators import PACKAGE_SEP
58
59
 
59
60
  # Structured formats that get an output-format prompt + a tolerant extractor.
60
61
  _STRUCTURED_FORMATS = frozenset({tc.TEMPLATE_FORMAT_JSON, tc.TEMPLATE_FORMAT_XML})
61
62
 
62
63
 
64
+ def _pkg_of(node: MetaData) -> str:
65
+ """The effective package of a node — its ``resolution_key()`` minus the
66
+ trailing ``::<name>`` ("" for a root-level node). Duplicated (not imported) to
67
+ match the existing per-generator convention. Used to derive a template's
68
+ referrer package for ``resolve_payload_vo`` (#228) — see that function's
69
+ docstring for why this ancestor-walk-aware form is used instead of the
70
+ loader's bare ``tpl.package or tpl.file_default_package or ""``."""
71
+ key = node.resolution_key()
72
+ i = key.rfind(PACKAGE_SEP)
73
+ return "" if i == -1 else key[:i]
74
+
75
+
63
76
  # ---------------------------------------------------------------------------
64
77
  # Applies-predicates — each REUSES the matching generator's own gate helpers, so
65
78
  # inclusion can never drift from emission. (The Python generators gate inline;
@@ -95,7 +108,9 @@ def _payload_resolves(tmpl: MetaData, root: MetaData) -> MetaObject | None:
95
108
  payload_ref = tmpl.get_meta_attr(tc.TEMPLATE_ATTR_PAYLOAD_REF) # ADR-0039: template attr resolves via extends (not origin; templates CAN extend)
96
109
  if not isinstance(payload_ref, str) or not payload_ref:
97
110
  return None
98
- return resolve_payload_vo(root, payload_ref)
111
+ # ADR-0042 (#228): the referrer is THIS template — a bare @payloadRef resolves
112
+ # in ITS OWN package first.
113
+ return resolve_payload_vo(root, payload_ref, _pkg_of(tmpl))
99
114
 
100
115
 
101
116
  def _is_email_kind(tmpl: MetaData) -> bool:
@@ -84,6 +84,17 @@ from metaobjects.render.verify import (
84
84
  verify as render_verify,
85
85
  )
86
86
  from metaobjects.shared.base_types import TYPE_TEMPLATE
87
+ from metaobjects.shared.separators import PACKAGE_SEP
88
+
89
+
90
+ def _pkg_of(node: MetaData) -> str:
91
+ """The effective package of a node — its ``resolution_key()`` minus the
92
+ trailing ``::<name>`` ("" for a root-level node). Duplicated (not imported) to
93
+ match the existing per-generator convention. Used to derive a template's
94
+ referrer package for ``_resolve_payload_vo`` (#228)."""
95
+ key = node.resolution_key()
96
+ i = key.rfind(PACKAGE_SEP)
97
+ return "" if i == -1 else key[:i]
87
98
 
88
99
 
89
100
  def _default_generators() -> list[Generator]:
@@ -642,7 +653,9 @@ def _verify_templates(args: argparse.Namespace) -> int:
642
653
  print(f"error: [{tmpl.name}] missing @payloadRef.", file=sys.stderr)
643
654
  error_count += 1
644
655
  continue
645
- vo = _resolve_payload_vo(root, payload_ref)
656
+ # ADR-0042 (#228): the referrer is THIS template — a bare @payloadRef
657
+ # resolves in ITS OWN package first.
658
+ vo = _resolve_payload_vo(root, payload_ref, _pkg_of(tmpl))
646
659
  if vo is None:
647
660
  print(
648
661
  f"error: [{tmpl.name}] @payloadRef '{payload_ref}' did not "
@@ -0,0 +1,110 @@
1
+ """ADR-0044 — collision-scoped nested-VO name assignment (shared).
2
+
3
+ Promoted out of ``payload_vo_generator.py`` (formerly the module-private
4
+ ``_package_qualified_name`` / ``_assign_nested_names``) so every Python generator that
5
+ walks a payload's nested-value-object closure derives IDENTICAL emitted names for an
6
+ IDENTICAL closure. Today that's the payload-record tier (``payload_vo_generator.py``)
7
+ AND the extract/output-parser tier (``extract_delegate_emitter.py`` /
8
+ ``extractor_generator.py`` / ``output_parser_generator.py``) — a nested class an
9
+ extractor module IMPORTS from the sibling payload module must be spelled exactly the
10
+ way the payload module itself emitted it, so both tiers MUST share one naming
11
+ function rather than re-derive a second (and possibly-diverging) copy (issue #228).
12
+
13
+ :func:`assign_nested_names` returns BASE names only — a bare short name when it is
14
+ unique across the closure, else its package-qualified derived form
15
+ (``acme::alpha`` + ``Note`` → ``AcmeAlphaNote``). It never bakes in a suffix; each
16
+ caller applies its OWN transform on top of the shared base (the payload tier:
17
+ ``payload_class_name(base)`` → ``...Payload``; the extract tier: ``f"{base}Extracted"``
18
+ for the mirror dataclass, ``f"_to_strict_{snake(base)}"`` / ``f"_from_{snake(base)}
19
+ _extracted"`` for the mapper function names) — one pure function of the closure feeds
20
+ every naming scheme that must agree on the same base.
21
+ """
22
+ from __future__ import annotations
23
+
24
+ from collections.abc import Callable, Mapping
25
+
26
+ from metaobjects.errors import ErrorCode
27
+ from metaobjects.meta.meta_data import MetaData
28
+ from metaobjects.shared.separators import PACKAGE_SEP
29
+
30
+ #: ADR-0044 backstop error code — REUSED (never redefined) from the shared cross-port
31
+ #: error-code ledger (``metaobjects.errors.ErrorCode``), which already carries it.
32
+ ERR_PAYLOAD_NAME_COLLISION = ErrorCode.ERR_PAYLOAD_NAME_COLLISION.value
33
+
34
+
35
+ def pascal_segment(name: str) -> str:
36
+ """``priority`` → ``Priority`` (leading char upper-cased only; no snake-splitting)
37
+ — matches the cross-port rule for PascalCasing a bare field/package segment."""
38
+ return name[:1].upper() + name[1:] if name else name
39
+
40
+
41
+ def package_qualified_name(pkg: str, short_name: str) -> str:
42
+ """PascalCase each ``::``-segment of *pkg*, concatenate, append the bare
43
+ *short_name* (``acme::alpha`` + ``Note`` → ``AcmeAlphaNote``). A root-level
44
+ (empty-package) node keeps its bare short name — the loader's own-package
45
+ uniqueness already precludes two root-level nodes sharing a name, so this can't
46
+ silently under-qualify."""
47
+ if pkg == "":
48
+ return short_name
49
+ return "".join(pascal_segment(seg) for seg in pkg.split(PACKAGE_SEP)) + short_name
50
+
51
+
52
+ def _pkg_of(node: MetaData) -> str:
53
+ """The effective package of an object — its ``resolution_key()`` minus the
54
+ trailing ``::<name>`` ("" for a root-level object). Derived from the resolution
55
+ key so it is correct for BOTH loaded trees (file_default_package) and
56
+ programmatically-built trees (package only on the root)."""
57
+ key = node.resolution_key()
58
+ i = key.rfind(PACKAGE_SEP)
59
+ return "" if i == -1 else key[:i]
60
+
61
+
62
+ def assign_nested_names(
63
+ closure: Mapping[str, MetaData],
64
+ class_name_fn: Callable[[str], str] | None = None,
65
+ ) -> dict[str, str]:
66
+ """ADR-0044 pass 2 — ``resolution_key()`` → emitted name. A PURE function of the
67
+ closure's ``(key, short-name, package)`` triples, never of traversal order: a bare
68
+ short name unique in the closure emits its bare form (byte-identical to
69
+ pre-ADR-0044 output); a short-name collision emits EVERY member under its
70
+ package-qualified derived form. If two distinct keys still derive the same name,
71
+ fails loud with ``ERR_PAYLOAD_NAME_COLLISION`` — never silently collides a second
72
+ time.
73
+
74
+ *class_name_fn*, when supplied, transforms each derived BASE name (bare or
75
+ package-qualified) into the caller's final emitted name — e.g.
76
+ ``payload_vo_generator`` passes ``payload_class_name`` (bare ``"Note"`` →
77
+ ``"NotePayload"``) so its own collision backstop message names the actual emitted
78
+ class. Omitted (``None``, the default) → identity, returning bare BASE names — the
79
+ extract tier's callers apply their OWN suffix/transform on top (see module
80
+ docstring) so every naming scheme derives from ONE shared base-assignment pass.
81
+ """
82
+ name_fn: Callable[[str], str] = class_name_fn if class_name_fn is not None else (lambda base: base)
83
+
84
+ by_short: dict[str, list[str]] = {}
85
+ for key, node in closure.items():
86
+ by_short.setdefault(node.name, []).append(key)
87
+
88
+ name_map: dict[str, str] = {}
89
+ for short, keys in by_short.items():
90
+ if len(keys) == 1:
91
+ name_map[keys[0]] = name_fn(short)
92
+ continue
93
+ for key in keys:
94
+ node = closure[key]
95
+ name_map[key] = name_fn(package_qualified_name(_pkg_of(node), short))
96
+
97
+ # Backstop — sorted by key so both the emptiness of the colliding set and the
98
+ # pair named in the message are a pure function of the closure, not dict order.
99
+ owner: dict[str, str] = {}
100
+ for key in sorted(name_map):
101
+ emitted = name_map[key]
102
+ existing = owner.get(emitted)
103
+ if existing is not None and existing != key:
104
+ raise ValueError(
105
+ f"{ERR_PAYLOAD_NAME_COLLISION}: payload record name collision: "
106
+ f'"{emitted}" derives from both "{existing}" and "{key}" — rename one '
107
+ "value-object or move it to a package that derives a distinct name"
108
+ )
109
+ owner[emitted] = key
110
+ return name_map
@@ -24,43 +24,55 @@ emitted code stays self-sufficient and reflection-free.
24
24
 
25
25
  Bounded by the cross-port ``MAX_NEST_DEPTH`` via the runtime — codegen here only mirrors
26
26
  the runtime's resolved object graph, so depth/cycle guarding lives in ``object_extract``.
27
- The emitter dedupes mirrors/mappers by VO simple name (cycle-safe).
27
+ The emitter dedupes mirrors/mappers by ``resolution_key()`` (the package-qualified FQN,
28
+ cycle-safe) — NOT the bare VO ``name``, which would silently collapse two same-short-name
29
+ value-objects from different packages into one (ADR-0044, #228). A bare-name collision
30
+ resolves to a package-qualified emitted name via the shared
31
+ :func:`~metaobjects.codegen.collision_names.assign_nested_names` pass (see
32
+ :func:`build_name_map`) — the SAME naming pass the payload-record tier
33
+ (``payload_vo_generator``) runs, so this tier's names never diverge from the payload
34
+ module's own.
28
35
  """
29
36
  from __future__ import annotations
30
37
 
31
38
  from metaobjects.codegen import fr010_field_mapping as fm
39
+ from metaobjects.codegen.collision_names import assign_nested_names
32
40
  from metaobjects.meta.core.field import field_constants as fc
33
41
  from metaobjects.meta.meta_data import MetaData
34
- from metaobjects.shared.base_types import TYPE_OBJECT
42
+ from metaobjects.naming_refs import resolve_object_ref
35
43
  from metaobjects.shared.separators import PACKAGE_SEP
36
44
 
37
45
 
38
- def _find_object(root: MetaData, name: str) -> MetaData | None:
39
- """The top-level ``object.*`` node named *name*, or ``None``.
40
-
41
- ADR-0039 sanctioned own: top-level object lookup on the loader ROOT
42
- (metadata.root is never extended, so own == effective) — mirrors the TS
43
- reference (``root.ownChildren()``).
44
- """
45
- for c in root.own_children():
46
- if c.type == TYPE_OBJECT and c.name == name:
47
- return c
48
- return None
46
+ def _pkg_of(node: MetaData) -> str:
47
+ """The effective package of an object — its ``resolution_key()`` minus the
48
+ trailing ``::<name>`` ("" for a root-level object). Duplicated (not imported) to
49
+ match the existing per-generator convention — ``payload_vo_generator.py`` and
50
+ ``render_helper_generator.py`` each carry their own identical copy."""
51
+ key = node.resolution_key()
52
+ i = key.rfind(PACKAGE_SEP)
53
+ return "" if i == -1 else key[:i]
49
54
 
50
55
 
51
56
  def ref_vo(field: MetaData, root: MetaData) -> MetaData | None:
52
57
  """The ``@objectRef`` target VO for a nested-object field, or ``None`` when
53
- unresolvable. Matches first on the full ref, then the trailing simple-name
54
- segment (mirrors the runtime ``_resolve_object_ref`` short-name fallback)."""
58
+ unresolvable.
59
+
60
+ ADR-0042 (#228) — resolves via the canonical `resolve_object_ref` package-local
61
+ contract: an FQN ref resolves EXACTLY; a bare ref resolves in the DECLARING
62
+ field's own package first, else a root-level object. NO bare-tail short-name
63
+ fallback — that pattern (matching an FQN ref by its trailing simple-name segment
64
+ against ANY same-named object root-wide) is the #219/ADR-0042-banned "wrong
65
+ node" bug: under a cross-package short-name collision it silently binds
66
+ whichever same-named object happens to load first, regardless of which package
67
+ the ref actually pointed at. *referrer_pkg* is the field's OWN declaring
68
+ package (which differs from the VO's when the field is inherited via `extends`
69
+ from an abstract VO in another package) — mirrors payload_vo_generator's
70
+ `_resolve_object_field_type`."""
55
71
  ref = field.attrs().get(fc.FIELD_ATTR_OBJECT_REF)
56
72
  if not isinstance(ref, str) or not ref:
57
73
  return None
58
- direct = _find_object(root, ref)
59
- if direct is not None:
60
- return direct
61
- if PACKAGE_SEP in ref:
62
- return _find_object(root, ref.rsplit(PACKAGE_SEP, 1)[-1])
63
- return None
74
+ referrer_pkg = _pkg_of(field.parent) if field.parent is not None else ""
75
+ return resolve_object_ref(root, ref, referrer_pkg)
64
76
 
65
77
 
66
78
  def _is_object_field(field: MetaData) -> bool:
@@ -69,14 +81,20 @@ def _is_object_field(field: MetaData) -> bool:
69
81
  return field.sub_type == fc.FIELD_SUBTYPE_OBJECT
70
82
 
71
83
 
72
- def mirror_name(vo: MetaData) -> str:
73
- """The extracted-mirror dataclass name for a value-object (``<Name>Extracted``)."""
74
- return f"{vo.name}Extracted"
84
+ def mirror_name(vo: MetaData, name_map: dict[str, str]) -> str:
85
+ """The extracted-mirror dataclass name for a value-object
86
+ (``<Base>Extracted``) — ADR-0044 (#228) collision-scoped: *base* is the bare
87
+ ``vo.name`` unless a cross-package bare-name collision requires the
88
+ package-qualified derived form (see :func:`build_name_map`)."""
89
+ base = name_map.get(vo.resolution_key(), vo.name)
90
+ return f"{base}Extracted"
75
91
 
76
92
 
77
- def _mapper_name(vo: MetaData) -> str:
78
- """The mapper function name for a value-object (``_from_<name>_extracted``)."""
79
- return f"_from_{_snake(vo.name)}_extracted"
93
+ def _mapper_name(vo: MetaData, name_map: dict[str, str]) -> str:
94
+ """The mapper function name for a value-object (``_from_<base_snake>_extracted``)
95
+ — *base* per :func:`mirror_name`."""
96
+ base = name_map.get(vo.resolution_key(), vo.name)
97
+ return f"_from_{_snake(base)}_extracted"
80
98
 
81
99
 
82
100
  def root_mapper_name(template_name: str) -> str:
@@ -101,12 +119,12 @@ def _snake(name: str) -> str:
101
119
  # =============================================================================
102
120
 
103
121
 
104
- def _nested_mirror_type(field: MetaData, root: MetaData) -> str:
122
+ def _nested_mirror_type(field: MetaData, root: MetaData, name_map: dict[str, str]) -> str:
105
123
  """The nullable mirror annotation for one field — nested-aware (nested objects
106
124
  become ``<Nested>Extracted``; array-of-objects become ``list[...]``)."""
107
125
  if _is_object_field(field):
108
126
  target = ref_vo(field, root)
109
- base = f'"{mirror_name(target)}"' if target is not None else "object"
127
+ base = f'"{mirror_name(target, name_map)}"' if target is not None else "object"
110
128
  elem = f"{base} | None"
111
129
  return f"list[{elem}] | None" if fm.is_array(field) else elem
112
130
  if fm.is_array(field):
@@ -130,20 +148,29 @@ def _nested_mirror_type(field: MetaData, root: MetaData) -> str:
130
148
 
131
149
  def reachable_vos(vo: MetaData, root: MetaData) -> list[MetaData]:
132
150
  """``vo`` + every value-object reachable through nested ``@objectRef`` fields, in
133
- stable BFS order, deduped by simple name (cycle-safe)."""
151
+ stable BFS order, deduped by ``resolution_key()`` (cycle-safe).
152
+
153
+ ADR-0044 (#228) — deduping by the bare ``name`` (pre-fix) silently DROPPED a
154
+ second cross-package value-object sharing the first one's bare short name (e.g.
155
+ ``acme::alpha::Note`` + ``acme::beta::Note``): once the first ``Note`` was seen,
156
+ the second's bare name matched ``seen`` and it was never queued/emitted — a
157
+ silent shape loss, not merely a naming cosmetic. ``resolution_key()`` is the
158
+ package-qualified FQN, so two same-short-name VOs from different packages are
159
+ two distinct keys and both survive the walk."""
134
160
  out: list[MetaData] = []
135
161
  seen: set[str] = set()
136
162
  queue: list[MetaData] = [vo]
137
163
  while queue:
138
164
  cur = queue.pop(0)
139
- if cur.name in seen:
165
+ key = cur.resolution_key()
166
+ if key in seen:
140
167
  continue
141
- seen.add(cur.name)
168
+ seen.add(key)
142
169
  out.append(cur)
143
170
  for f in fm.fields(cur):
144
171
  if _is_object_field(f):
145
172
  target = ref_vo(f, root)
146
- if target is not None and target.name not in seen:
173
+ if target is not None and target.resolution_key() not in seen:
147
174
  queue.append(target)
148
175
  return out
149
176
 
@@ -156,30 +183,55 @@ def has_nested(vo: MetaData, root: MetaData) -> bool:
156
183
  return False
157
184
 
158
185
 
186
+ def build_name_map(vo: MetaData, root: MetaData) -> dict[str, str]:
187
+ """ADR-0044 (#228) — the collision-scoped BASE name map for ``vo``'s reachable
188
+ nested-VO closure, keyed by ``resolution_key()``. ``vo`` itself (the PRIMARY —
189
+ named after the enclosing template/payload, never its own bare name) is
190
+ excluded from the collision domain, mirroring payload_vo_generator's
191
+ `_collect_nested_closure` (which seeds ``seen`` with the primary's own key for
192
+ the identical reason).
193
+
194
+ Reuses the SAME shared :func:`~metaobjects.codegen.collision_names.assign_nested_names`
195
+ pass the payload-record tier runs, so a nested VO's derived BASE here agrees
196
+ exactly with the payload module's own emitted class name (modulo the
197
+ ``Payload``/``Extracted`` suffix each tier applies on top) — the extractor's
198
+ imports and the payload module's declarations can never diverge."""
199
+ primary_key = vo.resolution_key()
200
+ closure: dict[str, MetaData] = {
201
+ cur.resolution_key(): cur
202
+ for cur in reachable_vos(vo, root)
203
+ if cur.resolution_key() != primary_key
204
+ }
205
+ return assign_nested_names(closure)
206
+
207
+
159
208
  # =============================================================================
160
209
  # Nested-aware mirror dataclasses
161
210
  # =============================================================================
162
211
 
163
212
 
164
213
  def nested_mirror_dataclasses(
165
- vo: MetaData, root: MetaData, payload_mirror: str
214
+ vo: MetaData, root: MetaData, payload_mirror: str, name_map: dict[str, str]
166
215
  ) -> list[str]:
167
216
  """Emit the nested-aware mirror dataclass for ``vo`` and every reachable nested VO
168
217
  (deduped). The payload mirror keeps the canonical ``<Template>Extracted`` name
169
218
  (``payload_mirror``) so the existing self-contained ``extract_<name>()`` initializer
170
219
  and the delegating path share ONE mirror type. The nested mirrors carry their own
171
- ``<VO>Extracted`` name. Returns source lines (blank-line separated)."""
220
+ ADR-0044 (#228) collision-scoped ``<Base>Extracted`` name (*name_map*, from
221
+ :func:`build_name_map`). Returns source lines (blank-line separated)."""
172
222
  lines: list[str] = []
173
223
  for i, cur in enumerate(reachable_vos(vo, root)):
174
224
  if i > 0:
175
225
  lines.append("")
176
226
  lines.append("")
177
- name = payload_mirror if i == 0 else mirror_name(cur)
178
- lines.extend(_one_mirror(cur, root, name))
227
+ name = payload_mirror if i == 0 else mirror_name(cur, name_map)
228
+ lines.extend(_one_mirror(cur, root, name, name_map))
179
229
  return lines
180
230
 
181
231
 
182
- def _one_mirror(vo: MetaData, root: MetaData, record_name: str) -> list[str]:
232
+ def _one_mirror(
233
+ vo: MetaData, root: MetaData, record_name: str, name_map: dict[str, str]
234
+ ) -> list[str]:
183
235
  base = (
184
236
  record_name[: -len("Extracted")]
185
237
  if record_name.endswith("Extracted")
@@ -192,7 +244,8 @@ def _one_mirror(vo: MetaData, root: MetaData, record_name: str) -> list[str]:
192
244
  ' (``None`` where the value was lost or malformed)."""',
193
245
  ]
194
246
  field_lines = [
195
- f" {f.name}: {_nested_mirror_type(f, root)} = None" for f in fm.fields(vo)
247
+ f" {f.name}: {_nested_mirror_type(f, root, name_map)} = None"
248
+ for f in fm.fields(vo)
196
249
  ]
197
250
  lines.extend(field_lines or [" pass"])
198
251
  return lines
@@ -204,26 +257,31 @@ def _one_mirror(vo: MetaData, root: MetaData, record_name: str) -> list[str]:
204
257
 
205
258
 
206
259
  def nested_mappers(
207
- vo: MetaData, root: MetaData, root_mapper_fn: str, root_mirror: str
260
+ vo: MetaData,
261
+ root: MetaData,
262
+ root_mapper_fn: str,
263
+ root_mirror: str,
264
+ name_map: dict[str, str],
208
265
  ) -> list[str]:
209
- """Emit one ``_from_<vo>_extracted(o)`` mapper per reachable VO (payload + nested,
210
- deduped). The ROOT mapper is overridden to the template-derived ``root_mapper_fn`` /
211
- ``root_mirror`` so it returns the canonically-named root mirror. Returns source
212
- lines (blank-line separated)."""
266
+ """Emit one ``_from_<base>_extracted(o)`` mapper per reachable VO (payload +
267
+ nested, deduped). The ROOT mapper is overridden to the template-derived
268
+ ``root_mapper_fn`` / ``root_mirror`` so it returns the canonically-named root
269
+ mirror. Nested mappers use the ADR-0044 (#228) collision-scoped *name_map* (from
270
+ :func:`build_name_map`). Returns source lines (blank-line separated)."""
213
271
  lines: list[str] = []
214
272
  vos = reachable_vos(vo, root)
215
273
  for i, cur in enumerate(vos):
216
274
  if i > 0:
217
275
  lines.append("")
218
276
  lines.append("")
219
- fn = root_mapper_fn if i == 0 else _mapper_name(cur)
220
- mir = root_mirror if i == 0 else mirror_name(cur)
221
- lines.extend(_one_mapper(cur, root, fn, mir))
277
+ fn = root_mapper_fn if i == 0 else _mapper_name(cur, name_map)
278
+ mir = root_mirror if i == 0 else mirror_name(cur, name_map)
279
+ lines.extend(_one_mapper(cur, root, fn, mir, name_map))
222
280
  return lines
223
281
 
224
282
 
225
283
  def _one_mapper(
226
- vo: MetaData, root: MetaData, fn: str, mirror: str
284
+ vo: MetaData, root: MetaData, fn: str, mirror: str, name_map: dict[str, str]
227
285
  ) -> list[str]:
228
286
  lines: list[str] = [
229
287
  f'def {fn}(o: object | None) -> "{mirror} | None":',
@@ -234,19 +292,19 @@ def _one_mapper(
234
292
  f" return {mirror}(",
235
293
  ]
236
294
  for f in fm.fields(vo):
237
- lines.append(f" {f.name}={_mapper_arg(f, root)},")
295
+ lines.append(f" {f.name}={_mapper_arg(f, root, name_map)},")
238
296
  lines.append(" )")
239
297
  return lines
240
298
 
241
299
 
242
- def _mapper_arg(field: MetaData, root: MetaData) -> str:
300
+ def _mapper_arg(field: MetaData, root: MetaData, name_map: dict[str, str]) -> str:
243
301
  """The mirror-field initializer that reads ``field`` from the assembled object ``o``."""
244
302
  key = f'"{field.name}"'
245
303
  if _is_object_field(field):
246
304
  target = ref_vo(field, root)
247
305
  if target is None:
248
306
  return "None # unresolved @objectRef"
249
- fn = _mapper_name(target)
307
+ fn = _mapper_name(target, name_map)
250
308
  if fm.is_array(field):
251
309
  return f"_map_object_list(_read_prop(o, {key}), {fn})"
252
310
  return f"{fn}(_read_prop(o, {key}))"
@@ -52,6 +52,7 @@ from metaobjects.meta.core.object.meta_object import MetaObject
52
52
  from metaobjects.meta.meta_data import MetaData
53
53
  from metaobjects.meta.template import template_constants as tc
54
54
  from metaobjects.shared.base_types import TYPE_TEMPLATE
55
+ from metaobjects.shared.separators import PACKAGE_SEP
55
56
 
56
57
  _GENERATOR_NAME = "extractor-generator"
57
58
 
@@ -59,21 +60,45 @@ _GENERATOR_NAME = "extractor-generator"
59
60
  _EXTRACT_FORMATS = frozenset({tc.TEMPLATE_FORMAT_JSON, tc.TEMPLATE_FORMAT_XML})
60
61
 
61
62
 
62
- def _strict_class(vo: MetaData, root_vo: MetaData, template_name: str) -> str:
63
- """The strict Pydantic class name for a value-object. The ROOT payload VO maps to
64
- the template-named ``<Template>Payload`` (payload_vo emits the primary class under
65
- the template name); every nested VO maps to ``<Vo>Payload``."""
66
- if vo.name == root_vo.name:
63
+ def _pkg_of(node: MetaData) -> str:
64
+ """The effective package of a node — its ``resolution_key()`` minus the
65
+ trailing ``::<name>`` ("" for a root-level node). Duplicated (not imported) to
66
+ match the existing per-generator convention. Used to derive a template's
67
+ referrer package for ``resolve_payload_vo`` (#228) — see that function's
68
+ docstring for why this ancestor-walk-aware form is used instead of the
69
+ loader's bare ``tpl.package or tpl.file_default_package or ""``."""
70
+ key = node.resolution_key()
71
+ i = key.rfind(PACKAGE_SEP)
72
+ return "" if i == -1 else key[:i]
73
+
74
+
75
+ def _strict_class(
76
+ vo: MetaData, root_vo: MetaData, template_name: str, name_map: dict[str, str]
77
+ ) -> str:
78
+ """The strict Pydantic class name for a value-object. The ROOT payload VO
79
+ (matched by ``resolution_key()`` — NOT bare ``name``, so a nested VO that
80
+ happens to share the root's bare name across packages is never mistaken for
81
+ the root) maps to the template-named ``<Template>Payload`` (payload_vo emits
82
+ the primary class under the template name); every OTHER (nested) VO maps to
83
+ its ADR-0044 (#228) *name_map* base + ``Payload`` — bare when unique in the
84
+ payload's nested-VO closure, package-qualified on a cross-package short-name
85
+ collision (see :func:`~metaobjects.codegen.extract_delegate_emitter.build_name_map`,
86
+ which reuses the SAME naming pass ``payload_vo_generator`` runs, so this name
87
+ always matches the payload module's own emitted class)."""
88
+ if vo.resolution_key() == root_vo.resolution_key():
67
89
  return payload_class_name(template_name)
68
- return payload_class_name(vo.name)
90
+ base = name_map.get(vo.resolution_key(), vo.name)
91
+ return payload_class_name(base)
69
92
 
70
93
 
71
- def _mapper_name(vo: MetaData) -> str:
72
- """``_to_strict_<vo_snake>`` — the recursive mirror→strict mapper for a VO."""
73
- return f"_to_strict_{_snake_case(vo.name)}"
94
+ def _mapper_name(vo: MetaData, name_map: dict[str, str]) -> str:
95
+ """``_to_strict_<base_snake>`` — the recursive mirror→strict mapper for a VO,
96
+ *base* per the ADR-0044 (#228) *name_map* (see :func:`_strict_class`)."""
97
+ base = name_map.get(vo.resolution_key(), vo.name)
98
+ return f"_to_strict_{_snake_case(base)}"
74
99
 
75
100
 
76
- def _strict_arg(field: MetaData, root: MetaData) -> str:
101
+ def _strict_arg(field: MetaData, root: MetaData, name_map: dict[str, str]) -> str:
77
102
  """The strict-payload initializer expression for one field, reading the mirror
78
103
  member ``m.<name>`` and mapping it onto the strict payload's exact optionality
79
104
  (``is_field_required`` — shared with payload_vo so there is no skew).
@@ -93,7 +118,7 @@ def _strict_arg(field: MetaData, root: MetaData) -> str:
93
118
  target = rde.ref_vo(field, root)
94
119
  if target is None:
95
120
  return f"m.{name}" # unresolved @objectRef — pass the mirror value through
96
- fn = _mapper_name(target)
121
+ fn = _mapper_name(target, name_map)
97
122
  if fm.is_array(field):
98
123
  # Required or optional array-of-objects: map present elements (drop Nones).
99
124
  return f"[{fn}(e) for e in (m.{name} or [])]" if required else (
@@ -119,11 +144,17 @@ def _strict_arg(field: MetaData, root: MetaData) -> str:
119
144
  return f"m.{name}"
120
145
 
121
146
 
122
- def _emit_mapper(vo: MetaData, root: MetaData, root_vo: MetaData, template_name: str) -> list[str]:
123
- """One ``_to_strict_<vo>(m) -> <Strict>`` mapper, one-shot-constructing the strict
147
+ def _emit_mapper(
148
+ vo: MetaData,
149
+ root: MetaData,
150
+ root_vo: MetaData,
151
+ template_name: str,
152
+ name_map: dict[str, str],
153
+ ) -> list[str]:
154
+ """One ``_to_strict_<base>(m) -> <Strict>`` mapper, one-shot-constructing the strict
124
155
  Pydantic model from the mirror ``m``."""
125
- fn = _mapper_name(vo)
126
- strict = _strict_class(vo, root_vo, template_name)
156
+ fn = _mapper_name(vo, name_map)
157
+ strict = _strict_class(vo, root_vo, template_name, name_map)
127
158
  lines: list[str] = [
128
159
  f"def {fn}(m) -> {strict}:",
129
160
  f' """Map the all-nullable extracted mirror onto the strict ``{strict}``.',
@@ -131,7 +162,7 @@ def _emit_mapper(vo: MetaData, root: MetaData, root_vo: MetaData, template_name:
131
162
  f" return {strict}(",
132
163
  ]
133
164
  for f in fm.fields(vo):
134
- lines.append(f" {f.name}={_strict_arg(f, root)},")
165
+ lines.append(f" {f.name}={_strict_arg(f, root, name_map)},")
135
166
  lines.append(" )")
136
167
  return lines
137
168
 
@@ -154,7 +185,9 @@ def render_extractor(
154
185
  payload_ref = template.get_meta_attr(tc.TEMPLATE_ATTR_PAYLOAD_REF) # ADR-0039: template attr resolves via extends (not origin; templates CAN extend)
155
186
  if not isinstance(payload_ref, str) or not payload_ref:
156
187
  return None
157
- payload = resolve_payload_vo(root, payload_ref)
188
+ # ADR-0042 (#228): the referrer is THIS template — a bare @payloadRef resolves
189
+ # in ITS OWN package first.
190
+ payload = resolve_payload_vo(root, payload_ref, _pkg_of(template))
158
191
  if payload is None:
159
192
  return None
160
193
 
@@ -171,18 +204,22 @@ def render_extractor(
171
204
  extract_lenient_fn = f"extract_lenient_{snake}"
172
205
  extract_fn = f"extract_{snake}"
173
206
  root_strict = payload_class_name(template_name)
174
- root_mapper = _mapper_name(payload)
175
207
 
176
208
  fqn = f"{payload.package}::{template_name}" if payload.package else template_name
177
209
 
178
210
  # The strict payload graph: root payload class (template-named) + every nested
179
- # VO's ``<Vo>Payload`` (reachable through @objectRef, deduped/cycle-safe — the SAME
180
- # walk payload_vo emits the nested classes for, so each import resolves).
211
+ # VO's ADR-0044 (#228) collision-scoped ``<Base>Payload`` (reachable through
212
+ # @objectRef, deduped/cycle-safe — the SAME walk + the SAME shared name-map
213
+ # payload_vo emits the nested classes for, so each import resolves to the exact
214
+ # class payload_vo_generator declared).
181
215
  vos = rde.reachable_vos(payload, root)
216
+ name_map = rde.build_name_map(payload, root)
217
+ root_mapper = _mapper_name(payload, name_map)
182
218
  strict_imports = {root_strict}
183
219
  for vo in vos:
184
- if vo.name != payload.name:
185
- strict_imports.add(payload_class_name(vo.name))
220
+ if vo.resolution_key() != payload.resolution_key():
221
+ base = name_map.get(vo.resolution_key(), vo.name)
222
+ strict_imports.add(payload_class_name(base))
186
223
 
187
224
  lines: list[str] = [
188
225
  generated_header(template_name, fqn),
@@ -233,7 +270,7 @@ def render_extractor(
233
270
  if i > 0:
234
271
  lines.append("")
235
272
  lines.append("")
236
- lines.extend(emit_mapper(vo, root, payload, template_name))
273
+ lines.extend(emit_mapper(vo, root, payload, template_name, name_map))
237
274
 
238
275
  lines.append("")
239
276
  lines.append("")
@@ -257,12 +294,14 @@ class ExtractorGenerator:
257
294
  root: MetaData,
258
295
  root_vo: MetaData,
259
296
  template_name: str,
297
+ name_map: dict[str, str],
260
298
  ) -> list[str]:
261
- """EXTENSION SEAM — one ``_to_strict_<vo>(m) -> <Strict>`` mirror→strict
299
+ """EXTENSION SEAM — one ``_to_strict_<base>(m) -> <Strict>`` mirror→strict
262
300
  mapper block. Defaults to the module-level :func:`_emit_mapper`; override to
263
301
  customize how the extracted mirror graph is mapped onto the strict Pydantic
264
- payload (e.g. coercion, post-validation, default-filling)."""
265
- return _emit_mapper(vo, root, root_vo, template_name)
302
+ payload (e.g. coercion, post-validation, default-filling). *name_map* is the
303
+ ADR-0044 (#228) collision-scoped name map (see :func:`_strict_class`)."""
304
+ return _emit_mapper(vo, root, root_vo, template_name, name_map)
266
305
 
267
306
  def _render_module(self, template: MetaData, root: MetaData) -> str | None:
268
307
  """EXTENSION SEAM — render the whole extractor module for one