Skip to content
Open
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
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,13 @@
(including `None`) are no longer allowed, hence missing base IRIs in the
JSON-LD context are now handled outside the function call.
- Add unittests
- **BREAKING**: The `IdentifierIssuer` class was moved to `identifier_issuer.py`. It's now available
at `pyld.identifier_issuer`.
- **BREAKING**: The classes `URDNA2015` and `URGNA2012` were moved to `canon.py`. They are now available
at `pyld.canon`.
- `jsonld.expand()` now accepts a `on_key_dropped` parameter which is a handler called on every ignored key.
- **BREAKING**: In cases where there is no document base (for instance, when using a string as input),
'http://example.org/base/' is used as the base IRI when `@base` is absent or explicitely set to `null`.

## 2.0.4 - 2024-02-16

Expand Down
15 changes: 15 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,21 @@ If Requests_ is not available, the loader is set to aiohttp_. The fallback
document loader is a dummy document loader that raises an exception on every
invocation.

Handling ignored keys during JSON-LD expansion
----------------------------------------------

If a key in a JSON-LD document does not map to an absolute IRI then it is ignored and logged by default.
You can customize this behaviour by passing a customizable handler to `on_key_dropped` parameter of `jsonld.expand()`.

For example, you can introduce a strict mode by raising a ValueError on every dropped key:

```python
def raise_this(value):
raise ValueError(value)

jsonld.expand(doc, None, on_key_dropped=raise_this)
```

Commercial Support
------------------

Expand Down
554 changes: 554 additions & 0 deletions lib/pyld/canon.py

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions lib/pyld/context_resolver.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,8 +153,8 @@ def _fetch_context(self, active_ctx, url, cycles):
'non-JSON response, or more than one HTTP Link Header was ' +
'provided for a remote context.',
'jsonld.InvalidUrl',
{'url': url, 'cause': cause},
code='loading remote context failed')
{'url': url},
code='loading remote context failed') from cause

# ensure ctx is an object
if not isinstance(context, dict) and not isinstance(context, frozendict):
Expand Down
4 changes: 2 additions & 2 deletions lib/pyld/documentloader/aiohttp.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,8 @@ async def async_loader(url, headers):
except Exception as cause:
raise JsonLdError(
'Could not retrieve a JSON-LD document from the URL.',
'jsonld.LoadDocumentError', code='loading document failed',
cause=cause)
'jsonld.LoadDocumentError',
code='loading document failed') from cause

def loader(url, options=None):
"""
Expand Down
4 changes: 2 additions & 2 deletions lib/pyld/documentloader/requests.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ def loader(url, options={}):
except Exception as cause:
raise JsonLdError(
'Could not retrieve a JSON-LD document from the URL.',
'jsonld.LoadDocumentError', code='loading document failed',
cause=cause)
'jsonld.LoadDocumentError',
code='loading document failed') from cause

return loader
52 changes: 52 additions & 0 deletions lib/pyld/identifier_issuer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
class IdentifierIssuer(object):
"""
An IdentifierIssuer issues unique identifiers, keeping track of any
previously issued identifiers.
"""

def __init__(self, prefix):
"""
Initializes a new IdentifierIssuer.

:param prefix: the prefix to use ('<prefix><counter>').
"""
self.prefix = prefix
self.counter = 0
self.existing = {}
self.order = []

"""
Gets the new identifier for the given old identifier, where if no old
identifier is given a new identifier will be generated.

:param [old]: the old identifier to get the new identifier for.

:return: the new identifier.
"""
def get_id(self, old=None):
# return existing old identifier
if old and old in self.existing:
return self.existing[old]

# get next identifier
id_ = self.prefix + str(self.counter)
self.counter += 1

# save mapping
if old is not None:
self.existing[old] = id_
self.order.append(old)

return id_

def has_id(self, old):
"""
Returns True if the given old identifier has already been assigned a
new identifier.

:param old: the old identifier to check.

:return: True if the old identifier has been assigned a new identifier,
False if not.
"""
return old in self.existing
Loading
Loading