diff --git a/.mailmap b/.mailmap index d953d228f..06db195ac 100644 --- a/.mailmap +++ b/.mailmap @@ -65,9 +65,10 @@ Maurizio Nagni kusamau Michel Pelletier michel Mikael Nilsson mikael Nathan Maynes Nathan M -Nicholas J. Car Nicholas Car -Nicholas J. Car Nicholas Car -Nicholas J. Car nicholascar +Nicholas J. Car Nicholas Car +Nicholas J. Car Nicholas Car +Nicholas J. Car nicholascar +Nicholas J. Car Nicholas Car Niklas Lindström lindstream Niklas Lindström Niklas Lindstrom Olivier Grisel ogrisel @@ -98,4 +99,4 @@ William Waites wwaites William Waites ww@epsilon.styx.org Whit Morriss whit Zach Lûster kernc -Zach Lûster Kernc \ No newline at end of file +Zach Lûster Kernc diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 51e1456fb..ca8b2025c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -7,13 +7,13 @@ ci: # https://pre-commit.com/#adding-pre-commit-plugins-to-your-project repos: - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.4.1 + rev: v0.4.9 hooks: - id: ruff args: ["--fix"] - repo: https://github.com/psf/black-pre-commit-mirror # WARNING: version should be the same as in `pyproject.toml` - rev: "24.4.0" + rev: "24.4.2" hooks: - id: black pass_filenames: false diff --git a/Taskfile.yml b/Taskfile.yml index cc596398f..2b9582f5f 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -139,14 +139,14 @@ tasks: desc: Fix auto-fixable linting errors cmds: - task: ruff - vars: { FIX: true } + vars: { FIX: "true" } - task: black lint: desc: Perform linting cmds: - task: black - vars: { CHECK: true } + vars: { CHECK: "true" } - task: ruff validate:static: @@ -250,7 +250,7 @@ tasks: - task: install:system-deps - task: install:tox vars: - WITH_GITHUB_ACTIONS: true + WITH_GITHUB_ACTIONS: "true" - cmd: "{{.PYTHON}} -m pip install coveralls" - task: tox vars: diff --git a/devtools/requirements-poetry.in b/devtools/requirements-poetry.in index 783d0a538..51526d194 100644 --- a/devtools/requirements-poetry.in +++ b/devtools/requirements-poetry.in @@ -1,3 +1,3 @@ # Fixing this here as readthedocs can't use the compiled requirements-poetry.txt # due to conflicts. -poetry==1.8.2 +poetry==1.8.3 diff --git a/docker/latest/Dockerfile b/docker/latest/Dockerfile index 23a2b5df0..afc7862d1 100644 --- a/docker/latest/Dockerfile +++ b/docker/latest/Dockerfile @@ -1,4 +1,4 @@ -FROM docker.io/library/python:3.12.2-slim@sha256:eb53cb99a609b86da6e239b16e1f2aed5e10cfbc538671fc4631093a00f133f2 +FROM docker.io/library/python:3.12.2-slim@sha256:5c73034c2bc151596ee0f1335610735162ee2b148816710706afec4757ad5b1e COPY docker/latest/requirements.txt /var/tmp/build/ diff --git a/docs/developers.rst b/docs/developers.rst index 8d21ef8e7..7e00dc950 100644 --- a/docs/developers.rst +++ b/docs/developers.rst @@ -345,7 +345,7 @@ Some useful commands for working with the task in the taskfile is given below: task validate # Build docs - task docs:build + task docs # Run live-preview on the docs task docs:live-server diff --git a/docs/intro_to_parsing.rst b/docs/intro_to_parsing.rst index 4593aa7d9..8b011c53f 100644 --- a/docs/intro_to_parsing.rst +++ b/docs/intro_to_parsing.rst @@ -116,7 +116,7 @@ Working with multi-graphs ------------------------- To read and query multi-graphs, that is RDF data that is context-aware, you need to use rdflib's -:class:`rdflib.ConjunctiveGraph` or :class:`rdflib.Dataset` class. These are extensions to :class:`rdflib.Graph` that +:class:`rdflib.Dataset` class. This an extension to :class:`rdflib.Graph` that know all about quads (triples + graph IDs). If you had this multi-graph data file (in the ``trig`` format, using new-style ``PREFIX`` statement (not the older diff --git a/docs/merging.rst b/docs/merging.rst index d0e5f5e51..1721d9206 100644 --- a/docs/merging.rst +++ b/docs/merging.rst @@ -25,7 +25,7 @@ In RDFLib, blank nodes are given unique IDs when parsing, so graph merging can b ``graph`` now contains the merged graph of ``input1`` and ``input2``. -.. note:: However, the set-theoretic graph operations in RDFLib are assumed to be performed in sub-graphs of some larger data-base (for instance, in the context of a :class:`~rdflib.graph.ConjunctiveGraph`) and assume shared blank node IDs, and therefore do NOT do *correct* merging, i.e.:: +.. note:: However, the set-theoretic graph operations in RDFLib are assumed to be performed in sub-graphs of some larger data-base (for instance, in the context of a :class:`~rdflib.graph.Dataset`) and assume shared blank node IDs, and therefore do NOT do *correct* merging, i.e.:: from rdflib import Graph diff --git a/docs/plugin_parsers.rst b/docs/plugin_parsers.rst index f199b9226..7b3c2a568 100644 --- a/docs/plugin_parsers.rst +++ b/docs/plugin_parsers.rst @@ -32,9 +32,8 @@ xml :class:`~rdflib.plugins.parsers.rdfxml.RDFXMLParser` Multi-graph IDs --------------- -Note that for correct parsing of multi-graph data, e.g. Trig, HexT, etc., into a ``ConjunctiveGraph`` or a ``Dataset``, -as opposed to a context-unaware ``Graph``, you will need to set the ``publicID`` of the ``ConjunctiveGraph`` a -``Dataset`` to the identifier of the ``default_context`` (default graph), for example:: +Note that for correct parsing of multi-graph data, e.g. Trig, HexT, etc., into a ``Dataset``, +as opposed to a context-unaware ``Graph``, you will need to set the ``publicID`` of the ``Dataset`` to the identifier of the ``default_context`` (default graph), for example:: d = Dataset() d.parse( diff --git a/poetry.lock b/poetry.lock index f24fdb693..0e50a87b6 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. [[package]] name = "alabaster" @@ -726,20 +726,20 @@ testing-docutils = ["pygments", "pytest (>=7,<8)", "pytest-param-files (>=0.3.4, [[package]] name = "networkx" -version = "2.8.8" +version = "3.1" description = "Python package for creating and manipulating graphs and networks" optional = true python-versions = ">=3.8" files = [ - {file = "networkx-2.8.8-py3-none-any.whl", hash = "sha256:e435dfa75b1d7195c7b8378c3859f0445cd88c6b0375c181ed66823a9ceb7524"}, - {file = "networkx-2.8.8.tar.gz", hash = "sha256:230d388117af870fce5647a3c52401fcf753e94720e6ea6b4197a5355648885e"}, + {file = "networkx-3.1-py3-none-any.whl", hash = "sha256:4f33f68cb2afcf86f28a45f43efc27a9386b535d567d2127f8f61d51dec58d36"}, + {file = "networkx-3.1.tar.gz", hash = "sha256:de346335408f84de0eada6ff9fafafff9bcda11f0a0dfaa931133debb146ab61"}, ] [package.extras] -default = ["matplotlib (>=3.4)", "numpy (>=1.19)", "pandas (>=1.3)", "scipy (>=1.8)"] -developer = ["mypy (>=0.982)", "pre-commit (>=2.20)"] -doc = ["nb2plots (>=0.6)", "numpydoc (>=1.5)", "pillow (>=9.2)", "pydata-sphinx-theme (>=0.11)", "sphinx (>=5.2)", "sphinx-gallery (>=0.11)", "texext (>=0.6.6)"] -extra = ["lxml (>=4.6)", "pydot (>=1.4.2)", "pygraphviz (>=1.9)", "sympy (>=1.10)"] +default = ["matplotlib (>=3.4)", "numpy (>=1.20)", "pandas (>=1.3)", "scipy (>=1.8)"] +developer = ["mypy (>=1.1)", "pre-commit (>=3.2)"] +doc = ["nb2plots (>=0.6)", "numpydoc (>=1.5)", "pillow (>=9.4)", "pydata-sphinx-theme (>=0.13)", "sphinx (>=6.1)", "sphinx-gallery (>=0.12)", "texext (>=0.6.7)"] +extra = ["lxml (>=4.6)", "pydot (>=1.4.2)", "pygraphviz (>=1.10)", "sympy (>=1.10)"] test = ["codecov (>=2.1)", "pytest (>=7.2)", "pytest-cov (>=4.0)"] [[package]] @@ -1286,4 +1286,4 @@ networkx = ["networkx"] [metadata] lock-version = "2.0" python-versions = "^3.8.1" -content-hash = "883a563380c9450e52778d40e6b38d8393237d077d690b10e5a43438d9443820" +content-hash = "ac6ecc3bb7a6d80073ed33c06832f3dd71a7fa584c24690ba2593513f6dde076" diff --git a/pyproject.toml b/pyproject.toml index f1868ad48..c0944b0c0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -42,7 +42,7 @@ python = "^3.8.1" isodate = "^0.6.0" pyparsing = ">=2.1.0,<4" berkeleydb = {version = "^18.1.0", optional = true} -networkx = {version = "^2.0.0", optional = true} +networkx = {version = ">=2,<4", optional = true} html5lib = {version = "^1.0", optional = true} lxml = {version = "^4.3.0", optional = true} diff --git a/rdflib/graph.py b/rdflib/graph.py index a8b1593ea..f268b5304 100644 --- a/rdflib/graph.py +++ b/rdflib/graph.py @@ -19,6 +19,9 @@ Conjunctive Graph ----------------- +.. warning:: + ConjunctiveGraph is deprecated, use :class:`~rdflib.graph.Dataset` instead. + A Conjunctive Graph is the most relevant collection of graphs that are considered to be the boundary for closed world assumptions. This boundary is equivalent to that of the store instance (which is itself @@ -249,6 +252,7 @@ import logging import pathlib import random +import warnings from io import BytesIO from typing import ( IO, @@ -1893,6 +1897,9 @@ class ConjunctiveGraph(Graph): """A ConjunctiveGraph is an (unnamed) aggregation of all the named graphs in a store. + .. warning:: + ConjunctiveGraph is deprecated, use :class:`~rdflib.graph.Dataset` instead. + It has a ``default`` graph, whose name is associated with the graph throughout its life. :meth:`__init__` can take an identifier to use as the name of this default graph or it will assign a @@ -1910,6 +1917,14 @@ def __init__( default_graph_base: Optional[str] = None, ): super(ConjunctiveGraph, self).__init__(store, identifier=identifier) + + if type(self) is ConjunctiveGraph: + warnings.warn( + "ConjunctiveGraph is deprecated, use Dataset instead.", + DeprecationWarning, + stacklevel=2, + ) + assert self.store.context_aware, ( "ConjunctiveGraph must be backed by" " a context aware store." ) diff --git a/rdflib/namespace/_GEO.py b/rdflib/namespace/_GEO.py index 4cddc5b43..d7168d64c 100644 --- a/rdflib/namespace/_GEO.py +++ b/rdflib/namespace/_GEO.py @@ -26,19 +26,39 @@ class GEO(DefinedNamespace): """ # http://www.w3.org/2000/01/rdf-schema#Datatype + dggsLiteral: URIRef # A DGGS serialization of a geometry object. + geoJSONLiteral: URIRef # A GeoJSON serialization of a geometry object. gmlLiteral: URIRef # A GML serialization of a geometry object. + kmlLiteral: URIRef # A KML serialization of a geometry object. wktLiteral: URIRef # A Well-known Text serialization of a geometry object. # http://www.w3.org/2002/07/owl#Class Feature: URIRef # This class represents the top-level feature type. This class is equivalent to GFI_Feature defined in ISO 19156:2011, and it is superclass of all feature types. + FeatureCollection: URIRef # A collection of individual Features. Geometry: URIRef # The class represents the top-level geometry type. This class is equivalent to the UML class GM_Object defined in ISO 19107, and it is superclass of all geometry types. + GeometryCollection: URIRef # A collection of individual Geometries. SpatialObject: URIRef # The class spatial-object represents everything that can have a spatial representation. It is superclass of feature and geometry. + SpatialObjectCollection: URIRef # A collection of individual Spatial Objects. This is the superclass of Feature Collection and Geometry Collection. # http://www.w3.org/2002/07/owl#DatatypeProperty asGML: URIRef # The GML serialization of a geometry asWKT: URIRef # The WKT serialization of a geometry + asGeoJSON: URIRef # The GeoJSON serialization of a geometry + asKML: URIRef # The KML serialization of a geometry + asDGGS: URIRef # The DGGS serialization of a geometry coordinateDimension: URIRef # The number of measurements or axes needed to describe the position of this geometry in a coordinate system. dimension: URIRef # The topological dimension of this geometric object, which must be less than or equal to the coordinate dimension. In non-homogeneous collections, this will return the largest topological dimension of the contained objects. + hasMetricArea: URIRef # The area of a Spatial Object in square meters. + hasMetricLength: URIRef # The length of a Spatial Object in meters. + hasMetricPerimeterLength: ( + URIRef # The length of the perimeter of a Spatial Object in meters. + ) + hasMetricSpatialAccuracy: URIRef # The spatial resolution of a Geometry in meters. + hasMetricSpatialResolution: ( + URIRef # The spatial resolution of a Geometry in meters. + ) + hasMetricSize: URIRef # Subproperties of this property are used to indicate the size of a Spatial Object as a measurement or estimate of one or more dimensions of the Spatial Object's spatial presence. Units are always metric (meter, square meter or cubic meter) + hasMetricVolume: URIRef # The volume of a Spatial Object in cubic meters. hasSerialization: ( URIRef # Connects a geometry object with its text-based serialization. ) @@ -56,7 +76,21 @@ class GEO(DefinedNamespace): ehInside: URIRef # Exists if the subject SpatialObject is spatially inside the object SpatialObject. DE-9IM: TFF*FFT** ehMeet: URIRef # Exists if the subject SpatialObject spatially meets the object SpatialObject. DE-9IM: FT******* ^ F**T***** ^ F***T**** ehOverlap: URIRef # Exists if the subject SpatialObject spatially overlaps the object SpatialObject. DE-9IM: T*T***T** + hasArea: URIRef # The area of a Spatial Object. + hasBoundingBox: ( + URIRef # The minimum or smallest bounding or enclosing box of a given Feature. + ) + hasCentroid: URIRef # The arithmetic mean position of all the geometry points of a given Feature. + hasDefaultGeometry: URIRef # The default geometry to be used in spatial calculations, usually the most detailed geometry. hasGeometry: URIRef # A spatial representation for a given feature. + hasLength: URIRef # The length of a Spatial Object. + hasPerimeterLength: URIRef # The length of the perimeter of a Spatial Object. + hasSize: URIRef # Subproperties of this property are used to indicate the size of a Spatial Object as a measurement or estimate of one or more dimensions of the Spatial Object's spatial presence. + hasSpatialAccuracy: ( + URIRef # The positional accuracy of the coordinates of a Geometry. + ) + hasSpatialResolution: URIRef # The spatial resolution of a Geometry. + hasVolume: URIRef # he volume of a three-dimensional Spatial Object. rcc8dc: URIRef # Exists if the subject SpatialObject is spatially disjoint from the object SpatialObject. DE-9IM: FFTFFTTTT rcc8ec: URIRef # Exists if the subject SpatialObject spatially meets the object SpatialObject. DE-9IM: FFTFTTTTT rcc8eq: URIRef # Exists if the subject SpatialObject spatially equals the object SpatialObject. DE-9IM: TFFFTFFFT diff --git a/rdflib/plugins/sparql/algebra.py b/rdflib/plugins/sparql/algebra.py index 8830d2738..39c6ea224 100644 --- a/rdflib/plugins/sparql/algebra.py +++ b/rdflib/plugins/sparql/algebra.py @@ -1007,8 +1007,6 @@ def convert_node_arg( return node_arg.n3() elif isinstance(node_arg, CompValue): return "{" + node_arg.name + "}" - elif isinstance(node_arg, Expr): - return "{" + node_arg.name + "}" elif isinstance(node_arg, str): return node_arg else: diff --git a/test/data/suites/w3c/dawg-data-r2/sort/.manifest.ttl.swp b/test/data/suites/w3c/dawg-data-r2/sort/.manifest.ttl.swp deleted file mode 100644 index 9a14952b6..000000000 Binary files a/test/data/suites/w3c/dawg-data-r2/sort/.manifest.ttl.swp and /dev/null differ diff --git a/test/test_conjunctivegraph/test_conjunctive_graph.py b/test/test_conjunctivegraph/test_conjunctive_graph.py index 19992a064..0fdb0af1d 100644 --- a/test/test_conjunctivegraph/test_conjunctive_graph.py +++ b/test/test_conjunctivegraph/test_conjunctive_graph.py @@ -57,6 +57,13 @@ def test_context_namespaces(): assert ("ex", ns) in g.namespace_manager.namespaces() +def test_deprecated(): + with pytest.warns( + DeprecationWarning, match="ConjunctiveGraph is deprecated, use Dataset instead." + ): + ConjunctiveGraph() + + def get_graph_ids_tests(): def check(kws): cg = ConjunctiveGraph() diff --git a/test/test_dataset/test_dataset.py b/test/test_dataset/test_dataset.py index a6e005c08..358230ea7 100644 --- a/test/test_dataset/test_dataset.py +++ b/test/test_dataset/test_dataset.py @@ -1,6 +1,7 @@ import os import shutil import tempfile +import warnings from test.data import CONTEXT1, LIKES, PIZZA, TAREK from test.utils.namespace import EGSCHEME @@ -261,3 +262,14 @@ def test_subgraph_without_identifier() -> None: ) == ("genid", genid_prefix) assert f"{subgraph.identifier}".startswith(genid_prefix) + + +def test_not_deprecated(): + """ + Ensure Dataset does not trigger the deprecation warning + from the ConjunctiveGraph superclass. + """ + + with warnings.catch_warnings(): + warnings.simplefilter("error") + Dataset()