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.
- {metaobjects-0.19.7 → metaobjects-0.19.9}/PKG-INFO +1 -1
- {metaobjects-0.19.7 → metaobjects-0.19.9}/pyproject.toml +1 -1
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/apidocs/builder.py +16 -1
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/cli.py +14 -1
- metaobjects-0.19.9/src/metaobjects/codegen/collision_names.py +110 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/codegen/extract_delegate_emitter.py +109 -51
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/codegen/generators/extractor_generator.py +65 -26
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/codegen/generators/output_parser_generator.py +119 -19
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/codegen/generators/output_prompt_generator.py +16 -1
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/codegen/generators/payload_vo_generator.py +43 -62
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/codegen/generators/render_helper_generator.py +23 -18
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/codegen/generators/trace_helper_generator.py +19 -1
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/codegen/type_map.py +8 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/core_types.py +9 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/core/field/field_constants.py +5 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/spec_metamodel/field.json +9 -3
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_cli_verify_subverbs.py +110 -0
- metaobjects-0.19.9/tests/codegen/test_extract_tier_collision.py +507 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_payload_vo_generator.py +15 -3
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_render_helper_generator.py +11 -4
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_validation_conformance.py +19 -3
- {metaobjects-0.19.7 → metaobjects-0.19.9}/uv.lock +1 -1
- {metaobjects-0.19.7 → metaobjects-0.19.9}/.gitignore +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/LICENSE +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/README.md +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/hatch_build.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/__init__.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/agent_context/__init__.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/agent_context/scaffold.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/apidocs/__init__.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/apidocs/api_model.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/apidocs/naming.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/apidocs/paths.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/apidocs/renderer.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/attr_class_map.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/codegen/KNOWN_GAPS.md +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/codegen/__init__.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/codegen/config.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/codegen/constants.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/codegen/extract_schema_emitter.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/codegen/format.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/codegen/fr010_field_mapping.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/codegen/generator.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/codegen/generator_registry.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/codegen/generators/__init__.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/codegen/generators/entity_model.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/codegen/generators/filter_allowlist_generator.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/codegen/generators/fr019_shared_enum.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/codegen/generators/m2m_codegen.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/codegen/generators/router_generator.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/codegen/generators/template_generator.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/codegen/generators/tph_plan.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/codegen/instance_artifacts.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/codegen/output_format_spec_emitter.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/codegen/overwrite_policy.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/codegen/runner.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/codegen/runtime/__init__.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/codegen/runtime/filter_parser.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/codegen/template_codegen/__init__.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/codegen/template_codegen/output_pattern.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/codegen/template_codegen/template_data.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/codegen/template_codegen/template_spec.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/datatype.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/documentation/__init__.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/documentation/doc_constants.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/documentation/doc_provider.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/documentation/doc_schema.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/errors.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/loader/__init__.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/loader/merge.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/loader/meta_data_loader.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/loader/registered_validation.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/loader/sources/__init__.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/loader/sources/directory_source.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/loader/sources/file_source.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/loader/sources/meta_data_source.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/loader/sources/uri_source.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/loader/validate_discriminator.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/loader/validate_field_readonly.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/loader/validate_source_escapes.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/loader/validate_source_parameter_ref.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/loader/validate_source_physical_names.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/loader/validation_passes.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/__init__.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/core/__init__.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/core/attr/__init__.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/core/attr/attr_constants.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/core/attr/meta_attr.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/core/field/__init__.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/core/field/meta_field.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/core/identity/__init__.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/core/identity/identity_constants.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/core/identity/meta_identity.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/core/index/__init__.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/core/index/index_constants.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/core/index/meta_index.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/core/object/__init__.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/core/object/meta_object.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/core/object/meta_object_aware.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/core/object/object_class_registry.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/core/object/object_constants.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/core/object/object_extract.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/core/object/value_object.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/core/relationship/__init__.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/core/relationship/derive_m2m_fields.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/core/relationship/meta_relationship.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/core/relationship/relationship_constants.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/core/validator/__init__.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/core/validator/validator_constants.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/meta_data.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/meta_root.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/persistence/__init__.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/persistence/db/__init__.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/persistence/db/db_constants.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/persistence/db/db_provider.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/persistence/origin/__init__.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/persistence/origin/meta_origin.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/persistence/origin/origin_constants.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/persistence/source/__init__.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/persistence/source/meta_source.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/persistence/source/source_constants.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/presentation/__init__.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/presentation/layout/__init__.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/presentation/layout/layout_constants.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/presentation/layout/meta_layout.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/presentation/ui/__init__.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/presentation/ui/ui_provider.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/presentation/view/__init__.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/presentation/view/meta_view.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/presentation/view/view_constants.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/provider_extends.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/template/__init__.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/template/meta_template.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/template/prompt_provider.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/meta/template/template_constants.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/naming_refs.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/parser.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/parser_yaml.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/provider.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/py.typed +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/registry.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/registry_manifest.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/render/__init__.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/render/email_document.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/render/escapers.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/render/extract/KNOWN_GAPS.md +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/render/extract/__init__.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/render/extract/coerce.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/render/extract/extract.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/render/extract/extract_map.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/render/extract/json_forgiving_reader.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/render/extract/locate.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/render/extract/normalize.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/render/extract/strip.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/render/extract/types.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/render/extract/xml_forgiving_reader.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/render/filesystem_provider.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/render/prompt/__init__.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/render/prompt/output_format_renderer.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/render/prompt/output_format_spec.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/render/prompt/prompt_field.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/render/prompt/prompt_overrides.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/render/prompt/prompt_style.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/render/renderer.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/render/verify.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/runtime/__init__.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/runtime/llm_recorder.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/runtime/n2m_resolver.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/runtime/object_manager.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/runtime/tph.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/serializer_json.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/shared/__init__.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/shared/base_types.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/shared/separators.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/shared/structural.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/source/__init__.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/source/error_source.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/source/json_path.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/source/semantic_diff.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/source/yaml_positions.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/spec_metamodel/__init__.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/spec_metamodel/attr.json +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/spec_metamodel/db.json +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/spec_metamodel/documentation.json +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/spec_metamodel/identity.json +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/spec_metamodel/index.json +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/spec_metamodel/layout.json +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/spec_metamodel/object.json +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/spec_metamodel/origin.json +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/spec_metamodel/prompt.json +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/spec_metamodel/relationship.json +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/spec_metamodel/source.json +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/spec_metamodel/template.json +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/spec_metamodel/ui-web.json +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/spec_metamodel/ui.json +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/spec_metamodel/validator.json +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/spec_metamodel/view.json +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/super_resolve.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/validation_types.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/yaml_desugar.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/__init__.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/__init__.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/golden/extends/expected/BaseEntity.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/golden/extends/expected/Program.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/golden/extends/meta.json +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/golden/nested-array/expected/AuthorBrief.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/golden/nested-array/expected/PostBrief.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/golden/nested-array/meta.json +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/golden/scalars/expected/Metric.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/golden/scalars/expected/Report.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/golden/scalars/meta.json +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/golden/vanilla/expected/Subscriber.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/golden/vanilla/meta.json +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_abstract_conformance.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_api_docs_builder.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_api_docs_paths.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_cli.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_cli_providers.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_cli_registry.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_cli_staleness_nudge.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_cli_verify_strict.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_constants_config.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_entity_model.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_enum_conformance.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_extends_abstract_field_inheritance.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_extractor_generator.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_filter_allowlist_generator.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_format.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_fr010_nested_object_prompt.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_fr010_output_codegen.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_fr019_shared_provided_conformance.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_generator.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_generator_extension_seams.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_golden.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_inherit_without_restate_gate.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_inheritance_conformance.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_instance_artifacts.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_m2m_codegen.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_origin_nullability.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_output_parser_generator.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_overwrite_policy.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_projection_compile.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_render_helper_conformance.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_reverse_finders.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_router_autoset.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_router_generator.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_runner.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_template_data.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_template_generator.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_template_output_pattern.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_template_scope_helpers.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_template_scope_walk.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_template_spec.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_tph_codegen.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_trace_helper_generator.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_type_map.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/codegen/test_write_through.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/conformance/__init__.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/conformance/capabilities.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/conformance/conformance-expected-failures.json +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/conformance/conformance_adapter.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/conformance/corpus.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/conformance/expected_failures.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/conformance/fixture_discovery.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/conformance/navigator.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/conformance/test_api_docs_cross_port_conformance.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/conformance/test_conformance.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/conformance/test_extract_conformance.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/conformance/test_extract_object_verdict.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/conformance/test_fr010_loader_attrs.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/conformance/test_fr011_attrs.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/conformance/test_generator_registry_conformance.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/conformance/test_object_model_conformance.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/conformance/test_provider_composition_conformance.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/conformance/test_registry_conformance.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/conformance/test_runner_hardfail.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/conformance/test_spec_metamodel_embed.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/conformance/test_strict_attr_load.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/conformance/test_template_codegen_conformance.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/conformance/test_template_generator_conformance.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/conformance/test_yaml_conformance.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/conformance/yaml-conformance-expected-failures.json +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/integration/__init__.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/integration/api_contract_assertions.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/integration/api_contract_jsonb_server.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/integration/api_contract_m2m_server.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/integration/api_contract_server.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/integration/generated_jsonb_app.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/integration/generated_m2m_app.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/integration/generated_router_app.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/integration/generated_tph_app.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/integration/meta_ai_trace.yaml +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/integration/normalization.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/integration/postgres_container.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/integration/query_runner.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/integration/scenarios.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/integration/test_api_contract.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/integration/test_api_contract_generated.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/integration/test_api_contract_jsonb.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/integration/test_api_contract_m2m.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/integration/test_api_contract_m2m_generated.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/integration/test_api_contract_tph_generated.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/integration/test_generated_router_uuid_pk.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/integration/test_llm_call_trace.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/integration/test_normalization.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/integration/test_query_scenarios.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/integration/test_runtime_return_types.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/open_closed_proof_test.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/render/__init__.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/render/extract/__init__.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/render/extract/test_coerce.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/render/extract/test_extract.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/render/extract/test_extract_map.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/render/extract/test_json_forgiving_reader.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/render/extract/test_locate.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/render/extract/test_model.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/render/extract/test_normalize.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/render/extract/test_strip.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/render/extract/test_xml_forgiving_reader.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/render/prompt/__init__.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/render/prompt/test_output_format_renderer.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/render/test_email_document.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/render/test_filesystem_provider.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/render/test_output_format_renderer_nested.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/render/test_output_prompt_conformance.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/render/test_render_conformance.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/render/test_render_max_chars.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/render/test_verify.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/render/test_verify_conformance.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/source/__init__.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/source/test_fr5c_merge_attribution.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/source/test_fr5d_reference_resolution.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/source/test_fr5e_database_source_shape.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/source/test_json_path.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/source/test_semantic_diff.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/source/test_source_on_node.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/source/test_yaml_positions.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/test_api_docs_accuracy.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/__init__.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_agent_context_staleness.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_capabilities.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_common_attrs.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_core_types.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_effective_package.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_errors.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_field_enum.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_field_map_validation.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_field_uuid_dbcolumntype.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_fr016_source_name_and_kind_aliases.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_index_lookup.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_llm_recorder.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_loader.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_loader_bom.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_loader_class.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_merge.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_meta_attr.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_meta_data.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_meta_source.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_module_shortcuts.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_n2m_resolver.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_n2m_resolver_inherited.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_object_manager_autoset_stamping.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_object_manager_uuid_coercion.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_object_manager_write_through.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_one_primary_source.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_parser.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_parser_yaml.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_provider.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_provider_extension.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_registry.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_registry_completeness.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_registry_extend.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_registry_sealed.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_relationship_referential_actions.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_resolution_key.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_runtime_resolution_key_binding.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_serializer.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_shared_constants.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_smoke.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_source_escapes.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_sources.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_strict_child_placement.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_super_resolve.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_template_toolcall.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_template_wrong_subtype_attrs.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_validation_attr_schema.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_validation_filter_values.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_validation_origin_195.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_validation_origin_paths.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_validation_sort_field.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_validation_warnings.py +0 -0
- {metaobjects-0.19.7 → metaobjects-0.19.9}/tests/unit/test_write_coercion_arrays.py +0 -0
- {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.
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
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
|
{metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/codegen/extract_delegate_emitter.py
RENAMED
|
@@ -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
|
|
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.
|
|
42
|
+
from metaobjects.naming_refs import resolve_object_ref
|
|
35
43
|
from metaobjects.shared.separators import PACKAGE_SEP
|
|
36
44
|
|
|
37
45
|
|
|
38
|
-
def
|
|
39
|
-
"""The
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
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.
|
|
54
|
-
|
|
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
|
-
|
|
59
|
-
|
|
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
|
|
74
|
-
|
|
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_<
|
|
79
|
-
|
|
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
|
|
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
|
-
|
|
165
|
+
key = cur.resolution_key()
|
|
166
|
+
if key in seen:
|
|
140
167
|
continue
|
|
141
|
-
seen.add(
|
|
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.
|
|
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
|
-
``<
|
|
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(
|
|
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"
|
|
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,
|
|
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_<
|
|
210
|
-
deduped). The ROOT mapper is overridden to the template-derived
|
|
211
|
-
``root_mirror`` so it returns the canonically-named root
|
|
212
|
-
|
|
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}))"
|
{metaobjects-0.19.7 → metaobjects-0.19.9}/src/metaobjects/codegen/generators/extractor_generator.py
RENAMED
|
@@ -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
|
|
63
|
-
"""The
|
|
64
|
-
|
|
65
|
-
the
|
|
66
|
-
|
|
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
|
-
|
|
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_<
|
|
73
|
-
|
|
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(
|
|
123
|
-
|
|
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
|
-
|
|
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 ``<
|
|
180
|
-
#
|
|
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.
|
|
185
|
-
|
|
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_<
|
|
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
|
-
|
|
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
|