[med-svn] [Git][med-team/python-rdflib-jsonld][upstream] New upstream version 0.5.0

Michael R. Crusoe gitlab at salsa.debian.org
Sat Apr 11 13:24:19 BST 2020



Michael R. Crusoe pushed to branch upstream at Debian Med / python-rdflib-jsonld


Commits:
bb9d6112 by Michael R. Crusoe at 2020-04-11T14:16:40+02:00
New upstream version 0.5.0
- - - - -


27 changed files:

- PKG-INFO
- README.md
- docs/jsonld-parser.rst
- docs/jsonld-serializer.rst
- rdflib_jsonld.egg-info/PKG-INFO
- rdflib_jsonld.egg-info/SOURCES.txt
- + rdflib_jsonld.egg-info/not-zip-safe
- rdflib_jsonld.egg-info/requires.txt
- rdflib_jsonld/__init__.py
- + rdflib_jsonld/_compat.py
- rdflib_jsonld/context.py
- rdflib_jsonld/parser.py
- rdflib_jsonld/serializer.py
- rdflib_jsonld/util.py
- setup.cfg
- setup.py
- + test/local-suite/manifest.jsonld
- + test/local-suite/sample-urn-in.jsonld
- + test/local-suite/sample-urn-out.nq
- + test/local-suite/toRdf-twoidnodes-in.jsonld
- + test/local-suite/toRdf-twoidnodes-out.nq
- + test/runner.py
- test/test_compaction.py
- test/test_context.py
- + test/test_localsuite.py
- + test/test_named_graphs.py
- test/test_testsuite.py


Changes:

=====================================
PKG-INFO
=====================================
@@ -1,31 +1,97 @@
 Metadata-Version: 1.1
 Name: rdflib-jsonld
-Version: 0.4.0
+Version: 0.5.0
 Summary: rdflib extension adding JSON-LD parser and serializer
 Home-page: https://github.com/RDFLib/rdflib-jsonld
 Author: RDFLib Team
-Author-email: http://groups.google.com/group/rdflib-dev
+Author-email: rdflib-dev at google.com
 License: BSD
-Download-URL: https://github.com/RDFLib/rdflib-jsonld/zipball/master
-Description: 
-            This parser/serialiser will
+Description: RDFLib plugin providing JSON-LD parsing and serialization
+        =========================================================
         
-            * read in an JSON-LD formatted document and create an RDF graph
-            * serialize an RDF graph to JSON-LD formatted output
+        This is an implementation of `JSON-LD <http://www.w3.org/TR/json-ld/>`_
+        for `RDFLib <https://github.com/RDFLib/rdflib>`_.
+        For more information about this technology, see the `JSON-LD website <http://json-ld.org/>`_.
         
-            See:
+        This implementation will:
         
-                http://json-ld.org/
+        - read in an JSON-LD formatted document and create an RDF graph
+        - serialize an RDF graph to JSON-LD formatted output
+        
+        
+        Installation
+        ------------
+        
+        The easiest way to install the RDFLib JSON-LD plugin is directly from PyPi using pip by running the command below:
+        
+        .. code-block:: shell
+        
+            pip install rdflib-jsonld
+            
+        
+        
+        Otherwise you can download the source and install it directly by running:
+        
+        .. code-block:: shell
+        
+            python setup.py install
+            
+        
+        
+        
+        Using the plug-in JSONLD serializer/parser with RDFLib
+        ------------------------------------------------------
+        
+        The plugin parser and serializer are automatically registered if installed by
+        setuptools.
+        
+        .. code-block:: python
+        
+            >>> from rdflib import Graph, plugin
+            >>> from rdflib.serializer import Serializer
+            
+            >>> testrdf = '''
+            ... @prefix dc: <http://purl.org/dc/terms/> .
+            ... <http://example.org/about>
+            ...     dc:title "Someone's Homepage"@en .
+            ... '''
             
+            >>> g = Graph().parse(data=testrdf, format='n3')
+            
+            >>> print(g.serialize(format='json-ld', indent=4))
+            {
+                "@id": "http://example.org/about",
+                "http://purl.org/dc/terms/title": [
+                    {
+                        "@language": "en",
+                        "@value": "Someone's Homepage"
+                    }
+                ]
+            }
+            
+            >>> context = {"@vocab": "http://purl.org/dc/terms/", "@language": "en"}
+            >>> print(g.serialize(format='json-ld', context=context, indent=4))
+            {
+                "@context": {
+                    "@language": "en",
+                    "@vocab": "http://purl.org/dc/terms/"
+                },
+                "@id": "http://example.org/about",
+                "title": "Someone's Homepage"
+            }
+            
+        
+        
+        
 Platform: any
 Classifier: Programming Language :: Python
 Classifier: Programming Language :: Python :: 2
-Classifier: Programming Language :: Python :: 2.5
-Classifier: Programming Language :: Python :: 2.6
 Classifier: Programming Language :: Python :: 2.7
 Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.2
 Classifier: Programming Language :: Python :: 3.3
+Classifier: Programming Language :: Python :: 3.4
+Classifier: Programming Language :: Python :: 3.5
+Classifier: Programming Language :: Python :: 3.6
 Classifier: License :: OSI Approved :: BSD License
 Classifier: Topic :: Software Development :: Libraries :: Python Modules
 Classifier: Operating System :: OS Independent


=====================================
README.md
=====================================
@@ -1,32 +1,35 @@
-RDFLib plugin providing JSON-LD parsing and serialization
-=========================================================
+# RDFLib plugin providing JSON-LD parsing and serialization
 
-This is an implementation of [JSON-LD](http://www.w3.org/TR/json-ld/) for [RDFLib](https://github.com/RDFLib/rdflib). For more information about this technology, see the [JSON-LD website](http://json-ld.org/).
+This is an implementation of [JSON-LD](http://www.w3.org/TR/json-ld/)
+for [RDFLib](https://github.com/RDFLib/rdflib).
+For more information about this technology, see the [JSON-LD website](http://json-ld.org/).
 
 This implementation will:
 
-* read in an JSON-LD formatted document and create an RDF graph
-* serialize an RDF graph to JSON-LD formatted output
+- read in an JSON-LD formatted document and create an RDF graph
+- serialize an RDF graph to JSON-LD formatted output
 
 
-Installation
-------------
+## Installation
 
 The easiest way to install the RDFLib JSON-LD plugin is directly from PyPi using pip by running the command below:
 
-    pip install rdflib-jsonld
+```shell
+pip install rdflib-jsonld
+```
 
 Otherwise you can download the source and install it directly by running:
 
-    python setup.py install
+```shell
+python setup.py install
+```
 
 
-Using the plug-in JSONLD serializer/parser with RDFLib
-------------------------------------------------------
+## Using the plug-in JSONLD serializer/parser with RDFLib
 
 The plugin parser and serializer are automatically registered if installed by
 setuptools.
-    
+
 ```python
 >>> from rdflib import Graph, plugin
 >>> from rdflib.serializer import Serializer
@@ -62,18 +65,20 @@ setuptools.
 }
 ```
 
+<!-- CUT HERE -->
+<!-- Text after this comment won't appear on PyPI -->
 
-Building the Sphinx documentation
----------------------------------
+## Building the Sphinx documentation
 
-If Sphinx is installed, Sphinx documentation can be generated with::
+If Sphinx is installed, Sphinx documentation can be generated with:
 
-    $ python setup.py build_sphinx
+```shell
+$ python setup.py build_sphinx
+```
 
 The documentation will be created in ./build/sphinx.
 
 
-Continuous integration tests
-----------------------------
+## Continuous integration tests
 
-[![Build Status](https://travis-ci.org/RDFLib/rdflib-jsonld.png?branch=master)](https://travis-ci.org/RDFLib/rdflib-jsonld)
+[![Build Status](https://travis-ci.org/RDFLib/rdflib-jsonld.svg?branch=master)](https://travis-ci.org/RDFLib/rdflib-jsonld)


=====================================
docs/jsonld-parser.rst
=====================================
@@ -40,9 +40,9 @@ manipulate the resulting graph.
 Module contents
 ---------------
 
-.. currentmodule:: rdflib_jsonld.jsonld_parser
+.. currentmodule:: rdflib_jsonld.parser
 
-.. automodule:: rdflib_jsonld.jsonld_parser
+.. automodule:: rdflib_jsonld.parser
 
 .. autoclass:: JsonLDParser
    :members: parse


=====================================
docs/jsonld-serializer.rst
=====================================
@@ -41,9 +41,9 @@ Read in an RDFLib Graph and serialize it, specifying ``format='json-ld'``.
 Module contents
 ---------------
 
-.. currentmodule:: rdflib_jsonld.jsonld_serializer
+.. currentmodule:: rdflib_jsonld.serializer
 
 .. autoclass:: JsonLDSerializer
    :members: serialize
 
-.. autofunction:: to_tree
+.. autofunction:: from_rdf


=====================================
rdflib_jsonld.egg-info/PKG-INFO
=====================================
@@ -1,31 +1,97 @@
 Metadata-Version: 1.1
 Name: rdflib-jsonld
-Version: 0.4.0
+Version: 0.5.0
 Summary: rdflib extension adding JSON-LD parser and serializer
 Home-page: https://github.com/RDFLib/rdflib-jsonld
 Author: RDFLib Team
-Author-email: http://groups.google.com/group/rdflib-dev
+Author-email: rdflib-dev at google.com
 License: BSD
-Download-URL: https://github.com/RDFLib/rdflib-jsonld/zipball/master
-Description: 
-            This parser/serialiser will
+Description: RDFLib plugin providing JSON-LD parsing and serialization
+        =========================================================
         
-            * read in an JSON-LD formatted document and create an RDF graph
-            * serialize an RDF graph to JSON-LD formatted output
+        This is an implementation of `JSON-LD <http://www.w3.org/TR/json-ld/>`_
+        for `RDFLib <https://github.com/RDFLib/rdflib>`_.
+        For more information about this technology, see the `JSON-LD website <http://json-ld.org/>`_.
         
-            See:
+        This implementation will:
         
-                http://json-ld.org/
+        - read in an JSON-LD formatted document and create an RDF graph
+        - serialize an RDF graph to JSON-LD formatted output
+        
+        
+        Installation
+        ------------
+        
+        The easiest way to install the RDFLib JSON-LD plugin is directly from PyPi using pip by running the command below:
+        
+        .. code-block:: shell
+        
+            pip install rdflib-jsonld
+            
+        
+        
+        Otherwise you can download the source and install it directly by running:
+        
+        .. code-block:: shell
+        
+            python setup.py install
+            
+        
+        
+        
+        Using the plug-in JSONLD serializer/parser with RDFLib
+        ------------------------------------------------------
+        
+        The plugin parser and serializer are automatically registered if installed by
+        setuptools.
+        
+        .. code-block:: python
+        
+            >>> from rdflib import Graph, plugin
+            >>> from rdflib.serializer import Serializer
+            
+            >>> testrdf = '''
+            ... @prefix dc: <http://purl.org/dc/terms/> .
+            ... <http://example.org/about>
+            ...     dc:title "Someone's Homepage"@en .
+            ... '''
             
+            >>> g = Graph().parse(data=testrdf, format='n3')
+            
+            >>> print(g.serialize(format='json-ld', indent=4))
+            {
+                "@id": "http://example.org/about",
+                "http://purl.org/dc/terms/title": [
+                    {
+                        "@language": "en",
+                        "@value": "Someone's Homepage"
+                    }
+                ]
+            }
+            
+            >>> context = {"@vocab": "http://purl.org/dc/terms/", "@language": "en"}
+            >>> print(g.serialize(format='json-ld', context=context, indent=4))
+            {
+                "@context": {
+                    "@language": "en",
+                    "@vocab": "http://purl.org/dc/terms/"
+                },
+                "@id": "http://example.org/about",
+                "title": "Someone's Homepage"
+            }
+            
+        
+        
+        
 Platform: any
 Classifier: Programming Language :: Python
 Classifier: Programming Language :: Python :: 2
-Classifier: Programming Language :: Python :: 2.5
-Classifier: Programming Language :: Python :: 2.6
 Classifier: Programming Language :: Python :: 2.7
 Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.2
 Classifier: Programming Language :: Python :: 3.3
+Classifier: Programming Language :: Python :: 3.4
+Classifier: Programming Language :: Python :: 3.5
+Classifier: Programming Language :: Python :: 3.6
 Classifier: License :: OSI Approved :: BSD License
 Classifier: Topic :: Software Development :: Libraries :: Python Modules
 Classifier: Operating System :: OS Independent


=====================================
rdflib_jsonld.egg-info/SOURCES.txt
=====================================
@@ -10,6 +10,7 @@ docs/jsonld-parser.rst
 docs/jsonld-serializer.rst
 docs/make.bat
 rdflib_jsonld/__init__.py
+rdflib_jsonld/_compat.py
 rdflib_jsonld/context.py
 rdflib_jsonld/errors.py
 rdflib_jsonld/keys.py
@@ -20,14 +21,23 @@ rdflib_jsonld.egg-info/PKG-INFO
 rdflib_jsonld.egg-info/SOURCES.txt
 rdflib_jsonld.egg-info/dependency_links.txt
 rdflib_jsonld.egg-info/entry_points.txt
+rdflib_jsonld.egg-info/not-zip-safe
 rdflib_jsonld.egg-info/requires.txt
 rdflib_jsonld.egg-info/top_level.txt
 test/README.md
 test/__init__.py
+test/runner.py
 test/test_api.py
 test/test_compaction.py
 test/test_context.py
+test/test_localsuite.py
+test/test_named_graphs.py
 test/test_testsuite.py
+test/local-suite/manifest.jsonld
+test/local-suite/sample-urn-in.jsonld
+test/local-suite/sample-urn-out.nq
+test/local-suite/toRdf-twoidnodes-in.jsonld
+test/local-suite/toRdf-twoidnodes-out.nq
 test/test-suite/README
 test/test-suite/context.jsonld
 test/test-suite/manifest.jsonld


=====================================
rdflib_jsonld.egg-info/not-zip-safe
=====================================
@@ -0,0 +1 @@
+


=====================================
rdflib_jsonld.egg-info/requires.txt
=====================================
@@ -1 +1 @@
-rdflib>=4.2
+rdflib>=4.2.2


=====================================
rdflib_jsonld/__init__.py
=====================================
@@ -1,3 +1,3 @@
 """
 """
-__version__ = "0.4.0"
+__version__ = "0.5.0"


=====================================
rdflib_jsonld/_compat.py
=====================================
@@ -0,0 +1,6 @@
+import sys
+
+IS_PY3 = sys.version_info[0] >= 3
+
+basestring = str if IS_PY3 else basestring  # noqa
+unicode = str if IS_PY3 else unicode  # noqa


=====================================
rdflib_jsonld/context.py
=====================================
@@ -8,6 +8,7 @@ Implementation of the JSON-LD Context structure. See:
 from collections import namedtuple
 from rdflib.namespace import RDF
 
+from ._compat import basestring, unicode
 from .keys import (BASE, CONTAINER, CONTEXT, GRAPH, ID, INDEX, LANG, LIST,
         REV, SET, TYPE, VALUE, VOCAB)
 from . import errors
@@ -28,6 +29,7 @@ class Context(object):
         self.base = base
         self.doc_base = base
         self.terms = {}
+        # _alias maps NODE_KEY to list of aliases
         self._alias = {}
         self._lookup = {}
         self._prefixes = {}
@@ -88,10 +90,16 @@ class Context(object):
         return self._get(obj, REV)
 
     def _get(self, obj, key):
-        return obj.get(self._alias.get(key)) or obj.get(key)
+        for alias in self._alias.get(key, []):
+            if alias in obj:
+                return obj.get(alias)
+        return obj.get(key)
 
     def get_key(self, key):
-        return self._alias.get(key, key)
+        return self.get_keys(key)[0]
+
+    def get_keys(self, key):
+        return self._alias.get(key, [key])
 
     lang_key = property(lambda self: self.get_key(LANG))
     id_key = property(lambda self: self.get_key(ID))
@@ -232,6 +240,7 @@ class Context(object):
                 self._read_term(source, key, value)
 
     def _read_term(self, source, name, dfn):
+        idref = None
         if isinstance(dfn, dict):
             #term = self._create_term(source, key, value)
             rev = dfn.get(REV)
@@ -250,17 +259,28 @@ class Context(object):
             self.add_term(name, idref, coercion,
                     dfn.get(CONTAINER, UNDEF), dfn.get(LANG, UNDEF), bool(rev))
         else:
-            idref = self._rec_expand(source, dfn)
+            if isinstance(dfn, unicode):
+                idref = self._rec_expand(source, dfn)
             self.add_term(name, idref)
+
         if idref in NODE_KEYS:
-            self._alias[idref] = name
+            self._alias.setdefault(idref, []).append(name)
 
     def _rec_expand(self, source, expr, prev=None):
         if expr == prev or expr in NODE_KEYS:
             return expr
+
         is_term, pfx, nxt = self._prep_expand(expr)
         if pfx:
-            iri = self._get_source_id(source, pfx) or self.expand(pfx)
+            iri = self._get_source_id(source, pfx)
+            if iri is None:
+                if pfx + ':' == self.vocab:
+                    return expr
+                else:
+                    term = self.terms.get(pfx)
+                    if term:
+                        iri = term.id
+
             if iri is None:
                 nxt = expr
             else:
@@ -269,6 +289,7 @@ class Context(object):
             nxt = self._get_source_id(source, nxt) or nxt
             if ':' not in nxt and self.vocab:
                 return self.vocab + nxt
+
         return self._rec_expand(source, nxt, expr)
 
     def _prep_expand(self, expr):


=====================================
rdflib_jsonld/parser.py
=====================================
@@ -40,6 +40,7 @@ from rdflib.parser import Parser, URLInputSource
 from rdflib.namespace import RDF, XSD
 from rdflib.term import URIRef, BNode, Literal
 
+from ._compat import basestring, unicode
 from .context import Context, Term, UNDEF
 from .util import source_to_json, VOCAB_DELIMS, context_from_urlinputsource
 from .keys import CONTEXT, GRAPH, ID, INDEX, LANG, LIST, REV, SET, TYPE, VALUE, VOCAB
@@ -47,6 +48,15 @@ from .keys import CONTEXT, GRAPH, ID, INDEX, LANG, LIST, REV, SET, TYPE, VALUE,
 __all__ = ['JsonLDParser', 'to_rdf']
 
 
+# Add jsonld suffix so RDFLib can guess format from file name
+try:
+    from rdflib.util import SUFFIX_FORMAT_MAP
+    if 'jsonld' not in SUFFIX_FORMAT_MAP:
+        SUFFIX_FORMAT_MAP['jsonld'] = 'application/ld+json'
+except ImportError:
+    pass
+
+
 TYPE_TERM = Term(unicode(RDF.type), TYPE, VOCAB)
 
 ALLOW_LISTS_OF_LISTS = True # NOTE: Not allowed in JSON-LD 1.0
@@ -71,12 +81,21 @@ class JsonLDParser(Parser):
         produce_generalized_rdf = kwargs.get('produce_generalized_rdf', False)
 
         data = source_to_json(source)
-        conj_sink = ConjunctiveGraph(
-            store=sink.store, identifier=sink.identifier)
+
+        # NOTE: A ConjunctiveGraph parses into a Graph sink, so no sink will be
+        # context_aware. Keeping this check in case RDFLib is changed, or
+        # someone passes something context_aware to this parser directly.
+        if not sink.context_aware:
+            conj_sink = ConjunctiveGraph(
+                store=sink.store,
+                identifier=sink.identifier)
+        else:
+            conj_sink = sink
+
         to_rdf(data, conj_sink, base, context_data)
 
 
-def to_rdf(data, graph, base=None, context_data=None,
+def to_rdf(data, dataset, base=None, context_data=None,
         produce_generalized_rdf=False,
         allow_lists_of_lists=None):
     # TODO: docstring w. args and return value
@@ -85,7 +104,7 @@ def to_rdf(data, graph, base=None, context_data=None,
         context.load(context_data)
     parser = Parser(generalized_rdf=produce_generalized_rdf,
             allow_lists_of_lists=allow_lists_of_lists)
-    return parser.parse(data, context, graph)
+    return parser.parse(data, context, dataset)
 
 
 class Parser(object):
@@ -95,7 +114,7 @@ class Parser(object):
         self.allow_lists_of_lists = (allow_lists_of_lists
                 if allow_lists_of_lists is not None else ALLOW_LISTS_OF_LISTS)
 
-    def parse(self, data, context, graph):
+    def parse(self, data, context, dataset):
         topcontext = False
 
         if isinstance(data, list):
@@ -110,13 +129,15 @@ class Parser(object):
                 resources = [resources]
 
         if context.vocab:
-            graph.bind(None, context.vocab)
+            dataset.bind(None, context.vocab)
         for name, term in context.terms.items():
             if term.id and term.id.endswith(VOCAB_DELIMS):
-                graph.bind(name, term.id)
+                dataset.bind(name, term.id)
+
+        graph = dataset.default_context if dataset.context_aware else dataset
 
         for node in resources:
-            self._add_to_graph(graph, graph, context, node, topcontext)
+            self._add_to_graph(dataset, graph, context, node, topcontext)
 
         return graph
 
@@ -141,19 +162,25 @@ class Parser(object):
         if subj is None:
             return None
 
+        # NOTE: crude way to signify that this node might represent a named graph
+        no_id = id_val is None
+
         for key, obj in node.items():
-            if key in (CONTEXT, ID, context.get_key(ID)):
+            if key in (CONTEXT, ID) or key in context.get_keys(ID):
                 continue
-            if key in (REV, context.get_key(REV)):
+            if key == REV or key in context.get_keys(REV):
                 for rkey, robj in obj.items():
-                    self._key_to_graph(dataset, graph, context, subj, rkey, robj, True)
+                    self._key_to_graph(dataset, graph, context, subj, rkey, robj,
+                            reverse=True, no_id=no_id)
             else:
-                self._key_to_graph(dataset, graph, context, subj, key, obj)
+                self._key_to_graph(dataset, graph, context, subj, key, obj,
+                        no_id=no_id)
 
         return subj
 
 
-    def _key_to_graph(self, dataset, graph, context, subj, key, obj, reverse=False):
+    def _key_to_graph(self, dataset, graph, context, subj, key, obj,
+            reverse=False, no_id=False):
 
         if isinstance(obj, list):
             obj_nodes = obj
@@ -186,8 +213,10 @@ class Parser(object):
         if TYPE in (key, term_id):
             term = TYPE_TERM
         elif GRAPH in (key, term_id):
-            #assert graph.context_aware
-            subgraph = dataset.get_context(subj)
+            if dataset.context_aware and not no_id:
+                subgraph = dataset.get_context(subj)
+            else:
+                subgraph = graph
             for onode in obj_nodes:
                 self._add_to_graph(dataset, subgraph, context, onode)
             return


=====================================
rdflib_jsonld/serializer.py
=====================================
@@ -45,6 +45,7 @@ from rdflib.graph import Graph
 from rdflib.term import URIRef, Literal, BNode
 from rdflib.namespace import RDF, XSD
 
+from ._compat import unicode
 from .context import Context, UNDEF
 from .util import json
 from .keys import CONTEXT, GRAPH, ID, VOCAB, LIST, SET, LANG
@@ -180,7 +181,7 @@ class Converter(object):
                     and not any(graph.subjects(None, s))):
                 self.process_subject(graph, s, nodemap)
 
-        return nodemap.values()
+        return list(nodemap.values())
 
     def process_subject(self, graph, s, nodemap):
         if isinstance(s, URIRef):


=====================================
rdflib_jsonld/util.py
=====================================
@@ -4,7 +4,7 @@ try:
 except ImportError:
     import simplejson as json
 
-from rdflib.py3compat import PY3, format_doctest_out
+from ._compat import IS_PY3 as PY3
 
 from os import sep
 from os.path import normpath
@@ -41,7 +41,6 @@ def split_iri(iri):
             return iri[:at+1], iri[at+1:]
     return iri, None
 
- at format_doctest_out
 def norm_url(base, url):
     """
     >>> norm_url('http://example.org/', '/one')
@@ -54,6 +53,8 @@ def norm_url(base, url):
     'http://example.org/one/two'
     >>> norm_url('http://example.org/', 'http://example.net/one')
     'http://example.net/one'
+    >>> norm_url('http://example.org/', 'http://example.org//one')
+    'http://example.org//one'
     """
     parts = urlsplit(urljoin(base, url))
     path = normpath(parts[2])


=====================================
setup.cfg
=====================================
@@ -3,8 +3,10 @@ attr = !known_issue
 verbosity = 1
 with-doctest = 1
 
+[wheel]
+universal = 1
+
 [egg_info]
 tag_build = 
 tag_date = 0
-tag_svn_revision = 0
 


=====================================
setup.py
=====================================
@@ -1,100 +1,108 @@
 #!/usr/bin/env python
 # -*- coding: utf-8 -*-
-import sys
+from __future__ import unicode_literals
+
+import io
 import re
 
-# Ridiculous as it may seem, we need to import multiprocessing and logging here
-# in order to get tests to pass smoothly on python 2.7.
-try:
-    import multiprocessing
-    import logging
-except:
-    pass
-
-
-def setup_python3():
-    # Taken from "distribute" setup.py
-    from distutils.filelist import FileList
-    from distutils import dir_util, file_util, util, log
-    from os.path import join
-
-    tmp_src = join("build", "src")
-    # log.set_verbosity(1)
-    fl = FileList()
-    for line in open("MANIFEST.in"):
-        if not line.strip():
-            continue
-        fl.process_template_line(line)
-    dir_util.create_tree(tmp_src, fl.files)
-    outfiles_2to3 = []
-    for f in fl.files:
-        outf, copied = file_util.copy_file(f, join(tmp_src, f), update=1)
-        if copied and outf.endswith(".py"):
-            outfiles_2to3.append(outf)
-
-    util.run_2to3(outfiles_2to3)
-
-    # arrange setup to use the copy
-    sys.path.insert(0, tmp_src)
-
-    return tmp_src
-
-
-# Find version. We have to do this because we can't import it in Python 3 until
-# its been automatically converted in the setup process.
-def find_version(filename):
-    _version_re = re.compile(r'__version__ = "(.*)"')
-    for line in open(filename):
-        version_match = _version_re.match(line)
-        if version_match:
-            return version_match.group(1)
-
-__version__ = find_version('rdflib_jsonld/__init__.py')
-
-install_requires = ["rdflib>=4.0", ] 
-
-if sys.version_info[:2] < (2, 6):
-    install_requires += ["simplejson"]
-
-config = dict(
-    name = 'rdflib-jsonld',
-    description = "rdflib extension adding JSON-LD parser and serializer",
-    maintainer = "RDFLib Team",
-    maintainer_email = "http://groups.google.com/group/rdflib-dev",
-    url = "https://github.com/RDFLib/rdflib-jsonld",
-    version = __version__,
-    download_url = "https://github.com/RDFLib/rdflib-jsonld/zipball/master",
-    license = "BSD",
-    platforms = ["any"],
-    long_description = \
-    """
-    This parser/serialiser will
-
-    * read in an JSON-LD formatted document and create an RDF graph
-    * serialize an RDF graph to JSON-LD formatted output
-
-    See:
-
-        http://json-ld.org/
-    """,
-    classifiers = [
-        "Programming Language :: Python",
-        "Programming Language :: Python :: 2",
-        "Programming Language :: Python :: 2.5",
-        "Programming Language :: Python :: 2.6",
-        "Programming Language :: Python :: 2.7",
-        "Programming Language :: Python :: 3",
-        "Programming Language :: Python :: 3.2",
-        "Programming Language :: Python :: 3.3",
-        "License :: OSI Approved :: BSD License",
-        "Topic :: Software Development :: Libraries :: Python Modules",
-        "Operating System :: OS Independent",
-        "Natural Language :: English",
-                   ],
-    packages = ["rdflib_jsonld"],
-    test_suite = "test",
-    install_requires = ["rdflib>=4.2"],
-    entry_points = {
+from os.path import dirname
+from setuptools import setup
+
+ROOT = dirname(__file__)
+
+RE_REQUIREMENT = re.compile(r'^\s*-r\s*(?P<filename>.*)$')
+
+RE_MD_CODE_BLOCK = re.compile(r'```(?P<language>\w+)?\n(?P<lines>.*?)```', re.S)
+RE_SELF_LINK = re.compile(r'\[(.*?)\]\[\]')
+RE_LINK_TO_URL = re.compile(r'\[(?P<text>.*?)\]\((?P<url>.*?)\)')
+RE_LINK_TO_REF = re.compile(r'\[(?P<text>.*?)\]\[(?P<ref>.*?)\]')
+RE_LINK_REF = re.compile(r'^\[(?P<key>[^!].*?)\]:\s*(?P<url>.*)$', re.M)
+RE_TITLE = re.compile(r'^(?P<level>#+)\s*(?P<title>.*)$', re.M)
+CUT = '<!-- CUT HERE -->'
+
+RST_TITLE_LEVELS = ['=', '-', '*']
+
+
+def md2pypi(filename):
+    '''
+    Load .md (markdown) file and sanitize it for PyPI.
+    Remove unsupported github tags:
+     - travis ci build badges
+    '''
+    content = io.open(filename).read().split(CUT)[0]
+
+    for match in RE_MD_CODE_BLOCK.finditer(content):
+        rst_block = '\n'.join(
+            ['.. code-block:: {language}'.format(**match.groupdict()), ''] +
+            ['    {0}'.format(l) for l in match.group('lines').split('\n')] +
+            ['']
+        )
+        content = content.replace(match.group(0), rst_block)
+
+    refs = dict(RE_LINK_REF.findall(content))
+    content = RE_LINK_REF.sub('.. _\g<key>: \g<url>', content)
+    content = RE_SELF_LINK.sub('`\g<1>`_', content)
+    content = RE_LINK_TO_URL.sub('`\g<text> <\g<url>>`_', content)
+
+    for match in RE_LINK_TO_REF.finditer(content):
+        content = content.replace(match.group(0), '`{text} <{url}>`_'.format(
+            text=match.group('text'),
+            url=refs[match.group('ref')]
+        ))
+
+    for match in RE_TITLE.finditer(content):
+        underchar = RST_TITLE_LEVELS[len(match.group('level')) - 1]
+        title = match.group('title')
+        underline = underchar * len(title)
+
+        full_title = '\n'.join((title, underline))
+        content = content.replace(match.group(0), full_title)
+
+    return content
+
+
+name = 'rdflib-jsonld'
+version = __import__('rdflib_jsonld').__version__
+
+
+setup(
+    name=name,
+    version=version,
+    description='rdflib extension adding JSON-LD parser and serializer',
+    long_description=md2pypi('README.md'),
+    maintainer='RDFLib Team',
+    maintainer_email='rdflib-dev at google.com',
+    url='https://github.com/RDFLib/rdflib-jsonld',
+    license='BSD',
+    packages=['rdflib_jsonld'],
+    use_2to3=True,
+    zip_safe=False,
+    platforms=['any'],
+    classifiers=[
+        'Programming Language :: Python',
+        'Programming Language :: Python :: 2',
+        'Programming Language :: Python :: 2.7',
+        'Programming Language :: Python :: 3',
+        'Programming Language :: Python :: 3.3',
+        'Programming Language :: Python :: 3.4',
+        'Programming Language :: Python :: 3.5',
+        'Programming Language :: Python :: 3.6',
+        'License :: OSI Approved :: BSD License',
+        'Topic :: Software Development :: Libraries :: Python Modules',
+        'Operating System :: OS Independent',
+        'Natural Language :: English',
+    ],
+    test_suite='nose.collector',
+    install_requires = ['rdflib>=4.2.2'],
+    tests_require=['nose'],
+    command_options={
+        'build_sphinx': {
+            'project': ('setup.py', name),
+            'version': ('setup.py', '.'.join(version.split('.')[:2])),
+            'release': ('setup.py', version)
+        }
+    },
+    entry_points={
         'rdf.plugins.parser': [
             'json-ld = rdflib_jsonld.parser:JsonLDParser',
             'application/ld+json = rdflib_jsonld.parser:JsonLDParser',
@@ -105,17 +113,3 @@ config = dict(
         ],
     }
 )
-
-if sys.version_info[0] >= 3:
-    from setuptools import setup
-    config.update({'use_2to3': True})
-    config.update({'src_root': setup_python3()})
-else:
-    try:
-        from setuptools import setup
-        config.update({'test_suite' : "nose.collector"})
-    except ImportError:
-        from distutils.core import setup
-
-
-setup(**config)


=====================================
test/local-suite/manifest.jsonld
=====================================
@@ -0,0 +1,24 @@
+{
+  "@context": "http://json-ld.org/test-suite/context.jsonld",
+  "@id": "",
+  "@type": "mf:Manifest",
+  "name": "RDFLib-jsonld local test suite",
+  "sequence": [
+    {
+      "@id": "#toRdf-twoidnodes",
+      "@type": ["jld:PositiveEvaluationTest", "jld:ToRDFTest"],
+      "name": "Two identifier nodes",
+      "purpose": "Multiple @id aliases.  Issue #58",
+      "input": "toRdf-twoidnodes-in.jsonld",
+      "expect": "toRdf-twoidnodes-out.nq"
+    },
+    {
+      "@id": "#toRdf-urn-in-vocab-and-prefix-values",
+      "@type": ["jld:PositiveEvaluationTest", "jld:ToRDFTest"],
+      "name": "URN in vocab and prefix values",
+      "purpose": "Expanding urn IRIs recursively. Issue #75",
+      "input": "sample-urn-in.jsonld",
+      "expect": "sample-urn-out.nq"
+    }
+  ]
+}


=====================================
test/local-suite/sample-urn-in.jsonld
=====================================
@@ -0,0 +1,12 @@
+{
+    "@context": {
+        "@vocab": "urn:example:1:",
+        "": "urn:example:2:",
+        "x": "urn:example:",
+        "y": "x:3:"
+    },
+    "@id": ":nsvocab",
+    "@type": "nsthing",
+    "foo": ":bar",
+    "y:baz": ":qwerty"
+}


=====================================
test/local-suite/sample-urn-out.nq
=====================================
@@ -0,0 +1,3 @@
+<urn:example:2:nsvocab> <urn:example:1:foo> ":bar" .
+<urn:example:2:nsvocab> <urn:example:3:baz> ":qwerty" .
+<urn:example:2:nsvocab> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <urn:example:1:nsthing> .


=====================================
test/local-suite/toRdf-twoidnodes-in.jsonld
=====================================
@@ -0,0 +1,10 @@
+{
+   "id": "https://monarchinitiative.org/genelist/",
+   "kg_source": "Test",
+   "type": "biolink:KnowledgeGraph",
+   "@context": {
+        "id": "@id",
+        "type": "@type",
+        "z": "@id"
+    }
+}
\ No newline at end of file


=====================================
test/local-suite/toRdf-twoidnodes-out.nq
=====================================
@@ -0,0 +1 @@
+<https://monarchinitiative.org/genelist/> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <biolink:KnowledgeGraph> .
\ No newline at end of file


=====================================
test/runner.py
=====================================
@@ -0,0 +1,119 @@
+from __future__ import with_statement
+import json
+from rdflib import ConjunctiveGraph
+from rdflib.compare import isomorphic
+from rdflib_jsonld._compat import IS_PY3
+from rdflib_jsonld.parser import to_rdf
+from rdflib_jsonld.serializer import from_rdf
+from rdflib_jsonld.keys import CONTEXT, GRAPH
+
+
+# monkey-patch NTriplesParser to keep source bnode id:s ..
+from rdflib.plugins.parsers.ntriples import NTriplesParser, r_nodeid, bNode
+def _preserving_nodeid(self):
+    if not self.peek('_'):
+        return False
+    return bNode(self.eat(r_nodeid).group(1))
+NTriplesParser.nodeid = _preserving_nodeid
+# .. and accept bnodes everywhere
+_uriref = NTriplesParser.uriref
+def _uriref_or_nodeid(self):
+    return _uriref(self) or self.nodeid()
+NTriplesParser.uriref = _uriref_or_nodeid
+
+
+TC_BASE = "http://json-ld.org/test-suite/tests/"
+
+
+def do_test_json(cat, num, inputpath, expectedpath, context, options):
+    base = TC_BASE + inputpath
+    input_obj = _load_json(inputpath)
+    input_graph = ConjunctiveGraph()
+    to_rdf(input_obj, input_graph, base=base, context_data=context,
+            produce_generalized_rdf=True)
+    expected_json = _load_json(expectedpath)
+    use_native_types = True # CONTEXT in input_obj
+    result_json = from_rdf(input_graph, context, base=TC_BASE + inputpath,
+            use_native_types=options.get('useNativeTypes', use_native_types),
+            use_rdf_type=options.get('useRdfType', False))
+
+    def _prune_json(data):
+        if CONTEXT in data:
+            data.pop(CONTEXT)
+        if GRAPH in data:
+            data = data[GRAPH]
+        #def _remove_empty_sets(obj):
+        return data
+
+    expected_json = _prune_json(expected_json)
+    result_json = _prune_json(result_json)
+
+    _compare_json(expected_json, result_json)
+
+
+def do_test_parser(cat, num, inputpath, expectedpath, context, options):
+    input_obj = _load_json(inputpath)
+    expected_graph = _load_nquads(expectedpath)
+    base = TC_BASE + inputpath
+    result_graph = ConjunctiveGraph()
+    to_rdf(input_obj, result_graph, base=base, context_data=context,
+            produce_generalized_rdf = options.get('produceGeneralizedRdf', False))
+    assert isomorphic(
+            result_graph, expected_graph), "Expected:\n%s\nGot:\n%s" % (
+            expected_graph.serialize(format='turtle'),
+            result_graph.serialize(format='turtle'))
+
+
+def do_test_serializer(cat, num, inputpath, expectedpath, context, options):
+    input_graph = _load_nquads(inputpath)
+    expected_json = _load_json(expectedpath)
+    result_json = from_rdf(input_graph, context, base=TC_BASE + inputpath,
+            use_native_types=options.get('useNativeTypes', False),
+            use_rdf_type=options.get('useRdfType', False))
+    _compare_json(expected_json, result_json)
+
+
+def _load_nquads(source):
+    graph = ConjunctiveGraph()
+    with open(source) as f:
+        data = f.read() if IS_PY3 else f.read().decode('utf-8')
+    graph.parse(data=data, format='nquads')
+    return graph
+
+
+def _load_json(source):
+    with open(source) as f:
+        return json.load(f)
+
+
+def _to_ordered(obj):
+    if isinstance(obj, list):
+        # NOTE: use type in key to handle mixed
+        # lists of e.g. bool, int, float.
+        return sorted((_to_ordered(lv) for lv in obj),
+                key=lambda x: (_ord_key(x), type(x).__name__))
+    if not isinstance(obj, dict):
+        return obj
+    return sorted((k, _to_ordered(v))
+            for k, v in obj.items())
+
+
+def _ord_key(x):
+    if isinstance(x, dict) and '@id' in x:
+        return x['@id']
+    else:
+        return x
+
+
+def _dump_json(obj):
+    return json.dumps(obj,
+            indent=4, separators=(',', ': '),
+            sort_keys=True, check_circular=True)
+
+
+def _compare_json(expected, result):
+    expected = json.loads(_dump_json(expected))
+    result = json.loads(_dump_json(result))
+    assert _to_ordered(expected) == _to_ordered(result), \
+            "Expected JSON:\n%s\nGot:\n%s" % (
+                    _dump_json(expected), _dump_json(result))


=====================================
test/test_compaction.py
=====================================
@@ -56,7 +56,7 @@ case("""
 )
 
 
-# .. Requires set values to be sorted to be predicatble
+# .. Requires set values to be sorted to be predictable
 #case("""
 #@prefix dc: <http://purl.org/dc/terms/> .
 #<http://example.org/>
@@ -234,7 +234,7 @@ def run(data, expected):
     sort_graph(result)
     result = json.dumps(result, **json_kwargs)
     incr = itertools.count(1)
-    result = re.sub(r'"_:[^"]+"', lambda m: '"_:blank-%s"' % incr.next(), result)
+    result = re.sub(r'"_:[^"]+"', lambda m: '"_:blank-%s"' % next(incr), result)
 
     sort_graph(expected)
     expected = json.dumps(expected, **json_kwargs)


=====================================
test/test_context.py
=====================================
@@ -108,6 +108,12 @@ def test_creating_a_subcontext():
     assert ctx4.get_language({'lang': 'en'}) == 'en'
 
 
+def test_prefix_like_vocab():
+    ctx = Context({'@vocab': 'ex:', 'term': 'ex:term'})
+    term = ctx.terms.get('term')
+    assert term.id == 'ex:term'
+
+
 # Mock external sources loading
 from rdflib_jsonld import context
 _source_to_sjon = context.source_to_json


=====================================
test/test_localsuite.py
=====================================
@@ -0,0 +1,33 @@
+from os import environ, chdir, path as p
+import json
+from . import runner
+
+
+testsuite_dir = p.join(p.abspath(p.dirname(__file__)), "local-suite")
+
+
+def read_manifest():
+    f = open(p.join(testsuite_dir, "manifest.jsonld"), 'r')
+    manifestdata = json.load(f)
+    f.close()
+    for test in manifestdata.get('sequence'):
+        parts = test.get(u'input', '').split('.')[0].split('-')
+        category, name, direction = parts
+        inputpath = test.get(u'input')
+        expectedpath = test.get(u'expect')
+        context = test.get(u'context', False)
+        options = test.get(u'option') or {}
+        yield category, name, inputpath, expectedpath, context, options
+
+
+def test_suite():
+    chdir(testsuite_dir)
+    for cat, num, inputpath, expectedpath, context, options in read_manifest():
+        if inputpath.endswith(".jsonld"): # toRdf
+            if expectedpath.endswith(".jsonld"): # compact/expand/flatten
+                func = runner.do_test_json
+            else: # toRdf
+                func = runner.do_test_parser
+        else:  # fromRdf
+            func = runner.do_test_serializer
+        yield func, cat, num, inputpath, expectedpath, context, options


=====================================
test/test_named_graphs.py
=====================================
@@ -0,0 +1,55 @@
+from __future__ import unicode_literals, print_function
+from rdflib import *
+from rdflib.plugin import register, Parser
+register('application/ld+json', Parser, 'rdflib_jsonld.parser', 'JsonLDParser')
+
+data = """
+{
+    "@context": {"@vocab": "http://schema.org/"},
+    "@graph": [
+        { "@id": "http://example.org/data#jdoe",
+          "name": "John"
+        },
+        { "@id": "http://example.org/data#janedoe",
+          "name": "Jane"
+        },
+        { "@id": "http://example.org/data#metadata",
+          "@graph": [
+              { "@id": "http://example.org/data",
+                "creator": "http://example.org/data#janedoe"
+              }
+          ]
+        }
+    ]
+}
+"""
+
+meta_ctx = URIRef('http://example.org/data#metadata')
+
+def test_graph():
+    g = Graph()
+    g.parse(data=data, format="application/ld+json")
+    assert len(g) == 2
+
+def test_conjunctive_graph():
+    cg = ConjunctiveGraph()
+    cg.default_context.parse(data=data, format="application/ld+json")
+    assert len(cg) == 3
+
+    print("default graph (%s) contains %s triples (expected 2)" % (cg.identifier, len(cg.default_context)))
+    for ctx in cg.contexts():
+        print("named graph (%s) contains %s triples" % (ctx.identifier, len(ctx)))
+    assert len(cg.default_context) == 2
+    assert len(list(cg.contexts())) == 2
+
+def test_dataset():
+    ds = Dataset()
+    ds.default_context.parse(data=data, format="application/ld+json")
+    assert len(ds) == 3
+
+    assert len(ds.default_context) == 2
+    print("default graph (%s) contains %s triples (expected 2)" % (ds.identifier, len(ds.default_context)))
+    contexts = dict((ctx.identifier, ctx) for ctx in ds.contexts())
+    assert len(contexts) == 2
+    assert len(contexts.pop(meta_ctx)) == 1
+    assert len(list(contexts.values())[0]) == 2


=====================================
test/test_testsuite.py
=====================================
@@ -1,33 +1,8 @@
-from __future__ import with_statement
 from os import environ, chdir, path as p
-try:
-    import json
-    assert json
-except ImportError:
-    import simplejson as json
+import json
 from rdflib import ConjunctiveGraph, Graph, Literal, URIRef
-from rdflib.compare import isomorphic
-from rdflib.py3compat import PY3
 import rdflib_jsonld.parser
-from rdflib_jsonld.parser import to_rdf
-from rdflib_jsonld.serializer import from_rdf
-from rdflib_jsonld.keys import CONTEXT, GRAPH
-
-
-rdflib_jsonld.parser.ALLOW_LISTS_OF_LISTS = False
-
-# monkey-patch NTriplesParser to keep source bnode id:s ..
-from rdflib.plugins.parsers.ntriples import NTriplesParser, r_nodeid, bNode
-def _preserving_nodeid(self):
-    if not self.peek('_'):
-        return False
-    return bNode(self.eat(r_nodeid).group(1))
-NTriplesParser.nodeid = _preserving_nodeid
-# .. and accept bnodes everywhere
-_uriref = NTriplesParser.uriref
-def _uriref_or_nodeid(self):
-    return _uriref(self) or self.nodeid()
-NTriplesParser.uriref = _uriref_or_nodeid
+from . import runner
 
 
 unsupported_tests = ("frame", "normalize")
@@ -48,8 +23,6 @@ if sys.version_info[:2] < (2, 6):
     # Fails on bug in older urlparse.urljoin; ignoring..
     known_bugs += ('toRdf-0069-in','toRdf-0102-in')
 
-TC_BASE = "http://json-ld.org/test-suite/tests/"
-
 
 testsuite_dir = environ.get("JSONLD_TESTSUITE") or p.join(
         p.abspath(p.dirname(__file__)), "test-suite")
@@ -82,6 +55,9 @@ def read_manifest(skiptests):
 
 
 def test_suite(skip_known_bugs=True):
+    default_allow = rdflib_jsonld.parser.ALLOW_LISTS_OF_LISTS
+    rdflib_jsonld.parser.ALLOW_LISTS_OF_LISTS = False
+
     skiptests = unsupported_tests
     if skip_known_bugs:
         skiptests += known_bugs
@@ -89,110 +65,16 @@ def test_suite(skip_known_bugs=True):
     for cat, num, inputpath, expectedpath, context, options in read_manifest(skiptests):
         if inputpath.endswith(".jsonld"): # toRdf
             if expectedpath.endswith(".jsonld"): # compact/expand/flatten
-                func = _test_json
+                func = runner.do_test_json
             else: # toRdf
-                func = _test_parser
+                func = runner.do_test_parser
         else:  # fromRdf
-            func = _test_serializer
+            func = runner.do_test_serializer
         #func.description = "%s-%s-%s" % (group, case)
         yield func, cat, num, inputpath, expectedpath, context, options
 
+    rdflib_jsonld.parser.ALLOW_LISTS_OF_LISTS = default_allow
 
-def _test_json(cat, num, inputpath, expectedpath, context, options):
-    base = TC_BASE + inputpath
-    input_obj = _load_json(inputpath)
-    input_graph = ConjunctiveGraph()
-    to_rdf(input_obj, input_graph, base=base, context_data=context,
-            produce_generalized_rdf=True)
-    expected_json = _load_json(expectedpath)
-    use_native_types = True # CONTEXT in input_obj
-    result_json = from_rdf(input_graph, context, base=TC_BASE + inputpath,
-            use_native_types=options.get('useNativeTypes', use_native_types),
-            use_rdf_type=options.get('useRdfType', False))
-
-    def _prune_json(data):
-        if CONTEXT in data:
-            data.pop(CONTEXT)
-        if GRAPH in data:
-            data = data[GRAPH]
-        #def _remove_empty_sets(obj):
-        return data
-
-    expected_json = _prune_json(expected_json)
-    result_json = _prune_json(result_json)
-
-    _compare_json(expected_json, result_json)
-
-
-def _test_parser(cat, num, inputpath, expectedpath, context, options):
-    input_obj = _load_json(inputpath)
-    expected_graph = _load_nquads(expectedpath)
-    base = TC_BASE + inputpath
-    result_graph = ConjunctiveGraph()
-    to_rdf(input_obj, result_graph, base=base, context_data=context,
-            produce_generalized_rdf = options.get('produceGeneralizedRdf', False))
-    assert isomorphic(
-            result_graph, expected_graph), "Expected:\n%s\nGot:\n%s" % (
-            expected_graph.serialize(format='turtle'),
-            result_graph.serialize(format='turtle'))
-
-
-def _test_serializer(cat, num, inputpath, expectedpath, context, options):
-    input_graph = _load_nquads(inputpath)
-    expected_json = _load_json(expectedpath)
-    result_json = from_rdf(input_graph, context, base=TC_BASE + inputpath,
-            use_native_types=options.get('useNativeTypes', False),
-            use_rdf_type=options.get('useRdfType', False))
-    _compare_json(expected_json, result_json)
-
-
-def _load_nquads(source):
-    graph = ConjunctiveGraph()
-    with open(source) as f:
-        if PY3:
-            data = f.read()
-        else:
-            data = f.read().decode('utf-8')
-    graph.parse(data=data, format='nquads')
-    return graph
-
-
-def _load_json(source):
-    with open(source) as f:
-        return json.load(f)
-
-
-def _to_ordered(obj):
-    if isinstance(obj, list):
-        # NOTE: use type in key to handle mixed
-        # lists of e.g. bool, int, float.
-        return sorted((_to_ordered(lv) for lv in obj),
-                key=lambda x: (_ord_key(x), type(x).__name__))
-    if not isinstance(obj, dict):
-        return obj
-    return sorted((k, _to_ordered(v))
-            for k, v in obj.items())
-
-
-def _ord_key(x):
-    if isinstance(x, dict) and '@id' in x:
-        return x['@id']
-    else:
-        return x
-
-
-def _dump_json(obj):
-    return json.dumps(obj,
-            indent=4, separators=(',', ': '),
-            sort_keys=True, check_circular=True)
-
-
-def _compare_json(expected, result):
-    expected = json.loads(_dump_json(expected))
-    result = json.loads(_dump_json(result))
-    assert _to_ordered(expected) == _to_ordered(result), \
-            "Expected JSON:\n%s\nGot:\n%s" % (
-                    _dump_json(expected), _dump_json(result))
 
 if __name__ == '__main__':
     import sys



View it on GitLab: https://salsa.debian.org/med-team/python-rdflib-jsonld/-/commit/bb9d61122462d16660a0289873745b61d3c2ccaa

-- 
View it on GitLab: https://salsa.debian.org/med-team/python-rdflib-jsonld/-/commit/bb9d61122462d16660a0289873745b61d3c2ccaa
You're receiving this email because of your account on salsa.debian.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/debian-med-commit/attachments/20200411/aaff5f8e/attachment-0001.html>


More information about the debian-med-commit mailing list