openmaterica 0.1.0.dev1__py3-none-any.whl
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.
- materica/README.md +33 -0
- materica/__init__.py +8 -0
- materica/core/README.md +72 -0
- materica/core/__init__.py +2 -0
- materica/core/canonical.py +92 -0
- materica/core/envelope.py +93 -0
- materica/core/hashing.py +38 -0
- materica/core/identifiers.py +67 -0
- materica/core/jsonio.py +102 -0
- materica/core/read.py +301 -0
- materica/core/reasons.py +46 -0
- materica/core/record.py +107 -0
- materica/core/resolve.py +82 -0
- materica/core/status.py +17 -0
- materica/core/vocabulary.py +139 -0
- materica/data/conformance/README.md +103 -0
- materica/data/conformance/hash/CASES.md +105 -0
- materica/data/conformance/hash/README.md +45 -0
- materica/data/conformance/hash/cases/HS-001.escaped_names.json +24 -0
- materica/data/conformance/hash/cases/HS-001.names_exact.json +24 -0
- materica/data/conformance/hash/cases/HS-001.nested_names_kept.json +24 -0
- materica/data/conformance/hash/cases/HS-001.outside_kept.json +24 -0
- materica/data/conformance/hash/cases/HS-001.provenance_anywhere.json +24 -0
- materica/data/conformance/hash/cases/HS-001.provenance_arrays.json +24 -0
- materica/data/conformance/hash/cases/HS-001.provenance_depth.json +24 -0
- materica/data/conformance/hash/cases/HS-001.provenance_inside_non_object.json +24 -0
- materica/data/conformance/hash/cases/HS-001.provenance_members.json +24 -0
- materica/data/conformance/hash/cases/HS-001.provenance_nested_in_provenance.json +24 -0
- materica/data/conformance/hash/cases/HS-001.provenance_not_object.json +24 -0
- materica/data/conformance/hash/cases/HS-001.top_level_absent.json +24 -0
- materica/data/conformance/hash/cases/HS-001.top_level_any_value.json +24 -0
- materica/data/conformance/hash/cases/HS-001.top_level_array.json +24 -0
- materica/data/conformance/hash/cases/HS-001.top_level_removed.json +24 -0
- materica/data/conformance/hash/cases/HS-001.top_level_scalar.json +24 -0
- materica/data/conformance/hash/cases/HS-002.material.json +24 -0
- materica/data/conformance/hash/cases/HS-002.material_table.json +24 -0
- materica/data/conformance/hash/cases/HS-002.overlay.json +24 -0
- materica/data/conformance/hash/cases/HS-002.string_escapes.json +24 -0
- materica/data/conformance/hash/cases/HS-003.depth_64.json +24 -0
- materica/data/conformance/hash/cases/HS-003.depth_64_scalar.json +24 -0
- materica/data/conformance/hash/cases/HS-003.integer_1e20.json +24 -0
- materica/data/conformance/hash/cases/HS-003.integer_1e21.json +24 -0
- materica/data/conformance/hash/cases/HS-003.integer_9007199254740993.json +24 -0
- materica/data/conformance/hash/cases/HS-003.largest_double.json +24 -0
- materica/data/conformance/hash/cases/HS-003.malformed_bom.json +27 -0
- materica/data/conformance/hash/cases/HS-003.malformed_depth_65.json +27 -0
- materica/data/conformance/hash/cases/HS-003.malformed_duplicate_name.json +27 -0
- materica/data/conformance/hash/cases/HS-003.malformed_duplicate_removed_member.json +27 -0
- materica/data/conformance/hash/cases/HS-003.malformed_nan.json +27 -0
- materica/data/conformance/hash/cases/HS-003.malformed_overflow.json +27 -0
- materica/data/conformance/hash/cases/HS-003.malformed_overlong_utf8.json +27 -0
- materica/data/conformance/hash/cases/HS-003.malformed_trailing_comma.json +27 -0
- materica/data/conformance/hash/cases/HS-003.malformed_unpaired_surrogate.json +27 -0
- materica/data/conformance/hash/cases/HS-003.negative_zero.json +24 -0
- materica/data/conformance/hash/cases/HS-003.nfc_decomposed.json +24 -0
- materica/data/conformance/hash/cases/HS-003.nfc_side_by_side.json +24 -0
- materica/data/conformance/hash/cases/HS-003.null_in_unknown_member.json +24 -0
- materica/data/conformance/hash/cases/HS-003.number_0_0000001.json +24 -0
- materica/data/conformance/hash/cases/HS-003.number_1.json +24 -0
- materica/data/conformance/hash/cases/HS-003.number_1_0.json +24 -0
- materica/data/conformance/hash/cases/HS-003.number_1e2.json +24 -0
- materica/data/conformance/hash/cases/HS-003.provenance_not_object.json +24 -0
- materica/data/conformance/hash/cases/HS-003.review_copy_at_depth.json +24 -0
- materica/data/conformance/hash/cases/HS-003.review_copy_view.json +24 -0
- materica/data/conformance/hash/cases/HS-003.true_beside_one.json +24 -0
- materica/data/conformance/hash/cases/HS-003.underflow.json +24 -0
- materica/data/conformance/hash/cases/HS-003.unknown_members_hashed.json +24 -0
- materica/data/conformance/hash/cases/HS-003.utf16_order_escaped.json +24 -0
- materica/data/conformance/hash/cases/HS-003.utf16_order_raw.json +24 -0
- materica/data/conformance/hash/cases/HS-010.control_hash_verifies.json +58 -0
- materica/data/conformance/hash/cases/HS-010.envelope_refused.json +58 -0
- materica/data/conformance/hash/cases/HS-010.licence_edited.json +61 -0
- materica/data/conformance/hash/cases/HS-010.member_added.json +61 -0
- materica/data/conformance/hash/cases/HS-010.name_edited.json +61 -0
- materica/data/conformance/hash/cases/HS-010.other_version.json +58 -0
- materica/data/conformance/hash/cases/HS-010.type_edited.json +61 -0
- materica/data/conformance/hash/cases/HS-010.value_edited.json +61 -0
- materica/data/conformance/hash/cases/HS-011.edited_after_pinning.json +61 -0
- materica/data/conformance/hash/cases/HS-011.stated_differs.json +58 -0
- materica/data/conformance/hash/cases/HS-011.stated_differs_recomputed_equals.json +58 -0
- materica/data/conformance/hash/inputs/depth_64.json +1 -0
- materica/data/conformance/hash/inputs/depth_64_scalar.json +1 -0
- materica/data/conformance/hash/inputs/interface_fixture.json +14 -0
- materica/data/conformance/hash/inputs/malformed_bom.json +1 -0
- materica/data/conformance/hash/inputs/malformed_depth_65.json +1 -0
- materica/data/conformance/hash/inputs/malformed_duplicate_name.json +1 -0
- materica/data/conformance/hash/inputs/malformed_duplicate_removed_member.json +1 -0
- materica/data/conformance/hash/inputs/malformed_nan.json +1 -0
- materica/data/conformance/hash/inputs/malformed_overflow.json +1 -0
- materica/data/conformance/hash/inputs/malformed_overlong_utf8.json +1 -0
- materica/data/conformance/hash/inputs/malformed_trailing_comma.json +1 -0
- materica/data/conformance/hash/inputs/malformed_unpaired_surrogate.json +1 -0
- materica/data/conformance/hash/inputs/nfc_decomposed.json +5 -0
- materica/data/conformance/hash/inputs/nfc_side_by_side.json +4 -0
- materica/data/conformance/hash/inputs/number_0_0000001.json +1 -0
- materica/data/conformance/hash/inputs/number_1.json +1 -0
- materica/data/conformance/hash/inputs/number_1_0.json +1 -0
- materica/data/conformance/hash/inputs/number_1e2.json +1 -0
- materica/data/conformance/hash/inputs/number_9007199254740993.json +1 -0
- materica/data/conformance/hash/inputs/number_integer_1e20.json +1 -0
- materica/data/conformance/hash/inputs/number_integer_1e21.json +1 -0
- materica/data/conformance/hash/inputs/number_largest_double.json +1 -0
- materica/data/conformance/hash/inputs/number_negative_zero.json +1 -0
- materica/data/conformance/hash/inputs/number_underflow.json +1 -0
- materica/data/conformance/hash/inputs/strings_canonical.json +4 -0
- materica/data/conformance/hash/inputs/true_beside_one.json +1 -0
- materica/data/conformance/hash/inputs/utf16_order_escaped.json +7 -0
- materica/data/conformance/hash/inputs/utf16_order_raw.json +7 -0
- materica/data/conformance/hash/inputs/view_escaped_names.json +7 -0
- materica/data/conformance/hash/inputs/view_names_exact.json +8 -0
- materica/data/conformance/hash/inputs/view_nested_names_kept.json +5 -0
- materica/data/conformance/hash/inputs/view_outside_kept.json +7 -0
- materica/data/conformance/hash/inputs/view_provenance_anywhere.json +5 -0
- materica/data/conformance/hash/inputs/view_provenance_arrays.json +11 -0
- materica/data/conformance/hash/inputs/view_provenance_depth.json +12 -0
- materica/data/conformance/hash/inputs/view_provenance_inside_non_object.json +1 -0
- materica/data/conformance/hash/inputs/view_provenance_members.json +7 -0
- materica/data/conformance/hash/inputs/view_provenance_nested_in_provenance.json +1 -0
- materica/data/conformance/hash/inputs/view_provenance_not_object.json +7 -0
- materica/data/conformance/hash/inputs/view_top_level_absent.json +1 -0
- materica/data/conformance/hash/inputs/view_top_level_any_value.json +1 -0
- materica/data/conformance/hash/inputs/view_top_level_array.json +1 -0
- materica/data/conformance/hash/inputs/view_top_level_removed.json +5 -0
- materica/data/conformance/hash/inputs/view_top_level_scalar.json +1 -0
- materica/data/conformance/hash/inputs/water_density_fixture.json +117 -0
- materica/data/conformance/hash/inputs/water_fixture.json +99 -0
- materica/data/conformance/hash/inputs/water_fixture_envelope_refused.json +96 -0
- materica/data/conformance/hash/inputs/water_fixture_licence_edited.json +99 -0
- materica/data/conformance/hash/inputs/water_fixture_member_added.json +100 -0
- materica/data/conformance/hash/inputs/water_fixture_name_edited.json +99 -0
- materica/data/conformance/hash/inputs/water_fixture_null_unknown.json +103 -0
- materica/data/conformance/hash/inputs/water_fixture_other_version.json +99 -0
- materica/data/conformance/hash/inputs/water_fixture_provenance_not_object.json +117 -0
- materica/data/conformance/hash/inputs/water_fixture_review_copy.json +139 -0
- materica/data/conformance/hash/inputs/water_fixture_review_copy_view.json +122 -0
- materica/data/conformance/hash/inputs/water_fixture_type_edited.json +99 -0
- materica/data/conformance/hash/inputs/water_fixture_unknown_members.json +128 -0
- materica/data/conformance/hash/inputs/water_fixture_value_edited.json +99 -0
- materica/data/conformance/hash/inputs/water_overlay_fixture.json +97 -0
- materica/data/conformance/plain_read/CASES.md +504 -0
- materica/data/conformance/plain_read/README.md +61 -0
- materica/data/conformance/plain_read/cases/PR-001.cbor.json +53 -0
- materica/data/conformance/plain_read/cases/PR-001.listing_yaml_not_listed.json +32 -0
- materica/data/conformance/plain_read/cases/PR-001.toml.json +53 -0
- materica/data/conformance/plain_read/cases/PR-001.yaml.json +53 -0
- materica/data/conformance/plain_read/cases/PR-002.body_not_object.json +53 -0
- materica/data/conformance/plain_read/cases/PR-002.bom.json +53 -0
- materica/data/conformance/plain_read/cases/PR-002.card_not_string.json +53 -0
- materica/data/conformance/plain_read/cases/PR-002.comment.json +53 -0
- materica/data/conformance/plain_read/cases/PR-002.content_hash_63_digits.json +53 -0
- materica/data/conformance/plain_read/cases/PR-002.content_hash_no_prefix.json +53 -0
- materica/data/conformance/plain_read/cases/PR-002.content_hash_not_string.json +53 -0
- materica/data/conformance/plain_read/cases/PR-002.content_hash_trailing_newline.json +53 -0
- materica/data/conformance/plain_read/cases/PR-002.content_hash_uppercase.json +53 -0
- materica/data/conformance/plain_read/cases/PR-002.content_hash_uppercase_pinned_as_stated.json +53 -0
- materica/data/conformance/plain_read/cases/PR-002.duplicate_member.json +53 -0
- materica/data/conformance/plain_read/cases/PR-002.duplicate_member_escaped.json +53 -0
- materica/data/conformance/plain_read/cases/PR-002.encoded_surrogate.json +53 -0
- materica/data/conformance/plain_read/cases/PR-002.extensions_not_object.json +53 -0
- materica/data/conformance/plain_read/cases/PR-002.fields_array.json +53 -0
- materica/data/conformance/plain_read/cases/PR-002.id_namespace_uppercase.json +53 -0
- materica/data/conformance/plain_read/cases/PR-002.id_not_string.json +53 -0
- materica/data/conformance/plain_read/cases/PR-002.id_without_namespace.json +53 -0
- materica/data/conformance/plain_read/cases/PR-002.infinity.json +53 -0
- materica/data/conformance/plain_read/cases/PR-002.invalid_json.json +53 -0
- materica/data/conformance/plain_read/cases/PR-002.known_section_fields_missing.json +53 -0
- materica/data/conformance/plain_read/cases/PR-002.known_section_not_object.json +53 -0
- materica/data/conformance/plain_read/cases/PR-002.licence_evidence_missing.json +53 -0
- materica/data/conformance/plain_read/cases/PR-002.licence_evidence_not_string.json +53 -0
- materica/data/conformance/plain_read/cases/PR-002.licence_not_object.json +53 -0
- materica/data/conformance/plain_read/cases/PR-002.licence_values_missing.json +53 -0
- materica/data/conformance/plain_read/cases/PR-002.local_id_empty.json +53 -0
- materica/data/conformance/plain_read/cases/PR-002.local_id_trailing_newline.json +53 -0
- materica/data/conformance/plain_read/cases/PR-002.local_id_with_space.json +53 -0
- materica/data/conformance/plain_read/cases/PR-002.missing_body.json +53 -0
- materica/data/conformance/plain_read/cases/PR-002.missing_content_hash.json +53 -0
- materica/data/conformance/plain_read/cases/PR-002.missing_id.json +53 -0
- materica/data/conformance/plain_read/cases/PR-002.missing_licence.json +53 -0
- materica/data/conformance/plain_read/cases/PR-002.missing_name.json +53 -0
- materica/data/conformance/plain_read/cases/PR-002.missing_record_type.json +53 -0
- materica/data/conformance/plain_read/cases/PR-002.missing_version.json +53 -0
- materica/data/conformance/plain_read/cases/PR-002.name_not_string.json +53 -0
- materica/data/conformance/plain_read/cases/PR-002.nan.json +53 -0
- materica/data/conformance/plain_read/cases/PR-002.negative_infinity.json +53 -0
- materica/data/conformance/plain_read/cases/PR-002.nesting_100000.json +53 -0
- materica/data/conformance/plain_read/cases/PR-002.nesting_65.json +53 -0
- materica/data/conformance/plain_read/cases/PR-002.number_overflow.json +53 -0
- materica/data/conformance/plain_read/cases/PR-002.number_overflow_exponent.json +53 -0
- materica/data/conformance/plain_read/cases/PR-002.overlay_base_content_hash_missing.json +53 -0
- materica/data/conformance/plain_read/cases/PR-002.overlay_base_content_hash_not_string.json +53 -0
- materica/data/conformance/plain_read/cases/PR-002.overlay_base_id_missing.json +53 -0
- materica/data/conformance/plain_read/cases/PR-002.overlay_base_id_not_string.json +53 -0
- materica/data/conformance/plain_read/cases/PR-002.overlay_base_missing.json +53 -0
- materica/data/conformance/plain_read/cases/PR-002.overlay_base_not_object.json +53 -0
- materica/data/conformance/plain_read/cases/PR-002.overlay_base_version_missing.json +53 -0
- materica/data/conformance/plain_read/cases/PR-002.overlay_base_version_not_string.json +53 -0
- materica/data/conformance/plain_read/cases/PR-002.overlay_purpose_missing.json +53 -0
- materica/data/conformance/plain_read/cases/PR-002.overlay_purpose_not_string.json +53 -0
- materica/data/conformance/plain_read/cases/PR-002.overlay_replaces_missing.json +53 -0
- materica/data/conformance/plain_read/cases/PR-002.overlay_replaces_not_object.json +53 -0
- materica/data/conformance/plain_read/cases/PR-002.overlay_scope_consumer_missing.json +53 -0
- materica/data/conformance/plain_read/cases/PR-002.overlay_scope_consumer_not_string.json +53 -0
- materica/data/conformance/plain_read/cases/PR-002.overlay_scope_missing.json +53 -0
- materica/data/conformance/plain_read/cases/PR-002.overlay_scope_model_configuration_hash_not_string.json +53 -0
- materica/data/conformance/plain_read/cases/PR-002.overlay_scope_model_empty.json +53 -0
- materica/data/conformance/plain_read/cases/PR-002.overlay_scope_model_name_missing.json +53 -0
- materica/data/conformance/plain_read/cases/PR-002.overlay_scope_model_name_not_string.json +53 -0
- materica/data/conformance/plain_read/cases/PR-002.overlay_scope_model_not_object.json +53 -0
- materica/data/conformance/plain_read/cases/PR-002.overlay_scope_model_version_missing.json +53 -0
- materica/data/conformance/plain_read/cases/PR-002.overlay_scope_model_version_not_string.json +53 -0
- materica/data/conformance/plain_read/cases/PR-002.overlay_scope_not_object.json +53 -0
- materica/data/conformance/plain_read/cases/PR-002.overlay_scope_run_not_string.json +53 -0
- materica/data/conformance/plain_read/cases/PR-002.overlong.json +53 -0
- materica/data/conformance/plain_read/cases/PR-002.read_escaped_nul.json +31 -0
- materica/data/conformance/plain_read/cases/PR-002.read_nesting_64.json +31 -0
- materica/data/conformance/plain_read/cases/PR-002.read_noncharacter.json +31 -0
- materica/data/conformance/plain_read/cases/PR-002.read_noncharacter_escaped.json +31 -0
- materica/data/conformance/plain_read/cases/PR-002.record_type_not_string.json +53 -0
- materica/data/conformance/plain_read/cases/PR-002.sections_missing.json +53 -0
- materica/data/conformance/plain_read/cases/PR-002.sections_not_object.json +53 -0
- materica/data/conformance/plain_read/cases/PR-002.trailing_comma.json +53 -0
- materica/data/conformance/plain_read/cases/PR-002.trailing_content.json +53 -0
- materica/data/conformance/plain_read/cases/PR-002.truncated_utf8.json +53 -0
- materica/data/conformance/plain_read/cases/PR-002.unescaped_control_character.json +53 -0
- materica/data/conformance/plain_read/cases/PR-002.unpaired_low_surrogate_escape.json +53 -0
- materica/data/conformance/plain_read/cases/PR-002.unpaired_surrogate_escape.json +53 -0
- materica/data/conformance/plain_read/cases/PR-002.utf16be.json +53 -0
- materica/data/conformance/plain_read/cases/PR-002.utf16le.json +53 -0
- materica/data/conformance/plain_read/cases/PR-002.utf16le_bom.json +53 -0
- materica/data/conformance/plain_read/cases/PR-002.utf32be.json +53 -0
- materica/data/conformance/plain_read/cases/PR-002.utf32le.json +53 -0
- materica/data/conformance/plain_read/cases/PR-002.version_leading_zero.json +53 -0
- materica/data/conformance/plain_read/cases/PR-002.version_not_string.json +53 -0
- materica/data/conformance/plain_read/cases/PR-002.version_off_pattern.json +53 -0
- materica/data/conformance/plain_read/cases/PR-004.interface_missing_licence.json +53 -0
- materica/data/conformance/plain_read/cases/PR-004.interface_missing_name.json +53 -0
- materica/data/conformance/plain_read/cases/PR-004.material_and_overlay_listed.json +36 -0
- materica/data/conformance/plain_read/cases/PR-004.material_listed.json +31 -0
- materica/data/conformance/plain_read/cases/PR-004.namespaced_type_missing_name.json +53 -0
- materica/data/conformance/plain_read/cases/PR-004.overlay_licence_evidence_not_string.json +53 -0
- materica/data/conformance/plain_read/cases/PR-004.overlay_listed.json +31 -0
- materica/data/conformance/plain_read/cases/PR-004.overlay_missing_body.json +53 -0
- materica/data/conformance/plain_read/cases/PR-004.overlay_missing_licence.json +53 -0
- materica/data/conformance/plain_read/cases/PR-004.overlay_missing_name.json +53 -0
- materica/data/conformance/plain_read/cases/PR-004.overlay_missing_name_not_listed.json +32 -0
- materica/data/conformance/plain_read/cases/PR-004.overlay_missing_record_type.json +53 -0
- materica/data/conformance/plain_read/cases/PR-004.overlay_missing_schema_version.json +53 -0
- materica/data/conformance/plain_read/cases/PR-004.overlay_scope_model_complete_listed.json +31 -0
- materica/data/conformance/plain_read/cases/PR-004.unknown_type_missing_body.json +53 -0
- materica/data/conformance/plain_read/cases/PR-006.all_sources.json +46 -0
- materica/data/conformance/plain_read/cases/PR-006.array_source_not_listed.json +32 -0
- materica/data/conformance/plain_read/cases/PR-006.document_type_without_record_type_skipped.json +32 -0
- materica/data/conformance/plain_read/cases/PR-006.engine_crosswalk_skipped.json +32 -0
- materica/data/conformance/plain_read/cases/PR-006.id_only_object_not_listed.json +32 -0
- materica/data/conformance/plain_read/cases/PR-006.interface_skipped.json +32 -0
- materica/data/conformance/plain_read/cases/PR-006.namespaced_type_skipped.json +32 -0
- materica/data/conformance/plain_read/cases/PR-006.number_source_not_listed.json +32 -0
- materica/data/conformance/plain_read/cases/PR-006.record_with_document_type_member_listed.json +31 -0
- materica/data/conformance/plain_read/cases/PR-006.scene_manifest_skipped.json +32 -0
- materica/data/conformance/plain_read/cases/PR-006.unknown_type_skipped.json +32 -0
- materica/data/conformance/plain_read/cases/PR-007.interface.json +53 -0
- materica/data/conformance/plain_read/cases/PR-007.interface_other_version.json +53 -0
- materica/data/conformance/plain_read/cases/PR-007.interface_pin_mismatch.json +53 -0
- materica/data/conformance/plain_read/cases/PR-007.namespaced_type.json +53 -0
- materica/data/conformance/plain_read/cases/PR-007.record_type_capitalised.json +53 -0
- materica/data/conformance/plain_read/cases/PR-007.unknown_type.json +53 -0
- materica/data/conformance/plain_read/cases/PR-026.minor_0_0_1.json +53 -0
- materica/data/conformance/plain_read/cases/PR-026.minor_0_10_0.json +53 -0
- materica/data/conformance/plain_read/cases/PR-026.minor_0_2_0.json +53 -0
- materica/data/conformance/plain_read/cases/PR-026.minor_0_2_0_not_listed.json +26 -0
- materica/data/conformance/plain_read/cases/PR-027.major_1_0_0.json +53 -0
- materica/data/conformance/plain_read/cases/PR-027.major_1_1_0.json +53 -0
- materica/data/conformance/plain_read/cases/PR-027.major_2_0_0.json +53 -0
- materica/data/conformance/plain_read/cases/PR-048.absent.json +53 -0
- materica/data/conformance/plain_read/cases/PR-048.arabic_indic_digits.json +53 -0
- materica/data/conformance/plain_read/cases/PR-048.leading_zero_major.json +53 -0
- materica/data/conformance/plain_read/cases/PR-048.leading_zero_minor.json +53 -0
- materica/data/conformance/plain_read/cases/PR-048.major_100_digits.json +53 -0
- materica/data/conformance/plain_read/cases/PR-048.minor_100_digits.json +53 -0
- materica/data/conformance/plain_read/cases/PR-048.not_string_array.json +53 -0
- materica/data/conformance/plain_read/cases/PR-048.not_string_null.json +53 -0
- materica/data/conformance/plain_read/cases/PR-048.not_string_number.json +53 -0
- materica/data/conformance/plain_read/cases/PR-048.other_version_before_envelope.json +53 -0
- materica/data/conformance/plain_read/cases/PR-048.patch_0_1_7_listed.json +31 -0
- materica/data/conformance/plain_read/cases/PR-048.patch_100_digits_listed.json +31 -0
- materica/data/conformance/plain_read/cases/PR-048.pre_release.json +53 -0
- materica/data/conformance/plain_read/cases/PR-048.trailing_newline.json +53 -0
- materica/data/conformance/plain_read/cases/PR-048.trailing_space.json +53 -0
- materica/data/conformance/plain_read/cases/PR-048.two_components.json +53 -0
- materica/data/conformance/plain_read/cases/PR-049.body_null.json +53 -0
- materica/data/conformance/plain_read/cases/PR-049.card_null.json +53 -0
- materica/data/conformance/plain_read/cases/PR-049.extensions_null.json +53 -0
- materica/data/conformance/plain_read/cases/PR-049.fields_null.json +53 -0
- materica/data/conformance/plain_read/cases/PR-049.known_section_null.json +53 -0
- materica/data/conformance/plain_read/cases/PR-049.licence_evidence_null.json +53 -0
- materica/data/conformance/plain_read/cases/PR-049.licence_null.json +53 -0
- materica/data/conformance/plain_read/cases/PR-049.licence_values_null.json +53 -0
- materica/data/conformance/plain_read/cases/PR-049.name_null.json +53 -0
- materica/data/conformance/plain_read/cases/PR-049.overlay_base_content_hash_null.json +53 -0
- materica/data/conformance/plain_read/cases/PR-049.overlay_base_id_null.json +53 -0
- materica/data/conformance/plain_read/cases/PR-049.overlay_base_null.json +53 -0
- materica/data/conformance/plain_read/cases/PR-049.overlay_base_version_null.json +53 -0
- materica/data/conformance/plain_read/cases/PR-049.overlay_purpose_null.json +53 -0
- materica/data/conformance/plain_read/cases/PR-049.overlay_replaces_null.json +53 -0
- materica/data/conformance/plain_read/cases/PR-049.overlay_scope_consumer_null.json +53 -0
- materica/data/conformance/plain_read/cases/PR-049.overlay_scope_model_configuration_hash_null.json +53 -0
- materica/data/conformance/plain_read/cases/PR-049.overlay_scope_model_null.json +53 -0
- materica/data/conformance/plain_read/cases/PR-049.overlay_scope_null.json +53 -0
- materica/data/conformance/plain_read/cases/PR-049.overlay_scope_run_null.json +53 -0
- materica/data/conformance/plain_read/cases/PR-049.record_type_null.json +53 -0
- materica/data/conformance/plain_read/cases/PR-049.sections_null.json +53 -0
- materica/data/conformance/plain_read/cases/PR-049.unknown_top_level_member_null_listed.json +31 -0
- materica/data/conformance/plain_read/cases/PR-300.no_records.json +51 -0
- materica/data/conformance/plain_read/cases/PR-300.record_binary_bytes.json +53 -0
- materica/data/conformance/plain_read/cases/PR-300.record_empty_file.json +53 -0
- materica/data/conformance/plain_read/cases/PR-300.request_empty_file.json +27 -0
- materica/data/conformance/plain_read/cases/PR-300.request_nesting_100000.json +27 -0
- materica/data/conformance/plain_read/cases/PR-301.hash_and_pin_mismatch_hs.json +61 -0
- materica/data/conformance/plain_read/cases/PR-301.hash_and_pin_mismatch_no_hs.json +60 -0
- materica/data/conformance/plain_read/cases/PR-301.incomplete_and_unit_mismatch.json +57 -0
- materica/data/conformance/plain_read/cases/PR-301.step0_ends_read.json +53 -0
- materica/data/conformance/plain_read/cases/PR-301.step1_ends_read.json +53 -0
- materica/data/conformance/plain_read/cases/PR-301.step2_ends_read.json +53 -0
- materica/data/conformance/plain_read/cases/PR-301.three_codes_step0.json +68 -0
- materica/data/conformance/plain_read/cases/PR-301.three_codes_step0_with_fd.json +65 -0
- materica/data/conformance/plain_read/cases/PR-301.want_suite_and_incomplete.json +59 -0
- materica/data/conformance/plain_read/cases/PR-301.want_suite_and_incomplete_with_fd.json +56 -0
- materica/data/conformance/plain_read/cases/PR-308.no_want.json +52 -0
- materica/data/conformance/plain_read/cases/PR-308.tolerance_with_other_operating_condition.json +54 -0
- materica/data/conformance/plain_read/cases/PR-308.tolerance_without_operating_conditions.json +48 -0
- materica/data/conformance/plain_read/cases/PR-310.absent.json +53 -0
- materica/data/conformance/plain_read/cases/PR-310.hash_mismatch.json +59 -0
- materica/data/conformance/plain_read/cases/PR-310.malformed.json +53 -0
- materica/data/conformance/plain_read/cases/PR-310.other_version.json +53 -0
- materica/data/conformance/plain_read/cases/PR-310.pin_mismatch.json +53 -0
- materica/data/conformance/plain_read/cases/PR-310.request_incomplete.json +53 -0
- materica/data/conformance/plain_read/cases/PR-310.request_unit_mismatch.json +54 -0
- materica/data/conformance/plain_read/cases/PR-310.unknown_type.json +53 -0
- materica/data/conformance/plain_read/cases/PR-310.want_mismatch.json +56 -0
- materica/data/conformance/plain_read/cases/PR-320.accept_entry_with_unit_accepted.json +59 -0
- materica/data/conformance/plain_read/cases/PR-320.operating_range_lo_above_hi_wrong_unit.json +65 -0
- materica/data/conformance/plain_read/cases/PR-320.operating_range_per_minute.json +61 -0
- materica/data/conformance/plain_read/cases/PR-320.operating_range_three_numbers_wrong_unit.json +66 -0
- materica/data/conformance/plain_read/cases/PR-320.operating_token_condition_with_unit.json +58 -0
- materica/data/conformance/plain_read/cases/PR-320.operating_unit_array.json +56 -0
- materica/data/conformance/plain_read/cases/PR-320.operating_unit_escaped_k_accepted.json +53 -0
- materica/data/conformance/plain_read/cases/PR-320.operating_unit_kelvin_sign.json +54 -0
- materica/data/conformance/plain_read/cases/PR-320.operating_unit_kelvin_sign_escaped.json +54 -0
- materica/data/conformance/plain_read/cases/PR-320.operating_unit_lowercase_k.json +54 -0
- materica/data/conformance/plain_read/cases/PR-320.operating_unit_null.json +54 -0
- materica/data/conformance/plain_read/cases/PR-320.operating_unit_number.json +54 -0
- materica/data/conformance/plain_read/cases/PR-320.operating_unit_per_s.json +58 -0
- materica/data/conformance/plain_read/cases/PR-320.operating_unit_s_minus_1.json +58 -0
- materica/data/conformance/plain_read/cases/PR-320.operating_unit_trailing_space.json +54 -0
- materica/data/conformance/plain_read/cases/PR-320.operating_unregistered_condition_with_unit.json +58 -0
- materica/data/conformance/plain_read/cases/PR-320.operating_value_and_range_wrong_unit.json +62 -0
- materica/data/conformance/plain_read/cases/PR-320.operating_value_cel.json +54 -0
- materica/data/conformance/plain_read/cases/PR-320.operating_value_missing_wrong_unit.json +57 -0
- materica/data/conformance/plain_read/cases/PR-320.operating_value_not_number_wrong_unit.json +58 -0
- materica/data/conformance/plain_read/cases/PR-320.operating_without_tolerance_cel.json +46 -0
- materica/data/conformance/plain_read/cases/PR-320.specimen_size_mm.json +58 -0
- materica/data/conformance/plain_read/cases/PR-320.tolerance_and_accept_wrong_unit.json +61 -0
- materica/data/conformance/plain_read/cases/PR-320.tolerance_below_zero_wrong_unit.json +58 -0
- materica/data/conformance/plain_read/cases/PR-320.tolerance_cel.json +54 -0
- materica/data/conformance/plain_read/cases/PR-320.tolerance_for_token_condition_with_unit.json +60 -0
- materica/data/conformance/plain_read/cases/PR-320.tolerance_unit_array.json +56 -0
- materica/data/conformance/plain_read/cases/PR-320.tolerance_unit_escaped_k_accepted.json +53 -0
- materica/data/conformance/plain_read/cases/PR-320.tolerance_unit_kelvin_sign.json +54 -0
- materica/data/conformance/plain_read/cases/PR-320.tolerance_unit_null.json +54 -0
- materica/data/conformance/plain_read/cases/PR-320.tolerance_unit_number.json +54 -0
- materica/data/conformance/plain_read/cases/PR-320.tolerance_unregistered_condition_with_unit.json +60 -0
- materica/data/conformance/plain_read/cases/PR-320.tolerance_value_not_number_wrong_unit.json +58 -0
- materica/data/conformance/plain_read/cases/PR-320.tolerance_without_operating_condition_wrong_unit.json +64 -0
- materica/data/conformance/plain_read/cases/PR-327.label_hs.json +58 -0
- materica/data/conformance/plain_read/cases/PR-327.label_no_hs.json +60 -0
- materica/data/conformance/plain_read/cases/PR-327.pin.json +55 -0
- materica/data/conformance/plain_read/cases/PR-327.pin_no_hs.json +58 -0
- materica/data/conformance/plain_read/cases/PR-328.array_source_malformed.json +54 -0
- materica/data/conformance/plain_read/cases/PR-328.engine_crosswalk_named_absent.json +54 -0
- materica/data/conformance/plain_read/cases/PR-328.id_only_object_malformed.json +54 -0
- materica/data/conformance/plain_read/cases/PR-328.ill_formed_hash_other_version_absent.json +53 -0
- materica/data/conformance/plain_read/cases/PR-328.no_candidate_absent.json +53 -0
- materica/data/conformance/plain_read/cases/PR-328.number_source_malformed.json +54 -0
- materica/data/conformance/plain_read/cases/PR-328.other_version_of_id_absent.json +53 -0
- materica/data/conformance/plain_read/cases/PR-328.other_version_supplied_absent.json +53 -0
- materica/data/conformance/plain_read/cases/PR-328.scene_manifest_absent.json +54 -0
- materica/data/conformance/plain_read/cases/PR-328.set_aside_and_unparsed_malformed.json +54 -0
- materica/data/conformance/plain_read/cases/PR-328.string_source_malformed.json +54 -0
- materica/data/conformance/plain_read/cases/PR-328.unparsed_source_malformed.json +54 -0
- materica/data/conformance/plain_read/cases/PR-328.unrelated_malformed_candidate_absent.json +53 -0
- materica/data/conformance/plain_read/cases/PR-328.version_not_string_source_malformed.json +54 -0
- materica/data/conformance/plain_read/cases/PR-329.hash_selects_other_version_copy.json +54 -0
- materica/data/conformance/plain_read/cases/PR-329.hash_selects_unknown_type_copy.json +54 -0
- materica/data/conformance/plain_read/cases/PR-329.identical_copies_read_once.json +54 -0
- materica/data/conformance/plain_read/cases/PR-329.match_beside_ill_formed_copy.json +54 -0
- materica/data/conformance/plain_read/cases/PR-329.match_beside_ill_formed_hash_other_version.json +54 -0
- materica/data/conformance/plain_read/cases/PR-329.match_beside_unparsed_source.json +54 -0
- materica/data/conformance/plain_read/cases/PR-329.none_with_hash_absent_content_hash.json +54 -0
- materica/data/conformance/plain_read/cases/PR-329.none_with_hash_beside_array_source.json +54 -0
- materica/data/conformance/plain_read/cases/PR-329.none_with_hash_beside_id_only_source.json +54 -0
- materica/data/conformance/plain_read/cases/PR-329.none_with_hash_beside_ill_formed_hash_other_version.json +54 -0
- materica/data/conformance/plain_read/cases/PR-329.none_with_hash_beside_malformed_other_candidate.json +54 -0
- materica/data/conformance/plain_read/cases/PR-329.none_with_hash_beside_number_source.json +54 -0
- materica/data/conformance/plain_read/cases/PR-329.none_with_hash_beside_scene_manifest.json +54 -0
- materica/data/conformance/plain_read/cases/PR-329.none_with_hash_beside_string_source.json +54 -0
- materica/data/conformance/plain_read/cases/PR-329.none_with_hash_beside_unparsed_source.json +54 -0
- materica/data/conformance/plain_read/cases/PR-329.none_with_hash_beside_version_not_string_source.json +54 -0
- materica/data/conformance/plain_read/cases/PR-329.none_with_hash_ill_formed_content_hash.json +54 -0
- materica/data/conformance/plain_read/cases/PR-329.none_with_hash_null_content_hash.json +54 -0
- materica/data/conformance/plain_read/cases/PR-329.none_with_hash_one_candidate.json +53 -0
- materica/data/conformance/plain_read/cases/PR-329.none_with_hash_several_candidates.json +54 -0
- materica/data/conformance/plain_read/cases/PR-329.two_with_hash_card_differs.json +54 -0
- materica/data/conformance/plain_read/cases/PR-329.two_with_hash_whitespace_differs.json +54 -0
- materica/data/conformance/plain_read/cases/PR-330.accept_for_numeric_condition.json +53 -0
- materica/data/conformance/plain_read/cases/PR-330.accept_list_accepted.json +58 -0
- materica/data/conformance/plain_read/cases/PR-330.accept_list_non_string.json +59 -0
- materica/data/conformance/plain_read/cases/PR-330.accept_not_list.json +57 -0
- materica/data/conformance/plain_read/cases/PR-330.condition_not_registered.json +59 -0
- materica/data/conformance/plain_read/cases/PR-330.field_empty_part.json +53 -0
- materica/data/conformance/plain_read/cases/PR-330.field_missing.json +52 -0
- materica/data/conformance/plain_read/cases/PR-330.field_no_dot.json +53 -0
- materica/data/conformance/plain_read/cases/PR-330.field_not_string.json +53 -0
- materica/data/conformance/plain_read/cases/PR-330.field_three_parts.json +53 -0
- materica/data/conformance/plain_read/cases/PR-330.field_trailing_newline.json +53 -0
- materica/data/conformance/plain_read/cases/PR-330.field_uppercase.json +53 -0
- materica/data/conformance/plain_read/cases/PR-330.not_json_bom.json +27 -0
- materica/data/conformance/plain_read/cases/PR-330.not_json_duplicate_member.json +27 -0
- materica/data/conformance/plain_read/cases/PR-330.not_json_nan.json +27 -0
- materica/data/conformance/plain_read/cases/PR-330.not_json_nesting_65.json +27 -0
- materica/data/conformance/plain_read/cases/PR-330.not_json_trailing_comma.json +27 -0
- materica/data/conformance/plain_read/cases/PR-330.not_object_array.json +30 -0
- materica/data/conformance/plain_read/cases/PR-330.not_object_string.json +27 -0
- materica/data/conformance/plain_read/cases/PR-330.operating_conditions_not_object.json +45 -0
- materica/data/conformance/plain_read/cases/PR-330.operating_conditions_not_object_beside_tolerance.json +57 -0
- materica/data/conformance/plain_read/cases/PR-330.operating_entry_not_object.json +51 -0
- materica/data/conformance/plain_read/cases/PR-330.operating_unit_missing.json +53 -0
- materica/data/conformance/plain_read/cases/PR-330.operating_value_and_range.json +58 -0
- materica/data/conformance/plain_read/cases/PR-330.operating_value_missing.json +53 -0
- materica/data/conformance/plain_read/cases/PR-330.operating_value_not_number.json +54 -0
- materica/data/conformance/plain_read/cases/PR-330.range_lo_above_hi.json +61 -0
- materica/data/conformance/plain_read/cases/PR-330.range_not_numbers.json +61 -0
- materica/data/conformance/plain_read/cases/PR-330.range_one_number.json +60 -0
- materica/data/conformance/plain_read/cases/PR-330.range_three_numbers.json +62 -0
- materica/data/conformance/plain_read/cases/PR-330.record_content_hash_not_string.json +55 -0
- materica/data/conformance/plain_read/cases/PR-330.record_id_missing.json +52 -0
- materica/data/conformance/plain_read/cases/PR-330.record_id_not_string.json +53 -0
- materica/data/conformance/plain_read/cases/PR-330.record_not_object.json +49 -0
- materica/data/conformance/plain_read/cases/PR-330.record_version_missing.json +52 -0
- materica/data/conformance/plain_read/cases/PR-330.record_version_not_string.json +53 -0
- materica/data/conformance/plain_read/cases/PR-330.record_without_content_hash.json +52 -0
- materica/data/conformance/plain_read/cases/PR-330.requirement_condition_empty.json +49 -0
- materica/data/conformance/plain_read/cases/PR-330.requirement_condition_not_object.json +49 -0
- materica/data/conformance/plain_read/cases/PR-330.requirement_conditions_not_object.json +53 -0
- materica/data/conformance/plain_read/cases/PR-330.requirement_missing.json +42 -0
- materica/data/conformance/plain_read/cases/PR-330.requirement_not_object.json +43 -0
- materica/data/conformance/plain_read/cases/PR-330.target_missing.json +45 -0
- materica/data/conformance/plain_read/cases/PR-330.target_neither_record_nor_region.json +48 -0
- materica/data/conformance/plain_read/cases/PR-330.target_not_object.json +46 -0
- materica/data/conformance/plain_read/cases/PR-330.tolerance_and_accept.json +57 -0
- materica/data/conformance/plain_read/cases/PR-330.tolerance_below_zero.json +54 -0
- materica/data/conformance/plain_read/cases/PR-330.tolerance_beside_accept_for_token_condition.json +63 -0
- materica/data/conformance/plain_read/cases/PR-330.tolerance_for_token_condition_without_unit.json +59 -0
- materica/data/conformance/plain_read/cases/PR-330.tolerance_negative_zero_accepted.json +53 -0
- materica/data/conformance/plain_read/cases/PR-330.tolerance_not_object.json +51 -0
- materica/data/conformance/plain_read/cases/PR-330.tolerance_unit_missing.json +53 -0
- materica/data/conformance/plain_read/cases/PR-330.tolerance_value_missing.json +53 -0
- materica/data/conformance/plain_read/cases/PR-330.tolerance_value_not_number.json +54 -0
- materica/data/conformance/plain_read/cases/PR-330.unknown_member_in_operating_condition.json +54 -0
- materica/data/conformance/plain_read/cases/PR-330.unknown_member_in_reference.json +54 -0
- materica/data/conformance/plain_read/cases/PR-330.unknown_member_in_requirement.json +54 -0
- materica/data/conformance/plain_read/cases/PR-330.unknown_member_in_target.json +54 -0
- materica/data/conformance/plain_read/cases/PR-330.unknown_member_in_tolerance.json +54 -0
- materica/data/conformance/plain_read/cases/PR-330.unknown_member_top_level.json +60 -0
- materica/data/conformance/plain_read/cases/PR-330.want_not_string.json +53 -0
- materica/data/conformance/plain_read/cases/PR-330.want_unknown_token.json +53 -0
- materica/data/conformance/plain_read/cases/PR-330.want_wrong_case.json +53 -0
- materica/data/conformance/plain_read/cases/PR-331.incomplete_and_unit_mismatch_once_each.json +58 -0
- materica/data/conformance/plain_read/cases/PR-331.malformed_once_step1.json +54 -0
- materica/data/conformance/plain_read/cases/PR-331.malformed_once_step1_pin.json +54 -0
- materica/data/conformance/plain_read/cases/PR-331.malformed_once_step3.json +53 -0
- materica/data/conformance/plain_read/cases/PR-331.request_incomplete_once_per_condition.json +54 -0
- materica/data/conformance/plain_read/cases/PR-331.request_incomplete_once_without_condition.json +52 -0
- materica/data/conformance/plain_read/cases/PR-331.request_incomplete_two_conditions.json +65 -0
- materica/data/conformance/plain_read/cases/PR-331.request_incomplete_with_and_without_condition.json +57 -0
- materica/data/conformance/plain_read/cases/PR-331.request_unit_mismatch_once.json +54 -0
- materica/data/conformance/plain_read/cases/PR-331.request_unit_mismatch_two_conditions.json +62 -0
- materica/data/conformance/plain_read/cases/PR-331.unregistered_condition_once.json +59 -0
- materica/data/conformance/plain_read/cases/PR-332.bounds_absent.json +53 -0
- materica/data/conformance/plain_read/cases/PR-332.components_absent.json +53 -0
- materica/data/conformance/plain_read/cases/PR-332.coverage_with_fd_absent.json +56 -0
- materica/data/conformance/plain_read/cases/PR-332.coverage_without_fd.json +56 -0
- materica/data/conformance/plain_read/cases/PR-332.evidence_absent.json +53 -0
- materica/data/conformance/plain_read/cases/PR-332.fit_with_fd_absent.json +56 -0
- materica/data/conformance/plain_read/cases/PR-332.fit_without_fd.json +56 -0
- materica/data/conformance/plain_read/cases/PR-332.reference_data_with_fd_absent.json +56 -0
- materica/data/conformance/plain_read/cases/PR-332.reference_data_without_fd.json +56 -0
- materica/data/conformance/plain_read/inputs/empty_file.json +0 -0
- materica/data/conformance/plain_read/inputs/engine_crosswalk_fixture.json +62 -0
- materica/data/conformance/plain_read/inputs/glycerol_fixture.json +87 -0
- materica/data/conformance/plain_read/inputs/interface_fixture.json +14 -0
- materica/data/conformance/plain_read/inputs/interface_fixture_copy.json +14 -0
- materica/data/conformance/plain_read/inputs/interface_fixture_edited.json +14 -0
- materica/data/conformance/plain_read/inputs/interface_fixture_edited_stale_hash.json +14 -0
- materica/data/conformance/plain_read/inputs/interface_missing_licence.json +10 -0
- materica/data/conformance/plain_read/inputs/interface_missing_name.json +13 -0
- materica/data/conformance/plain_read/inputs/interface_schema_0_2_0.json +14 -0
- materica/data/conformance/plain_read/inputs/namespaced_type_fixture.json +14 -0
- materica/data/conformance/plain_read/inputs/namespaced_type_missing_name.json +13 -0
- materica/data/conformance/plain_read/inputs/overlay_base_content_hash_missing.json +102 -0
- materica/data/conformance/plain_read/inputs/overlay_base_content_hash_not_string.json +103 -0
- materica/data/conformance/plain_read/inputs/overlay_base_content_hash_null.json +103 -0
- materica/data/conformance/plain_read/inputs/overlay_base_id_missing.json +102 -0
- materica/data/conformance/plain_read/inputs/overlay_base_id_not_string.json +103 -0
- materica/data/conformance/plain_read/inputs/overlay_base_id_null.json +103 -0
- materica/data/conformance/plain_read/inputs/overlay_base_missing.json +98 -0
- materica/data/conformance/plain_read/inputs/overlay_base_not_object.json +99 -0
- materica/data/conformance/plain_read/inputs/overlay_base_null.json +99 -0
- materica/data/conformance/plain_read/inputs/overlay_base_version_missing.json +102 -0
- materica/data/conformance/plain_read/inputs/overlay_base_version_not_string.json +103 -0
- materica/data/conformance/plain_read/inputs/overlay_base_version_null.json +103 -0
- materica/data/conformance/plain_read/inputs/overlay_licence_evidence_number.json +103 -0
- materica/data/conformance/plain_read/inputs/overlay_missing_body.json +13 -0
- materica/data/conformance/plain_read/inputs/overlay_missing_licence.json +99 -0
- materica/data/conformance/plain_read/inputs/overlay_missing_name.json +102 -0
- materica/data/conformance/plain_read/inputs/overlay_missing_record_type.json +102 -0
- materica/data/conformance/plain_read/inputs/overlay_missing_schema_version.json +102 -0
- materica/data/conformance/plain_read/inputs/overlay_purpose_missing.json +102 -0
- materica/data/conformance/plain_read/inputs/overlay_purpose_not_string.json +103 -0
- materica/data/conformance/plain_read/inputs/overlay_purpose_null.json +103 -0
- materica/data/conformance/plain_read/inputs/overlay_replaces_missing.json +24 -0
- materica/data/conformance/plain_read/inputs/overlay_replaces_not_object.json +25 -0
- materica/data/conformance/plain_read/inputs/overlay_replaces_null.json +25 -0
- materica/data/conformance/plain_read/inputs/overlay_scope_consumer_missing.json +101 -0
- materica/data/conformance/plain_read/inputs/overlay_scope_consumer_not_string.json +103 -0
- materica/data/conformance/plain_read/inputs/overlay_scope_consumer_null.json +103 -0
- materica/data/conformance/plain_read/inputs/overlay_scope_missing.json +100 -0
- materica/data/conformance/plain_read/inputs/overlay_scope_model_complete.json +109 -0
- materica/data/conformance/plain_read/inputs/overlay_scope_model_configuration_hash_not_string.json +108 -0
- materica/data/conformance/plain_read/inputs/overlay_scope_model_configuration_hash_null.json +108 -0
- materica/data/conformance/plain_read/inputs/overlay_scope_model_empty.json +105 -0
- materica/data/conformance/plain_read/inputs/overlay_scope_model_name_missing.json +107 -0
- materica/data/conformance/plain_read/inputs/overlay_scope_model_name_not_string.json +108 -0
- materica/data/conformance/plain_read/inputs/overlay_scope_model_not_object.json +105 -0
- materica/data/conformance/plain_read/inputs/overlay_scope_model_null.json +105 -0
- materica/data/conformance/plain_read/inputs/overlay_scope_model_version_missing.json +107 -0
- materica/data/conformance/plain_read/inputs/overlay_scope_model_version_not_string.json +108 -0
- materica/data/conformance/plain_read/inputs/overlay_scope_not_object.json +101 -0
- materica/data/conformance/plain_read/inputs/overlay_scope_null.json +101 -0
- materica/data/conformance/plain_read/inputs/overlay_scope_run_not_string.json +109 -0
- materica/data/conformance/plain_read/inputs/overlay_scope_run_null.json +109 -0
- materica/data/conformance/plain_read/inputs/record_binary_bytes.json +0 -0
- materica/data/conformance/plain_read/inputs/request_bom.json +27 -0
- materica/data/conformance/plain_read/inputs/request_duplicate_member.json +29 -0
- materica/data/conformance/plain_read/inputs/request_nan.json +28 -0
- materica/data/conformance/plain_read/inputs/request_nesting_100000.json +28 -0
- materica/data/conformance/plain_read/inputs/request_nesting_65.json +28 -0
- materica/data/conformance/plain_read/inputs/request_trailing_comma.json +27 -0
- materica/data/conformance/plain_read/inputs/scene_manifest_fixture.json +36 -0
- materica/data/conformance/plain_read/inputs/source_array_of_record.json +89 -0
- materica/data/conformance/plain_read/inputs/source_id_only.json +3 -0
- materica/data/conformance/plain_read/inputs/source_number.json +1 -0
- materica/data/conformance/plain_read/inputs/source_string.json +1 -0
- materica/data/conformance/plain_read/inputs/unknown_type_fixture.json +14 -0
- materica/data/conformance/plain_read/inputs/unknown_type_missing_body.json +13 -0
- materica/data/conformance/plain_read/inputs/unknown_type_two_envelope_faults.json +10 -0
- materica/data/conformance/plain_read/inputs/water_body_wrong_type.json +14 -0
- materica/data/conformance/plain_read/inputs/water_card_wrong_type.json +87 -0
- materica/data/conformance/plain_read/inputs/water_content_hash_63_digits.json +87 -0
- materica/data/conformance/plain_read/inputs/water_content_hash_no_prefix.json +87 -0
- materica/data/conformance/plain_read/inputs/water_content_hash_not_string.json +87 -0
- materica/data/conformance/plain_read/inputs/water_content_hash_null.json +87 -0
- materica/data/conformance/plain_read/inputs/water_content_hash_trailing_newline.json +87 -0
- materica/data/conformance/plain_read/inputs/water_content_hash_uppercase.json +87 -0
- materica/data/conformance/plain_read/inputs/water_document_type_without_record_type.json +87 -0
- materica/data/conformance/plain_read/inputs/water_escaped_nul.json +87 -0
- materica/data/conformance/plain_read/inputs/water_extensions_array.json +88 -0
- materica/data/conformance/plain_read/inputs/water_fault_bom.json +87 -0
- materica/data/conformance/plain_read/inputs/water_fault_comment.json +88 -0
- materica/data/conformance/plain_read/inputs/water_fault_control_character.json +87 -0
- materica/data/conformance/plain_read/inputs/water_fault_duplicate_member.json +88 -0
- materica/data/conformance/plain_read/inputs/water_fault_duplicate_member_escaped.json +88 -0
- materica/data/conformance/plain_read/inputs/water_fault_encoded_surrogate.json +87 -0
- materica/data/conformance/plain_read/inputs/water_fault_infinity.json +87 -0
- materica/data/conformance/plain_read/inputs/water_fault_nan.json +87 -0
- materica/data/conformance/plain_read/inputs/water_fault_negative_infinity.json +87 -0
- materica/data/conformance/plain_read/inputs/water_fault_nesting_100000.json +88 -0
- materica/data/conformance/plain_read/inputs/water_fault_nesting_65.json +88 -0
- materica/data/conformance/plain_read/inputs/water_fault_number_1e400.json +87 -0
- materica/data/conformance/plain_read/inputs/water_fault_number_overflow.json +87 -0
- materica/data/conformance/plain_read/inputs/water_fault_overlong.json +87 -0
- materica/data/conformance/plain_read/inputs/water_fault_trailing_comma.json +87 -0
- materica/data/conformance/plain_read/inputs/water_fault_trailing_content.json +88 -0
- materica/data/conformance/plain_read/inputs/water_fault_truncated.json +86 -0
- materica/data/conformance/plain_read/inputs/water_fault_truncated_utf8.json +87 -0
- materica/data/conformance/plain_read/inputs/water_fault_unpaired_high_surrogate.json +87 -0
- materica/data/conformance/plain_read/inputs/water_fault_unpaired_low_surrogate.json +87 -0
- materica/data/conformance/plain_read/inputs/water_fault_utf16be.json +0 -0
- materica/data/conformance/plain_read/inputs/water_fault_utf16le.json +0 -0
- materica/data/conformance/plain_read/inputs/water_fault_utf16le_bom.json +0 -0
- materica/data/conformance/plain_read/inputs/water_fault_utf32be.json +0 -0
- materica/data/conformance/plain_read/inputs/water_fault_utf32le.json +0 -0
- materica/data/conformance/plain_read/inputs/water_fields_array.json +20 -0
- materica/data/conformance/plain_read/inputs/water_fixture.cbor +1 -0
- materica/data/conformance/plain_read/inputs/water_fixture.json +87 -0
- materica/data/conformance/plain_read/inputs/water_fixture.toml +86 -0
- materica/data/conformance/plain_read/inputs/water_fixture.yaml +60 -0
- materica/data/conformance/plain_read/inputs/water_fixture_as_interface.json +14 -0
- materica/data/conformance/plain_read/inputs/water_fixture_edited.json +87 -0
- materica/data/conformance/plain_read/inputs/water_fixture_edited_2.json +87 -0
- materica/data/conformance/plain_read/inputs/water_fixture_edited_stale_hash.json +87 -0
- materica/data/conformance/plain_read/inputs/water_fixture_other_card.json +87 -0
- materica/data/conformance/plain_read/inputs/water_fixture_reformatted.json +1 -0
- materica/data/conformance/plain_read/inputs/water_fixture_schema_0_2_0.json +87 -0
- materica/data/conformance/plain_read/inputs/water_fixture_v2.json +87 -0
- materica/data/conformance/plain_read/inputs/water_fixture_v2_content_hash_uppercase.json +87 -0
- materica/data/conformance/plain_read/inputs/water_fluid_section_number.json +18 -0
- materica/data/conformance/plain_read/inputs/water_fluid_section_without_fields.json +18 -0
- materica/data/conformance/plain_read/inputs/water_id_uppercase_namespace.json +87 -0
- materica/data/conformance/plain_read/inputs/water_id_without_namespace.json +87 -0
- materica/data/conformance/plain_read/inputs/water_id_wrong_type.json +87 -0
- materica/data/conformance/plain_read/inputs/water_licence_evidence_missing.json +86 -0
- materica/data/conformance/plain_read/inputs/water_licence_evidence_wrong_type.json +87 -0
- materica/data/conformance/plain_read/inputs/water_licence_values_missing.json +86 -0
- materica/data/conformance/plain_read/inputs/water_licence_wrong_type.json +84 -0
- materica/data/conformance/plain_read/inputs/water_local_id_empty.json +87 -0
- materica/data/conformance/plain_read/inputs/water_local_id_space.json +87 -0
- materica/data/conformance/plain_read/inputs/water_local_id_trailing_newline.json +87 -0
- materica/data/conformance/plain_read/inputs/water_missing_body.json +13 -0
- materica/data/conformance/plain_read/inputs/water_missing_content_hash.json +86 -0
- materica/data/conformance/plain_read/inputs/water_missing_id.json +86 -0
- materica/data/conformance/plain_read/inputs/water_missing_licence.json +83 -0
- materica/data/conformance/plain_read/inputs/water_missing_name.json +86 -0
- materica/data/conformance/plain_read/inputs/water_missing_record_type.json +86 -0
- materica/data/conformance/plain_read/inputs/water_missing_version.json +86 -0
- materica/data/conformance/plain_read/inputs/water_name_wrong_type.json +89 -0
- materica/data/conformance/plain_read/inputs/water_nesting_64.json +88 -0
- materica/data/conformance/plain_read/inputs/water_noncharacter.json +87 -0
- materica/data/conformance/plain_read/inputs/water_noncharacter_escaped.json +87 -0
- materica/data/conformance/plain_read/inputs/water_null_body.json +14 -0
- materica/data/conformance/plain_read/inputs/water_null_card.json +87 -0
- materica/data/conformance/plain_read/inputs/water_null_extensions.json +88 -0
- materica/data/conformance/plain_read/inputs/water_null_fields.json +20 -0
- materica/data/conformance/plain_read/inputs/water_null_known_section.json +18 -0
- materica/data/conformance/plain_read/inputs/water_null_licence.json +84 -0
- materica/data/conformance/plain_read/inputs/water_null_licence_evidence.json +87 -0
- materica/data/conformance/plain_read/inputs/water_null_licence_values.json +87 -0
- materica/data/conformance/plain_read/inputs/water_null_name.json +87 -0
- materica/data/conformance/plain_read/inputs/water_null_record_type.json +87 -0
- materica/data/conformance/plain_read/inputs/water_null_sections.json +16 -0
- materica/data/conformance/plain_read/inputs/water_overlay_fixture.json +103 -0
- materica/data/conformance/plain_read/inputs/water_record_type_capitalised.json +87 -0
- materica/data/conformance/plain_read/inputs/water_record_type_wrong_type.json +87 -0
- materica/data/conformance/plain_read/inputs/water_schema_00_1_0.json +87 -0
- materica/data/conformance/plain_read/inputs/water_schema_0_01_0.json +87 -0
- materica/data/conformance/plain_read/inputs/water_schema_0_0_1.json +87 -0
- materica/data/conformance/plain_read/inputs/water_schema_0_1.json +87 -0
- materica/data/conformance/plain_read/inputs/water_schema_0_10_0.json +87 -0
- materica/data/conformance/plain_read/inputs/water_schema_0_1_0_rc1.json +87 -0
- materica/data/conformance/plain_read/inputs/water_schema_0_1_7.json +87 -0
- materica/data/conformance/plain_read/inputs/water_schema_0_2_0_bad_licence.json +84 -0
- materica/data/conformance/plain_read/inputs/water_schema_0_2_0_missing_name.json +86 -0
- materica/data/conformance/plain_read/inputs/water_schema_1_0_0.json +87 -0
- materica/data/conformance/plain_read/inputs/water_schema_1_1_0.json +87 -0
- materica/data/conformance/plain_read/inputs/water_schema_2_0_0.json +87 -0
- materica/data/conformance/plain_read/inputs/water_schema_absent.json +86 -0
- materica/data/conformance/plain_read/inputs/water_schema_arabic_indic.json +87 -0
- materica/data/conformance/plain_read/inputs/water_schema_array.json +89 -0
- materica/data/conformance/plain_read/inputs/water_schema_major_100_digits.json +87 -0
- materica/data/conformance/plain_read/inputs/water_schema_minor_100_digits.json +87 -0
- materica/data/conformance/plain_read/inputs/water_schema_null.json +87 -0
- materica/data/conformance/plain_read/inputs/water_schema_number.json +87 -0
- materica/data/conformance/plain_read/inputs/water_schema_patch_100_digits.json +87 -0
- materica/data/conformance/plain_read/inputs/water_schema_trailing_newline.json +87 -0
- materica/data/conformance/plain_read/inputs/water_schema_trailing_space.json +87 -0
- materica/data/conformance/plain_read/inputs/water_sections_array.json +16 -0
- materica/data/conformance/plain_read/inputs/water_sections_missing.json +14 -0
- materica/data/conformance/plain_read/inputs/water_unknown_member_null.json +88 -0
- materica/data/conformance/plain_read/inputs/water_version_01_0_0.json +87 -0
- materica/data/conformance/plain_read/inputs/water_version_1_0.json +87 -0
- materica/data/conformance/plain_read/inputs/water_version_wrong_type.json +87 -0
- materica/data/conformance/plain_read/inputs/water_with_document_type_member.json +88 -0
- materica/io/README.md +10 -0
- materica/io/__init__.py +2 -0
- materica/io/plain.py +17 -0
- materica/py.typed +0 -0
- materica/schema/0.1/README.md +15 -0
- materica/schema/0.1/case.json +82 -0
- materica/schema/0.1/read_request.json +104 -0
- materica/schema/0.1/read_result.json +37 -0
- materica/schema/0.1/record.reader.json +253 -0
- materica/schema/0.1/record.writer.json +192 -0
- materica/schema/0.1/vocabulary/README.md +17 -0
- materica/schema/0.1/vocabulary/acceptances.json +15 -0
- materica/schema/0.1/vocabulary/conditions.json +63 -0
- materica/schema/0.1/vocabulary/fields.json +83 -0
- materica/schema/0.1/vocabulary/reasons.json +292 -0
- materica/schema/0.1/vocabulary/specimen_facts.json +49 -0
- materica/schema/README.md +29 -0
- materica/shapes.py +409 -0
- materica/shapes.pyi +366 -0
- openmaterica-0.1.0.dev1.dist-info/METADATA +71 -0
- openmaterica-0.1.0.dev1.dist-info/RECORD +704 -0
- openmaterica-0.1.0.dev1.dist-info/WHEEL +4 -0
- openmaterica-0.1.0.dev1.dist-info/licenses/LICENSE +201 -0
materica/README.md
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# `materica`
|
|
2
|
+
|
|
3
|
+
The Python package. It implements the reader side of the OpenMaterica specification (`docs/specification/`).
|
|
4
|
+
The specification is normative: where this code and it differ, the code is wrong.
|
|
5
|
+
|
|
6
|
+
## Layers
|
|
7
|
+
|
|
8
|
+
The package is built in layers (AD 7.1), and a module imports only from its own layer or a lower one.
|
|
9
|
+
|
|
10
|
+
| Layer | Directory | What it holds |
|
|
11
|
+
|---|---|---|
|
|
12
|
+
| L0, schemas | `schema/`, `shapes.py` | the JSON Schemas (`schema/README.md`), and the JSON shapes as TypedDicts generated from them |
|
|
13
|
+
| L1, data | `data/`, `schema/0.1/vocabulary/` | the specification's conformance cases and the inputs they supply (`data/conformance/`, with their own `README.md`), and its vocabulary, published with the schemas |
|
|
14
|
+
| L2, core | `core/` | strict JSON, the canonical form and the content hash; identifiers, the envelope checks and the read up to step 5; Python's standard library only (`core/README.md`) |
|
|
15
|
+
| L4, readers | `io/` | files into the core's types (`io/README.md`) |
|
|
16
|
+
|
|
17
|
+
The authoring tools (L3), the sampling helpers (`sample/`, L5) and the command line (`tools/`, L6) arrive in
|
|
18
|
+
later steps. `tests/unit/test_source_files.py` walks every module's imports: a module imports only its own
|
|
19
|
+
layer or a lower one; `core/` imports only the standard library, itself and `shapes.py`, which imports only the
|
|
20
|
+
standard library; and nothing imports `materica_authoring`.
|
|
21
|
+
|
|
22
|
+
## What holds across the package
|
|
23
|
+
|
|
24
|
+
- No run-time dependency (AD 7.2): the built wheel declares none (`scripts/check_wheel.py`).
|
|
25
|
+
- It is typed (PEP 561) and ships `py.typed`. `mypy --strict` and pyright in strict mode pass over it, and a
|
|
26
|
+
consumer's code type-checks against the installed wheel (`tests/typing/`). `shapes.pyi`, which type checkers
|
|
27
|
+
read in place of `shapes.py`, marks what a read returns read-only (PEP 705).
|
|
28
|
+
- Everything under `data/` and `schema/` ships in the wheel byte for byte, since the conformance inputs are
|
|
29
|
+
byte-exact and the reader loads the vocabulary (`scripts/check_wheel.py`).
|
|
30
|
+
- Generated files are never edited by hand. `scripts/` regenerates them and CI fails on any difference: the
|
|
31
|
+
vocabulary from the specification's tables, the reader schema and the shapes from the writer schemas
|
|
32
|
+
(CONTRIBUTING, "Changing the schema").
|
|
33
|
+
- `__init__.py` holds the public API built so far: `content_hash`, `load_records` and `read`.
|
materica/__init__.py
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
"""OpenMaterica: material records and the reader of their specification (`docs/specification/`)."""
|
|
3
|
+
|
|
4
|
+
from materica.core.hashing import content_hash
|
|
5
|
+
from materica.core.read import read
|
|
6
|
+
from materica.io.plain import load_records
|
|
7
|
+
|
|
8
|
+
__all__ = ["content_hash", "load_records", "read"]
|
materica/core/README.md
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# `materica.core`
|
|
2
|
+
|
|
3
|
+
The core (layer L2, AD 7.1): the code that reads and checks records. It uses Python's standard library only
|
|
4
|
+
(AD 7.2, CONTRIBUTING constraint 3), so it adds nothing to a consumer's dependencies; the shapes it types its
|
|
5
|
+
results with (`materica.shapes`, generated) use the standard library only too.
|
|
6
|
+
|
|
7
|
+
## The data paths
|
|
8
|
+
|
|
9
|
+
The content hash:
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
bytes ─▶ jsonio.parse ─▶ value ─▶ hashing.hashable_view ─▶ view ─▶ canonical.canonicalize ─▶ bytes ─▶ SHA-256
|
|
13
|
+
│ (hashing.content_hash runs these three, and writes "sha256:<hex>")
|
|
14
|
+
└─▶ Reason("malformed")
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
A read, steps 0 to 5 of `read_side_contract.md` section 3:
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
request ─▶ read.ReadRequest.from_json ─▶ step 0, the request on its own ─▶ reasons, or a ReadRequest
|
|
21
|
+
│
|
|
22
|
+
sources ─▶ record.RecordStore.add ─▶ candidates by id and version, ▼
|
|
23
|
+
and the unreadable sources resolve.resolve_record
|
|
24
|
+
1 the candidate that states the pin
|
|
25
|
+
2 its schema version ┐
|
|
26
|
+
3 envelope.py's checks ├ kept on the Record
|
|
27
|
+
5 its type ┘
|
|
28
|
+
4 the hash, with HS: recomputed on every read,
|
|
29
|
+
between steps 3 and 5
|
|
30
|
+
│
|
|
31
|
+
read.ReadResult (status, reasons, labels) ◀────────┘ or NotImplementedError for steps 6 to 13
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
| Module | Implements |
|
|
35
|
+
|---|---|
|
|
36
|
+
| `reasons.py` | a reason as `read_side_contract.md` section 2 shapes it, each code and condition once; codes from the table in section 4 |
|
|
37
|
+
| `status.py` | the three statuses of a read, and the worst of several (section 2) |
|
|
38
|
+
| `jsonio.py` | `record_format.md` section 1 item 6, strict JSON; `JsonValue`, the type of what it reads |
|
|
39
|
+
| `canonical.py` | `record_format.md` section 9 item 2: RFC 8785, with no Unicode normalisation |
|
|
40
|
+
| `hashing.py` | `record_format.md` section 9 items 1 and 2: what the hash leaves out, and the hash |
|
|
41
|
+
| `identifiers.py` | `record_format.md` sections 7 and 8: identifiers and versions, matched in full; material references |
|
|
42
|
+
| `vocabulary.py` | the tokens of the specification's tables, read from `schema/0.1/vocabulary/` |
|
|
43
|
+
| `envelope.py` | the reader schema's checks by hand (`record_format.md` section 1 item 2) |
|
|
44
|
+
| `record.py` | the records a read resolves among, and the checks that depend on one record alone (steps 2, 3 and 5) |
|
|
45
|
+
| `resolve.py` | steps 1 to 5: a material reference to the record it pins, or the reasons it is refused |
|
|
46
|
+
| `read.py` | the request's own check (step 0), and the read; steps 6 to 13 are not built yet |
|
|
47
|
+
|
|
48
|
+
The conformance cases HS-001 to HS-003 check the hash end to end; the plain-read cases, HS-010 and HS-011 the
|
|
49
|
+
read up to step 5 (`tests/conformance/`).
|
|
50
|
+
|
|
51
|
+
## Invariants
|
|
52
|
+
|
|
53
|
+
- **Results, never exceptions, for content.** `parse` gives a value or `malformed` for any bytes, running out
|
|
54
|
+
of stack or memory included, and a read gives a result for any request and any records. An exception means
|
|
55
|
+
a misuse of the Python API (`canonicalize` given a value `parse` would never give; claims no reader makes, a
|
|
56
|
+
suite that does not exist or claims without plain read) or a step not built yet: a read whose answer a later
|
|
57
|
+
step would decide raises `NotImplementedError` rather than give one, whatever else is wrong with the request
|
|
58
|
+
(`tests/property/test_read_properties.py`, `tests/unit/test_read.py`).
|
|
59
|
+
- **A request is JSON text or a value.** Text is a `str` or bytes-like (`bytes`, `bytearray`, `memoryview`),
|
|
60
|
+
read like a record's bytes; a `str` is always text, as a JSON string is never a request. Any other value is
|
|
61
|
+
read as the JSON text `json.dumps` writes of it.
|
|
62
|
+
- **Every number is a float.** An integer reads as the nearest double; `JsonValue` has no `int`, and
|
|
63
|
+
`canonicalize` refuses one. A request given as a Python value is read through JSON text, so its integers too.
|
|
64
|
+
(The reader's properties compare types exactly; `tests/unit/test_canonical.py`.)
|
|
65
|
+
- **Stored JSON is never mutated.** `hashable_view` builds new containers and leaves its argument as it was
|
|
66
|
+
(`tests/unit/test_hashing.py`); a `Record` keeps the value its bytes parse to as it is.
|
|
67
|
+
- **Identifiers match in full**, by `re.fullmatch` with character classes written out
|
|
68
|
+
(`tests/property/test_version_properties.py`).
|
|
69
|
+
- **One envelope check, in two forms.** `envelope.py` and `schema/0.1/record.reader.json` accept and refuse
|
|
70
|
+
the same records (`tests/spec_sync/test_envelope.py`, `tests/property/test_envelope_properties.py`).
|
|
71
|
+
- **Standard library only**, with `materica.shapes`, itself standard library only, and, for type checkers
|
|
72
|
+
only, `typing_extensions`; relative imports are checked like absolute ones (`tests/unit/test_source_files.py`).
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
"""RFC 8785 canonical JSON, which the content hash is taken over (`record_format.md` section 9 item 2)."""
|
|
3
|
+
|
|
4
|
+
import math
|
|
5
|
+
|
|
6
|
+
from materica.core.jsonio import JsonValue
|
|
7
|
+
|
|
8
|
+
_ESCAPES = {code: f"\\u{code:04x}" for code in range(0x20)} | {
|
|
9
|
+
ord('"'): '\\"',
|
|
10
|
+
ord("\\"): "\\\\",
|
|
11
|
+
ord("\b"): "\\b",
|
|
12
|
+
ord("\f"): "\\f",
|
|
13
|
+
ord("\n"): "\\n",
|
|
14
|
+
ord("\r"): "\\r",
|
|
15
|
+
ord("\t"): "\\t",
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def canonicalize(value: JsonValue) -> bytes:
|
|
20
|
+
"""`value`, as `parse` gives it, serialised by RFC 8785 in UTF-8.
|
|
21
|
+
|
|
22
|
+
Strings are written as they are, never Unicode-normalised. A value `parse` would never give raises rather
|
|
23
|
+
than being written: `TypeError` for an `int` or a tuple, say, and `ValueError` for a number that is not
|
|
24
|
+
finite or a lone surrogate.
|
|
25
|
+
"""
|
|
26
|
+
parts: list[str] = []
|
|
27
|
+
_write(value, parts)
|
|
28
|
+
return "".join(parts).encode("utf-8")
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def _write(value: JsonValue, parts: list[str]) -> None:
|
|
32
|
+
if value is None:
|
|
33
|
+
parts.append("null")
|
|
34
|
+
elif isinstance(value, bool):
|
|
35
|
+
parts.append("true" if value else "false")
|
|
36
|
+
elif isinstance(value, float):
|
|
37
|
+
parts.append(_number(value))
|
|
38
|
+
elif isinstance(value, str):
|
|
39
|
+
parts.append(_string(value))
|
|
40
|
+
elif isinstance(value, list):
|
|
41
|
+
parts.append("[")
|
|
42
|
+
for index, item in enumerate(value):
|
|
43
|
+
if index:
|
|
44
|
+
parts.append(",")
|
|
45
|
+
_write(item, parts)
|
|
46
|
+
parts.append("]")
|
|
47
|
+
elif isinstance(value, dict):
|
|
48
|
+
parts.append("{")
|
|
49
|
+
for index, name in enumerate(sorted(value, key=_utf16_units)):
|
|
50
|
+
if index:
|
|
51
|
+
parts.append(",")
|
|
52
|
+
parts.append(_string(name))
|
|
53
|
+
parts.append(":")
|
|
54
|
+
_write(value[name], parts)
|
|
55
|
+
parts.append("}")
|
|
56
|
+
else:
|
|
57
|
+
raise TypeError(f"not a JSON value as parse gives it: {type(value).__name__}")
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def _number(number: float) -> str:
|
|
61
|
+
"""ECMAScript's `Number.prototype.toString`, as RFC 8785 section 3.2.2.3 requires."""
|
|
62
|
+
if not math.isfinite(number):
|
|
63
|
+
raise ValueError(f"{number} has no JSON form")
|
|
64
|
+
if number == 0:
|
|
65
|
+
return "0"
|
|
66
|
+
# repr gives the fewest digits that read back as the same double, the nearest where several do, as
|
|
67
|
+
# ECMAScript does. Here the double is 0.<digits> times 10**point.
|
|
68
|
+
mantissa, _, exponent = repr(abs(number)).partition("e")
|
|
69
|
+
whole, _, fraction = mantissa.partition(".")
|
|
70
|
+
written = whole + fraction
|
|
71
|
+
digits = written.strip("0")
|
|
72
|
+
leading_zeros = len(written) - len(written.lstrip("0"))
|
|
73
|
+
point = len(whole) - leading_zeros + int(exponent or "0")
|
|
74
|
+
count = len(digits)
|
|
75
|
+
sign = "-" if number < 0 else ""
|
|
76
|
+
if count <= point <= 21:
|
|
77
|
+
return sign + digits + "0" * (point - count)
|
|
78
|
+
if 0 < point <= 21:
|
|
79
|
+
return sign + digits[:point] + "." + digits[point:]
|
|
80
|
+
if -6 < point <= 0:
|
|
81
|
+
return sign + "0." + "0" * -point + digits
|
|
82
|
+
fraction_part = "." + digits[1:] if count > 1 else ""
|
|
83
|
+
return f"{sign}{digits[0]}{fraction_part}e{point - 1:+d}"
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def _string(text: str) -> str:
|
|
87
|
+
return '"' + text.translate(_ESCAPES) + '"'
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def _utf16_units(name: str) -> bytes:
|
|
91
|
+
# Big-endian bytes order as the UTF-16 code units they encode.
|
|
92
|
+
return name.encode("utf-16-be")
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
"""The reader schema's checks, written by hand (`record_format.md` section 1 item 2), so that the core reads
|
|
3
|
+
records with no JSON Schema validator.
|
|
4
|
+
|
|
5
|
+
`schema/0.1/record.reader.json` states the same checks for other languages. Tests hold the two to agreement,
|
|
6
|
+
on every conformance input and on records drawn near each boundary of the item.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from materica.core.identifiers import CONTENT_HASH, RECORD_ID, VERSION, Version
|
|
10
|
+
from materica.core.jsonio import JsonValue
|
|
11
|
+
from materica.core.vocabulary import VOCABULARY
|
|
12
|
+
|
|
13
|
+
SCHEMA_VERSION = Version("0", "1", "0")
|
|
14
|
+
"""The schema version these checks are the reader schema of."""
|
|
15
|
+
|
|
16
|
+
Members = dict[str, type[object]]
|
|
17
|
+
|
|
18
|
+
_KINDS: dict[type[object], str] = {str: "a string", dict: "an object"}
|
|
19
|
+
_ENVELOPE: Members = {
|
|
20
|
+
"schema_version": str,
|
|
21
|
+
"record_type": str,
|
|
22
|
+
"id": str,
|
|
23
|
+
"version": str,
|
|
24
|
+
"name": str,
|
|
25
|
+
"licence": dict,
|
|
26
|
+
"content_hash": str,
|
|
27
|
+
"body": dict,
|
|
28
|
+
}
|
|
29
|
+
_PATTERNS = {"id": RECORD_ID, "version": VERSION, "content_hash": CONTENT_HASH}
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def envelope_problems(record: JsonValue) -> list[str]:
|
|
33
|
+
"""Each way `record` breaks the reader schema of schema 0.1, in words: none where it passes.
|
|
34
|
+
|
|
35
|
+
The body is checked by its `record_type`: a material's sections, as far as this version knows them, and an
|
|
36
|
+
overlay's members. A body of another type, a section of another name, `extensions`' contents, a section's
|
|
37
|
+
`specimen` and every value field are left unchecked.
|
|
38
|
+
"""
|
|
39
|
+
if not isinstance(record, dict):
|
|
40
|
+
return ["the record is not an object"]
|
|
41
|
+
problems = _members(record, "", _ENVELOPE, {"card": str})
|
|
42
|
+
for name, pattern in _PATTERNS.items():
|
|
43
|
+
value = record.get(name)
|
|
44
|
+
if isinstance(value, str) and not pattern.fullmatch(value):
|
|
45
|
+
problems.append(f"{name} does not match its pattern: {value!r}")
|
|
46
|
+
licence, body = record.get("licence"), record.get("body")
|
|
47
|
+
if isinstance(licence, dict):
|
|
48
|
+
problems += _members(licence, "licence.", {"values": str, "evidence": str})
|
|
49
|
+
if isinstance(body, dict) and record.get("record_type") == "material":
|
|
50
|
+
problems += _material_body(body)
|
|
51
|
+
elif isinstance(body, dict) and record.get("record_type") == "overlay":
|
|
52
|
+
problems += _overlay_body(body)
|
|
53
|
+
return problems
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def _material_body(body: dict[str, JsonValue]) -> list[str]:
|
|
57
|
+
problems = _members(body, "body.", {"sections": dict}, {"extensions": dict})
|
|
58
|
+
sections = body.get("sections")
|
|
59
|
+
if isinstance(sections, dict):
|
|
60
|
+
for name in sorted(VOCABULARY.sections & sections.keys()):
|
|
61
|
+
section = sections[name]
|
|
62
|
+
if isinstance(section, dict):
|
|
63
|
+
problems += _members(section, f"body.sections.{name}.", {"fields": dict})
|
|
64
|
+
else:
|
|
65
|
+
problems.append(f"body.sections.{name} is not an object")
|
|
66
|
+
return problems
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def _overlay_body(body: dict[str, JsonValue]) -> list[str]:
|
|
70
|
+
problems = _members(body, "body.", {"purpose": str, "base": dict, "scope": dict, "replaces": dict})
|
|
71
|
+
base, scope = body.get("base"), body.get("scope")
|
|
72
|
+
if isinstance(base, dict):
|
|
73
|
+
problems += _members(base, "body.base.", {"id": str, "version": str, "content_hash": str})
|
|
74
|
+
if isinstance(scope, dict):
|
|
75
|
+
optional: Members = {"model": dict, "model_configuration_hash": str, "run": str}
|
|
76
|
+
problems += _members(scope, "body.scope.", {"consumer": str}, optional)
|
|
77
|
+
model = scope.get("model")
|
|
78
|
+
if isinstance(model, dict):
|
|
79
|
+
problems += _members(model, "body.scope.model.", {"name": str, "version": str})
|
|
80
|
+
return problems
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def _members(
|
|
84
|
+
value: dict[str, JsonValue], where: str, required: Members, optional: Members | None = None
|
|
85
|
+
) -> list[str]:
|
|
86
|
+
problems: list[str] = []
|
|
87
|
+
for name, kind in (required | (optional or {})).items():
|
|
88
|
+
if name not in value:
|
|
89
|
+
if name in required:
|
|
90
|
+
problems.append(f"{where}{name} is missing")
|
|
91
|
+
elif not isinstance(value[name], kind):
|
|
92
|
+
problems.append(f"{where}{name} is not {_KINDS[kind]}")
|
|
93
|
+
return problems
|
materica/core/hashing.py
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
"""The content hash of a record, or of any JSON value (`record_format.md` section 9)."""
|
|
3
|
+
|
|
4
|
+
import hashlib
|
|
5
|
+
|
|
6
|
+
from materica.core.canonical import canonicalize
|
|
7
|
+
from materica.core.jsonio import JsonValue
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def hashable_view(value: JsonValue) -> JsonValue:
|
|
11
|
+
"""`value` without the members `record_format.md` section 9 item 1 removes; `value` is left unchanged.
|
|
12
|
+
|
|
13
|
+
The top-level `content_hash` and `card` go only when `value` is an object. `review` and `copy` go at any
|
|
14
|
+
depth inside an object that is the value of a member named `provenance`, through objects and arrays.
|
|
15
|
+
"""
|
|
16
|
+
if isinstance(value, dict):
|
|
17
|
+
value = {name: member for name, member in value.items() if name not in ("content_hash", "card")}
|
|
18
|
+
return _view(value, inside_provenance=False)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def _view(value: JsonValue, *, inside_provenance: bool) -> JsonValue:
|
|
22
|
+
if isinstance(value, dict):
|
|
23
|
+
return {
|
|
24
|
+
name: _view(
|
|
25
|
+
member,
|
|
26
|
+
inside_provenance=inside_provenance or (name == "provenance" and isinstance(member, dict)),
|
|
27
|
+
)
|
|
28
|
+
for name, member in value.items()
|
|
29
|
+
if not (inside_provenance and name in ("review", "copy"))
|
|
30
|
+
}
|
|
31
|
+
if isinstance(value, list):
|
|
32
|
+
return [_view(item, inside_provenance=inside_provenance) for item in value]
|
|
33
|
+
return value
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def content_hash(value: JsonValue) -> str:
|
|
37
|
+
"""`sha256:` and the lowercase hexadecimal SHA-256 of `value`'s hashable view in RFC 8785 form."""
|
|
38
|
+
return "sha256:" + hashlib.sha256(canonicalize(hashable_view(value))).hexdigest()
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
"""Identifiers and versions (`record_format.md` sections 7 and 8), and material references.
|
|
3
|
+
|
|
4
|
+
Every pattern here is matched in full, with `re.fullmatch`, never searched: `$` also matches before a final
|
|
5
|
+
newline. Character classes are written out, since `\\d` would match any Unicode digit.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import functools
|
|
9
|
+
import re
|
|
10
|
+
from dataclasses import dataclass
|
|
11
|
+
|
|
12
|
+
from materica import shapes
|
|
13
|
+
|
|
14
|
+
NAMESPACE = re.compile(r"[a-z0-9_]+")
|
|
15
|
+
RECORD_ID = re.compile(r"[a-z0-9_]+/[A-Za-z0-9_.-]+")
|
|
16
|
+
FAMILY_ID = re.compile(r"[a-z0-9_]+(?:\.[a-z0-9_]+)+\.v[1-9][0-9]*")
|
|
17
|
+
VERSION = re.compile(r"(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)")
|
|
18
|
+
_COMPONENT = re.compile(r"0|[1-9][0-9]*")
|
|
19
|
+
CONTENT_HASH = re.compile(r"sha256:[0-9a-f]{64}")
|
|
20
|
+
# A request's field, `<section>.<field>` (`read_side_contract.md` section 1).
|
|
21
|
+
FIELD = re.compile(r"[a-z0-9_]+\.[a-z0-9_]+")
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@functools.total_ordering
|
|
25
|
+
@dataclass(frozen=True)
|
|
26
|
+
class Version:
|
|
27
|
+
"""`MAJOR.MINOR.PATCH`, its components kept as their digits.
|
|
28
|
+
|
|
29
|
+
Section 8 compares components as numbers. With no leading zeros, which construction refuses, comparing
|
|
30
|
+
their lengths and then their digits gives that order for any length, where `int` refuses more than 4300
|
|
31
|
+
digits.
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
major: str
|
|
35
|
+
minor: str
|
|
36
|
+
patch: str
|
|
37
|
+
|
|
38
|
+
def __post_init__(self) -> None:
|
|
39
|
+
for component in (self.major, self.minor, self.patch):
|
|
40
|
+
if not _COMPONENT.fullmatch(component):
|
|
41
|
+
raise ValueError(f"not a version component: {component!r}")
|
|
42
|
+
|
|
43
|
+
def __lt__(self, other: object) -> bool:
|
|
44
|
+
if not isinstance(other, Version):
|
|
45
|
+
return NotImplemented
|
|
46
|
+
return self._key() < other._key()
|
|
47
|
+
|
|
48
|
+
def _key(self) -> tuple[tuple[int, str], ...]:
|
|
49
|
+
return tuple((len(component), component) for component in (self.major, self.minor, self.patch))
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def parse_version(text: str) -> Version | None:
|
|
53
|
+
"""The version `text` writes, or None where it does not match section 8's pattern in full."""
|
|
54
|
+
matched = VERSION.fullmatch(text)
|
|
55
|
+
return None if matched is None else Version(matched[1], matched[2], matched[3])
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
@dataclass(frozen=True)
|
|
59
|
+
class MaterialRef:
|
|
60
|
+
"""A material reference: a record's `id` and `version`, and its `content_hash` as the pin."""
|
|
61
|
+
|
|
62
|
+
id: str
|
|
63
|
+
version: str
|
|
64
|
+
content_hash: str
|
|
65
|
+
|
|
66
|
+
def to_json(self) -> shapes.MaterialRef:
|
|
67
|
+
return {"id": self.id, "version": self.version, "content_hash": self.content_hash}
|
materica/core/jsonio.py
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
"""Strict JSON: bytes to a value, or the reason `malformed` (`record_format.md` section 1 item 6).
|
|
3
|
+
|
|
4
|
+
The item applies to records, scene documents, engine crosswalks, read requests and conformance case files.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import codecs
|
|
8
|
+
import json
|
|
9
|
+
import math
|
|
10
|
+
import re
|
|
11
|
+
from collections.abc import Iterator
|
|
12
|
+
from typing import NoReturn, TypeAlias
|
|
13
|
+
|
|
14
|
+
from materica.core.reasons import Reason
|
|
15
|
+
|
|
16
|
+
JsonValue: TypeAlias = bool | float | str | list["JsonValue"] | dict[str, "JsonValue"] | None
|
|
17
|
+
"""A value as `parse` gives it: every number is a float."""
|
|
18
|
+
|
|
19
|
+
MAX_DEPTH = 64
|
|
20
|
+
|
|
21
|
+
# A whole string, so that brackets inside one are skipped, or a bracket.
|
|
22
|
+
_STRING_OR_BRACKET = re.compile(r'"[^"\\]*(?:\\.[^"\\]*)*"|[][{}]', re.DOTALL)
|
|
23
|
+
_SURROGATE = re.compile("[\ud800-\udfff]")
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def parse(data: bytes) -> JsonValue | Reason:
|
|
27
|
+
"""Read `data` by `record_format.md` section 1 item 6.
|
|
28
|
+
|
|
29
|
+
Gives the value, or `Reason("malformed")` with a detail for anything that item refuses. Never raises for
|
|
30
|
+
any bytes.
|
|
31
|
+
"""
|
|
32
|
+
try:
|
|
33
|
+
return _parse(data)
|
|
34
|
+
except (ValueError, RecursionError, MemoryError) as error:
|
|
35
|
+
return Reason("malformed", detail=str(error) or type(error).__name__)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def _parse(data: bytes) -> JsonValue:
|
|
39
|
+
if data.startswith(codecs.BOM_UTF8):
|
|
40
|
+
raise ValueError("a byte-order mark")
|
|
41
|
+
text = data.decode("utf-8")
|
|
42
|
+
# Counted before json runs, so that json never recurses deeper than this: 100000 levels would exhaust
|
|
43
|
+
# its stack.
|
|
44
|
+
if _nesting_exceeds(text, MAX_DEPTH):
|
|
45
|
+
raise ValueError(f"nested more than {MAX_DEPTH} deep")
|
|
46
|
+
value: JsonValue = json.loads(
|
|
47
|
+
text, object_pairs_hook=_object, parse_float=_double, parse_int=_double, parse_constant=_constant
|
|
48
|
+
)
|
|
49
|
+
# json joins a paired surrogate escape into one character and keeps an unpaired one; the strict decoding
|
|
50
|
+
# above has refused any surrogate written as bytes.
|
|
51
|
+
if any(_SURROGATE.search(string) for string in _strings(value)):
|
|
52
|
+
raise ValueError("an unpaired surrogate escape")
|
|
53
|
+
return value
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def _nesting_exceeds(text: str, limit: int) -> bool:
|
|
57
|
+
depth = 0
|
|
58
|
+
for token in _STRING_OR_BRACKET.finditer(text):
|
|
59
|
+
if token.group() in ("[", "{"):
|
|
60
|
+
depth += 1
|
|
61
|
+
if depth > limit:
|
|
62
|
+
return True
|
|
63
|
+
elif token.group() in ("]", "}"):
|
|
64
|
+
depth -= 1
|
|
65
|
+
return False
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def _object(pairs: list[tuple[str, JsonValue]]) -> dict[str, JsonValue]:
|
|
69
|
+
members: dict[str, JsonValue] = {}
|
|
70
|
+
for name, value in pairs:
|
|
71
|
+
if name in members:
|
|
72
|
+
raise ValueError(f"the member name {name!r} repeated")
|
|
73
|
+
members[name] = value
|
|
74
|
+
return members
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def _double(text: str) -> float:
|
|
78
|
+
# Integers come here too, as text: int() refuses more than 4300 digits, and float(int) overflows where
|
|
79
|
+
# float(text) rounds. json's pure-Python scanner, used where its C one is missing, matches any Unicode
|
|
80
|
+
# digit as a digit.
|
|
81
|
+
if not text.isascii():
|
|
82
|
+
raise ValueError(f"not a JSON number: {text!r}")
|
|
83
|
+
number = float(text)
|
|
84
|
+
if math.isinf(number):
|
|
85
|
+
raise ValueError("a number that rounds to an infinity")
|
|
86
|
+
return number
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def _constant(name: str) -> NoReturn:
|
|
90
|
+
raise ValueError(f"{name} is not JSON")
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def _strings(value: JsonValue) -> Iterator[str]:
|
|
94
|
+
if isinstance(value, str):
|
|
95
|
+
yield value
|
|
96
|
+
elif isinstance(value, list):
|
|
97
|
+
for item in value:
|
|
98
|
+
yield from _strings(item)
|
|
99
|
+
elif isinstance(value, dict):
|
|
100
|
+
for name, member in value.items():
|
|
101
|
+
yield name
|
|
102
|
+
yield from _strings(member)
|