Skip to content

Commit 5021dc1

Browse files
authored
Merge pull request #244 from vemonet/fix-tests
Fix tests and make them more reliable
2 parents b3c0d30 + 7e52e29 commit 5021dc1

25 files changed

+992
-16002
lines changed

.github/workflows/test.yml

Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
name: Test
2-
32
on:
43
push:
54
branches: ["master"]
@@ -13,32 +12,25 @@ jobs:
1312
fail-fast: false
1413
max-parallel: 1
1514
matrix:
16-
python-version: ["3.7", "3.8", "3.9", "3.10"]
15+
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"]
1716
steps:
18-
- uses: actions/checkout@v2
17+
- uses: actions/checkout@v4
1918
- name: Set up Python ${{ matrix.python-version }}
20-
uses: actions/setup-python@v2
19+
uses: actions/setup-python@v5
2120
with:
2221
python-version: ${{ matrix.python-version }}
22+
2323
- name: Install dependencies
2424
run: |
2525
pip install -U pip
2626
pip install '.[dev]'
27+
2728
- name: Mypy
28-
run: |
29-
mypy --show-error-context --show-error-codes
29+
run: mypy --show-error-context
30+
3031
- name: Test [wrapper]
3132
if: ${{ always() }}
32-
run: |
33-
python -m unittest test/test_wrapper.py -v
33+
run: pytest test/test_wrapper.py
34+
3435
- name: Test [all]
35-
run: |
36-
python -m unittest -v |& tee log.txt
37-
grep '^FAIL:' log.txt > fails.txt
38-
# if all failures is not raised in `test.test_wrapper`:
39-
if [ "$(grep 'test.test_wrapper' fails.txt | wc -l)" -ne "$(wc -l < fails.txt)" ]; then
40-
exit 1
41-
else
42-
echo 'All of the above failures are maybe false errors.'
43-
echo 'See: https://github.com/RDFLib/sparqlwrapper/issues/192'
44-
fi
36+
run: pytest

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,4 @@ doc
1111
.settings/
1212
.venv/
1313
.tox/
14+
.coverage

README.rst

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ About
1818

1919
**SPARQLWrapper** is a simple Python wrapper around a `SPARQL <https://www.w3.org/TR/sparql11-overview/>`_ service to
2020
remotely execute your queries. It helps by creating the query
21-
invocation and, optionally, converting the result into a more manageable
22-
format.
21+
invocation and, optionally, converting the result into more manageable
22+
formats.
2323

2424
Installation & Distribution
2525
===========================
@@ -35,13 +35,13 @@ You can install SPARQLWrapper from GitHub::
3535
You can install SPARQLWrapper from Debian::
3636

3737
$ sudo apt-get install python-sparqlwrapper
38-
38+
3939
.. note::
4040

4141
Be aware that there could be a gap between the latest version of SPARQLWrapper
4242
and the version available as Debian package.
4343

44-
Also, the source code of the package can be downloaded
44+
Also, the source code of the package can be downloaded
4545
in ``.zip`` and ``.tar.gz`` formats from `GitHub SPARQLWrapper releases <https://github.com/RDFLib/sparqlwrapper/releases>`_.
4646
Documentation is included in the distribution.
4747

@@ -125,9 +125,9 @@ This query gets a boolean response from DBPedia's SPARQL endpoint:
125125
126126
sparql = SPARQLWrapper("http://dbpedia.org/sparql")
127127
sparql.setQuery("""
128-
ASK WHERE {
128+
ASK WHERE {
129129
<http://dbpedia.org/resource/Asturias> rdfs:label "Asturias"@es
130-
}
130+
}
131131
""")
132132
sparql.setReturnFormat(XML)
133133
results = sparql.query().convert()
@@ -307,7 +307,7 @@ Return formats
307307

308308
The expected return formats differs per query type (``SELECT``, ``ASK``, ``CONSTRUCT``, ``DESCRIBE``...).
309309

310-
.. note:: From the `SPARQL specification <https://www.w3.org/TR/sparql11-protocol/#query-success>`_,
310+
.. note:: From the `SPARQL specification <https://www.w3.org/TR/sparql11-protocol/#query-success>`_,
311311
*The response body of a successful query operation with a 2XX response is either:*
312312

313313
* ``SELECT`` and ``ASK``: a SPARQL Results Document in XML, JSON, or CSV/TSV format.
@@ -430,12 +430,12 @@ in the return value). This features becomes particularly useful when the ``OPTIO
430430
GET or POST
431431
^^^^^^^^^^^
432432

433-
By default, all SPARQL services are invoked using HTTP **GET** verb. However,
433+
By default, all SPARQL services are invoked using HTTP **GET** verb. However,
434434
**POST** might be useful if the size of the query
435435
extends a reasonable size; this can be set in the query instance.
436436

437437
Note that some combinations may not work yet with all SPARQL processors
438-
(e.g., there are implementations where **POST + JSON return** does not work).
438+
(e.g., there are implementations where **POST + JSON return** does not work).
439439
Hopefully, this problem will eventually disappear.
440440

441441

@@ -914,8 +914,7 @@ Organizations involved:
914914
* `Salzburg Research <http://www.salzburgresearch.at>`_
915915
* `Foundation CTIC <http://www.fundacionctic.org/>`_
916916

917-
918-
.. |Build Status| image:: https://secure.travis-ci.org/RDFLib/sparqlwrapper.svg?branch=master
919-
:target: https://travis-ci.org/RDFLib/sparqlwrapper
917+
.. |Build Status| image:: https://github.com/RDFLib/sparqlwrapper/actions/workflows/test.yml/badge.svg
918+
:target: https://github.com/RDFLib/sparqlwrapper/actions/workflows/test.yml
920919
.. |PyPi version| image:: https://badge.fury.io/py/SPARQLWrapper.svg
921920
:target: https://pypi.python.org/pypi/SPARQLWrapper

SPARQLWrapper/Wrapper.py

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
from SPARQLWrapper import __agent__
4040

4141
if TYPE_CHECKING:
42-
from rdflib import Graph
42+
from rdflib import Dataset, Graph
4343

4444

4545

@@ -649,7 +649,7 @@ def setUseKeepAlive(self) -> None:
649649
:raises ImportError: when could not be imported ``keepalive.HTTPHandler``.
650650
"""
651651
try:
652-
from keepalive import HTTPHandler # type: ignore[import]
652+
from keepalive import HTTPHandler # type: ignore[import-not-found]
653653

654654
if urllib.request._opener and any( # type: ignore[attr-defined]
655655
isinstance(h, HTTPHandler) for h in urllib.request._opener.handlers # type: ignore[attr-defined]
@@ -1071,21 +1071,21 @@ def _convertXML(self) -> Document:
10711071
:return: converted result.
10721072
:rtype: :class:`xml.dom.minidom.Document`
10731073
"""
1074-
doc = parse(self.response)
1074+
doc: Any = parse(self.response)
10751075
rdoc = cast(Document, doc)
10761076
return rdoc
10771077

1078-
def _convertRDF(self) -> "Graph":
1078+
def _convertRDF(self) -> "Dataset":
10791079
"""
10801080
Convert a RDF/XML result into an RDFLib Graph. This method can be overwritten
10811081
in a subclass for a different conversion method.
10821082
10831083
:return: converted result.
10841084
:rtype: :class:`rdflib.graph.Graph`
10851085
"""
1086-
from rdflib import ConjunctiveGraph
1087-
retval = ConjunctiveGraph()
1088-
retval.parse(self.response, format="xml") # type: ignore[no-untyped-call]
1086+
from rdflib import Dataset
1087+
retval = Dataset()
1088+
retval.parse(self.response, format="xml")
10891089
return retval
10901090

10911091
def _convertN3(self) -> bytes:
@@ -1118,18 +1118,18 @@ def _convertTSV(self) -> bytes:
11181118
"""
11191119
return self.response.read()
11201120

1121-
def _convertJSONLD(self) -> "Graph":
1121+
def _convertJSONLD(self) -> "Dataset":
11221122
"""
11231123
Convert a RDF JSON-LD result into an RDFLib Graph. This method can be overwritten
11241124
in a subclass for a different conversion method.
11251125
11261126
:return: converted result
11271127
:rtype: :class:`rdflib.graph.Graph`
11281128
"""
1129-
from rdflib import ConjunctiveGraph
1129+
from rdflib import Dataset
11301130

1131-
retval = ConjunctiveGraph()
1132-
retval.parse(self.response, format="json-ld") # type: ignore[no-untyped-call]
1131+
retval = Dataset()
1132+
retval.parse(self.response, format="json-ld")
11331133
return retval
11341134

11351135
def convert(self) -> ConvertResult:

SPARQLWrapper/main.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ def main(test: Optional[List[str]] = None) -> None:
145145
elif isinstance(results, bytes):
146146
# "csv", "tsv", "turtle", "n3"
147147
print(results.decode("utf-8"))
148-
elif isinstance(results, rdflib.graph.ConjunctiveGraph):
148+
elif isinstance(results, rdflib.graph.Dataset):
149149
# "rdf"
150150
print(results.serialize())
151151
else:

SPARQLWrapper/sparql_dataframe.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
Query a SPARQL endpoint and return results as a Pandas dataframe.
33
"""
44
import io
5-
from typing import TYPE_CHECKING, Any, Dict, List, Union
5+
from typing import TYPE_CHECKING, Dict, List, Union
66

77
from SPARQLWrapper.SmartWrapper import Bindings, SPARQLWrapper2, Value
88
from SPARQLWrapper.Wrapper import CSV, SELECT, SPARQLWrapper
@@ -39,8 +39,6 @@ def get_sparql_typed_dict(
3939
endpoint: str, query: Union[str, bytes]
4040
) -> List[Dict[str, Value]]:
4141
"""modified from: https://github.com/lawlesst/sparql-dataframe"""
42-
# pandas inside to avoid requiring it
43-
import pandas as pd
4442
# rdflib in here because there is some meta stuff in the setup.py and Travis fails because rdflib is installed later
4543
import rdflib.term
4644
sparql = SPARQLWrapper2(endpoint)
@@ -58,7 +56,7 @@ def get_sparql_typed_dict(
5856
row = {}
5957
for k in x:
6058
v = x[k]
61-
vv = rdflib.term.Literal(v.value, datatype=v.datatype).toPython() # type: ignore[no-untyped-call]
59+
vv = rdflib.term.Literal(v.value, datatype=v.datatype).toPython()
6260
row[k] = vv
6361
d.append(row)
6462
return d

pyproject.toml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,25 @@
11
[build-system]
22
requires = ["wheel", "setuptools"]
33
build-backend = "setuptools.build_meta"
4+
5+
[tool.pytest.ini_options]
6+
addopts = [
7+
"--cov=SPARQLWrapper",
8+
"--cov-report=term-missing",
9+
"--durations=3", # Show slowest tests durations
10+
]
11+
12+
[tool.mypy]
13+
files = ["SPARQLWrapper"]
14+
exclude = ["test"]
15+
python_version = "3.7"
16+
show_error_codes = true
17+
strict = true
18+
pretty = true
19+
warn_unused_configs = true
20+
warn_unused_ignores = true
21+
warn_unreachable = true
22+
23+
# [[tool.mypy.overrides]]
24+
# module = "tests.*"
25+
# disallow_untyped_defs = false

setup.cfg

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ dev =
4949
mypy>=0.931
5050
pandas>=1.3.5
5151
pandas-stubs>=1.2.0.48
52+
pytest>=8.3.5
53+
pytest-cov>=5.0.0
5254

5355
pandas =
5456
pandas>=1.3.5
@@ -61,13 +63,3 @@ docs =
6163
[options.entry_points]
6264
console_scripts =
6365
rqw = SPARQLWrapper.main:main
64-
65-
[mypy]
66-
files = SPARQLWrapper
67-
python_version = 3.7
68-
show_error_codes = True
69-
strict = True
70-
pretty = True
71-
warn_unused_configs = True
72-
warn_unused_ignores = True
73-
warn_unreachable = True

test/test.rq

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,5 @@ WHERE {
55
?pl
66
a dbo:ProgrammingLanguage;
77
rdfs:label ?pllabel.
8-
FILTER(SUBSTR(STR(?pllabel), 1, 1) = "P")
8+
FILTER(SUBSTR(STR(?pllabel), 1, 5) = "PARLO")
99
} ORDER BY ?pllabel LIMIT 1

0 commit comments

Comments
 (0)