Skip to content

Add SPARQL query result type assertions #102

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 13 commits into from
Mar 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
repos:
- repo: https://github.com/psf/black
rev: 22.10.0
rev: 23.1.0
hooks:
- id: black
- repo: https://github.com/pycqa/flake8
rev: 5.0.4
rev: 6.0.0
hooks:
- id: flake8
- repo: https://github.com/pycqa/isort
rev: 5.10.1
rev: 5.12.0
hooks:
- id: isort
name: isort (python)
1 change: 1 addition & 0 deletions case_utils/case_file/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@

DEFAULT_PREFIX = "http://example.org/kb/"


# Shortcut syntax for defining an immutable named tuple is noted here:
# https://docs.python.org/3/library/typing.html#typing.NamedTuple
# via the "See also" box here: https://docs.python.org/3/library/collections.html#collections.namedtuple
Expand Down
5 changes: 3 additions & 2 deletions case_utils/case_sparql_construct/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,10 +98,11 @@ def main() -> None:
construct_query_result = in_graph.query(construct_query_object)
_logger.debug("type(construct_query_result) = %r." % type(construct_query_result))
_logger.debug("len(construct_query_result) = %d." % len(construct_query_result))
for (row_no, row) in enumerate(construct_query_result):
for row_no, row in enumerate(construct_query_result):
assert isinstance(row, tuple)
if row_no == 0:
_logger.debug("row[0] = %r." % (row,))
out_graph.add(row)
out_graph.add((row[0], row[1], row[2]))

output_format = None
if args.output_format is None:
Expand Down
23 changes: 12 additions & 11 deletions case_utils/case_sparql_select/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,26 +86,27 @@ def graph_and_query_to_data_frame(
select_query_object = rdflib.plugins.sparql.processor.prepareQuery(
select_query_text, initNs=nsdict
)
for (row_no, row) in enumerate(_graph.query(select_query_object)):
for row_no, row in enumerate(_graph.query(select_query_object)):
assert isinstance(row, rdflib.query.ResultRow)
tally = row_no + 1
record = []
for (column_no, column) in enumerate(row):
for column_no, column in enumerate(row):
if column is None:
column_value = ""
elif (
isinstance(column, rdflib.term.Literal)
and column.datatype == NS_XSD.hexBinary
):
# Use hexlify to convert xsd:hexBinary to ASCII.
# The render to ASCII is in support of this script rendering results for website viewing.
# .decode() is because hexlify returns bytes.
column_value = binascii.hexlify(column.toPython()).decode()
elif isinstance(column, rdflib.term.Literal):
if column.datatype == NS_XSD.hexBinary:
# Use hexlify to convert xsd:hexBinary to ASCII.
# The render to ASCII is in support of this script rendering results for website viewing.
# .decode() is because hexlify returns bytes.
column_value = binascii.hexlify(column.toPython()).decode()
else:
column_value = column.toPython()
elif isinstance(column, rdflib.URIRef):
if use_prefixes:
column_value = graph.namespace_manager.qname(column.toPython())
else:
column_value = column.toPython()
else:
elif isinstance(column, rdflib.BNode):
column_value = column.toPython()
if row_no == 0:
_logger.debug("row[0]column[%d] = %r." % (column_no, column_value))
Expand Down
3 changes: 2 additions & 1 deletion case_utils/ontology/src/ontology_and_version_iris.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@

def concept_is_cdo_concept(n_concept: rdflib.URIRef) -> bool:
"""
This function is purposefully distinct from the function used in case_validate. Within this script, the publishing history of CASE and UCO is reviewed."""
This function is purposefully distinct from the function used in case_validate. Within this script, the publishing history of CASE and UCO is reviewed.
"""
concept_iri = str(n_concept)
return (
concept_iri.startswith("https://ontology.unifiedcyberontology.org/")
Expand Down
3 changes: 2 additions & 1 deletion tests/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -81,12 +81,13 @@ check-isomorphic_diff: \
--directory isomorphic_diff \
check

# TODO - Fix type signatures in UCO test.
# TODO - Add and strict-check type signatures for CASE and UCO tests.
check-mypy: \
.venv.done.log
source venv/bin/activate \
&& mypy \
--exclude case_utils/case_validate/case_test_examples/test_case_validation.py \
--exclude case_utils/case_validate/uco_test_examples/test_uco_validation.py \
--exclude venv \
--strict \
$(top_srcdir)/case_utils \
Expand Down
8 changes: 7 additions & 1 deletion tests/case_utils/case_file/test_case_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,11 @@ def test_confirm_hashes(graph_case_file: rdflib.Graph) -> None:
)

for result in graph_case_file.query(query_object):
(l_hash_method, l_hash_value) = result
assert isinstance(result, rdflib.query.ResultRow)
assert isinstance(result[0], rdflib.Literal)
assert isinstance(result[1], rdflib.Literal)
l_hash_method = result[0]
l_hash_value = result[1]
# .toPython() with the non-XSD datatype returns the original Literal object again. Hence, str().
hash_method = str(l_hash_method)
hash_value = binascii.hexlify(l_hash_value.toPython()).decode().upper()
Expand Down Expand Up @@ -117,13 +121,15 @@ def test_confirm_mtime(

n_observable_object = None
for result in graph_case_file_disable_hashes.query(query_object):
assert isinstance(result, rdflib.query.ResultRow)
(n_observable_object,) = result
assert (
n_observable_object is not None
), "File object with expected mtime not found in hashless graph."

n_observable_object = None
for result in graph_case_file.query(query_object):
assert isinstance(result, rdflib.query.ResultRow)
(n_observable_object,) = result
assert (
n_observable_object is not None
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ def _test_subclass_templates_result(filename: str, expected: typing.Set[str]) ->
}
"""
for result in graph.query(query_string):
assert isinstance(result, rdflib.query.ResultRow)
assert isinstance(result[0], rdflib.URIRef)
n_entity = result[0]
computed.add(n_entity.toPython())
assert expected == computed
Expand All @@ -54,7 +56,11 @@ def _test_w3_templates_with_blank_nodes_result(filename: str) -> None:
}
"""
for result in graph.query(query_string):
(l_given_name, l_family_name) = result
assert isinstance(result, rdflib.query.ResultRow)
assert isinstance(result[0], rdflib.Literal)
assert isinstance(result[1], rdflib.term.Literal)
l_given_name = result[0]
l_family_name = result[1]
computed.add((l_given_name.toPython(), l_family_name.toPython()))
assert expected == computed

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@
)


def make_data_frame_to_json_table_text_parameters() -> typing.Iterator[
typing.Tuple[str, str, bool, bool]
]:
def make_data_frame_to_json_table_text_parameters() -> (
typing.Iterator[typing.Tuple[str, str, bool, bool]]
):
for use_header in [False, True]:
for use_index in [False, True]:
for output_mode in ["csv", "html", "json", "md", "tsv"]:
Expand Down
50 changes: 38 additions & 12 deletions tests/hexbinary/test_hexbinary.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,9 @@ def test_sparql_syntax_bind_boolean() -> None:
}
"""
):
(l_value,) = result
assert isinstance(result, rdflib.query.ResultRow)
assert isinstance(result[0], rdflib.Literal)
l_value = result[0]
confirmed = l_value.toPython()
assert confirmed

Expand All @@ -100,7 +102,9 @@ def test_pytest_syntax_xfail() -> None:
}
"""
):
(l_value,) = result
assert isinstance(result, rdflib.query.ResultRow)
assert isinstance(result[0], rdflib.Literal)
l_value = result[0]
confirmed = l_value.toPython()
assert confirmed

Expand All @@ -119,7 +123,9 @@ def test_sparql_syntax_integer_coercion() -> None:
}
"""
):
(l_value,) = result
assert isinstance(result, rdflib.query.ResultRow)
assert isinstance(result[0], rdflib.Literal)
l_value = result[0]
confirmed = l_value.toPython()
assert confirmed

Expand All @@ -138,7 +144,9 @@ def test_sparql_syntax_integer_cast() -> None:
}
"""
):
(l_value,) = result
assert isinstance(result, rdflib.query.ResultRow)
assert isinstance(result[0], rdflib.Literal)
l_value = result[0]
confirmed = l_value.toPython()
assert confirmed

Expand All @@ -158,7 +166,9 @@ def test_sparql_cast_custom_type() -> None:
}
"""
):
(l_value,) = result
assert isinstance(result, rdflib.query.ResultRow)
assert isinstance(result[0], rdflib.Literal)
l_value = result[0]
confirmed = l_value.toPython()
assert confirmed

Expand All @@ -174,7 +184,9 @@ def test_sparql_compare_hexbinary_mixcase() -> None:
}
"""
):
(l_value,) = result
assert isinstance(result, rdflib.query.ResultRow)
assert isinstance(result[0], rdflib.Literal)
l_value = result[0]
confirmed = l_value.toPython()
assert confirmed

Expand All @@ -190,7 +202,9 @@ def test_sparql_compare_hexbinary_matchcase() -> None:
}
"""
):
(l_value,) = result
assert isinstance(result, rdflib.query.ResultRow)
assert isinstance(result[0], rdflib.Literal)
l_value = result[0]
confirmed = l_value.toPython()
assert confirmed

Expand All @@ -206,7 +220,9 @@ def test_sparql_compare_hexbinarycanonical_matchcase() -> None:
}
"""
):
(l_value,) = result
assert isinstance(result, rdflib.query.ResultRow)
assert isinstance(result[0], rdflib.Literal)
l_value = result[0]
confirmed = l_value.toPython()
assert confirmed

Expand All @@ -226,7 +242,9 @@ def test_sparql_compare_hexbinarycanonical_mixcase() -> None:
}
"""
):
(l_value,) = result
assert isinstance(result, rdflib.query.ResultRow)
assert isinstance(result[0], rdflib.Literal)
l_value = result[0]
confirmed = l_value.toPython()
assert confirmed

Expand All @@ -246,7 +264,9 @@ def test_sparql_compare_hb_hbc_mixcase() -> None:
}
"""
):
(l_value,) = result
assert isinstance(result, rdflib.query.ResultRow)
assert isinstance(result[0], rdflib.Literal)
l_value = result[0]
confirmed = l_value.toPython()
assert confirmed

Expand All @@ -266,7 +286,9 @@ def test_sparql_compare_hb_hbc_mixcase_cast() -> None:
}
"""
):
(l_value,) = result
assert isinstance(result, rdflib.query.ResultRow)
assert isinstance(result[0], rdflib.Literal)
l_value = result[0]
confirmed = l_value.toPython()
assert confirmed

Expand Down Expand Up @@ -315,7 +337,11 @@ def _query_all_value_matches(graph: rdflib.Graph) -> typing.Set[str]:
FILTER ( ?nNode1 != ?nNode2 )
}"""
):
(n_node1, n_node2) = result
assert isinstance(result, rdflib.query.ResultRow)
assert isinstance(result[0], rdflib.URIRef)
assert isinstance(result[1], rdflib.URIRef)
n_node1 = result[0]
n_node2 = result[1]
computed.add(n_node1.toPython())
computed.add(n_node2.toPython())
return computed
Expand Down