metaobjects 0.22.1__tar.gz → 0.23.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {metaobjects-0.22.1 → metaobjects-0.23.1}/PKG-INFO +1 -1
- {metaobjects-0.22.1 → metaobjects-0.23.1}/pyproject.toml +1 -1
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/codegen/generators/fr019_shared_enum.py +15 -6
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/core_types.py +44 -8
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/meta/core/requirement/meta_requirement.py +46 -9
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/meta/core/requirement/requirement_constants.py +31 -0
- metaobjects-0.23.1/src/metaobjects/render/payload_accessors.py +134 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/render/renderer.py +5 -1
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/render/verify.py +11 -1
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/spec_metamodel/documentation.json +4 -4
- metaobjects-0.23.1/src/metaobjects/spec_metamodel/requirement.json +209 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/integration/postgres_container.py +84 -14
- {metaobjects-0.22.1 → metaobjects-0.23.1}/uv.lock +1 -1
- metaobjects-0.22.1/src/metaobjects/spec_metamodel/requirement.json +0 -140
- {metaobjects-0.22.1 → metaobjects-0.23.1}/.gitignore +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/LICENSE +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/README.md +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/hatch_build.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/__init__.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/agent_context/__init__.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/agent_context/scaffold.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/apidocs/__init__.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/apidocs/api_model.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/apidocs/builder.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/apidocs/naming.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/apidocs/paths.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/apidocs/renderer.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/attr_class_map.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/cli.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/codegen/KNOWN_GAPS.md +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/codegen/__init__.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/codegen/collision_names.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/codegen/config.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/codegen/constants.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/codegen/extract_delegate_emitter.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/codegen/extract_schema_emitter.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/codegen/format.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/codegen/fr010_field_mapping.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/codegen/generator.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/codegen/generator_registry.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/codegen/generators/__init__.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/codegen/generators/entity_model.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/codegen/generators/extractor_generator.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/codegen/generators/filter_allowlist_generator.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/codegen/generators/m2m_codegen.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/codegen/generators/output_parser_generator.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/codegen/generators/output_prompt_generator.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/codegen/generators/payload_vo_generator.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/codegen/generators/render_helper_generator.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/codegen/generators/router_generator.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/codegen/generators/template_generator.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/codegen/generators/tph_plan.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/codegen/generators/trace_helper_generator.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/codegen/instance_artifacts.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/codegen/metaobjects-config.schema.json +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/codegen/output_format_spec_emitter.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/codegen/overwrite_policy.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/codegen/project_config.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/codegen/runner.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/codegen/runtime/__init__.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/codegen/runtime/filter_parser.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/codegen/template_codegen/__init__.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/codegen/template_codegen/output_pattern.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/codegen/template_codegen/template_data.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/codegen/template_codegen/template_spec.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/codegen/type_map.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/datatype.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/documentation/__init__.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/documentation/doc_constants.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/documentation/doc_provider.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/documentation/doc_schema.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/errors.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/loader/__init__.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/loader/merge.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/loader/meta_data_loader.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/loader/registered_validation.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/loader/sources/__init__.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/loader/sources/directory_source.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/loader/sources/file_source.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/loader/sources/meta_data_source.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/loader/sources/uri_source.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/loader/validate_discriminator.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/loader/validate_enum_normalize_ambiguity.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/loader/validate_field_readonly.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/loader/validate_source_escapes.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/loader/validate_source_parameter_ref.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/loader/validate_source_physical_names.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/loader/validation_passes.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/meta/__init__.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/meta/core/__init__.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/meta/core/attr/__init__.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/meta/core/attr/attr_constants.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/meta/core/attr/meta_attr.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/meta/core/field/__init__.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/meta/core/field/field_constants.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/meta/core/field/meta_field.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/meta/core/identity/__init__.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/meta/core/identity/identity_constants.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/meta/core/identity/meta_identity.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/meta/core/index/__init__.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/meta/core/index/index_constants.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/meta/core/index/meta_index.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/meta/core/object/__init__.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/meta/core/object/meta_object.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/meta/core/object/meta_object_aware.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/meta/core/object/object_class_registry.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/meta/core/object/object_constants.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/meta/core/object/object_extract.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/meta/core/object/value_object.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/meta/core/relationship/__init__.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/meta/core/relationship/derive_m2m_fields.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/meta/core/relationship/meta_relationship.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/meta/core/relationship/relationship_constants.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/meta/core/requirement/__init__.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/meta/core/validator/__init__.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/meta/core/validator/validator_constants.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/meta/meta_data.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/meta/meta_root.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/meta/persistence/__init__.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/meta/persistence/db/__init__.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/meta/persistence/db/db_constants.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/meta/persistence/db/db_provider.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/meta/persistence/origin/__init__.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/meta/persistence/origin/meta_origin.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/meta/persistence/origin/origin_constants.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/meta/persistence/source/__init__.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/meta/persistence/source/meta_source.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/meta/persistence/source/source_constants.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/meta/presentation/__init__.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/meta/presentation/layout/__init__.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/meta/presentation/layout/layout_constants.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/meta/presentation/layout/meta_layout.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/meta/presentation/ui/__init__.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/meta/presentation/ui/ui_provider.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/meta/presentation/view/__init__.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/meta/presentation/view/meta_view.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/meta/presentation/view/view_constants.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/meta/provider_extends.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/meta/template/__init__.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/meta/template/meta_template.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/meta/template/prompt_provider.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/meta/template/template_constants.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/naming_refs.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/parser.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/parser_yaml.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/provider.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/py.typed +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/registry.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/registry_manifest.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/render/__init__.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/render/email_document.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/render/escapers.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/render/extract/KNOWN_GAPS.md +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/render/extract/__init__.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/render/extract/coerce.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/render/extract/extract.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/render/extract/extract_map.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/render/extract/json_forgiving_reader.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/render/extract/locate.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/render/extract/normalize.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/render/extract/strip.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/render/extract/types.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/render/extract/xml_forgiving_reader.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/render/filesystem_provider.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/render/prompt/__init__.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/render/prompt/output_format_renderer.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/render/prompt/output_format_spec.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/render/prompt/prompt_field.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/render/prompt/prompt_overrides.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/render/prompt/prompt_style.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/runtime/__init__.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/runtime/llm_recorder.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/runtime/n2m_resolver.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/runtime/object_manager.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/runtime/tph.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/serializer_json.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/shared/__init__.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/shared/base_types.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/shared/separators.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/shared/structural.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/source/__init__.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/source/error_source.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/source/json_path.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/source/semantic_diff.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/source/yaml_positions.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/spec_metamodel/__init__.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/spec_metamodel/attr.json +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/spec_metamodel/db.json +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/spec_metamodel/field.json +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/spec_metamodel/identity.json +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/spec_metamodel/index.json +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/spec_metamodel/layout.json +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/spec_metamodel/object.json +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/spec_metamodel/origin.json +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/spec_metamodel/prompt.json +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/spec_metamodel/relationship.json +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/spec_metamodel/source.json +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/spec_metamodel/template.json +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/spec_metamodel/ui-web.json +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/spec_metamodel/ui.json +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/spec_metamodel/validator.json +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/spec_metamodel/view.json +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/super_resolve.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/validation_types.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/yaml_desugar.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/__init__.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/codegen/__init__.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/codegen/golden/extends/expected/BaseEntity.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/codegen/golden/extends/expected/Program.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/codegen/golden/extends/meta.json +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/codegen/golden/nested-array/expected/AuthorBrief.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/codegen/golden/nested-array/expected/PostBrief.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/codegen/golden/nested-array/meta.json +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/codegen/golden/scalars/expected/Metric.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/codegen/golden/scalars/expected/Report.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/codegen/golden/scalars/meta.json +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/codegen/golden/vanilla/expected/Subscriber.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/codegen/golden/vanilla/meta.json +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/codegen/test_abstract_conformance.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/codegen/test_api_docs_builder.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/codegen/test_api_docs_paths.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/codegen/test_cli.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/codegen/test_cli_config_gen.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/codegen/test_cli_config_verify.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/codegen/test_cli_providers.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/codegen/test_cli_registry.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/codegen/test_cli_staleness_nudge.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/codegen/test_cli_verify_strict.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/codegen/test_cli_verify_subverbs.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/codegen/test_constants_config.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/codegen/test_entity_model.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/codegen/test_enum_conformance.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/codegen/test_extends_abstract_field_inheritance.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/codegen/test_extract_tier_collision.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/codegen/test_extractor_generator.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/codegen/test_filter_allowlist_generator.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/codegen/test_format.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/codegen/test_fr010_nested_object_prompt.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/codegen/test_fr010_output_codegen.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/codegen/test_fr019_shared_provided_conformance.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/codegen/test_generator.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/codegen/test_generator_extension_seams.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/codegen/test_golden.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/codegen/test_inherit_without_restate_gate.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/codegen/test_inheritance_conformance.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/codegen/test_instance_artifacts.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/codegen/test_m2m_codegen.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/codegen/test_origin_nullability.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/codegen/test_output_parser_generator.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/codegen/test_overwrite_policy.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/codegen/test_payload_vo_generator.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/codegen/test_project_config.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/codegen/test_projection_compile.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/codegen/test_render_helper_conformance.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/codegen/test_render_helper_generator.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/codegen/test_reverse_finders.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/codegen/test_router_autoset.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/codegen/test_router_generator.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/codegen/test_runner.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/codegen/test_sourceless_projection.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/codegen/test_template_data.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/codegen/test_template_generator.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/codegen/test_template_output_pattern.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/codegen/test_template_scope_helpers.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/codegen/test_template_scope_walk.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/codegen/test_template_spec.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/codegen/test_tph_codegen.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/codegen/test_trace_helper_generator.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/codegen/test_type_map.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/codegen/test_validation_conformance.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/codegen/test_write_through.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/conformance/__init__.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/conformance/capabilities.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/conformance/conformance-expected-failures.json +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/conformance/conformance_adapter.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/conformance/corpus.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/conformance/expected_failures.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/conformance/fixture_discovery.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/conformance/navigator.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/conformance/test_api_docs_cross_port_conformance.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/conformance/test_conformance.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/conformance/test_extract_conformance.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/conformance/test_extract_object_verdict.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/conformance/test_fr010_loader_attrs.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/conformance/test_fr011_attrs.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/conformance/test_generator_registry_conformance.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/conformance/test_object_model_conformance.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/conformance/test_provider_composition_conformance.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/conformance/test_registry_conformance.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/conformance/test_runner_hardfail.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/conformance/test_spec_metamodel_embed.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/conformance/test_strict_attr_load.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/conformance/test_template_codegen_conformance.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/conformance/test_template_generator_conformance.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/conformance/test_yaml_conformance.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/conformance/yaml-conformance-expected-failures.json +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/integration/__init__.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/integration/api_contract_assertions.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/integration/api_contract_jsonb_server.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/integration/api_contract_m2m_server.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/integration/api_contract_server.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/integration/generated_jsonb_app.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/integration/generated_m2m_app.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/integration/generated_router_app.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/integration/generated_tph_app.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/integration/meta_ai_trace.yaml +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/integration/normalization.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/integration/query_runner.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/integration/scenarios.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/integration/test_api_contract.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/integration/test_api_contract_generated.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/integration/test_api_contract_jsonb.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/integration/test_api_contract_m2m.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/integration/test_api_contract_m2m_generated.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/integration/test_api_contract_tph_generated.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/integration/test_generated_router_uuid_pk.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/integration/test_llm_call_trace.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/integration/test_normalization.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/integration/test_query_scenarios.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/integration/test_runtime_return_types.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/loader/__init__.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/loader/test_enum_extends_values_conflict.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/loader/test_template_payload_target_210.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/open_closed_proof_test.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/render/__init__.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/render/extract/__init__.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/render/extract/test_coerce.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/render/extract/test_extract.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/render/extract/test_extract_map.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/render/extract/test_json_forgiving_reader.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/render/extract/test_locate.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/render/extract/test_model.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/render/extract/test_normalize.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/render/extract/test_strip.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/render/extract/test_xml_forgiving_reader.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/render/prompt/__init__.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/render/prompt/test_output_format_renderer.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/render/test_email_document.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/render/test_filesystem_provider.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/render/test_output_format_renderer_nested.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/render/test_output_prompt_conformance.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/render/test_render_conformance.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/render/test_render_max_chars.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/render/test_verify.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/render/test_verify_conformance.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/source/__init__.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/source/test_fr5c_merge_attribution.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/source/test_fr5d_reference_resolution.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/source/test_fr5e_database_source_shape.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/source/test_json_path.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/source/test_semantic_diff.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/source/test_source_on_node.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/source/test_yaml_positions.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/test_api_docs_accuracy.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/unit/__init__.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/unit/test_agent_context_staleness.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/unit/test_capabilities.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/unit/test_common_attrs.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/unit/test_core_types.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/unit/test_effective_package.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/unit/test_errors.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/unit/test_field_enum.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/unit/test_field_map_validation.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/unit/test_field_uuid_dbcolumntype.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/unit/test_fr016_source_name_and_kind_aliases.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/unit/test_index_lookup.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/unit/test_llm_recorder.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/unit/test_loader.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/unit/test_loader_bom.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/unit/test_loader_class.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/unit/test_merge.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/unit/test_meta_attr.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/unit/test_meta_data.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/unit/test_meta_source.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/unit/test_module_shortcuts.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/unit/test_n2m_resolver.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/unit/test_n2m_resolver_inherited.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/unit/test_object_manager_autoset_stamping.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/unit/test_object_manager_uuid_coercion.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/unit/test_object_manager_write_through.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/unit/test_one_primary_source.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/unit/test_parser.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/unit/test_parser_yaml.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/unit/test_provider.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/unit/test_provider_extension.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/unit/test_registry.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/unit/test_registry_completeness.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/unit/test_registry_extend.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/unit/test_registry_sealed.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/unit/test_relationship_referential_actions.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/unit/test_resolution_key.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/unit/test_runtime_resolution_key_binding.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/unit/test_serializer.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/unit/test_shared_constants.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/unit/test_smoke.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/unit/test_source_escapes.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/unit/test_sources.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/unit/test_strict_child_placement.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/unit/test_super_resolve.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/unit/test_template_toolcall.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/unit/test_template_wrong_subtype_attrs.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/unit/test_validation_attr_schema.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/unit/test_validation_filter_values.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/unit/test_validation_origin_195.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/unit/test_validation_origin_paths.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/unit/test_validation_sort_field.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/unit/test_validation_warnings.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/unit/test_write_coercion_arrays.py +0 -0
- {metaobjects-0.22.1 → metaobjects-0.23.1}/tests/unit/test_yaml_desugar.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: metaobjects
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.23.1
|
|
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.
|
|
3
|
+
version = "0.23.1"
|
|
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.22.1 → metaobjects-0.23.1}/src/metaobjects/codegen/generators/fr019_shared_enum.py
RENAMED
|
@@ -66,12 +66,21 @@ def resolve_shared_enum_decl(field: MetaField) -> MetaData | None:
|
|
|
66
66
|
|
|
67
67
|
|
|
68
68
|
def is_provided(decl: MetaData) -> bool:
|
|
69
|
-
"""
|
|
70
|
-
|
|
71
|
-
ADR-0039
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
69
|
+
"""``@provided`` truth of an enum DECLARATION.
|
|
70
|
+
|
|
71
|
+
ADR-0039 sanctioned own (Python naming inversion: ``attr()`` is the OWN read,
|
|
72
|
+
``get_meta_attr()`` resolves). ``@provided`` is a declaration-layer provenance
|
|
73
|
+
marker — "THIS type is supplied by hand-written/third-party code", like
|
|
74
|
+
``is_abstract`` — and does not flow down an ``extends`` chain.
|
|
75
|
+
|
|
76
|
+
This is only ever called on the resolved declaration (see
|
|
77
|
+
``shared_enum_for_field``), never on the consuming field, so own and resolving
|
|
78
|
+
agree for a plain ``field extends @provided decl``. They diverge on a CHAINED
|
|
79
|
+
declaration (root abstract ``B extends`` root abstract ``@provided A``): a
|
|
80
|
+
resolving read reports B provided and emits a reference to a hand-written ``B``
|
|
81
|
+
the adopter never declared, instead of materializing B. Matches the JVM ports.
|
|
82
|
+
"""
|
|
83
|
+
return decl.attr(fc.FIELD_ATTR_PROVIDED) is True
|
|
75
84
|
|
|
76
85
|
|
|
77
86
|
def _meta_package_of(decl: MetaData) -> str:
|
|
@@ -64,13 +64,16 @@ from .meta.core.object.object_constants import (
|
|
|
64
64
|
from .meta.core.relationship.meta_relationship import MetaRelationship
|
|
65
65
|
from .meta.core.requirement.meta_requirement import MetaRequirement
|
|
66
66
|
from .meta.core.requirement.requirement_constants import (
|
|
67
|
+
REQUIREMENT_ATTR_DISPOSITION,
|
|
67
68
|
REQUIREMENT_ATTR_IMPLEMENTED_BY,
|
|
68
69
|
REQUIREMENT_ATTR_LEVEL,
|
|
69
70
|
REQUIREMENT_ATTR_STATEMENT,
|
|
70
71
|
REQUIREMENT_ATTR_STATUS,
|
|
71
72
|
REQUIREMENT_ATTR_SUPERSEDED_BY,
|
|
73
|
+
REQUIREMENT_ATTR_TRACKED_BY,
|
|
72
74
|
REQUIREMENT_ATTR_VERIFIED_BY,
|
|
73
75
|
REQUIREMENT_ATTR_VIOLATION,
|
|
76
|
+
REQUIREMENT_DISPOSITIONS,
|
|
74
77
|
REQUIREMENT_STATUSES,
|
|
75
78
|
REQUIREMENT_SUBTYPE_ARCHITECTURAL,
|
|
76
79
|
REQUIREMENT_SUBTYPE_FUNCTIONAL,
|
|
@@ -589,6 +592,23 @@ _REQUIREMENT_COMMON_ATTRS = [
|
|
|
589
592
|
required=True,
|
|
590
593
|
allowed_values=REQUIREMENT_STATUSES,
|
|
591
594
|
),
|
|
595
|
+
# What was DECIDED about the outstanding work -- a different question from
|
|
596
|
+
# whether the work is done, which is what @status answers. ABSENT means
|
|
597
|
+
# UNDECIDED, a real state and the one a review exists to find.
|
|
598
|
+
AttrSchema(
|
|
599
|
+
name=REQUIREMENT_ATTR_DISPOSITION,
|
|
600
|
+
value_type=ATTR_SUBTYPE_STRING,
|
|
601
|
+
required=False,
|
|
602
|
+
allowed_values=REQUIREMENT_DISPOSITIONS,
|
|
603
|
+
),
|
|
604
|
+
# Issue/ticket references for outstanding work. Free-form and never resolved:
|
|
605
|
+
# verify has no network, so unlike @verifiedBy nothing here is checked to exist.
|
|
606
|
+
AttrSchema(
|
|
607
|
+
name=REQUIREMENT_ATTR_TRACKED_BY,
|
|
608
|
+
value_type=ATTR_SUBTYPE_STRING,
|
|
609
|
+
required=False,
|
|
610
|
+
is_array=True,
|
|
611
|
+
),
|
|
592
612
|
AttrSchema(name=REQUIREMENT_ATTR_STATEMENT, value_type=ATTR_SUBTYPE_STRING, required=True),
|
|
593
613
|
AttrSchema(name=REQUIREMENT_ATTR_VIOLATION, value_type=ATTR_SUBTYPE_STRING, required=True),
|
|
594
614
|
AttrSchema(
|
|
@@ -597,6 +617,12 @@ _REQUIREMENT_COMMON_ATTRS = [
|
|
|
597
617
|
required=False,
|
|
598
618
|
is_array=True,
|
|
599
619
|
),
|
|
620
|
+
AttrSchema(
|
|
621
|
+
name=REQUIREMENT_ATTR_VERIFIED_BY,
|
|
622
|
+
value_type=ATTR_SUBTYPE_STRING,
|
|
623
|
+
required=False,
|
|
624
|
+
is_array=True,
|
|
625
|
+
),
|
|
600
626
|
AttrSchema(name=REQUIREMENT_ATTR_SUPERSEDED_BY, value_type=ATTR_SUBTYPE_STRING, required=False),
|
|
601
627
|
]
|
|
602
628
|
core_provider.add(
|
|
@@ -605,14 +631,10 @@ core_provider.add(
|
|
|
605
631
|
sub_type=REQUIREMENT_SUBTYPE_FUNCTIONAL,
|
|
606
632
|
factory=MetaRequirement,
|
|
607
633
|
attrs=[
|
|
634
|
+
# REQUIRED on functional: levels are the object-in-focus decomposition
|
|
635
|
+
# and a functional requirement always sits at one.
|
|
608
636
|
AttrSchema(name=REQUIREMENT_ATTR_LEVEL, value_type=ATTR_SUBTYPE_INT, required=True),
|
|
609
637
|
*_REQUIREMENT_COMMON_ATTRS,
|
|
610
|
-
AttrSchema(
|
|
611
|
-
name=REQUIREMENT_ATTR_VERIFIED_BY,
|
|
612
|
-
value_type=ATTR_SUBTYPE_STRING,
|
|
613
|
-
required=False,
|
|
614
|
-
is_array=True,
|
|
615
|
-
),
|
|
616
638
|
],
|
|
617
639
|
child_rules=[
|
|
618
640
|
ChildRule(TYPE_ATTR, "*"),
|
|
@@ -626,8 +648,22 @@ core_provider.add(
|
|
|
626
648
|
type=TYPE_REQUIREMENT,
|
|
627
649
|
sub_type=REQUIREMENT_SUBTYPE_ARCHITECTURAL,
|
|
628
650
|
factory=MetaRequirement,
|
|
629
|
-
attrs=
|
|
630
|
-
|
|
651
|
+
attrs=[
|
|
652
|
+
# OPTIONAL on architectural: absent means a flat, object-independent
|
|
653
|
+
# policy (the original and still the default form); present opts the
|
|
654
|
+
# node into a levelled tree, e.g. a quality taxonomy over the
|
|
655
|
+
# non-functional set. Opt-in precisely so that adding a taxonomy over
|
|
656
|
+
# existing flat policies cannot invalidate them.
|
|
657
|
+
AttrSchema(name=REQUIREMENT_ATTR_LEVEL, value_type=ATTR_SUBTYPE_INT, required=False),
|
|
658
|
+
*_REQUIREMENT_COMMON_ATTRS,
|
|
659
|
+
],
|
|
660
|
+
child_rules=[
|
|
661
|
+
ChildRule(TYPE_ATTR, "*"),
|
|
662
|
+
# BOTH subtypes nest. Declaring this on `functional` only was an
|
|
663
|
+
# omission, not a design: it made an architectural node nestable under
|
|
664
|
+
# a FUNCTIONAL parent but never under another architectural one.
|
|
665
|
+
ChildRule(TYPE_REQUIREMENT, "*"),
|
|
666
|
+
],
|
|
631
667
|
)
|
|
632
668
|
)
|
|
633
669
|
|
{metaobjects-0.22.1 → metaobjects-0.23.1}/src/metaobjects/meta/core/requirement/meta_requirement.py
RENAMED
|
@@ -9,12 +9,16 @@ from __future__ import annotations
|
|
|
9
9
|
|
|
10
10
|
from ...meta_data import MetaData
|
|
11
11
|
from .requirement_constants import (
|
|
12
|
+
REQUIREMENT_ATTR_DISPOSITION,
|
|
12
13
|
REQUIREMENT_ATTR_IMPLEMENTED_BY,
|
|
13
14
|
REQUIREMENT_ATTR_LEVEL,
|
|
14
15
|
REQUIREMENT_ATTR_STATUS,
|
|
16
|
+
REQUIREMENT_ATTR_TRACKED_BY,
|
|
15
17
|
REQUIREMENT_ATTR_VERIFIED_BY,
|
|
16
18
|
REQUIREMENT_LINK_FLOOR_LEVEL,
|
|
19
|
+
REQUIREMENT_STATUS_PLANNED,
|
|
17
20
|
REQUIREMENT_STATUSES_REQUIRING_LIVE_NODES,
|
|
21
|
+
REQUIREMENT_STATUSES_WITH_OUTSTANDING_WORK,
|
|
18
22
|
REQUIREMENT_SUBTYPE_ARCHITECTURAL,
|
|
19
23
|
REQUIREMENT_SUBTYPE_FUNCTIONAL,
|
|
20
24
|
)
|
|
@@ -31,8 +35,9 @@ class MetaRequirement(MetaData):
|
|
|
31
35
|
|
|
32
36
|
def level(self) -> int | None:
|
|
33
37
|
"""ADR-0039: resolving. 1 solution · 2 segment · 3 service · 4 object ·
|
|
34
|
-
5 member.
|
|
35
|
-
object-independent
|
|
38
|
+
5 member. REQUIRED on functional; OPTIONAL on architectural, where absent
|
|
39
|
+
means a flat object-independent policy and present opts the node into a
|
|
40
|
+
levelled tree (e.g. a quality taxonomy over the non-functional set)."""
|
|
36
41
|
v = self.get_meta_attr(REQUIREMENT_ATTR_LEVEL)
|
|
37
42
|
return v if isinstance(v, int) and not isinstance(v, bool) else None
|
|
38
43
|
|
|
@@ -49,19 +54,51 @@ class MetaRequirement(MetaData):
|
|
|
49
54
|
return [str(x) for x in v] if isinstance(v, list) else []
|
|
50
55
|
|
|
51
56
|
def verified_by(self) -> list[str]:
|
|
52
|
-
"""ADR-0039: resolving. Names of
|
|
57
|
+
"""ADR-0039: resolving. Names of tests that ASSERT the behaviour — existence
|
|
58
|
+
evidence only; verify cannot tell whether a named test verifies this."""
|
|
53
59
|
v = self.get_meta_attr(REQUIREMENT_ATTR_VERIFIED_BY)
|
|
54
60
|
return [str(x) for x in v] if isinstance(v, list) else []
|
|
55
61
|
|
|
62
|
+
def disposition(self) -> str | None:
|
|
63
|
+
"""ADR-0039: resolving. What was DECIDED about the outstanding work — a
|
|
64
|
+
different question from whether the work is done, which is what
|
|
65
|
+
``status`` answers. ``None`` means UNDECIDED, a real state and the one a
|
|
66
|
+
review exists to find."""
|
|
67
|
+
v = self.get_meta_attr(REQUIREMENT_ATTR_DISPOSITION)
|
|
68
|
+
return v if isinstance(v, str) else None
|
|
69
|
+
|
|
70
|
+
def tracked_by(self) -> list[str]:
|
|
71
|
+
"""ADR-0039: resolving. Issue/ticket references for outstanding work.
|
|
72
|
+
Free-form and NEVER resolved — verify has no network, so unlike
|
|
73
|
+
``verified_by`` nothing here is checked to exist."""
|
|
74
|
+
v = self.get_meta_attr(REQUIREMENT_ATTR_TRACKED_BY)
|
|
75
|
+
return [str(x) for x in v] if isinstance(v, list) else []
|
|
76
|
+
|
|
77
|
+
def is_planned(self) -> bool:
|
|
78
|
+
"""Intended but not built. Its nodes may legitimately not exist yet, and
|
|
79
|
+
it must NOT count toward object coverage — planning a capability cannot
|
|
80
|
+
be allowed to silence the warning that nothing implements it."""
|
|
81
|
+
return self.status() == REQUIREMENT_STATUS_PLANNED
|
|
82
|
+
|
|
83
|
+
def has_outstanding_work(self) -> bool:
|
|
84
|
+
"""True when there is outstanding work, so a ``disposition`` says
|
|
85
|
+
something."""
|
|
86
|
+
s = self.status()
|
|
87
|
+
return s is not None and s in REQUIREMENT_STATUSES_WITH_OUTSTANDING_WORK
|
|
88
|
+
|
|
56
89
|
def may_reference_model(self) -> bool:
|
|
57
90
|
"""True when this requirement is permitted to reference the model at all.
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
91
|
+
|
|
92
|
+
An UNLEVELLED architectural requirement always may — its claim set is the
|
|
93
|
+
whole point, and that is the original flat form. Once a level is PRESENT
|
|
94
|
+
the node has opted into a tree, and the link floor applies to it exactly
|
|
95
|
+
as it does to a functional one, so an "ISO 25010 Security" grouping node
|
|
96
|
+
cannot quietly start naming entities. Levelling is the opt-in; enforcing
|
|
97
|
+
the floor unconditionally would have broken every existing flat policy."""
|
|
63
98
|
lvl = self.level()
|
|
64
|
-
|
|
99
|
+
if lvl is None:
|
|
100
|
+
return self.is_architectural()
|
|
101
|
+
return lvl >= REQUIREMENT_LINK_FLOOR_LEVEL
|
|
65
102
|
|
|
66
103
|
def requires_live_nodes(self) -> bool:
|
|
67
104
|
"""True when a dangling ``@implementedBy`` is an ERROR rather than
|
|
@@ -26,6 +26,8 @@ REQUIREMENT_SUBTYPES = (
|
|
|
26
26
|
#: 1 solution · 2 segment (app/library) · 3 service · 4 object · 5 member.
|
|
27
27
|
REQUIREMENT_ATTR_LEVEL = "level"
|
|
28
28
|
REQUIREMENT_ATTR_STATUS = "status"
|
|
29
|
+
REQUIREMENT_ATTR_DISPOSITION = "disposition"
|
|
30
|
+
REQUIREMENT_ATTR_TRACKED_BY = "trackedBy"
|
|
29
31
|
REQUIREMENT_ATTR_STATEMENT = "statement"
|
|
30
32
|
REQUIREMENT_ATTR_VIOLATION = "violation"
|
|
31
33
|
REQUIREMENT_ATTR_IMPLEMENTED_BY = "implementedBy"
|
|
@@ -35,12 +37,17 @@ REQUIREMENT_ATTR_SUPERSEDED_BY = "supersededBy"
|
|
|
35
37
|
# ---------------------------------------------------------------------------
|
|
36
38
|
# Status — a closed enum, enforced by the registry via allowed_values.
|
|
37
39
|
# ---------------------------------------------------------------------------
|
|
40
|
+
# Intended but not built. Its references may legitimately dangle, and it never
|
|
41
|
+
# contributes to object coverage -- planning a capability must not silence the
|
|
42
|
+
# warning that nothing implements it.
|
|
43
|
+
REQUIREMENT_STATUS_PLANNED = "planned"
|
|
38
44
|
REQUIREMENT_STATUS_LIVE = "live"
|
|
39
45
|
REQUIREMENT_STATUS_PARTIAL = "partial"
|
|
40
46
|
REQUIREMENT_STATUS_ABANDONED = "abandoned"
|
|
41
47
|
REQUIREMENT_STATUS_SUPERSEDED = "superseded"
|
|
42
48
|
|
|
43
49
|
REQUIREMENT_STATUSES = (
|
|
50
|
+
REQUIREMENT_STATUS_PLANNED,
|
|
44
51
|
REQUIREMENT_STATUS_LIVE,
|
|
45
52
|
REQUIREMENT_STATUS_PARTIAL,
|
|
46
53
|
REQUIREMENT_STATUS_ABANDONED,
|
|
@@ -59,6 +66,30 @@ REQUIREMENT_STATUSES_REQUIRING_LIVE_NODES = (
|
|
|
59
66
|
# ---------------------------------------------------------------------------
|
|
60
67
|
# Levels — organisational above the link floor, model-referencing at or below.
|
|
61
68
|
# ---------------------------------------------------------------------------
|
|
69
|
+
# Statuses with outstanding work, so a @disposition is meaningful on them. On any
|
|
70
|
+
# other status the decision IS the status, and recording a second one can only
|
|
71
|
+
# agree with it or contradict it.
|
|
72
|
+
REQUIREMENT_STATUSES_WITH_OUTSTANDING_WORK = (
|
|
73
|
+
REQUIREMENT_STATUS_PLANNED,
|
|
74
|
+
REQUIREMENT_STATUS_PARTIAL,
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
# ---------------------------------------------------------------------------
|
|
78
|
+
# Disposition -- what was DECIDED about the outstanding work. Orthogonal to
|
|
79
|
+
# status, which says whether the work is done. ABSENT means UNDECIDED, and that
|
|
80
|
+
# is the state a review exists to find; collapsing it into the status enum would
|
|
81
|
+
# make "there is a gap" and "we chose to live with it" the same fact.
|
|
82
|
+
# ---------------------------------------------------------------------------
|
|
83
|
+
|
|
84
|
+
REQUIREMENT_DISPOSITION_ACCEPTED = "accepted"
|
|
85
|
+
REQUIREMENT_DISPOSITION_DEFERRED = "deferred"
|
|
86
|
+
|
|
87
|
+
# Declaration order is contractual -- see REQUIREMENT_STATUSES.
|
|
88
|
+
REQUIREMENT_DISPOSITIONS = (
|
|
89
|
+
REQUIREMENT_DISPOSITION_ACCEPTED,
|
|
90
|
+
REQUIREMENT_DISPOSITION_DEFERRED,
|
|
91
|
+
)
|
|
92
|
+
|
|
62
93
|
REQUIREMENT_LEVEL_SOLUTION = 1
|
|
63
94
|
REQUIREMENT_LEVEL_SEGMENT = 2
|
|
64
95
|
REQUIREMENT_LEVEL_SERVICE = 3
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
"""Derived boolean accessors — ``{{#hasFoo}}`` over a payload field ``foo``.
|
|
2
|
+
|
|
3
|
+
A prompt needs conditional sections ("include the abilities block only when there ARE
|
|
4
|
+
abilities"), and the payload contract answers that with a DERIVED accessor rather than an
|
|
5
|
+
authored boolean field: the author declares ``abilities`` and ``hasAbilities`` follows
|
|
6
|
+
from it. Declaring both would let them disagree.
|
|
7
|
+
|
|
8
|
+
THE RULE IS SHARED ACROSS PORTS ON PURPOSE. The JVM has carried it since 7.7.7
|
|
9
|
+
(``com.metaobjects.render.PayloadAccessors``, emitted onto every generated payload record
|
|
10
|
+
and accepted by its ``Verify``), and its comment says the emitter and the verifier share
|
|
11
|
+
one rule so they "can never drift apart". Python had neither half, so the same template
|
|
12
|
+
verified clean on the JVM and reported drift here — and rendered WRONG rather than
|
|
13
|
+
failing, silently dropping the section. Gated cross-port by the
|
|
14
|
+
``render-derived-has-accessor`` conformance case.
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
19
|
+
import numbers
|
|
20
|
+
from collections.abc import Mapping, Sequence
|
|
21
|
+
from typing import Any
|
|
22
|
+
|
|
23
|
+
__all__ = [
|
|
24
|
+
"HAS_PREFIX",
|
|
25
|
+
"has_accessor_name",
|
|
26
|
+
"capitalize",
|
|
27
|
+
"accessor_value",
|
|
28
|
+
"with_derived_accessors",
|
|
29
|
+
"is_boolean_accessor",
|
|
30
|
+
]
|
|
31
|
+
|
|
32
|
+
#: The ``has`` prefix every derived boolean accessor carries.
|
|
33
|
+
HAS_PREFIX = "has"
|
|
34
|
+
|
|
35
|
+
_MAX_DEPTH = 32
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def capitalize(s: str) -> str:
|
|
39
|
+
"""Capitalize the first character, leaving an already-uppercase one untouched.
|
|
40
|
+
|
|
41
|
+
Deliberately NOT ``str.capitalize()``, which also lowercases the remainder.
|
|
42
|
+
"""
|
|
43
|
+
if not s:
|
|
44
|
+
return s
|
|
45
|
+
if s[0].isupper():
|
|
46
|
+
return s
|
|
47
|
+
return s[0].upper() + s[1:]
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def has_accessor_name(field_name: str) -> str:
|
|
51
|
+
"""``"has" + capitalize(name)`` (``abilities`` → ``hasAbilities``).
|
|
52
|
+
|
|
53
|
+
Byte-identical to the JVM's ``PayloadAccessors.hasAccessorName``.
|
|
54
|
+
"""
|
|
55
|
+
return HAS_PREFIX + capitalize(field_name)
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def accessor_value(value: Any) -> bool | None:
|
|
59
|
+
"""Is ``value`` "present" for the purposes of ``has<Field>``?
|
|
60
|
+
|
|
61
|
+
Mirrors the JVM emitter's per-type bodies exactly: string → non-null and non-blank;
|
|
62
|
+
collection → non-null and non-empty; reference → non-null.
|
|
63
|
+
|
|
64
|
+
Returns ``None`` for numbers and booleans, which the JVM deliberately emits NO
|
|
65
|
+
accessor for — they are always-present scalars, and ``{{#hasCount}}`` over an int is
|
|
66
|
+
drift rather than a conditional. Returning ``None`` (rather than ``False``) keeps that
|
|
67
|
+
distinction: nothing is injected, so the name stays unresolved exactly as it is on a
|
|
68
|
+
generated record with no such method.
|
|
69
|
+
"""
|
|
70
|
+
if value is None:
|
|
71
|
+
return False
|
|
72
|
+
if isinstance(value, str):
|
|
73
|
+
return bool(value.strip())
|
|
74
|
+
# bool before int — bool IS an int in Python, and a boolean field gets no accessor.
|
|
75
|
+
if isinstance(value, numbers.Number):
|
|
76
|
+
return None
|
|
77
|
+
if isinstance(value, Mapping):
|
|
78
|
+
return True
|
|
79
|
+
if isinstance(value, (Sequence, set, frozenset)):
|
|
80
|
+
return len(value) > 0
|
|
81
|
+
return True
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def with_derived_accessors(payload: Any, depth: int = 0) -> Any:
|
|
85
|
+
"""A view over ``payload`` carrying its derived ``has<Field>`` accessors, recursively.
|
|
86
|
+
|
|
87
|
+
NON-MUTATING — the caller's payload is never touched, because a render must not be
|
|
88
|
+
able to change the object it was handed. An AUTHORED key always wins: if a payload
|
|
89
|
+
genuinely carries ``hasFoo``, that value is kept rather than shadowed.
|
|
90
|
+
|
|
91
|
+
Recursion follows Mustache's own scoping: every nested mapping and every sequence
|
|
92
|
+
ELEMENT becomes a context in its own right, so a section over ``abilities`` sees the
|
|
93
|
+
accessors of the ability it is currently iterating.
|
|
94
|
+
"""
|
|
95
|
+
if depth > _MAX_DEPTH:
|
|
96
|
+
return payload # pathological graph; render is not a validator
|
|
97
|
+
if isinstance(payload, Mapping):
|
|
98
|
+
out: dict[str, Any] = {
|
|
99
|
+
k: with_derived_accessors(v, depth + 1) for k, v in payload.items()
|
|
100
|
+
}
|
|
101
|
+
for k, v in payload.items():
|
|
102
|
+
if not isinstance(k, str):
|
|
103
|
+
continue
|
|
104
|
+
name = has_accessor_name(k)
|
|
105
|
+
if name in payload: # authored wins
|
|
106
|
+
continue
|
|
107
|
+
derived = accessor_value(v)
|
|
108
|
+
if derived is not None:
|
|
109
|
+
out[name] = derived
|
|
110
|
+
return out
|
|
111
|
+
if isinstance(payload, (str, bytes)):
|
|
112
|
+
return payload
|
|
113
|
+
if isinstance(payload, Sequence):
|
|
114
|
+
return [with_derived_accessors(v, depth + 1) for v in payload]
|
|
115
|
+
return payload
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def is_boolean_accessor(stack: list[list[Any]], name: str) -> bool:
|
|
119
|
+
"""True when ``name`` is a derived accessor over a field reachable on ``stack``.
|
|
120
|
+
|
|
121
|
+
Mirrors the JVM's ``Verify.isBooleanAccessor``, including its deliberate
|
|
122
|
+
permissiveness: acceptance keys off the FIELD EXISTING, not off its type. Accessors
|
|
123
|
+
are simple (undotted) names; a dotted path is never an accessor.
|
|
124
|
+
"""
|
|
125
|
+
if "." in name:
|
|
126
|
+
return False
|
|
127
|
+
if not name.startswith(HAS_PREFIX):
|
|
128
|
+
return False
|
|
129
|
+
# Mustache outward walk (innermost → outermost).
|
|
130
|
+
for frame in reversed(stack):
|
|
131
|
+
for f in frame:
|
|
132
|
+
if name == has_accessor_name(f.name):
|
|
133
|
+
return True
|
|
134
|
+
return False
|
|
@@ -23,6 +23,7 @@ from dataclasses import dataclass, field
|
|
|
23
23
|
from typing import Any
|
|
24
24
|
|
|
25
25
|
from . import escapers
|
|
26
|
+
from .payload_accessors import with_derived_accessors
|
|
26
27
|
from .verify import InMemoryProvider, Provider
|
|
27
28
|
|
|
28
29
|
MAX_DEPTH = 32
|
|
@@ -59,7 +60,10 @@ def render(req: RenderRequest) -> str:
|
|
|
59
60
|
_validate(req)
|
|
60
61
|
body = req.template if req.template is not None else _resolve_or_raise(req.provider, req.ref)
|
|
61
62
|
expanded = _pre_expand_partials(body, req.provider, [])
|
|
62
|
-
|
|
63
|
+
# Derived `has<Field>` accessors are part of the payload contract, not of the
|
|
64
|
+
# caller's object — see payload_accessors. Injected here so a `{{#hasFoo}}` section
|
|
65
|
+
# resolves the same way it does against a generated JVM payload record.
|
|
66
|
+
out = _interpret(expanded, with_derived_accessors(req.payload), req.format)
|
|
63
67
|
# @maxChars is a fail-closed render budget: over-budget output RAISES (never
|
|
64
68
|
# silently truncates). Canonical cross-port behavior — message shape matches
|
|
65
69
|
# TS/C#/Java: "render exceeded maxChars budget: <len> > <cap>".
|
|
@@ -23,6 +23,8 @@ from __future__ import annotations
|
|
|
23
23
|
from dataclasses import dataclass
|
|
24
24
|
from typing import Protocol
|
|
25
25
|
|
|
26
|
+
from .payload_accessors import is_boolean_accessor
|
|
27
|
+
|
|
26
28
|
#: A ``{{var}}`` references a field the (contextual) payload does not declare.
|
|
27
29
|
ERR_VAR_NOT_ON_PAYLOAD = "ERR_VAR_NOT_ON_PAYLOAD"
|
|
28
30
|
#: A ``{{> ref}}`` partial does not resolve in the provider.
|
|
@@ -215,7 +217,9 @@ def verify(
|
|
|
215
217
|
continue # implicit iterator — always valid
|
|
216
218
|
if at_root:
|
|
217
219
|
referenced_at_root.add(tok.value.split(".")[0])
|
|
218
|
-
if _resolve(stack, tok.value) is None
|
|
220
|
+
if _resolve(stack, tok.value) is None and not is_boolean_accessor(
|
|
221
|
+
stack, tok.value
|
|
222
|
+
):
|
|
219
223
|
errors.append(VerifyError(ERR_VAR_NOT_ON_PAYLOAD, tok.value))
|
|
220
224
|
elif isinstance(tok, _Section):
|
|
221
225
|
if tok.value == ".":
|
|
@@ -225,6 +229,12 @@ def verify(
|
|
|
225
229
|
referenced_at_root.add(tok.value.split(".")[0])
|
|
226
230
|
field = _resolve(stack, tok.value)
|
|
227
231
|
if field is None:
|
|
232
|
+
# A derived `has<Field>` gate is a BOOLEAN over the current context:
|
|
233
|
+
# it resolves nothing and pushes nothing, so walk the body in the SAME
|
|
234
|
+
# scope — what `{{#hasAbilities}}{{#abilities}}…` depends on.
|
|
235
|
+
if is_boolean_accessor(stack, tok.value):
|
|
236
|
+
walk(tok.children, stack, seen)
|
|
237
|
+
continue
|
|
228
238
|
# Unresolved section head is itself drift; skip the body (its
|
|
229
239
|
# context is unknowable, walking it would cascade false errors).
|
|
230
240
|
errors.append(VerifyError(ERR_VAR_NOT_ON_PAYLOAD, tok.value))
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"name": "description",
|
|
13
13
|
"min": 0,
|
|
14
14
|
"max": 1,
|
|
15
|
-
"description": "
|
|
15
|
+
"description": "What this element IS and COVERS, written for someone using it. Markdown allowed, multi-line via YAML '|' block scalar. Flows into doc-gen surfaces (JSDoc / XML-doc / Postgres COMMENT / Mermaid prose). State scope and boundary — what it covers, what it deliberately does NOT, and which sibling owns the rest — all of which is derivable from the model itself. Anything you had to read the implementation to learn belongs in @notes, not here."
|
|
16
16
|
},
|
|
17
17
|
{
|
|
18
18
|
"type": "attr",
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"name": "summary",
|
|
21
21
|
"min": 0,
|
|
22
22
|
"max": 1,
|
|
23
|
-
"description": "Short single-line
|
|
23
|
+
"description": "Short single-line SENTENCE (OpenAPI `summary` pattern) — used in index tables, sidebar previews, and AI prompts where the full @description is too long. Distinct from @title, which is a noun label rather than a sentence. When @summary is unset, doc surfaces typically fall back to the first sentence of @description."
|
|
24
24
|
},
|
|
25
25
|
{
|
|
26
26
|
"type": "attr",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"name": "title",
|
|
29
29
|
"min": 0,
|
|
30
30
|
"max": 1,
|
|
31
|
-
"description": "Short single-line human label (e.g. 'Email' for a `field.string email`).
|
|
31
|
+
"description": "Short single-line human label — a NOUN PHRASE naming the element (e.g. 'Email' for a `field.string email`), never a sentence. What a tab, an index row or a sidebar shows when the name is an identifier rather than a label. See @summary for the one-line sentence form."
|
|
32
32
|
},
|
|
33
33
|
{
|
|
34
34
|
"type": "attr",
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"name": "notes",
|
|
37
37
|
"min": 0,
|
|
38
38
|
"max": 1,
|
|
39
|
-
"description": "Internal-only rationale
|
|
39
|
+
"description": "Internal-only rationale, never emitted to user-facing docs — the slot for what you had to look OUTSIDE the model to learn: evidence, measurements, citations, the control that proved an absence was real, and what breaks if this changes. It is NOT a longer @description, and restating the description here is the failure mode this slot invites. Mechanical test: a sentence belongs in @notes exactly when it would have to change because the IMPLEMENTATION changed while the model did not."
|
|
40
40
|
},
|
|
41
41
|
{
|
|
42
42
|
"type": "attr",
|