aboutsummaryrefslogtreecommitdiffstats
path: root/bsfs
diff options
context:
space:
mode:
authorMatthias Baumgartner <dev@igsor.net>2023-01-12 10:12:43 +0100
committerMatthias Baumgartner <dev@igsor.net>2023-01-12 10:12:43 +0100
commit3940cb3c79937a431ba2ae3b57fd0c6c2ccfff33 (patch)
tree109aba866e93651d02755981f63329341cedecc1 /bsfs
parent6fd984e694b0a7b749ab947211d792f5b011ee6f (diff)
downloadbsfs-3940cb3c79937a431ba2ae3b57fd0c6c2ccfff33.tar.gz
bsfs-3940cb3c79937a431ba2ae3b57fd0c6c2ccfff33.tar.bz2
bsfs-3940cb3c79937a431ba2ae3b57fd0c6c2ccfff33.zip
use Vertex in type annotations
Diffstat (limited to 'bsfs')
-rw-r--r--bsfs/graph/resolve.py28
-rw-r--r--bsfs/query/validator.py25
-rw-r--r--bsfs/triple_store/sparql/parse_filter.py39
3 files changed, 42 insertions, 50 deletions
diff --git a/bsfs/graph/resolve.py b/bsfs/graph/resolve.py
index feb0855..e398a5e 100644
--- a/bsfs/graph/resolve.py
+++ b/bsfs/graph/resolve.py
@@ -37,8 +37,6 @@ class Filter():
"""
- T_VERTEX = typing.Union[bsc.Node, bsc.Literal]
-
def __init__(self, schema):
self.schema = schema
@@ -47,7 +45,7 @@ class Filter():
def _parse_filter_expression(
self,
- type_: T_VERTEX,
+ type_: bsc.Vertex,
node: ast.filter.FilterExpression,
) -> ast.filter.FilterExpression:
"""Route *node* to the handler of the respective FilterExpression subclass."""
@@ -73,7 +71,7 @@ class Filter():
# invalid node
raise errors.BackendError(f'expected filter expression, found {node}')
- def _parse_predicate_expression(self, node: ast.filter.PredicateExpression) -> T_VERTEX:
+ def _parse_predicate_expression(self, node: ast.filter.PredicateExpression) -> bsc.Vertex:
"""Route *node* to the handler of the respective PredicateExpression subclass."""
if isinstance(node, ast.filter.Predicate):
return self._predicate(node)
@@ -82,7 +80,7 @@ class Filter():
# invalid node
raise errors.BackendError(f'expected predicate expression, found {node}')
- def _predicate(self, node: ast.filter.Predicate) -> T_VERTEX:
+ def _predicate(self, node: ast.filter.Predicate) -> bsc.Vertex:
if not self.schema.has_predicate(node.predicate):
raise errors.ConsistencyError(f'predicate {node.predicate} is not in the schema')
pred = self.schema.predicate(node.predicate)
@@ -91,7 +89,7 @@ class Filter():
dom, rng = rng, dom
return rng
- def _one_of(self, node: ast.filter.OneOf) -> T_VERTEX:
+ def _one_of(self, node: ast.filter.OneOf) -> bsc.Vertex:
# determine domain and range types
rng = None
for pred in node:
@@ -107,33 +105,33 @@ class Filter():
raise errors.UnreachableError()
return rng
- def _any(self, type_: T_VERTEX, node: ast.filter.Any) -> ast.filter.Any: # pylint: disable=unused-argument
+ def _any(self, type_: bsc.Vertex, node: ast.filter.Any) -> ast.filter.Any: # pylint: disable=unused-argument
next_type = self._parse_predicate_expression(node.predicate)
return ast.filter.Any(node.predicate, self._parse_filter_expression(next_type, node.expr))
- def _all(self, type_: T_VERTEX, node: ast.filter.All) -> ast.filter.All: # pylint: disable=unused-argument
+ def _all(self, type_: bsc.Vertex, node: ast.filter.All) -> ast.filter.All: # pylint: disable=unused-argument
next_type = self._parse_predicate_expression(node.predicate)
return ast.filter.All(node.predicate, self._parse_filter_expression(next_type, node.expr))
- def _and(self, type_: T_VERTEX, node: ast.filter.And) -> ast.filter.And:
+ def _and(self, type_: bsc.Vertex, node: ast.filter.And) -> ast.filter.And:
return ast.filter.And({self._parse_filter_expression(type_, expr) for expr in node})
- def _or(self, type_: T_VERTEX, node: ast.filter.Or) -> ast.filter.Or:
+ def _or(self, type_: bsc.Vertex, node: ast.filter.Or) -> ast.filter.Or:
return ast.filter.Or({self._parse_filter_expression(type_, expr) for expr in node})
- def _not(self, type_: T_VERTEX, node: ast.filter.Not) -> ast.filter.Not:
+ def _not(self, type_: bsc.Vertex, node: ast.filter.Not) -> ast.filter.Not:
return ast.filter.Not(self._parse_filter_expression(type_, node.expr))
- def _has(self, type_: T_VERTEX, node: ast.filter.Has) -> ast.filter.Has: # pylint: disable=unused-argument
+ def _has(self, type_: bsc.Vertex, node: ast.filter.Has) -> ast.filter.Has: # pylint: disable=unused-argument
return node
- def _value(self, type_: T_VERTEX, node: ast.filter._Value) -> ast.filter._Value: # pylint: disable=unused-argument
+ def _value(self, type_: bsc.Vertex, node: ast.filter._Value) -> ast.filter._Value: # pylint: disable=unused-argument
return node
- def _bounded(self, type_: T_VERTEX, node: ast.filter._Bounded) -> ast.filter._Bounded: # pylint: disable=unused-argument
+ def _bounded(self, type_: bsc.Vertex, node: ast.filter._Bounded) -> ast.filter._Bounded: # pylint: disable=unused-argument
return node
- def _is(self, type_: T_VERTEX, node: ast.filter.Is) -> typing.Union[ast.filter.Or, ast.filter.Is]:
+ def _is(self, type_: bsc.Vertex, node: ast.filter.Is) -> typing.Union[ast.filter.Or, ast.filter.Is]:
# check if action is needed
if not isinstance(node.value, nodes.Nodes):
return node
diff --git a/bsfs/query/validator.py b/bsfs/query/validator.py
index 352203a..6bf1b72 100644
--- a/bsfs/query/validator.py
+++ b/bsfs/query/validator.py
@@ -34,9 +34,6 @@ class Filter():
"""
- # vertex types
- T_VERTEX = typing.Union[bsc.Node, bsc.Literal] # FIXME: Shouldn't this be in the schema?
-
# schema to validate against.
schema: bsc.Schema
@@ -64,7 +61,7 @@ class Filter():
## routing methods
- def _parse_filter_expression(self, type_: T_VERTEX, node: ast.filter.FilterExpression):
+ def _parse_filter_expression(self, type_: bsc.Vertex, node: ast.filter.FilterExpression):
"""Route *node* to the handler of the respective FilterExpression subclass."""
if isinstance(node, ast.filter.Is):
return self._is(type_, node)
@@ -83,7 +80,7 @@ class Filter():
# invalid node
raise errors.BackendError(f'expected filter expression, found {node}')
- def _parse_predicate_expression(self, node: ast.filter.PredicateExpression) -> typing.Tuple[T_VERTEX, T_VERTEX]:
+ def _parse_predicate_expression(self, node: ast.filter.PredicateExpression) -> typing.Tuple[bsc.Vertex, bsc.Vertex]:
"""Route *node* to the handler of the respective PredicateExpression subclass."""
if isinstance(node, ast.filter.Predicate):
return self._predicate(node)
@@ -95,7 +92,7 @@ class Filter():
## predicate expressions
- def _predicate(self, node: ast.filter.Predicate) -> typing.Tuple[T_VERTEX, T_VERTEX]:
+ def _predicate(self, node: ast.filter.Predicate) -> typing.Tuple[bsc.Vertex, bsc.Vertex]:
# predicate exists in the schema
if not self.schema.has_predicate(node.predicate):
raise errors.ConsistencyError(f'predicate {node.predicate} is not in the schema')
@@ -110,7 +107,7 @@ class Filter():
# return domain and range
return dom, rng
- def _one_of(self, node: ast.filter.OneOf) -> typing.Tuple[T_VERTEX, T_VERTEX]:
+ def _one_of(self, node: ast.filter.OneOf) -> typing.Tuple[bsc.Vertex, bsc.Vertex]:
# determine domain and range types
# NOTE: select the most specific domain and the most generic range
dom, rng = None, None
@@ -146,7 +143,7 @@ class Filter():
## intermediates
- def _branch(self, type_: T_VERTEX, node: ast.filter._Branch):
+ def _branch(self, type_: bsc.Vertex, node: ast.filter._Branch):
# type is a Node
if not isinstance(type_, bsc.Node):
raise errors.ConsistencyError(f'expected a Node, found {type_}')
@@ -167,16 +164,16 @@ class Filter():
# child expression is valid
self._parse_filter_expression(rng, node.expr)
- def _agg(self, type_: T_VERTEX, node: ast.filter._Agg):
+ def _agg(self, type_: bsc.Vertex, node: ast.filter._Agg):
for expr in node:
# child expression is valid
self._parse_filter_expression(type_, expr)
- def _not(self, type_: T_VERTEX, node: ast.filter.Not):
+ def _not(self, type_: bsc.Vertex, node: ast.filter.Not):
# child expression is valid
self._parse_filter_expression(type_, node.expr)
- def _has(self, type_: T_VERTEX, node: ast.filter.Has):
+ def _has(self, type_: bsc.Vertex, node: ast.filter.Has):
# type is a Node
if not isinstance(type_, bsc.Node):
raise errors.ConsistencyError(f'expected a Node, found {type_}')
@@ -195,13 +192,13 @@ class Filter():
## conditions
- def _is(self, type_: T_VERTEX, node: ast.filter.Is): # pylint: disable=unused-argument # (node)
+ def _is(self, type_: bsc.Vertex, node: ast.filter.Is): # pylint: disable=unused-argument # (node)
if not isinstance(type_, bsc.Node):
raise errors.ConsistencyError(f'expected a Node, found {type_}')
if type_ not in self.schema.nodes():
raise errors.ConsistencyError(f'node {type_} is not in the schema')
- def _value(self, type_: T_VERTEX, node: ast.filter._Value): # pylint: disable=unused-argument # (node)
+ def _value(self, type_: bsc.Vertex, node: ast.filter._Value): # pylint: disable=unused-argument # (node)
# type is a literal
if not isinstance(type_, bsc.Literal):
raise errors.ConsistencyError(f'expected a Literal, found {type_}')
@@ -211,7 +208,7 @@ class Filter():
# FIXME: Check if node.value corresponds to type_
# FIXME: A specific literal might be requested (i.e., a numeric type when used in Has)
- def _bounded(self, type_: T_VERTEX, node: ast.filter._Bounded): # pylint: disable=unused-argument # (node)
+ def _bounded(self, type_: bsc.Vertex, node: ast.filter._Bounded): # pylint: disable=unused-argument # (node)
# type is a literal
if not isinstance(type_, bsc.Literal):
raise errors.ConsistencyError(f'expected a Literal, found {type_}')
diff --git a/bsfs/triple_store/sparql/parse_filter.py b/bsfs/triple_store/sparql/parse_filter.py
index d4db0aa..a851888 100644
--- a/bsfs/triple_store/sparql/parse_filter.py
+++ b/bsfs/triple_store/sparql/parse_filter.py
@@ -46,9 +46,6 @@ class Filter():
# Generator that produces unique symbol names.
ngen: _GenHopName
- # Vertex type.
- T_VERTEX = typing.Union[bsc.Node, bsc.Literal]
-
def __init__(self, schema):
self.schema = schema
self.ngen = _GenHopName()
@@ -79,7 +76,7 @@ class Filter():
}}
'''
- def _parse_filter_expression(self, type_: T_VERTEX, node: ast.filter.FilterExpression, head: str) -> str:
+ def _parse_filter_expression(self, type_: bsc.Vertex, node: ast.filter.FilterExpression, head: str) -> str:
"""Route *node* to the handler of the respective FilterExpression subclass."""
if isinstance(node, ast.filter.Is):
return self._is(type_, node, head)
@@ -112,9 +109,9 @@ class Filter():
def _parse_predicate_expression(
self,
- type_: T_VERTEX,
+ type_: bsc.Vertex,
node: ast.filter.PredicateExpression
- ) -> typing.Tuple[str, T_VERTEX]:
+ ) -> typing.Tuple[str, bsc.Vertex]:
"""Route *node* to the handler of the respective PredicateExpression subclass."""
if isinstance(node, ast.filter.Predicate):
return self._predicate(type_, node)
@@ -123,7 +120,7 @@ class Filter():
# invalid node
raise errors.BackendError(f'expected predicate expression, found {node}')
- def _one_of(self, node_type: T_VERTEX, node: ast.filter.OneOf) -> typing.Tuple[str, T_VERTEX]:
+ def _one_of(self, node_type: bsc.Vertex, node: ast.filter.OneOf) -> typing.Tuple[str, bsc.Vertex]:
"""
"""
if not isinstance(node_type, bsc.Node):
@@ -150,7 +147,7 @@ class Filter():
# return joint predicate expression and next range
return '|'.join(suburi), rng
- def _predicate(self, node_type: T_VERTEX, node: ast.filter.Predicate) -> typing.Tuple[str, T_VERTEX]:
+ def _predicate(self, node_type: bsc.Vertex, node: ast.filter.Predicate) -> typing.Tuple[str, bsc.Vertex]:
"""
"""
# check node_type
@@ -178,7 +175,7 @@ class Filter():
# return predicate URI and next node type
return puri, rng
- def _any(self, node_type: T_VERTEX, node: ast.filter.Any, head: str) -> str:
+ def _any(self, node_type: bsc.Vertex, node: ast.filter.Any, head: str) -> str:
"""
"""
if not isinstance(node_type, bsc.Node):
@@ -191,7 +188,7 @@ class Filter():
# combine results
return f'{head} {pred} {nexthead} . {expr}'
- def _all(self, node_type: T_VERTEX, node: ast.filter.All, head: str) -> str:
+ def _all(self, node_type: bsc.Vertex, node: ast.filter.All, head: str) -> str:
"""
"""
# NOTE: All(P, E) := Not(Any(P, Not(E))) and EXISTS(P, ?)
@@ -208,13 +205,13 @@ class Filter():
# return existence and rewritten expression
return f'FILTER EXISTS {{ {head} {pred} {temphead} }} . ' + expr
- def _and(self, node_type: T_VERTEX, node: ast.filter.And, head: str) -> str:
+ def _and(self, node_type: bsc.Vertex, node: ast.filter.And, head: str) -> str:
"""
"""
sub = [self._parse_filter_expression(node_type, expr, head) for expr in node]
return ' . '.join(sub)
- def _or(self, node_type: T_VERTEX, node: ast.filter.Or, head: str) -> str:
+ def _or(self, node_type: bsc.Vertex, node: ast.filter.Or, head: str) -> str:
"""
"""
# potential special case optimization:
@@ -224,7 +221,7 @@ class Filter():
sub = ['{' + expr + '}' for expr in sub]
return ' UNION '.join(sub)
- def _not(self, node_type: T_VERTEX, node: ast.filter.Not, head: str) -> str:
+ def _not(self, node_type: bsc.Vertex, node: ast.filter.Not, head: str) -> str:
"""
"""
expr = self._parse_filter_expression(node_type, node.expr, head)
@@ -235,7 +232,7 @@ class Filter():
# The simplest (and non-interfering) choice is a type statement.
return f'MINUS {{ {head} <{ns.rdf.type}>/<{ns.rdfs.subClassOf}>* <{node_type.uri}> . {expr} }}'
- def _has(self, node_type: T_VERTEX, node: ast.filter.Has, head: str) -> str:
+ def _has(self, node_type: bsc.Vertex, node: ast.filter.Has, head: str) -> str:
"""
"""
if not isinstance(node_type, bsc.Node):
@@ -253,42 +250,42 @@ class Filter():
# combine
return num_preds + ' . ' + count_bounds
- def _is(self, node_type: T_VERTEX, node: ast.filter.Is, head: str) -> str:
+ def _is(self, node_type: bsc.Vertex, node: ast.filter.Is, head: str) -> str:
"""
"""
if not isinstance(node_type, bsc.Node):
raise errors.BackendError(f'expected Node, found {node_type}')
return f'VALUES {head} {{ <{node.value}> }}'
- def _equals(self, node_type: T_VERTEX, node: ast.filter.Equals, head: str) -> str:
+ def _equals(self, node_type: bsc.Vertex, node: ast.filter.Equals, head: str) -> str:
"""
"""
if not isinstance(node_type, bsc.Literal):
raise errors.BackendError(f'expected Literal, found {node}')
return f'VALUES {head} {{ "{node.value}"^^<{node_type.uri}> }}'
- def _substring(self, node_type: T_VERTEX, node: ast.filter.Substring, head: str) -> str:
+ def _substring(self, node_type: bsc.Vertex, node: ast.filter.Substring, head: str) -> str:
"""
"""
if not isinstance(node_type, bsc.Literal):
raise errors.BackendError(f'expected Literal, found {node_type}')
return f'FILTER contains(str({head}), "{node.value}")'
- def _starts_with(self, node_type: T_VERTEX, node: ast.filter.StartsWith, head: str) -> str:
+ def _starts_with(self, node_type: bsc.Vertex, node: ast.filter.StartsWith, head: str) -> str:
"""
"""
if not isinstance(node_type, bsc.Literal):
raise errors.BackendError(f'expected Literal, found {node_type}')
return f'FILTER strstarts(str({head}), "{node.value}")'
- def _ends_with(self, node_type: T_VERTEX, node: ast.filter.EndsWith, head: str) -> str:
+ def _ends_with(self, node_type: bsc.Vertex, node: ast.filter.EndsWith, head: str) -> str:
"""
"""
if not isinstance(node_type, bsc.Literal):
raise errors.BackendError(f'expected Literal, found {node_type}')
return f'FILTER strends(str({head}), "{node.value}")'
- def _less_than(self, node_type: T_VERTEX, node: ast.filter.LessThan, head: str) -> str:
+ def _less_than(self, node_type: bsc.Vertex, node: ast.filter.LessThan, head: str) -> str:
"""
"""
if not isinstance(node_type, bsc.Literal):
@@ -296,7 +293,7 @@ class Filter():
equality = '=' if not node.strict else ''
return f'FILTER ({head} <{equality} {float(node.threshold)})'
- def _greater_than(self, node_type: T_VERTEX, node: ast.filter.GreaterThan, head: str) -> str:
+ def _greater_than(self, node_type: bsc.Vertex, node: ast.filter.GreaterThan, head: str) -> str:
"""
"""
if not isinstance(node_type, bsc.Literal):