metaobjects 0.19.2__tar.gz → 0.19.3__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.2 → metaobjects-0.19.3}/PKG-INFO +1 -1
- {metaobjects-0.19.2 → metaobjects-0.19.3}/pyproject.toml +1 -1
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/codegen/generators/payload_vo_generator.py +196 -34
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/errors.py +3 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/codegen/test_payload_vo_generator.py +89 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/codegen/test_render_helper_conformance.py +43 -1
- {metaobjects-0.19.2 → metaobjects-0.19.3}/.gitignore +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/LICENSE +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/README.md +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/hatch_build.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/__init__.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/agent_context/__init__.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/agent_context/scaffold.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/apidocs/__init__.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/apidocs/api_model.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/apidocs/builder.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/apidocs/naming.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/apidocs/paths.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/apidocs/renderer.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/attr_class_map.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/cli.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/codegen/KNOWN_GAPS.md +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/codegen/__init__.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/codegen/config.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/codegen/constants.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/codegen/extract_delegate_emitter.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/codegen/extract_schema_emitter.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/codegen/format.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/codegen/fr010_field_mapping.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/codegen/generator.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/codegen/generator_registry.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/codegen/generators/__init__.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/codegen/generators/entity_model.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/codegen/generators/extractor_generator.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/codegen/generators/filter_allowlist_generator.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/codegen/generators/fr019_shared_enum.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/codegen/generators/m2m_codegen.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/codegen/generators/output_parser_generator.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/codegen/generators/output_prompt_generator.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/codegen/generators/render_helper_generator.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/codegen/generators/router_generator.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/codegen/generators/template_generator.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/codegen/generators/tph_plan.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/codegen/generators/trace_helper_generator.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/codegen/instance_artifacts.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/codegen/output_format_spec_emitter.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/codegen/overwrite_policy.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/codegen/runner.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/codegen/runtime/__init__.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/codegen/runtime/filter_parser.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/codegen/template_codegen/__init__.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/codegen/template_codegen/output_pattern.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/codegen/template_codegen/template_data.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/codegen/template_codegen/template_spec.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/codegen/type_map.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/core_types.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/datatype.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/documentation/__init__.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/documentation/doc_constants.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/documentation/doc_provider.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/documentation/doc_schema.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/loader/__init__.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/loader/merge.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/loader/meta_data_loader.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/loader/registered_validation.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/loader/sources/__init__.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/loader/sources/directory_source.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/loader/sources/file_source.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/loader/sources/meta_data_source.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/loader/sources/uri_source.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/loader/validate_discriminator.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/loader/validate_field_readonly.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/loader/validate_source_escapes.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/loader/validate_source_parameter_ref.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/loader/validate_source_physical_names.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/loader/validation_passes.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/meta/__init__.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/meta/core/__init__.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/meta/core/attr/__init__.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/meta/core/attr/attr_constants.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/meta/core/attr/meta_attr.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/meta/core/field/__init__.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/meta/core/field/field_constants.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/meta/core/field/meta_field.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/meta/core/identity/__init__.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/meta/core/identity/identity_constants.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/meta/core/identity/meta_identity.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/meta/core/index/__init__.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/meta/core/index/index_constants.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/meta/core/index/meta_index.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/meta/core/object/__init__.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/meta/core/object/meta_object.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/meta/core/object/meta_object_aware.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/meta/core/object/object_class_registry.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/meta/core/object/object_constants.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/meta/core/object/object_extract.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/meta/core/object/value_object.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/meta/core/relationship/__init__.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/meta/core/relationship/derive_m2m_fields.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/meta/core/relationship/meta_relationship.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/meta/core/relationship/relationship_constants.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/meta/core/validator/__init__.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/meta/core/validator/validator_constants.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/meta/meta_data.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/meta/meta_root.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/meta/persistence/__init__.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/meta/persistence/db/__init__.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/meta/persistence/db/db_constants.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/meta/persistence/db/db_provider.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/meta/persistence/origin/__init__.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/meta/persistence/origin/meta_origin.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/meta/persistence/origin/origin_constants.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/meta/persistence/source/__init__.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/meta/persistence/source/meta_source.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/meta/persistence/source/source_constants.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/meta/presentation/__init__.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/meta/presentation/layout/__init__.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/meta/presentation/layout/layout_constants.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/meta/presentation/layout/meta_layout.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/meta/presentation/ui/__init__.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/meta/presentation/ui/ui_provider.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/meta/presentation/view/__init__.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/meta/presentation/view/meta_view.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/meta/presentation/view/view_constants.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/meta/provider_extends.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/meta/template/__init__.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/meta/template/meta_template.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/meta/template/prompt_provider.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/meta/template/template_constants.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/naming_refs.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/parser.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/parser_yaml.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/provider.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/py.typed +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/registry.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/registry_manifest.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/render/__init__.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/render/email_document.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/render/escapers.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/render/extract/KNOWN_GAPS.md +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/render/extract/__init__.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/render/extract/coerce.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/render/extract/extract.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/render/extract/extract_map.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/render/extract/json_forgiving_reader.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/render/extract/locate.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/render/extract/normalize.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/render/extract/strip.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/render/extract/types.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/render/extract/xml_forgiving_reader.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/render/filesystem_provider.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/render/prompt/__init__.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/render/prompt/output_format_renderer.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/render/prompt/output_format_spec.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/render/prompt/prompt_field.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/render/prompt/prompt_overrides.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/render/prompt/prompt_style.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/render/renderer.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/render/verify.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/runtime/__init__.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/runtime/llm_recorder.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/runtime/n2m_resolver.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/runtime/object_manager.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/runtime/tph.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/serializer_json.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/shared/__init__.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/shared/base_types.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/shared/separators.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/shared/structural.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/source/__init__.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/source/error_source.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/source/json_path.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/source/semantic_diff.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/source/yaml_positions.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/spec_metamodel/__init__.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/spec_metamodel/attr.json +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/spec_metamodel/db.json +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/spec_metamodel/documentation.json +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/spec_metamodel/field.json +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/spec_metamodel/identity.json +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/spec_metamodel/index.json +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/spec_metamodel/layout.json +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/spec_metamodel/object.json +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/spec_metamodel/origin.json +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/spec_metamodel/prompt.json +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/spec_metamodel/relationship.json +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/spec_metamodel/source.json +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/spec_metamodel/template.json +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/spec_metamodel/ui-web.json +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/spec_metamodel/ui.json +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/spec_metamodel/validator.json +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/spec_metamodel/view.json +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/super_resolve.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/validation_types.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/yaml_desugar.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/__init__.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/codegen/__init__.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/codegen/golden/extends/expected/BaseEntity.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/codegen/golden/extends/expected/Program.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/codegen/golden/extends/meta.json +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/codegen/golden/nested-array/expected/AuthorBrief.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/codegen/golden/nested-array/expected/PostBrief.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/codegen/golden/nested-array/meta.json +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/codegen/golden/scalars/expected/Metric.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/codegen/golden/scalars/expected/Report.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/codegen/golden/scalars/meta.json +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/codegen/golden/vanilla/expected/Subscriber.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/codegen/golden/vanilla/meta.json +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/codegen/test_abstract_conformance.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/codegen/test_api_docs_builder.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/codegen/test_api_docs_paths.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/codegen/test_cli.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/codegen/test_cli_providers.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/codegen/test_cli_registry.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/codegen/test_cli_staleness_nudge.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/codegen/test_cli_verify_strict.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/codegen/test_cli_verify_subverbs.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/codegen/test_constants_config.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/codegen/test_entity_model.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/codegen/test_enum_conformance.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/codegen/test_extends_abstract_field_inheritance.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/codegen/test_extractor_generator.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/codegen/test_filter_allowlist_generator.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/codegen/test_format.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/codegen/test_fr010_nested_object_prompt.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/codegen/test_fr010_output_codegen.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/codegen/test_fr019_shared_provided_conformance.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/codegen/test_generator.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/codegen/test_generator_extension_seams.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/codegen/test_golden.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/codegen/test_inherit_without_restate_gate.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/codegen/test_inheritance_conformance.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/codegen/test_instance_artifacts.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/codegen/test_m2m_codegen.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/codegen/test_origin_nullability.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/codegen/test_output_parser_generator.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/codegen/test_overwrite_policy.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/codegen/test_projection_compile.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/codegen/test_render_helper_generator.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/codegen/test_reverse_finders.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/codegen/test_router_generator.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/codegen/test_runner.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/codegen/test_template_data.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/codegen/test_template_generator.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/codegen/test_template_output_pattern.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/codegen/test_template_scope_helpers.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/codegen/test_template_scope_walk.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/codegen/test_template_spec.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/codegen/test_tph_codegen.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/codegen/test_trace_helper_generator.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/codegen/test_type_map.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/codegen/test_validation_conformance.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/codegen/test_write_through.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/conformance/__init__.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/conformance/capabilities.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/conformance/conformance-expected-failures.json +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/conformance/conformance_adapter.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/conformance/corpus.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/conformance/expected_failures.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/conformance/fixture_discovery.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/conformance/navigator.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/conformance/test_api_docs_cross_port_conformance.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/conformance/test_conformance.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/conformance/test_extract_conformance.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/conformance/test_extract_object_verdict.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/conformance/test_fr010_loader_attrs.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/conformance/test_fr011_attrs.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/conformance/test_generator_registry_conformance.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/conformance/test_object_model_conformance.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/conformance/test_provider_composition_conformance.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/conformance/test_registry_conformance.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/conformance/test_runner_hardfail.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/conformance/test_spec_metamodel_embed.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/conformance/test_strict_attr_load.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/conformance/test_template_codegen_conformance.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/conformance/test_template_generator_conformance.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/conformance/test_yaml_conformance.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/conformance/yaml-conformance-expected-failures.json +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/integration/__init__.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/integration/api_contract_assertions.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/integration/api_contract_jsonb_server.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/integration/api_contract_m2m_server.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/integration/api_contract_server.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/integration/generated_jsonb_app.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/integration/generated_m2m_app.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/integration/generated_router_app.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/integration/generated_tph_app.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/integration/meta_ai_trace.yaml +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/integration/normalization.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/integration/postgres_container.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/integration/query_runner.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/integration/scenarios.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/integration/test_api_contract.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/integration/test_api_contract_generated.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/integration/test_api_contract_jsonb.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/integration/test_api_contract_m2m.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/integration/test_api_contract_m2m_generated.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/integration/test_api_contract_tph_generated.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/integration/test_generated_router_uuid_pk.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/integration/test_llm_call_trace.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/integration/test_normalization.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/integration/test_query_scenarios.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/integration/test_runtime_return_types.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/open_closed_proof_test.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/render/__init__.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/render/extract/__init__.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/render/extract/test_coerce.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/render/extract/test_extract.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/render/extract/test_extract_map.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/render/extract/test_json_forgiving_reader.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/render/extract/test_locate.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/render/extract/test_model.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/render/extract/test_normalize.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/render/extract/test_strip.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/render/extract/test_xml_forgiving_reader.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/render/prompt/__init__.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/render/prompt/test_output_format_renderer.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/render/test_email_document.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/render/test_filesystem_provider.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/render/test_output_format_renderer_nested.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/render/test_output_prompt_conformance.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/render/test_render_conformance.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/render/test_render_max_chars.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/render/test_verify.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/render/test_verify_conformance.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/source/__init__.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/source/test_fr5c_merge_attribution.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/source/test_fr5d_reference_resolution.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/source/test_fr5e_database_source_shape.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/source/test_json_path.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/source/test_semantic_diff.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/source/test_source_on_node.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/source/test_yaml_positions.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/test_api_docs_accuracy.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/unit/__init__.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/unit/test_agent_context_staleness.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/unit/test_capabilities.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/unit/test_common_attrs.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/unit/test_core_types.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/unit/test_effective_package.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/unit/test_errors.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/unit/test_field_enum.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/unit/test_field_map_validation.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/unit/test_field_uuid_dbcolumntype.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/unit/test_fr016_source_name_and_kind_aliases.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/unit/test_index_lookup.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/unit/test_llm_recorder.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/unit/test_loader.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/unit/test_loader_bom.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/unit/test_loader_class.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/unit/test_merge.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/unit/test_meta_attr.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/unit/test_meta_data.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/unit/test_meta_source.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/unit/test_module_shortcuts.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/unit/test_n2m_resolver.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/unit/test_n2m_resolver_inherited.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/unit/test_object_manager_autoset_stamping.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/unit/test_object_manager_uuid_coercion.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/unit/test_object_manager_write_through.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/unit/test_one_primary_source.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/unit/test_parser.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/unit/test_parser_yaml.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/unit/test_provider.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/unit/test_provider_extension.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/unit/test_registry.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/unit/test_registry_completeness.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/unit/test_registry_extend.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/unit/test_registry_sealed.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/unit/test_relationship_referential_actions.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/unit/test_resolution_key.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/unit/test_runtime_resolution_key_binding.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/unit/test_serializer.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/unit/test_shared_constants.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/unit/test_smoke.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/unit/test_source_escapes.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/unit/test_sources.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/unit/test_strict_child_placement.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/unit/test_super_resolve.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/unit/test_template_toolcall.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/unit/test_template_wrong_subtype_attrs.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/unit/test_validation_attr_schema.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/unit/test_validation_filter_values.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/unit/test_validation_origin_195.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/unit/test_validation_origin_paths.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/unit/test_validation_sort_field.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/unit/test_validation_warnings.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/unit/test_write_coercion_arrays.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/tests/unit/test_yaml_desugar.py +0 -0
- {metaobjects-0.19.2 → metaobjects-0.19.3}/uv.lock +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: metaobjects
|
|
3
|
-
Version: 0.19.
|
|
3
|
+
Version: 0.19.3
|
|
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.3"
|
|
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"
|
{metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/codegen/generators/payload_vo_generator.py
RENAMED
|
@@ -69,6 +69,13 @@ from metaobjects.shared.separators import PACKAGE_SEP
|
|
|
69
69
|
|
|
70
70
|
_GENERATOR_NAME = "payload-vo-generator"
|
|
71
71
|
|
|
72
|
+
# ADR-0044 backstop error code — a codegen-time (not loader) error, peer of the
|
|
73
|
+
# render tier's ERR_VAR_NOT_ON_PAYLOAD. Declared LOCALLY here for the same reason
|
|
74
|
+
# the TS reference (codegen-ts/src/payload-codegen.ts) declares it locally rather
|
|
75
|
+
# than in the shared cross-port ledger: promoting it to the ledger is coordinated
|
|
76
|
+
# with the Java/Kotlin follow-up so no port reddens on a code it doesn't yet emit.
|
|
77
|
+
ERR_PAYLOAD_NAME_COLLISION = "ERR_PAYLOAD_NAME_COLLISION"
|
|
78
|
+
|
|
72
79
|
|
|
73
80
|
# ---------------------------------------------------------------------------
|
|
74
81
|
# Naming helpers (snake_case mirrors the router/output-parser local helpers).
|
|
@@ -193,13 +200,17 @@ def _resolve_object_field_type(
|
|
|
193
200
|
field: MetaField,
|
|
194
201
|
root: MetaData,
|
|
195
202
|
nested_emit_queue: list[tuple[MetaObject, str]],
|
|
196
|
-
|
|
203
|
+
emitted_nested_keys: set[str],
|
|
204
|
+
name_map: dict[str, str],
|
|
197
205
|
) -> tuple[str, set[str]]:
|
|
198
206
|
"""A plain ``field.object`` (``@objectRef``, no origin child) — resolve to the
|
|
199
|
-
nested
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
207
|
+
nested payload class (single) or ``list[...]`` (array). The class name comes
|
|
208
|
+
from the ADR-0044 *name_map* (bare ``<Short>Payload`` when unique in the module
|
|
209
|
+
closure, package-qualified on a cross-package short-name collision). The target
|
|
210
|
+
VO is scheduled for in-file emission, deduped by ``resolution_key()`` (NOT
|
|
211
|
+
``fqn()``, which returns the bare name and would collapse two same-short-name
|
|
212
|
+
VOs from different packages into one). Falls back to the bare type-map form when
|
|
213
|
+
the ``@objectRef`` can't be resolved (defensive — loader validation gates it)."""
|
|
203
214
|
ref = field.attrs().get(fc.FIELD_ATTR_OBJECT_REF)
|
|
204
215
|
if not isinstance(ref, str) or not ref:
|
|
205
216
|
return _fallback_type(field)
|
|
@@ -211,12 +222,14 @@ def _resolve_object_field_type(
|
|
|
211
222
|
# both loaded trees (file_default_package) and programmatic trees (root package).
|
|
212
223
|
referrer_pkg = _pkg_of(field.parent) if field.parent is not None else ""
|
|
213
224
|
target = resolve_object_ref(root, ref, referrer_pkg)
|
|
214
|
-
if target
|
|
225
|
+
if not isinstance(target, MetaObject): # narrows MetaData|None -> MetaObject
|
|
215
226
|
return _fallback_type(field)
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
227
|
+
target_key = target.resolution_key()
|
|
228
|
+
# name_map was populated by the ADR-0044 closure walk (pass 1/2), which visits
|
|
229
|
+
# the identical targets; the fallback guards a defensive gap only.
|
|
230
|
+
nested_class = name_map.get(target_key) or payload_class_name(target.name)
|
|
231
|
+
if target_key not in emitted_nested_keys:
|
|
232
|
+
emitted_nested_keys.add(target_key)
|
|
220
233
|
nested_emit_queue.append((target, nested_class))
|
|
221
234
|
if type_map.field_is_array(field):
|
|
222
235
|
return f"list[{nested_class}]", set()
|
|
@@ -345,16 +358,20 @@ def _resolve_collection_type(
|
|
|
345
358
|
root: MetaData,
|
|
346
359
|
fallback: MetaField,
|
|
347
360
|
nested_emit_queue: list[tuple[MetaObject, str]],
|
|
348
|
-
|
|
361
|
+
emitted_nested_keys: set[str],
|
|
362
|
+
name_map: dict[str, str],
|
|
349
363
|
) -> tuple[str, set[str]]:
|
|
350
364
|
"""``origin.collection @via "Parent.rel"`` — walk Parent's relationship to
|
|
351
|
-
its ``@objectRef`` target, schedule a nested
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
365
|
+
its ``@objectRef`` target, schedule a nested payload class for in-file
|
|
366
|
+
emission, return ``list[<NestedClass>]``. The class name comes from the
|
|
367
|
+
ADR-0044 *name_map* (bare when unique in the module closure, package-qualified
|
|
368
|
+
on a cross-package short-name collision).
|
|
369
|
+
|
|
370
|
+
Dedupe is per-file via *emitted_nested_keys*, keyed by ``resolution_key()`` —
|
|
371
|
+
if the same target is referenced by two fields in the same payload module,
|
|
372
|
+
only one nested class is emitted; two same-short-name targets in DIFFERENT
|
|
373
|
+
packages are NOT collapsed (each keeps its own key + qualified name).
|
|
374
|
+
Cross-file dedupe would leave forward-references dangling (module docstring)."""
|
|
358
375
|
via = origin.attr(ORIGIN_ATTR_VIA) # ADR-0039 sanctioned own: origin.* never inherits (ADR-0029)
|
|
359
376
|
if not isinstance(via, str) or not via:
|
|
360
377
|
return _fallback_type(fallback)
|
|
@@ -374,11 +391,10 @@ def _resolve_collection_type(
|
|
|
374
391
|
target = _resolve_object_by_short_or_fqn(root, target_ref)
|
|
375
392
|
if target is None:
|
|
376
393
|
return _fallback_type(fallback)
|
|
377
|
-
|
|
378
|
-
nested_class = payload_class_name(target.name)
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
emitted_nested_fqns.add(target_fqn)
|
|
394
|
+
target_key = target.resolution_key()
|
|
395
|
+
nested_class = name_map.get(target_key) or payload_class_name(target.name)
|
|
396
|
+
if target_key not in emitted_nested_keys:
|
|
397
|
+
emitted_nested_keys.add(target_key)
|
|
382
398
|
nested_emit_queue.append((target, nested_class))
|
|
383
399
|
return f"list[{nested_class}]", set()
|
|
384
400
|
|
|
@@ -393,8 +409,9 @@ def _resolve_field_type(
|
|
|
393
409
|
field: MetaField,
|
|
394
410
|
root: MetaData,
|
|
395
411
|
nested_emit_queue: list[tuple[MetaObject, str]],
|
|
396
|
-
|
|
412
|
+
emitted_nested_keys: set[str],
|
|
397
413
|
enum_aliases: dict[str, str],
|
|
414
|
+
name_map: dict[str, str],
|
|
398
415
|
) -> tuple[str, set[str]]:
|
|
399
416
|
"""Resolve the Python annotation for one payload-VO field, honoring any
|
|
400
417
|
``origin.*`` child. Falls back to ``type_map.py_type_for`` when none.
|
|
@@ -415,7 +432,7 @@ def _resolve_field_type(
|
|
|
415
432
|
# reference an undefined bare entity name (Pydantic "not fully defined").
|
|
416
433
|
if field.sub_type == fc.FIELD_SUBTYPE_OBJECT:
|
|
417
434
|
return _resolve_object_field_type(
|
|
418
|
-
field, root, nested_emit_queue,
|
|
435
|
+
field, root, nested_emit_queue, emitted_nested_keys, name_map
|
|
419
436
|
)
|
|
420
437
|
# A ``field.enum`` → Literal[...] (inline) or a named module alias (shared).
|
|
421
438
|
enum_type = _enum_field_type(field, enum_aliases)
|
|
@@ -429,11 +446,142 @@ def _resolve_field_type(
|
|
|
429
446
|
return _resolve_aggregate_type(origin, root, field)
|
|
430
447
|
if origin.sub_type == "collection":
|
|
431
448
|
return _resolve_collection_type(
|
|
432
|
-
origin, root, field, nested_emit_queue,
|
|
449
|
+
origin, root, field, nested_emit_queue, emitted_nested_keys, name_map
|
|
433
450
|
)
|
|
434
451
|
return _fallback_type(field)
|
|
435
452
|
|
|
436
453
|
|
|
454
|
+
# ---------------------------------------------------------------------------
|
|
455
|
+
# ADR-0044 — collision-scoped nested-payload naming (three-pass pipeline).
|
|
456
|
+
#
|
|
457
|
+
# A payload module is a SINGLE self-contained file, so its `@objectRef` /
|
|
458
|
+
# `origin.collection` closure is the collision domain (ADR-0044's "closure of the
|
|
459
|
+
# payload root(s) emitted into one artifact"). Two value-objects sharing a bare
|
|
460
|
+
# short name across packages (`acme::alpha::Note` + `acme::beta::Note`, both
|
|
461
|
+
# reachable from one payload) must emit as DISTINCT classes — the pre-ADR-0044
|
|
462
|
+
# code deduped by `fqn()` (which returns the BARE name here), collapsing them to
|
|
463
|
+
# one class, last-wins, silently dropping the second shape. Pass 1 collects the
|
|
464
|
+
# closure keyed by `resolution_key()` (the true package-qualified FQN); pass 2
|
|
465
|
+
# assigns names as a pure function of the closure (bare when unique, package-
|
|
466
|
+
# qualified on collision, hard fail on a still-colliding derived name); pass 3
|
|
467
|
+
# (the existing emit path) uses the name map for both declaration and reference.
|
|
468
|
+
# ---------------------------------------------------------------------------
|
|
469
|
+
|
|
470
|
+
|
|
471
|
+
def _package_qualified_name(pkg: str, short_name: str) -> str:
|
|
472
|
+
"""ADR-0044 — PascalCase each ``::``-segment of *pkg*, concatenate, append the
|
|
473
|
+
bare *short_name* (``acme::alpha`` + ``Note`` → ``AcmeAlphaNote``). A root-level
|
|
474
|
+
(empty-package) node keeps its bare short name — the loader's own-package
|
|
475
|
+
uniqueness already precludes two root-level VOs sharing a name, so this can't
|
|
476
|
+
silently under-qualify."""
|
|
477
|
+
if pkg == "":
|
|
478
|
+
return short_name
|
|
479
|
+
return "".join(_pascal(seg) for seg in pkg.split(PACKAGE_SEP)) + short_name
|
|
480
|
+
|
|
481
|
+
|
|
482
|
+
def _nested_target_of(field: MetaField, root: MetaData) -> MetaObject | None:
|
|
483
|
+
"""The nested-payload target VO a *field* contributes to the module closure,
|
|
484
|
+
or ``None`` when it contributes no nested class. Mirrors the resolution in
|
|
485
|
+
:func:`_resolve_object_field_type` (a plain ``field.object`` ``@objectRef``)
|
|
486
|
+
and :func:`_resolve_collection_type` (``origin.collection`` ``@via``) EXACTLY,
|
|
487
|
+
so the ADR-0044 closure walk and the emission walk agree on the target set.
|
|
488
|
+
``origin.passthrough`` / ``origin.aggregate`` yield scalar types (no nested
|
|
489
|
+
class) and so contribute nothing."""
|
|
490
|
+
origin = _find_origin_child(field)
|
|
491
|
+
if origin is None:
|
|
492
|
+
if field.sub_type != fc.FIELD_SUBTYPE_OBJECT:
|
|
493
|
+
return None
|
|
494
|
+
ref = field.attrs().get(fc.FIELD_ATTR_OBJECT_REF)
|
|
495
|
+
if not isinstance(ref, str) or not ref:
|
|
496
|
+
return None
|
|
497
|
+
referrer_pkg = _pkg_of(field.parent) if field.parent is not None else ""
|
|
498
|
+
target = resolve_object_ref(root, ref, referrer_pkg)
|
|
499
|
+
return target if isinstance(target, MetaObject) else None
|
|
500
|
+
if origin.sub_type == "collection":
|
|
501
|
+
via = origin.attr(ORIGIN_ATTR_VIA) # ADR-0039 sanctioned own: origin.* never inherits
|
|
502
|
+
if not isinstance(via, str) or not via:
|
|
503
|
+
return None
|
|
504
|
+
parts = _split_dotted_ref(via)
|
|
505
|
+
if parts is None:
|
|
506
|
+
return None
|
|
507
|
+
parent_name, rel_name = parts
|
|
508
|
+
parent = _resolve_object_by_short_or_fqn(root, parent_name)
|
|
509
|
+
if parent is None:
|
|
510
|
+
return None
|
|
511
|
+
rel = _find_relationship_on(parent, rel_name)
|
|
512
|
+
if rel is None:
|
|
513
|
+
return None
|
|
514
|
+
target_ref = rel.object_ref()
|
|
515
|
+
if not target_ref:
|
|
516
|
+
return None
|
|
517
|
+
return _resolve_object_by_short_or_fqn(root, target_ref)
|
|
518
|
+
return None
|
|
519
|
+
|
|
520
|
+
|
|
521
|
+
def _collect_nested_closure(
|
|
522
|
+
root: MetaData,
|
|
523
|
+
payload_vo: MetaObject,
|
|
524
|
+
closure: dict[str, MetaObject],
|
|
525
|
+
seen: set[str],
|
|
526
|
+
) -> None:
|
|
527
|
+
"""ADR-0044 pass 1 — walk *payload_vo*'s transitive nested-payload closure,
|
|
528
|
+
collecting each target VO keyed by ``resolution_key()`` (never ``fqn()`` —
|
|
529
|
+
which returns the bare name and would collapse a cross-package short-name
|
|
530
|
+
collision). *seen* is seeded with the primary payload VO's key so the primary
|
|
531
|
+
(which is named after the TEMPLATE, outside the VO-short-name collision
|
|
532
|
+
domain) is never treated as a nested class, and doubles as the cycle guard."""
|
|
533
|
+
for field in payload_vo.fields():
|
|
534
|
+
if not isinstance(field, MetaField):
|
|
535
|
+
continue
|
|
536
|
+
target = _nested_target_of(field, root)
|
|
537
|
+
if target is None:
|
|
538
|
+
continue
|
|
539
|
+
key = target.resolution_key()
|
|
540
|
+
if key in seen:
|
|
541
|
+
continue
|
|
542
|
+
seen.add(key)
|
|
543
|
+
closure[key] = target
|
|
544
|
+
_collect_nested_closure(root, target, closure, seen)
|
|
545
|
+
|
|
546
|
+
|
|
547
|
+
def _assign_nested_names(closure: dict[str, MetaObject]) -> dict[str, str]:
|
|
548
|
+
"""ADR-0044 pass 2 — ``resolution_key()`` → emitted class name. A PURE function
|
|
549
|
+
of the closure's ``(key, short-name, package)`` triples, never of traversal
|
|
550
|
+
order: a bare short name unique in the closure emits ``<Short>Payload``
|
|
551
|
+
(byte-identical to pre-ADR-0044 output); a short-name collision emits EVERY
|
|
552
|
+
member under its package-qualified derived name
|
|
553
|
+
(``<PkgSegmentsPascal><Short>Payload``). If two distinct keys still derive the
|
|
554
|
+
same name, fail loud with ``ERR_PAYLOAD_NAME_COLLISION`` — never silently
|
|
555
|
+
collide a second time."""
|
|
556
|
+
by_short: dict[str, list[str]] = {}
|
|
557
|
+
for key, node in closure.items():
|
|
558
|
+
by_short.setdefault(node.name, []).append(key)
|
|
559
|
+
|
|
560
|
+
name_map: dict[str, str] = {}
|
|
561
|
+
for short, keys in by_short.items():
|
|
562
|
+
if len(keys) == 1:
|
|
563
|
+
name_map[keys[0]] = payload_class_name(short)
|
|
564
|
+
continue
|
|
565
|
+
for key in keys:
|
|
566
|
+
node = closure[key]
|
|
567
|
+
name_map[key] = payload_class_name(_package_qualified_name(_pkg_of(node), short))
|
|
568
|
+
|
|
569
|
+
# Backstop — sorted by key so both the emptiness of the colliding set and the
|
|
570
|
+
# pair named in the message are a pure function of the closure, not dict order.
|
|
571
|
+
owner: dict[str, str] = {}
|
|
572
|
+
for key in sorted(name_map):
|
|
573
|
+
emitted = name_map[key]
|
|
574
|
+
existing = owner.get(emitted)
|
|
575
|
+
if existing is not None and existing != key:
|
|
576
|
+
raise ValueError(
|
|
577
|
+
f"{ERR_PAYLOAD_NAME_COLLISION}: payload record name collision: "
|
|
578
|
+
f'"{emitted}" derives from both "{existing}" and "{key}" — rename one '
|
|
579
|
+
"value-object or move it to a package that derives a distinct name"
|
|
580
|
+
)
|
|
581
|
+
owner[emitted] = key
|
|
582
|
+
return name_map
|
|
583
|
+
|
|
584
|
+
|
|
437
585
|
# ---------------------------------------------------------------------------
|
|
438
586
|
# Class-block emission.
|
|
439
587
|
# ---------------------------------------------------------------------------
|
|
@@ -444,10 +592,11 @@ def _emit_payload_class(
|
|
|
444
592
|
payload_vo: MetaObject,
|
|
445
593
|
root: MetaData,
|
|
446
594
|
nested_emit_queue: list[tuple[MetaObject, str]],
|
|
447
|
-
|
|
595
|
+
emitted_nested_keys: set[str],
|
|
448
596
|
extra_imports: set[str],
|
|
449
597
|
enum_aliases: dict[str, str],
|
|
450
598
|
docstring: str,
|
|
599
|
+
name_map: dict[str, str],
|
|
451
600
|
) -> list[str]:
|
|
452
601
|
"""Build the source lines for one Pydantic ``BaseModel`` subclass."""
|
|
453
602
|
lines: list[str] = [f"class {class_name}(BaseModel):", f' """{docstring}"""']
|
|
@@ -456,7 +605,7 @@ def _emit_payload_class(
|
|
|
456
605
|
if not isinstance(field, MetaField):
|
|
457
606
|
continue
|
|
458
607
|
annotation, imports = _resolve_field_type(
|
|
459
|
-
field, root, nested_emit_queue,
|
|
608
|
+
field, root, nested_emit_queue, emitted_nested_keys, enum_aliases, name_map
|
|
460
609
|
)
|
|
461
610
|
extra_imports.update(imports)
|
|
462
611
|
# Optionality mirrors the cross-port (TS) payload-codegen: a ``@required``
|
|
@@ -515,9 +664,18 @@ def render_payload_vo(
|
|
|
515
664
|
if payload is None:
|
|
516
665
|
return None
|
|
517
666
|
|
|
667
|
+
# ADR-0044 pass 1/2 — the collision domain is this module's nested-payload
|
|
668
|
+
# closure. Seed `seen` with the primary VO's key so the primary (named after
|
|
669
|
+
# the TEMPLATE, not the VO) stays out of the VO-short-name collision domain.
|
|
670
|
+
closure: dict[str, MetaObject] = {}
|
|
671
|
+
_collect_nested_closure(root, payload, closure, {payload.resolution_key()})
|
|
672
|
+
name_map = _assign_nested_names(closure)
|
|
673
|
+
|
|
518
674
|
# Per-file dedupe set: scoped to this single render call so each emitted
|
|
519
|
-
# module is self-contained (no cross-template forward references).
|
|
520
|
-
|
|
675
|
+
# module is self-contained (no cross-template forward references). Keyed by
|
|
676
|
+
# ``resolution_key()`` (see _resolve_object_field_type) so two same-short-name
|
|
677
|
+
# VOs from different packages both emit.
|
|
678
|
+
emitted_nested_keys: set[str] = set()
|
|
521
679
|
class_name = payload_class_name(template.name)
|
|
522
680
|
extra_imports: set[str] = set()
|
|
523
681
|
nested_emit_queue: list[tuple[MetaObject, str]] = []
|
|
@@ -541,13 +699,14 @@ def render_payload_vo(
|
|
|
541
699
|
payload_vo=payload,
|
|
542
700
|
root=root,
|
|
543
701
|
nested_emit_queue=nested_emit_queue,
|
|
544
|
-
|
|
702
|
+
emitted_nested_keys=emitted_nested_keys,
|
|
545
703
|
extra_imports=extra_imports,
|
|
546
704
|
enum_aliases=enum_aliases,
|
|
547
705
|
docstring=(
|
|
548
706
|
f"GENERATED payload for template ``{template.name}``.\n\n"
|
|
549
707
|
f" Field shape derived from the ``{payload.name}`` object.value."
|
|
550
708
|
),
|
|
709
|
+
name_map=name_map,
|
|
551
710
|
)
|
|
552
711
|
if strict_extras:
|
|
553
712
|
primary_block = _with_strict_extras(primary_block)
|
|
@@ -564,12 +723,13 @@ def render_payload_vo(
|
|
|
564
723
|
payload_vo=target,
|
|
565
724
|
root=root,
|
|
566
725
|
nested_emit_queue=nested_emit_queue,
|
|
567
|
-
|
|
726
|
+
emitted_nested_keys=emitted_nested_keys,
|
|
568
727
|
extra_imports=extra_imports,
|
|
569
728
|
enum_aliases=enum_aliases,
|
|
570
729
|
docstring=(
|
|
571
730
|
f"GENERATED nested payload for collection target ``{target.name}``."
|
|
572
731
|
),
|
|
732
|
+
name_map=name_map,
|
|
573
733
|
)
|
|
574
734
|
if strict_extras:
|
|
575
735
|
block = _with_strict_extras(block)
|
|
@@ -650,10 +810,11 @@ class PayloadVoGenerator:
|
|
|
650
810
|
payload_vo: MetaObject,
|
|
651
811
|
root: MetaData,
|
|
652
812
|
nested_emit_queue: list[tuple[MetaObject, str]],
|
|
653
|
-
|
|
813
|
+
emitted_nested_keys: set[str],
|
|
654
814
|
extra_imports: set[str],
|
|
655
815
|
enum_aliases: dict[str, str],
|
|
656
816
|
docstring: str,
|
|
817
|
+
name_map: dict[str, str],
|
|
657
818
|
) -> list[str]:
|
|
658
819
|
"""EXTENSION SEAM — the source lines for one Pydantic ``BaseModel`` subclass
|
|
659
820
|
(primary OR a nested collection target). Defaults to the module-level
|
|
@@ -664,10 +825,11 @@ class PayloadVoGenerator:
|
|
|
664
825
|
payload_vo,
|
|
665
826
|
root,
|
|
666
827
|
nested_emit_queue,
|
|
667
|
-
|
|
828
|
+
emitted_nested_keys,
|
|
668
829
|
extra_imports,
|
|
669
830
|
enum_aliases,
|
|
670
831
|
docstring,
|
|
832
|
+
name_map,
|
|
671
833
|
)
|
|
672
834
|
|
|
673
835
|
def _render_module(self, template: MetaTemplate, root: MetaData) -> str | None:
|
|
@@ -133,6 +133,9 @@ class ErrorCode(str, Enum):
|
|
|
133
133
|
ERR_PARTIAL_UNRESOLVED = "ERR_PARTIAL_UNRESOLVED"
|
|
134
134
|
ERR_REQUIRED_SLOT_UNUSED = "ERR_REQUIRED_SLOT_UNUSED"
|
|
135
135
|
ERR_VAR_NOT_ON_PAYLOAD = "ERR_VAR_NOT_ON_PAYLOAD"
|
|
136
|
+
# Codegen (ADR-0044): two value-object FQNs in one payload artifact derive the same
|
|
137
|
+
# emitted record name even after package-qualification. Peer of ERR_VAR_NOT_ON_PAYLOAD.
|
|
138
|
+
ERR_PAYLOAD_NAME_COLLISION = "ERR_PAYLOAD_NAME_COLLISION"
|
|
136
139
|
ERR_OUTPUT_TAG_MISSING = "ERR_OUTPUT_TAG_MISSING"
|
|
137
140
|
# SP-H Unit9 — @filterable: true on a field subtype with no filter-operator
|
|
138
141
|
# band (e.g. field.object). Would silently generate an empty-ops filter.
|
|
@@ -8,10 +8,13 @@ same target).
|
|
|
8
8
|
"""
|
|
9
9
|
from __future__ import annotations
|
|
10
10
|
|
|
11
|
+
import pytest
|
|
12
|
+
|
|
11
13
|
import metaobjects.core_types # noqa: F401 — side-effect: registers attr classes
|
|
12
14
|
from metaobjects.codegen.config import GenConfig
|
|
13
15
|
from metaobjects.codegen.generator import GenContext
|
|
14
16
|
from metaobjects.codegen.generators.payload_vo_generator import (
|
|
17
|
+
ERR_PAYLOAD_NAME_COLLISION,
|
|
15
18
|
PayloadVoGenerator,
|
|
16
19
|
payload_class_name,
|
|
17
20
|
payload_module_name,
|
|
@@ -428,6 +431,92 @@ def test_plain_object_field_strips_fqn_to_bare_nested_payload() -> None:
|
|
|
428
431
|
assert "::" not in code
|
|
429
432
|
|
|
430
433
|
|
|
434
|
+
def test_cross_package_short_name_collision_qualifies_both_nested_classes() -> None:
|
|
435
|
+
"""ADR-0044 — two ``object.value`` ``Note``s in different packages, both reachable
|
|
436
|
+
from one payload by FQN ``@objectRef``, emit as TWO distinct package-qualified
|
|
437
|
+
classes (``AcmeAlphaNotePayload`` / ``AcmeBetaNotePayload``) — never one shadowed
|
|
438
|
+
``NotePayload`` that drops the second shape. The un-colliding ``Digest`` primary
|
|
439
|
+
stays bare (template-named)."""
|
|
440
|
+
alpha = _value_object("Note", [_field("alphaText", fc.FIELD_SUBTYPE_STRING)], package="acme::alpha")
|
|
441
|
+
beta = _value_object("Note", [_field("betaText", fc.FIELD_SUBTYPE_STRING)], package="acme::beta")
|
|
442
|
+
digest = _value_object(
|
|
443
|
+
"Digest",
|
|
444
|
+
[
|
|
445
|
+
_object_field("fromAlpha", "acme::alpha::Note"),
|
|
446
|
+
_object_field("fromBeta", "acme::beta::Note"),
|
|
447
|
+
],
|
|
448
|
+
package="acme::app",
|
|
449
|
+
)
|
|
450
|
+
tmpl = _template("DigestOut", "Digest")
|
|
451
|
+
root = _root([alpha, beta, digest, tmpl])
|
|
452
|
+
out = render_payload_vo(tmpl, root)
|
|
453
|
+
assert out is not None
|
|
454
|
+
assert "class AcmeAlphaNotePayload(BaseModel):" in out
|
|
455
|
+
assert "class AcmeBetaNotePayload(BaseModel):" in out
|
|
456
|
+
assert "class NotePayload(BaseModel):" not in out
|
|
457
|
+
assert "fromAlpha: AcmeAlphaNotePayload | None = None" in out
|
|
458
|
+
assert "fromBeta: AcmeBetaNotePayload | None = None" in out
|
|
459
|
+
assert '__all__ = ["DigestOutPayload", "AcmeAlphaNotePayload", "AcmeBetaNotePayload"]' in out
|
|
460
|
+
|
|
461
|
+
|
|
462
|
+
def test_nested_of_nested_collision_qualifies_across_depths() -> None:
|
|
463
|
+
"""ADR-0044 — the collision domain is the WHOLE transitive closure, not one
|
|
464
|
+
depth. A ``Note`` reached at depth 2 (via ``Outer.inner``) collides with a
|
|
465
|
+
``Note`` reached at depth 1; both qualify (``AcmeBetaNotePayload`` /
|
|
466
|
+
``AcmeGammaNotePayload``) while the un-colliding intermediate ``Outer`` stays
|
|
467
|
+
bare. Guards the recursive `_collect_nested_closure` walk."""
|
|
468
|
+
beta_note = _value_object("Note", [_field("betaText", fc.FIELD_SUBTYPE_STRING)], package="acme::beta")
|
|
469
|
+
gamma_note = _value_object("Note", [_field("gammaText", fc.FIELD_SUBTYPE_STRING)], package="acme::gamma")
|
|
470
|
+
outer = _value_object(
|
|
471
|
+
"Outer", [_object_field("inner", "acme::beta::Note")], package="acme::alpha"
|
|
472
|
+
)
|
|
473
|
+
digest = _value_object(
|
|
474
|
+
"Digest",
|
|
475
|
+
[
|
|
476
|
+
_object_field("fromOuter", "acme::alpha::Outer"),
|
|
477
|
+
_object_field("fromGamma", "acme::gamma::Note"),
|
|
478
|
+
],
|
|
479
|
+
package="acme::app",
|
|
480
|
+
)
|
|
481
|
+
tmpl = _template("DigestOut", "Digest")
|
|
482
|
+
root = _root([beta_note, gamma_note, outer, digest, tmpl])
|
|
483
|
+
out = render_payload_vo(tmpl, root)
|
|
484
|
+
assert out is not None
|
|
485
|
+
assert "class OuterPayload(BaseModel):" in out # unique → bare
|
|
486
|
+
assert "class AcmeBetaNotePayload(BaseModel):" in out # depth-2 collision member
|
|
487
|
+
assert "class AcmeGammaNotePayload(BaseModel):" in out # depth-1 collision member
|
|
488
|
+
assert "class NotePayload(BaseModel):" not in out
|
|
489
|
+
assert "inner: AcmeBetaNotePayload | None = None" in out
|
|
490
|
+
assert "fromGamma: AcmeGammaNotePayload | None = None" in out
|
|
491
|
+
|
|
492
|
+
|
|
493
|
+
def test_derived_name_still_colliding_fails_loud() -> None:
|
|
494
|
+
"""ADR-0044 §4 backstop — two DISTINCT package FQNs whose package-qualified derived
|
|
495
|
+
names still collide (``acme::alpha`` and ``acmeAlpha`` both PascalCase-fold to
|
|
496
|
+
``AcmeAlpha``) must fail loud with ``ERR_PAYLOAD_NAME_COLLISION``, never silently
|
|
497
|
+
emit one class twice."""
|
|
498
|
+
a = _value_object("Note", [_field("a", fc.FIELD_SUBTYPE_STRING)], package="acme::alpha")
|
|
499
|
+
b = _value_object("Note", [_field("b", fc.FIELD_SUBTYPE_STRING)], package="acmeAlpha")
|
|
500
|
+
digest = _value_object(
|
|
501
|
+
"Digest",
|
|
502
|
+
[
|
|
503
|
+
_object_field("fromA", "acme::alpha::Note"),
|
|
504
|
+
_object_field("fromB", "acmeAlpha::Note"),
|
|
505
|
+
],
|
|
506
|
+
package="acme::app",
|
|
507
|
+
)
|
|
508
|
+
tmpl = _template("DigestOut", "Digest")
|
|
509
|
+
root = _root([a, b, digest, tmpl])
|
|
510
|
+
with pytest.raises(ValueError) as ei:
|
|
511
|
+
render_payload_vo(tmpl, root)
|
|
512
|
+
msg = str(ei.value)
|
|
513
|
+
assert ERR_PAYLOAD_NAME_COLLISION in msg
|
|
514
|
+
assert "AcmeAlphaNotePayload" in msg
|
|
515
|
+
# Both source FQNs are named so the author can find and rename one.
|
|
516
|
+
assert "acme::alpha::Note" in msg
|
|
517
|
+
assert "acmeAlpha::Note" in msg
|
|
518
|
+
|
|
519
|
+
|
|
431
520
|
# ---------------------------------------------------------------------------
|
|
432
521
|
# Resolution edge cases.
|
|
433
522
|
# ---------------------------------------------------------------------------
|
|
@@ -30,8 +30,8 @@ import metaobjects.core_types # noqa: F401 — side-effect: registers attr cla
|
|
|
30
30
|
from metaobjects import InMemoryStringSource, MetaDataLoader
|
|
31
31
|
from metaobjects.codegen.config import GenConfig
|
|
32
32
|
from metaobjects.codegen.generator import GenContext
|
|
33
|
+
from metaobjects.codegen.generators.payload_vo_generator import PayloadVoGenerator
|
|
33
34
|
from metaobjects.codegen.generators.render_helper_generator import RenderHelperGenerator
|
|
34
|
-
from metaobjects.meta.template import template_constants as tc
|
|
35
35
|
from metaobjects.render.email_document import EmailDocument
|
|
36
36
|
from metaobjects.render.filesystem_provider import FilesystemProvider
|
|
37
37
|
|
|
@@ -194,6 +194,48 @@ def test_document_digest_doc_resolves_fqn_nested_object_ref_across_collision(tmp
|
|
|
194
194
|
assert out == "Alpha=AA Beta=BB"
|
|
195
195
|
|
|
196
196
|
|
|
197
|
+
def test_payload_vo_collision_emits_distinct_package_qualified_classes(tmp_path) -> None:
|
|
198
|
+
"""ADR-0044 — the two colliding ``Note`` VOs (``acme::alpha`` / ``acme::beta``)
|
|
199
|
+
reachable from one payload module MUST emit as TWO distinct classes under their
|
|
200
|
+
package-qualified derived names (``AcmeAlphaNotePayload`` / ``AcmeBetaNotePayload``),
|
|
201
|
+
never one shadowed ``NotePayload`` (which dropped ``betaText`` and typed BOTH
|
|
202
|
+
fields against the alpha shape). The payload record is GENERATOR-emitted and
|
|
203
|
+
exercised by construction — the corpus README prohibits hand-authoring it."""
|
|
204
|
+
dir_root = CORPUS / "xpkg-collision"
|
|
205
|
+
root = _load_root_from_files(
|
|
206
|
+
dir_root / "meta.alpha.json",
|
|
207
|
+
dir_root / "meta.beta.json",
|
|
208
|
+
dir_root / "meta.app.json",
|
|
209
|
+
)
|
|
210
|
+
files = [f for f in PayloadVoGenerator().generate(_ctx(root))
|
|
211
|
+
if f.path == "digest_doc_payload.py"]
|
|
212
|
+
assert len(files) == 1
|
|
213
|
+
src = files[0].content
|
|
214
|
+
# Two DISTINCT package-qualified classes — and never the shadowed bare name.
|
|
215
|
+
assert "class AcmeAlphaNotePayload(BaseModel):" in src
|
|
216
|
+
assert "class AcmeBetaNotePayload(BaseModel):" in src
|
|
217
|
+
assert "class NotePayload(BaseModel):" not in src
|
|
218
|
+
# Each field binds to its OWN package's shape.
|
|
219
|
+
assert "fromAlpha: AcmeAlphaNotePayload | None = None" in src
|
|
220
|
+
assert "fromBeta: AcmeBetaNotePayload | None = None" in src
|
|
221
|
+
|
|
222
|
+
_materialize_and_import(files, tmp_path)
|
|
223
|
+
mod = import_module("_rh_conf_pkg.digest_doc_payload")
|
|
224
|
+
# The classes are real and DISTINCT: alpha carries alphaText, beta betaText.
|
|
225
|
+
alpha = mod.AcmeAlphaNotePayload(alphaText="AA")
|
|
226
|
+
beta = mod.AcmeBetaNotePayload(betaText="BB")
|
|
227
|
+
assert "alphaText" in mod.AcmeAlphaNotePayload.model_fields
|
|
228
|
+
assert "betaText" not in mod.AcmeAlphaNotePayload.model_fields
|
|
229
|
+
assert "betaText" in mod.AcmeBetaNotePayload.model_fields
|
|
230
|
+
assert "alphaText" not in mod.AcmeBetaNotePayload.model_fields
|
|
231
|
+
# No shadowed bare class leaked into the module namespace.
|
|
232
|
+
assert not hasattr(mod, "NotePayload")
|
|
233
|
+
# The primary payload composes the two distinct shapes.
|
|
234
|
+
digest = mod.DigestDocPayload(fromAlpha=alpha, fromBeta=beta)
|
|
235
|
+
assert digest.fromAlpha.alphaText == "AA"
|
|
236
|
+
assert digest.fromBeta.betaText == "BB"
|
|
237
|
+
|
|
238
|
+
|
|
197
239
|
# ---------------------------------------------------------------------------
|
|
198
240
|
# drift/ → codegen FAILS (ValueError) with ERR_VAR_NOT_ON_PAYLOAD.
|
|
199
241
|
# ---------------------------------------------------------------------------
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/codegen/extract_delegate_emitter.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/codegen/generators/entity_model.py
RENAMED
|
File without changes
|
{metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/codegen/generators/extractor_generator.py
RENAMED
|
File without changes
|
|
File without changes
|
{metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/codegen/generators/fr019_shared_enum.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/codegen/generators/router_generator.py
RENAMED
|
File without changes
|
{metaobjects-0.19.2 → metaobjects-0.19.3}/src/metaobjects/codegen/generators/template_generator.py
RENAMED
|
File without changes
|