Skip to content

Latest commit

 

History

History
443 lines (387 loc) · 22.1 KB

File metadata and controls

443 lines (387 loc) · 22.1 KB

pyld ChangeLog

4.0.0 - unreleased

Added

  • Migrate canon.py to rdflib
    • Added rdflib dependency in all relevant config and code files.
    • Added util.py:
      • Added the functions from_legacy_dataset() and to_legacy_dataset() to convert an rdflib.Dataset to an RDFJS-like dict and back wherever needed.
      • Added unittests in tests/test_util.py for these functions.
  • Implement RDFC1.0
    • Added new class RDFC10 (subclass of URDNA2015) in canon.py
    • Added the RDFC1.0 test-suite in tests/runtests.py
      • Added support for testing blank-node identifier maps.
      • Added support for testing with different hashing algorithms

Removed

  • BREAKING: Removed the internal pyld.nquads parser/serializer module.

Fixed

  • Preserved RDF literal lexical forms when converting through RDFLib, including canonical double output, large numeric values, and compound literal handling.
  • Fixed iri_resolver.unresolve() query/fragment reconstruction while cleaning up the resolver docstring.

Changed

  • BREAKING: Migrated jsonld.to_rdf(), jsonld.from_rdf(), and N-Quads parsing/serialization to use rdflib.Dataset and RDFLib terms directly.
    • jsonld.to_rdf() now returns an rdflib.Dataset by default when no output format is requested.
    • Added legacyMode to jsonld.to_rdf() to return the previous RDF.js-like dataset dict.
    • jsonld.from_rdf() now accepts both rdflib.Dataset inputs and the previous legacy dataset dict shape.
    • Updated RDF-related tests for RDFLib dataset and N-Quads serialization behavior.
  • BREAKING: nquads input/output now delegates to RDFLib instead of PyLD’s custom parser and serializer.
  • Migrate canon.py to rdflib:
    • Now use rdflib for RDF term type checking (e.g., checking is something is a bnode), looping over triples/quads, nquads serialization and constructing RDF terms (custom deepcopy is no longer needed)
    • Move nquads parsing fromJsonLdProcessor.normalize() to URDNA2015.main() so all parsing and serialization is handled by the same class.
    • Move the main logic to URDNA2015._canonicalize(self, dataset: Dataset) while keeping input and output in URDNA2015.main(). The method URDNA2015._canonicalize(self, dataset: Dataset) accepts an rdflib.Dataset and returns a tuple with
      • the canonicalized result as a nquads str and
      • the blank node identifier map as dict.
    • The method URDNA2015 .main(self, dataset: str | dict | Dataset, options) now
      • accepts a rdflib.Dataset object in addition to an nquads str or the original RDFJS-likedict.
      • returns
        • a str: the serialized nquads result, or
        • a dict: the result as RDFJS-like dataset or the blank node identifier map when the new parameter outputMap is True.
    • The hashing algorithm is now an class attribute URDNA2015.hash_algorithm so it configurable (required for RDFC1.0)
    • The permutations() function now uses itertools.permutations instead of a custom implementation.
    • Replacements for rdflib's _nq_row and _quoteLiteral (these should eventually move to a fix for rdflib's nquads serializer).
    • Re-enabled all skipped URDNA2015, URDNA2012 tests in tests/runtests.py
  • If the result of a test is a dict and the expected value is a string, the expected value is now parsed as JSON (needed for testing blank-node identifier maps).
  • BREAKING: Removed small Python 2-era compatibility code and simplified a few internal collection checks.

3.3.0 - unreleased

Added

  • pyld.FileDocumentLoader: a document loader for local file: URLs with optional root confinement.
  • pyld.SchemeDirectedDocumentLoader: a document loader that dispatches URL strings to per-scheme loaders.

3.2.0 - 2026-08-17

Added

  • *Options TypedDict types and a Context type alias in pyld.options for JSON-LD API option dicts (typing and documentation).
  • pyld.SqliteCacheRequestsDocumentLoader: a SQLite-backed HTTP cache document loader using requests-cache.

Fixed

  • If value objects contain array values for @type during expansion, an error is now raised. Fixes expand#ter54 and toRdf#ter54.
  • Inline contexts that try to redefine @context now raise an error. Fixes expand#ter56 and toRdf#ter56.
  • When using native types, values of xsd:boolean and xsd:integer are now properly converted. Fixes fromRdf#t0027.
  • Numbers with 0 as fractional part now parse to an xsd:integer instead of xsd:double. Fixes toRdf#ttn02.
  • Zeros are now truncated for numeric values with negative exponent.
  • Blank node prefixes are now also used in IRI expansion.
  • Numbers with no fractions but that are >= 1e21 are now represented as xsd:double in json-ld-1.1 processing mode.
  • In RequestsDocumentLoader, constructor-level headers are now removed from **kwargs and stored separately, avoiding duplicate headers= when calling session.get. Per-call options["headers"] still takes precedence.

3.1.0 - 2026-06-19

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 and compact#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
  • An empty property-scoped context no longer resets the active context in _create_term_definition. Now only explicit null becomes False; empty contexts are preserved. Fixes compact#tc028, toRdf#tc036 and expand#tc036.
  • Options from the test manifest now override the options configured in create_test_options(), instead of the other way around. This fixes tests not able to override default options in the test-setup such as extractAllScripts. Fixes html#tf004.
  • When @type is @json in a frame, it no longer raises an "Invalid JSON-LD syntax" error. Fixes frame#t0069.
  • Use safeguard for non-dict values of options['link']
  • Local and type-scoped contexts are now properly resolved for nested node objects, so a scoped context on a @nest term is being applied to nested properties. Fixes toRdf#tc037, toRdf#tc038, expand#tc037 and expand#tc038.

Changed

  • requests_document_loader() and aiohttp_document_loader() now return class-based DocumentLoader instances while preserving the existing callable factory API. The concrete RequestsDocumentLoader and AioHttpDocumentLoader classes are also importable from pyld.
  • The pytest test runner now uses plain assert result == expect instead of printing EXPECTED / ACTUAL and raising a generic failure. This enables pytests's native result comparison.
  • Convert ./README.rst and ./CONTRIBUTING.rst (reStructuredText) to ./README.md and ./CONTRIBUTING.md (markdown). Also update their contents to reflect the current state of the repo.
  • Replace the old Sphinx documentation with a MkDocs Material site and add a GitHub Pages documentation workflow.

Added

  • pyld.DocumentLoader abstract base class for class-based document loaders, with a RemoteDocument TypedDict describing the expected return shape.
  • pyld.FrozenDocumentLoader: a class-based loader that serves only URLs in its documents allowlist and refuses everything else with JsonLdError(code='loading document failed'). Instantiating with no arguments serves the curated pyld.BUNDLED_CONTEXTS set; instantiating with dict(BUNDLED_CONTEXTS, **extras) extends the bundle. Suitable for air-gapped, reproducible-build, and security-hardened deployments.
  • pyld.BUNDLED_CONTEXTS: curated mapping of high-traffic public W3C / W3ID JSON-LD contexts (ActivityStreams, DID v1, VC v1/v2, Linked Data Security v1/v2, Ed25519-2020, JWS-2020) to vendored on-disk copies. Refresh with make download-bundled-contexts.
  • pyld.ContextResolver: added the max_context_urls property that determines maximum number of times contexts can be recusively fetched, which replaces the role of the static MAX_CONTEXT_URLS. The constructor now accepts a max_context_urls parameter that sets the value of max_context_urls which defaults to MAX_CONTEXT_URLS.
  • pyld.fromRdf() and pyld.toRdf() now support compound literals when serializing/deserializing RDF to/from JSON-LD. Therefore, both methods accept the value 'compound-literal' for the 'rdfDirection' option. Fixes fromRdf#tdi11, fromRdf#tdi12, toRdf#tdi11, and toRdf#tdi12.

3.0.0 - 2026-04-02

Changed

  • BREAKING: Compaction term selection now follows the JSON-LD 1.1 spec (Inverse Context Creation, section 4.3 step 3): terms are ordered by shortest first, with lexicographic tiebreak. Previously terms were ordered lexicographically first, then by length. This changes which term is selected when multiple context keys map to the same IRI. See #247.
  • BREAKING: Require supported Python version >= 3.10.
  • Update aiohttp document loader to work with Python 3.14.
    • Minimize async related changes to library code in this release.
    • In sync environment use asyncio.run.
    • In async environment use background thread.
  • The default test manifests or directories now default to the ./specifications directory.
  • Add ability to run test suites using pytest and make pytest the default way for running (unit)tests.
  • The functionality to resolve relative IRIs to absolute IRIs has been moved from context_resolver.py to iri_resolver.py so it can be maintained and tested separately.
    • Migrate the prepend_base(base, iri) function to the resolve(iri, base) function.
    • Move the existing function remove_dot_segments(path) and update the implementation.
    • Migrate the remove_base(base, iri) function to the unresolve(iri, base) function and update the implementation to use stdlib urllib.parse and urllib.unparse to replace the custom implementation.
    • Update code to use resolve(iri, base) and unresolve(iri, base) instead. Invalid base IRIs (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 custom cause and traceback attributes on JsonLdError are replaced by Python exception chaining and the built-in __cause__ attribute.
  • 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_property_dropped parameter which is a handler called on every ignored JSON property.
  • 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.
  • BREAKING: Some internal parameters were renamed from camelCase to pythonic:
    • requestProfile to request_profile in load_document()
    • rdfDirection to rdf_direction in _list_to_rdf() and _object_to_rdf()

2.0.4 - 2024-02-16

Fixed

  • Use explicit None or False for context checks. Fixes an issue while framing with an empty context.

2.0.3 - 2020-08-06

Fixed

  • Fix deprecation warnings due to invalid escape sequences.

2.0.2 - 2020-04-20

Fixed

  • Fix inverse context cache indexing to use the uuid field.

2.0.1 - 2020-04-15

Changed

  • Improve EARL output.

2.0.0 - 2020-04-15

Notes

  • This release adds JSON-LD 1.1 support. Significant thanks goes to Gregg Kellogg!
  • BREAKING: It is highly recommended to do proper testing when upgrading from the previous version. The framing API in particular now follows the 1.1 spec and some of the defaults changed.

Changed

  • BREAKING: Versions of Python before 3.6 are no longer supported.
  • Update conformance docs.
  • Add all keywords and update options.
  • Default processingMode to json-ld-1.1.
  • Implement logic for marking tests as pending, so that it will fail if a pending test passes.
  • Consolidate documentLoader option and defaults into a load_document method to also handle JSON (eventually HTML) parsing.
  • Add support for rel=alternate for non-JSON-LD docs.
  • Use lxml.html to load HTML and parse in load_html.
    • For HTML, the API base option can be updated from base element.
  • Context processing:
    • Support @propagate in context processing and propagate option.
    • Support for @import. (Some issues confusing recursion errors for invalid contexts).
    • Make override_protected and propagate optional arguments to _create_term_definition and _process_context instead of using option argument.
    • Improve management of previous contexts.
    • Imported contexts must resolve to an object.
    • Do remote context processing from within _process_contexts, as logic is too complicated for pre-loading. Removes _find_context_urls and _retrieve_context_urls.
    • Added a ContextResolver which can use a shared LRU cache for storing externally retrieved contexts, and the result of processing them relative to a particular active context.
    • Return a frozendict from context processing and reduce deepcopies.
    • Store inverse context in an LRU cache rather than trying to modify a frozen context.
    • Don't set @base in initial context and don't resolve a relative IRI when setting @base in a context, so that the document location can be kept separate from the context itself.
    • Use static initial contexts composed of just mappings and processingMode to enhance preprocessed context cachability.
  • Create Term Definition:
    • Allow @type as a term under certain circumstances.
    • Reject and warn on keyword-like terms.
    • Support protected term definitions.
    • Look for keyword patterns and warn/return.
    • Look for terms that are compact IRIs that don't expand to the same thing.
    • Basic support for @json and @none as values of @type.
    • If @container includes @type, @type must be @id or @vocab.
    • Support @index and @direction.
    • Corner-case checking for @prefix.
    • Validate scoped contexts even if not used.
    • Support relative vocabulary IRIs.
    • Fix check that term has the form of an IRI.
    • Delay adding mapping to end of _create_term_definition.
    • If a scoped context is null, wrap it in an array so it doesn't seem to be undefined.
  • IRI Expansion:
    • Find keyword patterns.
    • Don't treat terms starting with a colon as IRIs.
    • Only return a resulting IRI if it is absolute.
    • Fix _is_absolute_iri to use a reasonable regular expression and some other _expand_iri issues.
    • Fix to detecting relative IRIs.
    • Fix special case where relative path should not have a leading '/'
    • Pass in document location (through 'base' option) and use when resolving document-relative IRIs.
  • IRI Compaction:
    • Pass in document location (through 'base' option) and use when compacting document-relative IRIs.
  • Compaction:
    • Compact @direction.
    • Compact @type: @none.
    • Compact @included.
    • Honor @container: @set on @type.
    • Lists of Lists.
    • Improve handling of scoped contexts and propagate.
    • Improve map compaction, including indexed properties.
    • Catch Absolute IRI confused with prefix.
  • Expansion:
    • Updates to expansion algorithm.
    • _expand_value adds @direction from term definition.
    • JSON Literals.
    • Support @direction when expanding.
    • Support lists of lists.
    • Support property indexes.
    • Improve graph container expansion.
    • Order types when applying scoped contexts.
    • Use type_scoped_ctx when expanding values of @type.
    • Use propagate and override_protected properly when creating expansion contexts.
  • Flattening:
    • Rewrite _create_node_map based on 1.1 algorithm.
    • Flatten @included.
    • Flatten lists of lists.
    • Update merge_node_maps for @type.
  • Framing:
    • Change default for requireAll from True to False.
    • Change default for 'embed' from '@last' to '@once'.
    • Add defaults for omitGraph and pruneBlankNodeIdentifiers based on processing mode.
    • Change _remove_preserve to _cleanup_preserve which happens before compaction.
    • Add _cleanup_null which happens after compaction.
    • Update frame matching to 1.1 spec.
    • Support @included.
  • ToRdf:
    • Support for I18N direction.
    • Support for Lists of Lists.
    • Partial support for JSON canonicalization of JSON literals.
      • Includes local copy of JCS library, but doesn't load.
    • Lists of Lists.
    • Text Direction 'i18n-datatype'.
  • Testing
    • Switched to argparse.
    • BREAKING: Removed -d and -m test runner options in favor of just listing as arguments.
    • If no test manifests or directories are specified, default to sibling directories for json-ld-api, json-ld-framing, and normalization.

1.0.5 - 2019-05-09

Fixed

  • Use return instead of raise StopIteration to terminate generator.

1.0.4 - 2018-12-11

Fixed

  • Accept N-Quads upper case language tag.

1.0.3 - 2018-03-09

Fixed

  • Reorder code to avoid undefined symbols.

1.0.2 - 2018-03-08

Fixed

  • Missing error parameter.

1.0.1 - 2018-03-06

Fixed

  • Include document loaders in distribution.

1.0.0 - 2018-03-06

Notes

  • 1.0.0!
  • Semantic Versioning is now past the "initial development" 0.x.y stage (after 6+ years!).
  • Conformance:
    • JSON-LD 1.0 + JSON-LD 1.0 errata
    • JSON-LD 1.1 drafts
  • Thanks to the JSON-LD and related communities and the many many people over the years who contributed ideas, code, bug reports, and support!

Fixed

  • Don't always use arrays for @graph. Fixes 1.0 compatibility issue.
  • Process @type term contexts before key iteration.

Changed

  • BREAKING: A dependency of pyld will not pull in Requests anymore. One needs to define a dependency to pyld[requests] or create an explicit dependency on requests seperately. Use pyld[aiohttp] for aiohttp.
  • The default document loader is set to request_document_loader. If Requests is not available, aiohttp_document_loader is used. When aiohttp is not availabke, a dummy_document_loader is used.
  • Use the W3C standard MIME type for N-Quads of "application/n-quads". Accept "application/nquads" for compatibility.

Added

  • Support for asynchronous document loader library aiohttp.
  • Added dummy_document_loader which allows libraries to depend on pyld without depending on Requests or aiohttp.
  • The test runner contains an additional parameter -l to specify the default document loader.
  • Expansion and Compaction using scoped contexts on property and @type terms.
  • Expansion and Compaction of nested properties.
  • Index graph containers using @id and @index, with @set variations.
  • Index node objects using @id and @type, with @set variations.
  • Framing default and named graphs in addition to merged graph.
  • Value patterns when framing, allowing a subset of values to appear in the output.

0.8.2 - 2017-10-24

Fixed

  • Use default document loader for older exposed load_document API.

0.8.1 - 2017-10-24

Fixed

  • Use __about__.py to hold versioning and other meta data. Load file in setup.py and jsonld.py. Fixes testing and installation issues.

0.8.0 - 2017-10-20

Fixed

  • BREAKING: Default http (80) and https (443) ports removed from URLs. This matches test suite behavior and other processing libs such as jsonld.js.
  • BREAKING: Fix path normalization to pass test suite RFC 3984 tests. This could change output for various relative URL edge cases.
  • Allow empty lists to be compacted to any @list container term. (Port from jsonld.js)

Changed

  • BREAKING: Remove older document loader code. SSL/SNI support wasn't working well with newer Pythons.
  • BREAKING: Switch to Requests for document loading. Some behavior could slightly change. Better supported in Python 2 and Python 3.

Added

  • Support for test suite using http or https.
  • Easier to create a custom Requests document loader with the requests_document_loader call. Adds a secure flag to always use HTTPS. Can pass in keywords that Requests understands. verify to disable SSL verification or use custom cert bundles. cert to use client certs. timeout to fail on timeouts (important for production use!). See Requests docs for more info.

Before 0.8.0

  • See git history for changes.