Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## 3.1.0 - unreleased

### Fixed
- When compacting, expands the index mapping first, then compacts that expanded IRI, matching the JSON-LD API compaction correction for compact-IRI index mappings. Fixes testcases [compact#t0112](https://w3c.github.io/json-ld-api/tests/compact-manifest.html#t0112) and [compact#t0113](https://w3c.github.io/json-ld-api/tests/compact-manifest.html#t0113).
- Fixes `AttributeError` when compacting with `@none`: the `@type` map compaction path now only calls `.pop()` and inspects keys when `compacted_item` is actually an object. Fixes [compact#tm023](https://w3c.github.io/json-ld-api/tests/compact-manifest.html#tm023)

### Added
- `pyld.DocumentLoader` abstract base class for class-based document loaders,
with a `RemoteDocument` `TypedDict` describing the expected return shape.
Expand Down
9 changes: 7 additions & 2 deletions lib/pyld/jsonld.py
Original file line number Diff line number Diff line change
Expand Up @@ -1947,10 +1947,14 @@ def _compact(self, active_ctx, active_property, element, options):
)
key = compacted_item.pop(id_key, None)
elif '@type' in container:
# Compact a type-map item an object or scalar (for
# example when a node reference is coerced to @id.
type_key = self._compact_iri(active_ctx, '@type')
# Only object items can carry an embedded @type,
# so only call .pop() on object to avoid AttributeError.
types = JsonLdProcessor.arrayify(
compacted_item.pop(type_key, [])
)
) if _is_object(compacted_item) else []
key = types.pop(0) if types else None
if types:
JsonLdProcessor.add_value(
Expand All @@ -1960,7 +1964,8 @@ def _compact(self, active_ctx, active_property, element, options):
# if compactedItem contains a single entry
# whose key maps to @id, recompact without @type
if (
len(compacted_item.keys()) == 1
_is_object(compacted_item)
and len(compacted_item.keys()) == 1
and '@id' in expanded_item
):
compacted_item = self._compact(
Expand Down
1 change: 0 additions & 1 deletion tests/runtests.py
Original file line number Diff line number Diff line change
Expand Up @@ -906,7 +906,6 @@ def write(self, filename):
'specVersion': ['json-ld-1.0'],
'idRegex': [
# uncategorized
'.*compact-manifest#tm023$',
'.*compact-manifest#tc028$',
],
},
Expand Down
25 changes: 25 additions & 0 deletions tests/test_jsonld.py
Original file line number Diff line number Diff line change
Expand Up @@ -867,6 +867,31 @@ def test_reverse_index_map_with_term_index_uses_property_value_as_key(self):
"statement": {"rdf:type": {"term": "A", "addedIn": "v1"}},
}

def test_node_reference_compacts_to_string_value_of_type_map(self):
"""
A node reference in a type map can compact to a string when the term
is type-coerced to @id. In that case the type map should use @none.
"""
input = {
"@context": {"@vocab": "http://schema.org/"},
"@type": "Event",
"location": {"@id": "http://kg.artsdata.ca/resource/K11-200"},
}
context = {
"@context": {
"@vocab": "http://schema.org/",
"location": {"@type": "@id", "@container": "@type"},
}
}

compacted = jsonld.compact(input, context)

assert compacted == {
"@context": context["@context"],
"@type": "Event",
"location": {"@none": "http://kg.artsdata.ca/resource/K11-200"},
}

# Issue 91
def test_empty_context(self):
"""
Expand Down
Loading