oold 2.3.0__tar.gz → 2.3.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.
- {oold-2.3.0 → oold-2.3.1}/CHANGELOG.md +19 -0
- {oold-2.3.0 → oold-2.3.1}/CITATION.cff +1 -1
- {oold-2.3.0 → oold-2.3.1}/PKG-INFO +1 -1
- {oold-2.3.0 → oold-2.3.1}/docs/how-to/controller.md +2 -0
- {oold-2.3.0 → oold-2.3.1}/pyproject.toml +1 -1
- {oold-2.3.0 → oold-2.3.1}/src/oold/validation/frame.py +75 -9
- {oold-2.3.0 → oold-2.3.1}/tests/test_validation/test_jsonld.py +135 -2
- {oold-2.3.0 → oold-2.3.1}/uv.lock +1 -6
- {oold-2.3.0 → oold-2.3.1}/.devcontainer/devcontainer.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/.devcontainer/postCreateCommand.sh +0 -0
- {oold-2.3.0 → oold-2.3.1}/.editorconfig +0 -0
- {oold-2.3.0 → oold-2.3.1}/.gitattributes +0 -0
- {oold-2.3.0 → oold-2.3.1}/.github/ISSUE_TEMPLATE.md +0 -0
- {oold-2.3.0 → oold-2.3.1}/.github/actions/setup-python-env/action.yml +0 -0
- {oold-2.3.0 → oold-2.3.1}/.github/workflows/main.yml +0 -0
- {oold-2.3.0 → oold-2.3.1}/.github/workflows/on-release-main.yml +0 -0
- {oold-2.3.0 → oold-2.3.1}/.github/workflows/validate-codecov-config.yml +0 -0
- {oold-2.3.0 → oold-2.3.1}/.gitignore +0 -0
- {oold-2.3.0 → oold-2.3.1}/.mcp.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/.pre-commit-config.yaml +0 -0
- {oold-2.3.0 → oold-2.3.1}/CLAUDE.md +0 -0
- {oold-2.3.0 → oold-2.3.1}/CONTRIBUTING.md +0 -0
- {oold-2.3.0 → oold-2.3.1}/Dockerfile +0 -0
- {oold-2.3.0 → oold-2.3.1}/LICENSE +0 -0
- {oold-2.3.0 → oold-2.3.1}/Makefile +0 -0
- {oold-2.3.0 → oold-2.3.1}/README.md +0 -0
- {oold-2.3.0 → oold-2.3.1}/codecov.yaml +0 -0
- {oold-2.3.0 → oold-2.3.1}/docs/about.md +0 -0
- {oold-2.3.0 → oold-2.3.1}/docs/api.md +0 -0
- {oold-2.3.0 → oold-2.3.1}/docs/architecture.md +0 -0
- {oold-2.3.0 → oold-2.3.1}/docs/assets/oold_concept.png +0 -0
- {oold-2.3.0 → oold-2.3.1}/docs/contributing.md +0 -0
- {oold-2.3.0 → oold-2.3.1}/docs/design/downstream-migration.md +0 -0
- {oold-2.3.0 → oold-2.3.1}/docs/design/graph-object-binding.md +0 -0
- {oold-2.3.0 → oold-2.3.1}/docs/get-started.md +0 -0
- {oold-2.3.0 → oold-2.3.1}/docs/how-to/backends.md +0 -0
- {oold-2.3.0 → oold-2.3.1}/docs/how-to/codegen.md +0 -0
- {oold-2.3.0 → oold-2.3.1}/docs/how-to/index.md +0 -0
- {oold-2.3.0 → oold-2.3.1}/docs/how-to/object-graph-mapping.md +0 -0
- {oold-2.3.0 → oold-2.3.1}/docs/how-to/rdf-export.md +0 -0
- {oold-2.3.0 → oold-2.3.1}/docs/how-to/validation.md +0 -0
- {oold-2.3.0 → oold-2.3.1}/docs/index.md +0 -0
- {oold-2.3.0 → oold-2.3.1}/docs/maintaining-meta-schemas.md +0 -0
- {oold-2.3.0 → oold-2.3.1}/docs/stylesheets/extra.css +0 -0
- {oold-2.3.0 → oold-2.3.1}/examples/backend_auth.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/examples/bench_attribute_access.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/examples/bench_binding_variants.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/examples/check_binding_features.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/examples/linked_data_editor.ipynb +0 -0
- {oold-2.3.0 → oold-2.3.1}/examples/linked_data_editor.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/examples/notation_example.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/examples/wiki_data.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/pytest.benchmark.ini +0 -0
- {oold-2.3.0 → oold-2.3.1}/scripts/check_markdown_extensions.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/scripts/compare_benchmarks.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/__init__.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/__init__.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/backend/__init__.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/backend/auth.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/backend/document_store.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/backend/interface.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/backend/sparql.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/cli.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/drafts/field_extras.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/drafts/ldc_generator.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/drafts/magic_field.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/experimental/__init__.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/experimental/codegen_spike.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/generator.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/model/__init__.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/model/_compat.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/model/_descriptor.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/model/_notation.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/model/_ref.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/model/v1/__init__.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/model/v1/_descriptor.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/static.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/ui/__init__.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/ui/anywidget/JsonEditorWidget.ipynb +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/ui/anywidget/__init__.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/ui/anywidget/jsoneditor.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/ui/nicegui/__init__.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/ui/nicegui/jsoneditor.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/ui/nicegui/main.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/ui/panel/__init__.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/ui/panel/anywidget_vite/jsoneditor.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/ui/panel/demo.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/ui/vue/README.md +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/ui/vue/package-lock.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/ui/vue/package.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/ui/vue/src/jsoneditor.vue +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/ui/vue/src/jsoneditor_component.js +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/ui/vue/src/jsoneditor_component.less +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/ui/vue/vite.config.anywidget.mjs +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/ui/vue/vite.config.js +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/ui/vue/vite.config.nicegui.js +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/utils/codegen.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/utils/environment.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/utils/json_tools.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/utils/transform.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/validation/__init__.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/validation/check_registry.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/validation/cli.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/validation/compliance.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/validation/context_graph.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/validation/context_resolution.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/validation/formats.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/validation/generate.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/validation/instance_checks.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/validation/loader.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/validation/mcp_server.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/validation/meta/0.7.0/oold-meta-schema.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/validation/meta/0.7.0/oold-pattern-lint.schema.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/validation/meta/0.7.0/oold-ui-meta-schema.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/validation/meta/0.8.0/oold-meta-schema.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/validation/meta/0.8.0/oold-pattern-lint.schema.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/validation/meta/0.8.0/oold-ui-meta-schema.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/validation/meta/1.0.0/oold-meta-schema-base.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/validation/meta/1.0.0/oold-meta-schema.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/validation/meta/1.0.0/oold-pattern-lint.schema.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/validation/meta/1.0.0/oold-rules.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/validation/meta/1.0.0/oold-rules.schema.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/validation/meta/1.0.0/oold-ui-meta-schema.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/validation/meta/1.0.0-rc.1/oold-meta-schema.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/validation/meta/1.0.0-rc.1/oold-pattern-lint.schema.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/validation/meta/1.0.0-rc.1/oold-rules.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/validation/meta/1.0.0-rc.1/oold-rules.schema.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/validation/meta/1.0.0-rc.1/oold-ui-meta-schema.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/validation/meta/1.0.0-rc.2/oold-meta-schema-base.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/validation/meta/1.0.0-rc.2/oold-meta-schema.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/validation/meta/1.0.0-rc.2/oold-pattern-lint.schema.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/validation/meta/1.0.0-rc.2/oold-rules.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/validation/meta/1.0.0-rc.2/oold-rules.schema.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/validation/meta/1.0.0-rc.2/oold-ui-meta-schema.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/validation/meta/1.0.0-rc.3/oold-meta-schema-base.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/validation/meta/1.0.0-rc.3/oold-meta-schema.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/validation/meta/1.0.0-rc.3/oold-pattern-lint.schema.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/validation/meta/1.0.0-rc.3/oold-rules.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/validation/meta/1.0.0-rc.3/oold-rules.schema.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/validation/meta/1.0.0-rc.3/oold-ui-meta-schema.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/validation/meta/1.0.0-rc.4/oold-meta-schema-base.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/validation/meta/1.0.0-rc.4/oold-meta-schema.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/validation/meta/1.0.0-rc.4/oold-pattern-lint.schema.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/validation/meta/1.0.0-rc.4/oold-rules.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/validation/meta/1.0.0-rc.4/oold-rules.schema.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/validation/meta/1.0.0-rc.4/oold-ui-meta-schema.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/validation/meta/1.0.0-rc.5/oold-meta-schema-base.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/validation/meta/1.0.0-rc.5/oold-meta-schema.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/validation/meta/1.0.0-rc.5/oold-pattern-lint.schema.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/validation/meta/1.0.0-rc.5/oold-rules.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/validation/meta/1.0.0-rc.5/oold-rules.schema.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/validation/meta/1.0.0-rc.5/oold-ui-meta-schema.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/validation/meta/index.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/validation/meta_store.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/validation/meta_vendor.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/validation/pattern_lint.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/validation/pipeline.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/validation/predicates.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/validation/report.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/validation/resolve.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/validation/roundtrip.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/src/oold/validation/schema_checks.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/conftest.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/data/__init__.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/data/class_hierarchy/__init__.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/data/class_hierarchy/model_v1.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/data/class_hierarchy/model_v2.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/data/enum_docstrings/__init__.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/data/enum_docstrings/model_v1.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/data/enum_docstrings/model_v2.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/data/format_parity.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/data/oneof_subschema/__init__.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/data/oneof_subschema/model_v1.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/data/oneof_subschema/model_v2.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/data/oold/Address.schema.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/data/oold/Contact.schema.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/data/oold/ContactSeparateKeys.schema.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/data/oold/Minimal.schema.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/data/oold/Organization.schema.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/data/oold/OwlOrganization.instance.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/data/oold/OwlOrganization.schema.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/data/oold/Person.schema.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/data/oold/PersonWithPet.instance.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/data/oold/PersonWithPet.schema.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/data/oold/Pet.schema.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/data/oold/RdfPerson.instance.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/data/oold/RdfPerson.schema.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/data/oold/Researcher.schema.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/data/oold/Thing.schema.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/data/oold/UiAnnotations.schema.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/data/oold/UiOverlay.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/data/oold/broken/Gauge.schema.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/data/oold/broken/NarrowBase.schema.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/data/oold/broken/Sensor.schema.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/data/oold/broken/array_without_container.schema.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/data/oold/broken/base_uri_misaligned.schema.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/data/oold/broken/branch_context_conflict.schema.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/data/oold/broken/closed_object_rejects_metadata.schema.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/data/oold/broken/context_array_order_mismatch.schema.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/data/oold/broken/inline_type_disagrees.schema.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/data/oold/broken/invalid_meta.schema.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/data/oold/broken/iri_reference_without_format.schema.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/data/oold/broken/legacy_dialect.schema.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/data/oold/broken/missing_context_term.schema.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/data/oold/broken/narrow_only_relaxation.schema.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/data/oold/broken/no_context.schema.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/data/oold/broken/root_ref_not_reflected.schema.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/data/oold/broken/undefined_prefix.schema.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/data/oold/broken/unresolvable_context_ref.schema.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/data/oold/broken/versioned_id_missing_version.schema.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/data/oold/broken/vocab_covers_the_remainder.schema.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/data/oold/broken/xsd_string_coercion.schema.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/data/oold/compliance/jsonld-features.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/data/oold/compliance/oold-vocab.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/data/oold/compliance/roundtrip-patterns.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/data/oold/remote_context/Leaf.schema.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/data/oold/x_oold_context/SkosSynonym.schema.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/data/quantities/__init__.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/data/quantities/model.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/data/resolver_cache/66a1009a2cf528dd525ec0c0150488fe.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/data/subclass_inheritance/__init__.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/data/subclass_inheritance/model_v1.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/data/subclass_inheritance/model_v2.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/data/test_core/__init__.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/data/test_core/model_v1.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/data/test_core/model_v1_nested.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/data/test_core/model_v2.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/data/test_core/model_v2_nested.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/data/test_core/src/Bar.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/data/test_core/src/Foo.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/data/test_core/src/bar2/Bar2.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/query_test.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/static.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/test_auth.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/test_auto_descriptor_binding.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/test_backends.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/test_base_controller.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/test_binding_switch.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/test_code_generation.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/test_compat_parity.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/test_compat_parity_v1.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/test_downstream_shapes.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/test_link_annotation.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/test_notation.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/test_oold.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/test_rdf.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/test_ref.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/test_register_controller_type.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/test_register_controller_type_v1.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/test_register_type.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/test_registry_precedence.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/test_schema_generation.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/test_serialization.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/test_sparql_query.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/test_transform.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/test_typing.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/test_validation/__init__.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/test_validation/conftest.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/test_validation/test_check_registry.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/test_validation/test_check_registry_drift.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/test_validation/test_checks.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/test_validation/test_cli.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/test_validation/test_compliance.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/test_validation/test_emitted_schema_conformance.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/test_validation/test_formats.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/test_validation/test_generate.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/test_validation/test_mcp_server.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/test_validation/test_meta_store.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/test_validation/test_meta_vendor.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/test_validation/test_parity_live.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/test_validation/test_pipeline.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/test_validation/test_resolve.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/test_validation/test_rules.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/test_validation/test_schema_levels.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/typing/links.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/typing/pyrightconfig.json +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/typing/query_dsl.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/ui/panel/conftest.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/ui/panel/panel_app.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/tests/ui/panel/panel_frontend_test.py +0 -0
- {oold-2.3.0 → oold-2.3.1}/tox.ini +0 -0
- {oold-2.3.0 → oold-2.3.1}/zensical.toml +0 -0
|
@@ -7,6 +7,25 @@ not edit released sections by hand.
|
|
|
7
7
|
|
|
8
8
|
<!-- version list -->
|
|
9
9
|
|
|
10
|
+
## v2.3.1 (2026-11-15)
|
|
11
|
+
|
|
12
|
+
### Bug Fixes
|
|
13
|
+
|
|
14
|
+
- **frame**: Anchor the frame on a type pinned as a default
|
|
15
|
+
([`fa22022`](https://github.com/OO-LD/oold-python/commit/fa220221e48feb83c26879748c317457d2484012))
|
|
16
|
+
|
|
17
|
+
- **frame**: Keep a $ref-valued embed out of the reference list
|
|
18
|
+
([`a7ac1d1`](https://github.com/OO-LD/oold-python/commit/a7ac1d1d153719258fb299c3f706a58238bbe9c4))
|
|
19
|
+
|
|
20
|
+
- **frame**: One reverse subframe per IRI, not per term
|
|
21
|
+
([`74a3adf`](https://github.com/OO-LD/oold-python/commit/74a3adf44fb647aa544c7432c0e5fd78f44949c1))
|
|
22
|
+
|
|
23
|
+
### Documentation
|
|
24
|
+
|
|
25
|
+
- **controller**: Name controller members for what they do
|
|
26
|
+
([`648018f`](https://github.com/OO-LD/oold-python/commit/648018fc480934b5b5185c6d0702860392e90c25))
|
|
27
|
+
|
|
28
|
+
|
|
10
29
|
## v2.3.0 (2026-10-15)
|
|
11
30
|
|
|
12
31
|
### Bug Fixes
|
|
@@ -3,7 +3,7 @@ message: "If you use this software, please cite it as below."
|
|
|
3
3
|
type: software
|
|
4
4
|
title: "oold-python: Object-Oriented Linked Data for Python"
|
|
5
5
|
# Managed by python-semantic-release (version_variables). Do not edit by hand.
|
|
6
|
-
version: 2.3.
|
|
6
|
+
version: 2.3.1
|
|
7
7
|
abstract: "A Python package for abstract and object-oriented access to knowledge graphs, bridging semantic web technologies (RDF, JSON-LD, SPARQL) with Pydantic type safety."
|
|
8
8
|
repository-code: "https://github.com/oo-ld/oold-python"
|
|
9
9
|
url: "https://OO-LD.github.io/oold-python/"
|
|
@@ -147,6 +147,8 @@ This is useful for checkpointing state (e.g. saving `joint_count` after a calibr
|
|
|
147
147
|
|
|
148
148
|
## Guidelines
|
|
149
149
|
|
|
150
|
+
- Name controller members for what they *do*: `connect()`, `download()`, `store()`, not `connection`, `url`, `storage`. A controller extends a model whose field names come from a schema, and a noun-named method or property competes with a field that the schema may gain at any regeneration - it shadows the field, or the field shadows it, and the two are hard to tell apart because both answer to attribute access. A verb is almost never a field name.
|
|
151
|
+
- The risk is worst for a property: it reads like data, so callers reach for it with `getattr()`, and anything it does on the way - opening a session, touching the filesystem - surfaces where a plain attribute read was expected. If a controller has to expose derived data, give it a method.
|
|
150
152
|
- Prefix controller-only attributes with `_` to make the distinction explicit
|
|
151
153
|
- Keep `__init__` arguments limited to data model fields - controllers should be constructed from data, not from runtime handles
|
|
152
154
|
- If a controller needs runtime resources (sockets, threads), initialize them in a dedicated `connect()` / `start()` method, not in `__init__`
|
|
@@ -9,7 +9,7 @@ keywords = ['python', 'linked-data', 'json-ld', 'pydantic', 'oo-ld']
|
|
|
9
9
|
requires-python = ">=3.10,<4.0"
|
|
10
10
|
# Version is managed by python-semantic-release (see [tool.semantic_release]).
|
|
11
11
|
# Do not edit by hand; it is bumped automatically on merge to main.
|
|
12
|
-
version = "2.3.
|
|
12
|
+
version = "2.3.1"
|
|
13
13
|
classifiers = [
|
|
14
14
|
"Development Status :: 4 - Beta",
|
|
15
15
|
"Intended Audience :: Developers",
|
|
@@ -41,14 +41,17 @@ IRI_FORMATS = frozenset({"iri", "iri-reference", "uri", "uri-reference"})
|
|
|
41
41
|
def is_embed(node: Any) -> bool:
|
|
42
42
|
"""True when a property's schema describes an embedded *object* value.
|
|
43
43
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
44
|
+
After dereferencing an embed is inlined as an object with its own properties, so the object
|
|
45
|
+
shape is the primary signal. On an undereferenced schema it is a ``$ref``, which therefore
|
|
46
|
+
counts too. A ``$ref`` pointing at a scalar DataType leaf is a literal rather than an embed,
|
|
47
|
+
but it costs only an empty subframe, and framing leaves a literal value alone.
|
|
47
48
|
"""
|
|
48
49
|
if not isinstance(node, dict):
|
|
49
50
|
return False
|
|
50
51
|
if node.get("type") == "object" and node.get("properties"):
|
|
51
52
|
return True
|
|
53
|
+
if isinstance(node.get("$ref"), str):
|
|
54
|
+
return True
|
|
52
55
|
if node.get("items") is not None:
|
|
53
56
|
return is_embed(node["items"])
|
|
54
57
|
for keyword in ("anyOf", "oneOf", "allOf"):
|
|
@@ -97,6 +100,25 @@ def embedded_properties(schema: dict[str, Any]) -> list[str]:
|
|
|
97
100
|
return list(dict.fromkeys([*structural, *scoped]))
|
|
98
101
|
|
|
99
102
|
|
|
103
|
+
def pinned_type_default(schema: Any) -> list[str] | None:
|
|
104
|
+
"""The instance type a schema pins through ``properties.type.default``.
|
|
105
|
+
|
|
106
|
+
``OOLD-INS-4b5c`` only fires where ``x-oold-instance-rdf-type`` is declared, so pinning the
|
|
107
|
+
type as a default on the ``@type``-aliased property is a permitted spelling, and the frame
|
|
108
|
+
needs that anchor as much as it needs the keyword's.
|
|
109
|
+
"""
|
|
110
|
+
if not isinstance(schema, dict):
|
|
111
|
+
return None
|
|
112
|
+
properties = schema.get("properties")
|
|
113
|
+
declaration = properties.get("type") if isinstance(properties, dict) else None
|
|
114
|
+
default = declaration.get("default") if isinstance(declaration, dict) else None
|
|
115
|
+
if isinstance(default, str):
|
|
116
|
+
return [default]
|
|
117
|
+
if isinstance(default, list) and default and all(isinstance(entry, str) for entry in default):
|
|
118
|
+
return list(default)
|
|
119
|
+
return None
|
|
120
|
+
|
|
121
|
+
|
|
100
122
|
def instance_rdf_types(schema: Any) -> list[str] | None:
|
|
101
123
|
"""The instance ``rdf:type``(s) a schema declares, most-derived-wins.
|
|
102
124
|
|
|
@@ -105,12 +127,18 @@ def instance_rdf_types(schema: Any) -> list[str] | None:
|
|
|
105
127
|
inference rather than being materialised. A subclass that wants supertypes in the data lists
|
|
106
128
|
them explicitly. After dereferencing the most-derived value sits at the top level; the
|
|
107
129
|
``allOf`` walk is the fallback for a subclass that omits its own declaration.
|
|
130
|
+
|
|
131
|
+
``properties.type.default`` is read where the keyword is absent, and it is read before the
|
|
132
|
+
``allOf`` walk, because a schema's own spelling of its type is nearer than an inherited one.
|
|
108
133
|
"""
|
|
109
134
|
if not isinstance(schema, dict):
|
|
110
135
|
return None
|
|
111
136
|
own = schema.get("x-oold-instance-rdf-type")
|
|
112
137
|
if isinstance(own, list) and own:
|
|
113
138
|
return own
|
|
139
|
+
pinned = pinned_type_default(schema)
|
|
140
|
+
if pinned:
|
|
141
|
+
return pinned
|
|
114
142
|
if isinstance(schema.get("allOf"), list):
|
|
115
143
|
for sub in schema["allOf"]:
|
|
116
144
|
types = instance_rdf_types(sub)
|
|
@@ -162,6 +190,22 @@ def _is_reference_term(definition: Any) -> bool:
|
|
|
162
190
|
return definition.get("@type") == "@id" or "@reverse" in definition
|
|
163
191
|
|
|
164
192
|
|
|
193
|
+
def reverse_predicates(schema: dict[str, Any]) -> dict[str, list[str]]:
|
|
194
|
+
"""The reverse IRI each reverse-mapped property compacts to, keyed by that IRI.
|
|
195
|
+
|
|
196
|
+
Several terms may share one reverse IRI, since nothing stops a schema from naming the same
|
|
197
|
+
relation twice. The IRI is taken as the term writes it, compact or absolute: the frame
|
|
198
|
+
resolves it against the same context the term was read from.
|
|
199
|
+
"""
|
|
200
|
+
properties = collect_composed_properties(schema)
|
|
201
|
+
grouped: dict[str, list[str]] = {}
|
|
202
|
+
for name, definition in context_terms(schema.get("@context")).items():
|
|
203
|
+
predicate = definition.get("@reverse")
|
|
204
|
+
if name in properties and isinstance(predicate, str):
|
|
205
|
+
grouped.setdefault(predicate, []).append(name)
|
|
206
|
+
return grouped
|
|
207
|
+
|
|
208
|
+
|
|
165
209
|
def reference_properties(schema: dict[str, Any]) -> list[str]:
|
|
166
210
|
"""Properties whose value is a reference, so framing must leave it an IRI.
|
|
167
211
|
|
|
@@ -173,8 +217,9 @@ def reference_properties(schema: dict[str, Any]) -> list[str]:
|
|
|
173
217
|
(JSON-LD 1.1 4.1.10), so ``"@type": "@id"`` beside it is redundant and authors omit it;
|
|
174
218
|
keying only on ``@type`` misses the idiomatic spelling and embeds the targets.
|
|
175
219
|
|
|
176
|
-
Embedding takes precedence where a property carries both
|
|
177
|
-
|
|
220
|
+
Embedding takes precedence where a property carries both, and the test is membership in
|
|
221
|
+
:func:`embedded_properties` rather than the shape alone, so the two lists cannot both claim a
|
|
222
|
+
property that embeds through a scoped ``@context``.
|
|
178
223
|
"""
|
|
179
224
|
|
|
180
225
|
def is_reference(node: Any) -> bool:
|
|
@@ -195,11 +240,12 @@ def reference_properties(schema: dict[str, Any]) -> list[str]:
|
|
|
195
240
|
properties = collect_composed_properties(schema)
|
|
196
241
|
terms = context_terms(schema.get("@context"))
|
|
197
242
|
aliases = keyword_alias_keys(schema)
|
|
243
|
+
embedded = set(embedded_properties(schema))
|
|
198
244
|
return [
|
|
199
245
|
name
|
|
200
246
|
for name, prop in properties.items()
|
|
201
247
|
if name not in aliases
|
|
202
|
-
and not
|
|
248
|
+
and name not in embedded
|
|
203
249
|
and (is_reference(prop) or _is_reference_term(terms.get(name, {})))
|
|
204
250
|
]
|
|
205
251
|
|
|
@@ -210,14 +256,34 @@ def schema_to_frame(schema: dict[str, Any], context_ref: Any = _UNSET) -> dict[s
|
|
|
210
256
|
``context_ref``, when given, is used as the frame's ``@context`` in place of the schema's
|
|
211
257
|
inline one. Pass the schema's URL so the document loader resolves inherited and scoped
|
|
212
258
|
contexts rather than losing them.
|
|
259
|
+
|
|
260
|
+
The reference subframes are written before the embedded ones, so a property both lists claim
|
|
261
|
+
keeps the ``{}`` that preserves its nested keys.
|
|
262
|
+
|
|
263
|
+
A reverse-mapped property is written under ``@reverse``, by its reverse IRI rather than by its
|
|
264
|
+
term name. Term names expand, so two terms sharing one reverse IRI would otherwise produce two
|
|
265
|
+
subframes under that IRI; a frame must be a single object, and a processor rejects the pair.
|
|
213
266
|
"""
|
|
214
267
|
frame: dict[str, Any] = {"@embed": "@once"}
|
|
215
268
|
frame["@context"] = schema.get("@context") if context_ref is _UNSET else context_ref
|
|
216
269
|
types = instance_rdf_types(schema)
|
|
217
270
|
if types:
|
|
218
271
|
frame["@type"] = types[0] if len(types) == 1 else types
|
|
219
|
-
|
|
220
|
-
|
|
272
|
+
|
|
273
|
+
predicate_of = {name: predicate for predicate, names in reverse_predicates(schema).items() for name in names}
|
|
274
|
+
grouped: dict[str, dict[str, Any]] = {}
|
|
275
|
+
|
|
276
|
+
def place(name: str, subframe: dict[str, Any]) -> None:
|
|
277
|
+
predicate = predicate_of.get(name)
|
|
278
|
+
if predicate is None:
|
|
279
|
+
frame[name] = subframe
|
|
280
|
+
else:
|
|
281
|
+
grouped[predicate] = subframe
|
|
282
|
+
|
|
221
283
|
for name in reference_properties(schema):
|
|
222
|
-
|
|
284
|
+
place(name, {"@embed": "@never"})
|
|
285
|
+
for name in embedded_properties(schema):
|
|
286
|
+
place(name, {})
|
|
287
|
+
if grouped:
|
|
288
|
+
frame["@reverse"] = grouped
|
|
223
289
|
return frame
|
|
@@ -14,6 +14,7 @@ from oold.validation.frame import (
|
|
|
14
14
|
is_embed,
|
|
15
15
|
keyword_alias_keys,
|
|
16
16
|
reference_properties,
|
|
17
|
+
reverse_predicates,
|
|
17
18
|
schema_to_frame,
|
|
18
19
|
)
|
|
19
20
|
from oold.validation.loader import DocumentLoader, describe_jsonld_error
|
|
@@ -98,6 +99,61 @@ def test_instance_rdf_types_is_most_derived_wins():
|
|
|
98
99
|
assert instance_rdf_types({"type": "object"}) is None
|
|
99
100
|
|
|
100
101
|
|
|
102
|
+
def test_a_type_pinned_as_a_default_anchors_the_frame():
|
|
103
|
+
"""OO-LD/oold-python#177.
|
|
104
|
+
|
|
105
|
+
Without an anchor the root is only the frame root while every edge runs forward; the first
|
|
106
|
+
backwards edge leaves nothing matched and framing returns a bare ``@graph``.
|
|
107
|
+
"""
|
|
108
|
+
context = {
|
|
109
|
+
"ex": "https://example.org/",
|
|
110
|
+
"obo": "http://purl.obolibrary.org/obo/",
|
|
111
|
+
"id": "@id",
|
|
112
|
+
"type": {"@id": "@type", "@container": "@set"},
|
|
113
|
+
"Material": "ex:Material",
|
|
114
|
+
"components": "ex:components",
|
|
115
|
+
"chemical_composition": {"@reverse": "obo:RO_0000080"},
|
|
116
|
+
}
|
|
117
|
+
schema = {
|
|
118
|
+
"type": "object",
|
|
119
|
+
"@context": context,
|
|
120
|
+
"properties": {
|
|
121
|
+
"type": {"type": "array", "items": {"type": "string"}, "default": ["Material"]},
|
|
122
|
+
"chemical_composition": {"type": "object", "properties": {"components": {}}},
|
|
123
|
+
},
|
|
124
|
+
}
|
|
125
|
+
assert instance_rdf_types(schema) == ["Material"]
|
|
126
|
+
frame = schema_to_frame(schema)
|
|
127
|
+
assert frame["@type"] == "Material"
|
|
128
|
+
|
|
129
|
+
rdf_type = "<http://www.w3.org/1999/02/22-rdf-syntax-ns#type>"
|
|
130
|
+
nq = "\n".join([
|
|
131
|
+
f"<https://example.org/m1> {rdf_type} <https://example.org/Material> .",
|
|
132
|
+
f"_:c {rdf_type} <https://example.org/ChemicalComposition> .",
|
|
133
|
+
"_:c <http://purl.obolibrary.org/obo/RO_0000080> <https://example.org/m1> .",
|
|
134
|
+
'_:c <https://example.org/components> "Fe" .',
|
|
135
|
+
"",
|
|
136
|
+
])
|
|
137
|
+
graph = jsonld.from_rdf(nq, {"format": "application/n-quads", "useNativeTypes": True})
|
|
138
|
+
framed = jsonld.frame(graph, frame, {"omitDefault": True})
|
|
139
|
+
|
|
140
|
+
assert "@graph" not in framed
|
|
141
|
+
assert framed["chemical_composition"]["components"] == "Fe"
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
def test_the_keyword_wins_over_a_type_pinned_as_a_default():
|
|
145
|
+
schema = {
|
|
146
|
+
"x-oold-instance-rdf-type": ["ex:B"],
|
|
147
|
+
"properties": {"type": {"default": ["ex:A"]}},
|
|
148
|
+
}
|
|
149
|
+
assert instance_rdf_types(schema) == ["ex:B"]
|
|
150
|
+
# A schema's own default is nearer than a type inherited through allOf.
|
|
151
|
+
assert instance_rdf_types({
|
|
152
|
+
"allOf": [{"x-oold-instance-rdf-type": ["ex:A"]}],
|
|
153
|
+
"properties": {"type": {"default": ["ex:B"]}},
|
|
154
|
+
}) == ["ex:B"]
|
|
155
|
+
|
|
156
|
+
|
|
101
157
|
def test_schema_to_frame_carries_type_context_and_subframes():
|
|
102
158
|
schema = {
|
|
103
159
|
"x-oold-instance-rdf-type": ["schema:Person"],
|
|
@@ -175,6 +231,35 @@ def test_embedding_wins_where_a_property_carries_both_signals():
|
|
|
175
231
|
assert reference_properties(schema) == []
|
|
176
232
|
|
|
177
233
|
|
|
234
|
+
def test_a_ref_valued_embed_keeps_its_subframe_before_dereferencing():
|
|
235
|
+
"""OO-LD/oold-python#175.
|
|
236
|
+
|
|
237
|
+
``$ref`` is the only trace of the embed while the schema is undereferenced, and the
|
|
238
|
+
``"@type": "@id"`` that OO-LD requires on such a term makes it look reference-valued at the
|
|
239
|
+
same time. With both lists claiming it, ``{}`` was overwritten by ``@embed: @never`` and the
|
|
240
|
+
framed node came back empty.
|
|
241
|
+
"""
|
|
242
|
+
schema = {
|
|
243
|
+
"type": "object",
|
|
244
|
+
"@context": {
|
|
245
|
+
"type": {"@id": "@type", "@container": "@set"},
|
|
246
|
+
"chemical_composition": {
|
|
247
|
+
"@id": "https://example.org/chemical_composition",
|
|
248
|
+
"@type": "@id",
|
|
249
|
+
"@context": "ChemicalComposition.schema.json",
|
|
250
|
+
},
|
|
251
|
+
},
|
|
252
|
+
"properties": {
|
|
253
|
+
"type": {"type": "array", "items": {"type": "string"}, "default": ["Material"]},
|
|
254
|
+
"chemical_composition": {"$ref": "ChemicalComposition.schema.json"},
|
|
255
|
+
},
|
|
256
|
+
}
|
|
257
|
+
assert is_embed({"$ref": "ChemicalComposition.schema.json"})
|
|
258
|
+
assert embedded_properties(schema) == ["chemical_composition"]
|
|
259
|
+
assert reference_properties(schema) == []
|
|
260
|
+
assert schema_to_frame(schema, "Material.schema.json")["chemical_composition"] == {}
|
|
261
|
+
|
|
262
|
+
|
|
178
263
|
def test_a_bare_reverse_term_is_reference_valued():
|
|
179
264
|
"""A reverse term's values are node references by definition (JSON-LD 1.1 4.1.10).
|
|
180
265
|
|
|
@@ -187,7 +272,55 @@ def test_a_bare_reverse_term_is_reference_valued():
|
|
|
187
272
|
"properties": {"employees": {"type": "array", "items": {"type": "string"}}},
|
|
188
273
|
}
|
|
189
274
|
assert reference_properties(schema) == ["employees"]
|
|
190
|
-
assert schema_to_frame(schema)["
|
|
275
|
+
assert schema_to_frame(schema)["@reverse"] == {"schema:worksFor": {"@embed": "@never"}}
|
|
276
|
+
|
|
277
|
+
|
|
278
|
+
def test_two_terms_on_one_reverse_iri_share_a_single_subframe():
|
|
279
|
+
"""OO-LD/oold-python#176.
|
|
280
|
+
|
|
281
|
+
Term names expand, so a subframe per term became two subframes under one IRI. A frame must be
|
|
282
|
+
a single object, and pyld raised ``invalid frame`` with ``{'frame': [{}, {}]}``.
|
|
283
|
+
"""
|
|
284
|
+
context = {
|
|
285
|
+
"ex": "https://example.org/",
|
|
286
|
+
"obo": "http://purl.obolibrary.org/obo/",
|
|
287
|
+
"id": "@id",
|
|
288
|
+
"type": {"@id": "@type", "@container": "@set"},
|
|
289
|
+
"Material": "ex:Material",
|
|
290
|
+
"components": "ex:components",
|
|
291
|
+
"chemical_composition": {"@reverse": "obo:RO_0000080"},
|
|
292
|
+
"material_composition": {"@reverse": "obo:RO_0000080"},
|
|
293
|
+
}
|
|
294
|
+
schema = {
|
|
295
|
+
"x-oold-instance-rdf-type": ["ex:Material"],
|
|
296
|
+
"type": "object",
|
|
297
|
+
"@context": context,
|
|
298
|
+
"properties": {
|
|
299
|
+
"chemical_composition": {"type": "object", "properties": {"components": {}}},
|
|
300
|
+
"material_composition": {"type": "object", "properties": {"components": {}}},
|
|
301
|
+
},
|
|
302
|
+
}
|
|
303
|
+
assert reverse_predicates(schema) == {"obo:RO_0000080": ["chemical_composition", "material_composition"]}
|
|
304
|
+
frame = schema_to_frame(schema)
|
|
305
|
+
assert frame["@reverse"] == {"obo:RO_0000080": {}}
|
|
306
|
+
assert "chemical_composition" not in frame
|
|
307
|
+
|
|
308
|
+
rdf_type = "<http://www.w3.org/1999/02/22-rdf-syntax-ns#type>"
|
|
309
|
+
nq = "\n".join([
|
|
310
|
+
f"<https://example.org/m1> {rdf_type} <https://example.org/Material> .",
|
|
311
|
+
f"_:c {rdf_type} <https://example.org/ChemicalComposition> .",
|
|
312
|
+
"_:c <http://purl.obolibrary.org/obo/RO_0000080> <https://example.org/m1> .",
|
|
313
|
+
'_:c <https://example.org/components> "Fe" .',
|
|
314
|
+
f"_:m {rdf_type} <https://example.org/MaterialComposition> .",
|
|
315
|
+
"_:m <http://purl.obolibrary.org/obo/RO_0000080> <https://example.org/m1> .",
|
|
316
|
+
'_:m <https://example.org/components> "steel" .',
|
|
317
|
+
"",
|
|
318
|
+
])
|
|
319
|
+
graph = jsonld.from_rdf(nq, {"format": "application/n-quads", "useNativeTypes": True})
|
|
320
|
+
framed = jsonld.frame(graph, frame, {"omitDefault": True})
|
|
321
|
+
|
|
322
|
+
compositions = framed["chemical_composition"]
|
|
323
|
+
assert sorted(entry["components"] for entry in compositions) == ["Fe", "steel"]
|
|
191
324
|
|
|
192
325
|
|
|
193
326
|
def test_a_keyword_alias_never_gets_a_subframe():
|
|
@@ -234,7 +367,7 @@ def test_schema_to_frame_keeps_reference_valued_properties_as_iris():
|
|
|
234
367
|
}
|
|
235
368
|
frame = schema_to_frame(schema, "Organization.schema.json")
|
|
236
369
|
assert frame["address"] == {}
|
|
237
|
-
assert frame["
|
|
370
|
+
assert frame["@reverse"] == {"schema:worksFor": {"@embed": "@never"}}
|
|
238
371
|
|
|
239
372
|
|
|
240
373
|
def test_framing_leaves_a_reference_whose_target_has_triples_as_an_iri():
|
|
@@ -2730,7 +2730,7 @@ wheels = [
|
|
|
2730
2730
|
|
|
2731
2731
|
[[package]]
|
|
2732
2732
|
name = "oold"
|
|
2733
|
-
version = "2.3.
|
|
2733
|
+
version = "2.3.1"
|
|
2734
2734
|
source = { editable = "." }
|
|
2735
2735
|
dependencies = [
|
|
2736
2736
|
{ name = "datamodel-code-generator" },
|
|
@@ -5613,13 +5613,8 @@ wheels = [
|
|
|
5613
5613
|
{ url = "https://files.pythonhosted.org/packages/ad/fd/6b84115e3bbe6b76ebb1265e8ff2161c0bc88dcd6499eaf29c61a66421e9/zensical-0.0.45-cp310-abi3-macosx_10_12_x86_64.whl", hash = "sha256:c4cb2e11132f02ae824e246e016e073458e12e9de1eaf86fd39f01890d41204c", size = 12698844, upload-time = "2026-06-09T11:22:56.537Z" },
|
|
5614
5614
|
{ url = "https://files.pythonhosted.org/packages/e2/dc/4ddf05d77c1455c32cb26da71f2a19d355927a45a3db5b26fb258a07ce8f/zensical-0.0.45-cp310-abi3-macosx_11_0_arm64.whl", hash = "sha256:799a01de2102b5f731744ad31bdbc464d0c07d484e67ba148f6923679afa6ce6", size = 12571590, upload-time = "2026-06-09T11:23:00.192Z" },
|
|
5615
5615
|
{ url = "https://files.pythonhosted.org/packages/4c/53/60c6cc7b2ce8b1a83eb87bff3f7289447995552fd9a30ca76ffba22ca9d5/zensical-0.0.45-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6201e79ea8a64bd3ced3f05ef4b1529da0e675d67b1395987c0ba942e4e10dc4", size = 12939590, upload-time = "2026-06-09T11:23:02.721Z" },
|
|
5616
|
-
{ url = "https://files.pythonhosted.org/packages/9f/1e/e9217ed75dba323a6f9a4eee28eb40416eff99932cd0ee6c394bf07b9ead/zensical-0.0.45-cp310-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:854aaf500e4a3ce64adea1faa7a1820c7cf9a4f66be1043e4e9ba727fe9cf2b5", size = 12911669, upload-time = "2026-06-09T11:23:05.407Z" },
|
|
5617
|
-
{ url = "https://files.pythonhosted.org/packages/71/3c/6fc9fe2334bb4460a8a8d732e23a30d2ddc2ecf63c2eb3487d9e7405e70d/zensical-0.0.45-cp310-abi3-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a80c57fd50fc60415914388286ac10a7d8b6f70b8ca7235597d09fb12c3171b0", size = 13267643, upload-time = "2026-06-09T11:23:07.915Z" },
|
|
5618
5616
|
{ url = "https://files.pythonhosted.org/packages/be/f9/5696114af4ede5f1bd01e641a4ff24ee8ca49810bfaa28e5be12d930c0ef/zensical-0.0.45-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:58c3510f69e08b6ed8bb9596fc9393e4687f90394aa0ef2d6118b1375ad97be5", size = 12972147, upload-time = "2026-06-09T11:23:12.069Z" },
|
|
5619
5617
|
{ url = "https://files.pythonhosted.org/packages/a3/9e/5c6acde480c43f8c993b13260925df8db31d51ab8a9977618e9efdd98d45/zensical-0.0.45-cp310-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:01c484bb2ee85e98e21e24b397ff52ffc31101f7485935eee5d3afa6cca6cc08", size = 13117360, upload-time = "2026-06-09T11:23:15.155Z" },
|
|
5620
|
-
{ url = "https://files.pythonhosted.org/packages/3d/31/ea21f102049b35a8fe5218c5331857a15eeb60deb1bb21823a4c0701e274/zensical-0.0.45-cp310-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:3654b708830303759e866a58a60c483cd2a1c56a44acdaae5bbb341a3f40ebce", size = 13185593, upload-time = "2026-06-09T11:23:18.166Z" },
|
|
5621
|
-
{ url = "https://files.pythonhosted.org/packages/b4/97/6ded39fe27fa8a292d17d9af713b018e4919315233b60fa4b4b0aca737a6/zensical-0.0.45-cp310-abi3-musllinux_1_2_i686.whl", hash = "sha256:c4da1c37eca1474b487def0ef40d7ac2aff31a9d7a029cb7479ef7c354437361", size = 13326882, upload-time = "2026-06-09T11:23:21.027Z" },
|
|
5622
5618
|
{ url = "https://files.pythonhosted.org/packages/79/80/075975032a9e20f319c0134f8ca659d295ee4908f15ab212702a2728247f/zensical-0.0.45-cp310-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:f8a1966c186feebd3b795f9d420000bfd582e16eefdd9bc7a286d878faabae52", size = 13253961, upload-time = "2026-06-09T11:23:23.99Z" },
|
|
5623
|
-
{ url = "https://files.pythonhosted.org/packages/3f/6a/0eab0eb311af6a07cde15ca58d5d720cbfa02cd509e4c7fb5fa20cda0b46/zensical-0.0.45-cp310-abi3-win32.whl", hash = "sha256:a1dd63a5efb8d0e5f2fadf862f02771a279dc5cbe9a982700194650065758f01", size = 12257083, upload-time = "2026-06-09T11:23:26.769Z" },
|
|
5624
5619
|
{ url = "https://files.pythonhosted.org/packages/1f/cd/b117e749c60b1d1e16b8450db1355f69f38376f783b8c6c8815202988933/zensical-0.0.45-cp310-abi3-win_amd64.whl", hash = "sha256:1f2c0e69839ce4274bde34d18139d3b0d96bbf02b245ada46243590c9eedebc1", size = 12498335, upload-time = "2026-06-09T11:23:29.702Z" },
|
|
5625
5620
|
]
|
|
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
|
|
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
|
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|