aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bsfs/graph/resolve.py10
-rw-r--r--bsfs/query/validator.py31
-rw-r--r--bsfs/schema/types.py16
-rw-r--r--bsfs/triple_store/sparql/parse_filter.py15
-rw-r--r--test/schema/test_types.py33
5 files changed, 52 insertions, 53 deletions
diff --git a/bsfs/graph/resolve.py b/bsfs/graph/resolve.py
index 9b5f631..b671204 100644
--- a/bsfs/graph/resolve.py
+++ b/bsfs/graph/resolve.py
@@ -96,11 +96,11 @@ class Filter():
# parse child expression
subrng = self._parse_predicate_expression(pred)
# determine the next type
- try:
- if rng is None or subrng > rng: # pick most generic range
- rng = subrng
- except TypeError as err:
- raise errors.ConsistencyError(f'ranges {subrng} and {rng} are not related') from err
+ if rng is None or subrng > rng: # pick most generic range
+ rng = subrng
+ # check range consistency
+ if not subrng <= rng and not subrng >= rng:
+ raise errors.ConsistencyError(f'ranges {subrng} and {rng} are not related')
if not isinstance(rng, (bsc.Node, bsc.Literal)):
raise errors.BackendError(f'the range of node {node} is undefined')
return rng
diff --git a/bsfs/query/validator.py b/bsfs/query/validator.py
index 75b51ca..ecea951 100644
--- a/bsfs/query/validator.py
+++ b/bsfs/query/validator.py
@@ -113,25 +113,18 @@ class Filter():
for pred in node:
# parse child expression
subdom, subrng = self._parse_predicate_expression(pred)
- try:
- # determine overall domain
- if dom is None or subdom < dom: # pick most specific domain
- dom = subdom
- # domains must be related across all child expressions
- if not subdom <= dom and not subdom >= dom:
- raise errors.ConsistencyError(f'domains {subdom} and {dom} are not related')
- except TypeError as err: # compared literal vs. node
- raise errors.ConsistencyError(f'domains {subdom} and {dom} are not of the same type') from err
-
- try:
- # determine overall range
- if rng is None or subrng > rng: # pick most generic range
- rng = subrng
- # ranges must be related across all child expressions
- if not subrng <= rng and not subrng >= rng:
- raise errors.ConsistencyError(f'ranges {subrng} and {rng} are not related')
- except TypeError as err: # compared literal vs. node
- raise errors.ConsistencyError(f'ranges {subrng} and {rng} are not of the same type') from err
+ # determine overall domain
+ if dom is None or subdom < dom: # pick most specific domain
+ dom = subdom
+ # domains must be related across all child expressions
+ if not subdom <= dom and not subdom >= dom:
+ raise errors.ConsistencyError(f'domains {subdom} and {dom} are not related')
+ # determine overall range
+ if rng is None or subrng > rng: # pick most generic range
+ rng = subrng
+ # ranges must be related across all child expressions
+ if not subrng <= rng and not subrng >= rng:
+ raise errors.ConsistencyError(f'ranges {subrng} and {rng} are not related')
# OneOf guarantees at least one expression, dom and rng are always bsc.Vertex.
# mypy does not realize this, hence we ignore the warning.
return dom, rng # type: ignore [return-value]
diff --git a/bsfs/schema/types.py b/bsfs/schema/types.py
index 6257dee..95dc66a 100644
--- a/bsfs/schema/types.py
+++ b/bsfs/schema/types.py
@@ -150,8 +150,10 @@ class _Type():
def __lt__(self, other: typing.Any) -> bool:
"""Return True iff *self* is a true subclass of *other*."""
- if not isinstance(other, type(self)):
+ if not isinstance(other, _Type):
return NotImplemented
+ if not isinstance(other, type(self)): # FIXME: necessary?
+ return False
if self.uri == other.uri: # equivalence
return False
if self in other.parents(): # superclass
@@ -163,8 +165,10 @@ class _Type():
def __le__(self, other: typing.Any) -> bool:
"""Return True iff *self* is equivalent or a subclass of *other*."""
- if not isinstance(other, type(self)):
+ if not isinstance(other, _Type):
return NotImplemented
+ if not isinstance(other, type(self)): # FIXME: necessary?
+ return False
if self.uri == other.uri: # equivalence
return True
if self in other.parents(): # superclass
@@ -176,8 +180,10 @@ class _Type():
def __gt__(self, other: typing.Any) -> bool:
"""Return True iff *self* is a true superclass of *other*."""
- if not isinstance(other, type(self)):
+ if not isinstance(other, _Type):
return NotImplemented
+ if not isinstance(other, type(self)): # FIXME: necessary?
+ return False
if self.uri == other.uri: # equivalence
return False
if self in other.parents(): # superclass
@@ -189,8 +195,10 @@ class _Type():
def __ge__(self, other: typing.Any) -> bool:
"""Return True iff *self* is eqiuvalent or a superclass of *other*."""
- if not isinstance(other, type(self)):
+ if not isinstance(other, _Type):
return NotImplemented
+ if not isinstance(other, type(self)): # FIXME: necessary?
+ return False
if self.uri == other.uri: # equivalence
return True
if self in other.parents(): # superclass
diff --git a/bsfs/triple_store/sparql/parse_filter.py b/bsfs/triple_store/sparql/parse_filter.py
index 18a3288..5d8a2d9 100644
--- a/bsfs/triple_store/sparql/parse_filter.py
+++ b/bsfs/triple_store/sparql/parse_filter.py
@@ -131,15 +131,12 @@ class Filter():
puri, subrng = self._parse_predicate_expression(node_type, pred)
# track predicate uris
suburi.add(puri)
- try:
- # check for more generic range
- if rng is None or subrng > rng:
- rng = subrng
- # check range consistency
- if not subrng <= rng and not subrng >= rng:
- raise errors.ConsistencyError(f'ranges {subrng} and {rng} are not related')
- except TypeError as err: # subrng and rng are not comparable
- raise errors.ConsistencyError(f'ranges {subrng} and {rng} are not related') from err
+ # check for more generic range
+ if rng is None or subrng > rng:
+ rng = subrng
+ # check range consistency
+ if not subrng <= rng and not subrng >= rng:
+ raise errors.ConsistencyError(f'ranges {subrng} and {rng} are not related')
# return joint predicate expression and next range
# OneOf guarantees at least one expression, rng is always a bsc.Vertex.
# mypy does not realize this, hence we ignore the warning.
diff --git a/test/schema/test_types.py b/test/schema/test_types.py
index 26da270..1eeafa1 100644
--- a/test/schema/test_types.py
+++ b/test/schema/test_types.py
@@ -140,30 +140,31 @@ class TestType(unittest.TestCase):
self.assertFalse(bike >= bicycle)
self.assertFalse(bike == bicycle)
- # can compare types along the class hierarchy
+ # comparing different classes returns False ...
+ # ... when classes are hierarchically related
class Foo(_Type): pass
foo = Foo('Foo', bike)
- self.assertTrue(foo < bike)
- self.assertTrue(foo <= bike)
+ self.assertFalse(foo < bike)
+ self.assertFalse(foo <= bike)
self.assertFalse(foo > bike)
self.assertFalse(foo >= bike)
# goes both ways
self.assertFalse(bike < foo)
self.assertFalse(bike <= foo)
- self.assertTrue(bike > foo)
- self.assertTrue(bike >= foo)
- # cannot compare unrelated classes
+ self.assertFalse(bike > foo)
+ self.assertFalse(bike >= foo)
+ # ... when classes are unrelated
class Bar(_Type): pass
bar = Bar('Bar', bike)
- self.assertRaises(TypeError, operator.lt, foo, bar)
- self.assertRaises(TypeError, operator.le, foo, bar)
- self.assertRaises(TypeError, operator.gt, foo, bar)
- self.assertRaises(TypeError, operator.ge, foo, bar)
+ self.assertFalse(foo < bar)
+ self.assertFalse(foo <= bar)
+ self.assertFalse(foo > bar)
+ self.assertFalse(foo >= bar)
# goes both ways
- self.assertRaises(TypeError, operator.lt, bar, foo)
- self.assertRaises(TypeError, operator.le, bar, foo)
- self.assertRaises(TypeError, operator.gt, bar, foo)
- self.assertRaises(TypeError, operator.ge, bar, foo)
+ self.assertFalse(bar < foo)
+ self.assertFalse(bar <= foo)
+ self.assertFalse(bar > foo)
+ self.assertFalse(bar >= foo)
class TestPredicate(unittest.TestCase):
@@ -262,7 +263,7 @@ class TestPredicate(unittest.TestCase):
# range must be subtype of parent's range
self.assertRaises(errors.ConsistencyError, tag.child, ns.bse.foo, range=n_root)
self.assertRaises(errors.ConsistencyError, tag.child, ns.bse.foo, range=Node(ns.bsfs.Image, n_root))
- self.assertRaises(TypeError, tag.child, ns.bse.foo, range=Literal(ns.bsfs.Tag, l_root))
+ self.assertRaises(errors.ConsistencyError, tag.child, ns.bse.foo, range=Literal(ns.bsfs.Tag, l_root))
# range can be subtyped from ROOT_VERTEX to Node or Literal
self.assertEqual(n_root, root.child(ns.bse.foo, range=n_root).range)
self.assertEqual(l_root, root.child(ns.bse.foo, range=l_root).range)
@@ -370,7 +371,7 @@ class TestFeature(unittest.TestCase):
# range must be subtype of parent's range
self.assertRaises(errors.ConsistencyError, colors.child, ns.bse.foo, range=Literal(ns.bsfs.Literal, None))
self.assertRaises(errors.ConsistencyError, colors.child, ns.bse.foo, range=Literal(ns.bsfs.foo, Literal(ns.bsfs.Literal, None)))
- self.assertRaises(TypeError, colors.child, ns.bse.foo, range=Node(ns.bsfs.Tag, n_root))
+ self.assertRaises(errors.ConsistencyError, colors.child, ns.bse.foo, range=Node(ns.bsfs.Tag, n_root))
## main ##