From 5acb2a8174a9db23e67ed8e5ce14ee5bb3d1506d Mon Sep 17 00:00:00 2001 From: David Robillard Date: Tue, 13 Oct 2020 18:47:29 +0200 Subject: fixup! WIP: Add Python bindings --- bindings/python/serd.pyx | 70 +++++++++++++++++++++++++++----------------- bindings/python/test_serd.py | 61 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 104 insertions(+), 27 deletions(-) diff --git a/bindings/python/serd.pyx b/bindings/python/serd.pyx index acaea085..8c0bfe1b 100644 --- a/bindings/python/serd.pyx +++ b/bindings/python/serd.pyx @@ -683,10 +683,19 @@ cdef SerdNode* _unwrap_node(node: Node): def _uri_from_param(param) -> Node: if isinstance(param, type("")): return uri(param) - elif isinstance(param, Node): + elif isinstance(param, Node) and (param).type() == NodeType.URI: return param - return None + raise TypeError("Expected string or URI node, got %s" % type(param)) + + +def _blank_from_param(param) -> Node: + if isinstance(param, type("")): + return blank(param) + elif isinstance(param, Node) and (param).type() == NodeType.BLANK: + return param + + raise TypeError("Expected string or blank node, got %s" % type(param)) def _tocstr(s: str): @@ -712,10 +721,7 @@ class Namespace: """ def __init__(self, prefix: str): - # TODO: node - assert isinstance(prefix, str) - - self.prefix = prefix + self.prefix = _uri_from_param(prefix) def __add__(self, suffix: str): return uri(self.prefix + suffix) @@ -1815,7 +1821,6 @@ cdef class Statement: self._ptr = NULL def __getitem__(self, field): - # TODO: test if field < 0 or field > 3: raise IndexError(field) @@ -1869,7 +1874,7 @@ cdef class Statement: def node(self, field: Field) -> Node: """Return the given node in this statement.""" - # TODO: check field + assert field >= Field.SUBJECT and field <= Field.GRAPH return Node._wrap(serd_statement_node(self._ptr, field)) def subject(self) -> Node: @@ -1925,13 +1930,11 @@ cdef class Iter: return Iter._manage(serd_iter_copy(ptr)) def __init__(self, iter: Iter): + assert type(iter) == Iter + self._is_end = False - if type(iter) == Iter: - self._ptr = serd_iter_copy(iter._ptr) - self._is_end = iter._is_end - else: - # FIXME? necessary - raise TypeError("Bad argument type for Iter(): %s" % type(iter)) + self._ptr = serd_iter_copy(iter._ptr) + self._is_end = iter._is_end def __dealloc__(self): serd_iter_free(self._ptr) @@ -1985,12 +1988,9 @@ cdef class Range: cdef _wrap(const SerdRange* ptr): return Range._manage(serd_range_copy(ptr)) - def __init__(self, range): - if type(range) == Range: - self._ptr = serd_range_copy((range)._ptr) - else: - # FIXME: Necessary? - raise TypeError("Bad argument type for Range(): %s" % type(range)) + def __init__(self, range: Range): + assert type(range) == Range + self._ptr = serd_range_copy((range)._ptr) def __dealloc__(self): serd_range_free(self._ptr) @@ -2146,7 +2146,7 @@ cdef class Event: """Return an event that sets the base URI.""" event = Event() event._type = EventType.BASE - event._uri = uri(base_uri) + event._uri = _uri_from_param(base_uri) return event @staticmethod @@ -2155,7 +2155,7 @@ cdef class Event: event = Event() event._type = EventType.PREFIX event._name = string(name) - event._uri = uri(namespace_uri) + event._uri = _uri_from_param(namespace_uri) return event @staticmethod @@ -2174,7 +2174,7 @@ cdef class Event: """Return an event that ends an anonymous node description.""" event = Event() event._type = EventType.END - event._node = uri(node) + event._node = _blank_from_param(node) return event def __eq__(self, rhs): @@ -2196,16 +2196,32 @@ cdef class Event: return False def __repr__(self): + def flags_repr(flags): + active = [] + for f in [StatementFlags.EMPTY_S, + StatementFlags.ANON_S, + StatementFlags.ANON_O, + StatementFlags.LIST_S, + StatementFlags.LIST_O, + StatementFlags.TERSE_S, + StatementFlags.TERSE_O]: + if flags & f: + active += ['serd.' + str(f)] + + return ' | '.join(active) + if self._type == EventType.BASE: return 'serd.Event.base("%s")' % self._uri elif self._type == EventType.PREFIX: return 'serd.Event.prefix("%s", "%s")' % (self._name, self._uri) elif self._type == EventType.STATEMENT: - # FIXME? - return 'serd.Event.statement(%s)' % repr(self._statement) + result = 'serd.Event.statement(%s' % repr(self._statement) + if self._flags: + result += ', %s' % flags_repr(self._flags) + + return result + ')' elif self._type == EventType.END: - # FIXME? - return 'serd.Event.end("%s")' % self._node + return 'serd.Event.end(%s)' % repr(self._node) return "None" diff --git a/bindings/python/test_serd.py b/bindings/python/test_serd.py index 74f125fd..712c21e5 100644 --- a/bindings/python/test_serd.py +++ b/bindings/python/test_serd.py @@ -588,6 +588,26 @@ class StatementTests(unittest.TestCase): self.g = serd.uri("http://example.org/g") self.cursor = serd.Cursor("foo.ttl", 1, 0) + def testGet(self): + s, p, o, g = self.s, self.p, self.o, self.g + statement = serd.Statement(s, p, o, g, self.cursor) + + self.assertEqual(statement[serd.Field.SUBJECT], s) + self.assertEqual(statement[serd.Field.PREDICATE], p) + self.assertEqual(statement[serd.Field.OBJECT], o) + self.assertEqual(statement[serd.Field.GRAPH], g) + + self.assertEqual(statement[0], s) + self.assertEqual(statement[1], p) + self.assertEqual(statement[2], o) + self.assertEqual(statement[3], g) + + with self.assertRaises(IndexError): + statement[-1] + + with self.assertRaises(IndexError): + statement[4] + def testAllFields(self): s, p, o, g = self.s, self.p, self.o, self.g statement = serd.Statement(s, p, o, g, self.cursor) @@ -806,6 +826,47 @@ class CursorTests(unittest.TestCase): ) +class EventTests(unittest.TestCase): + def testRepr(self): + base = serd.uri("http://example.org/base") + ns = serd.uri("http://example.org/ns") + + self.assertEqual( + repr(serd.Event.base(base)), + 'serd.Event.base("http://example.org/base")', + ) + + self.assertEqual( + repr(serd.Event.prefix("eg", ns)), + 'serd.Event.prefix("eg", "http://example.org/ns")', + ) + + s = serd.blank("s") + p = serd.uri("http://example.org/p") + o = serd.uri("http://example.org/o") + g = serd.uri("http://example.org/g") + statement = serd.Statement(s, p, o, g) + + self.assertEqual( + repr(serd.Event.statement(statement)), + 'serd.Event.statement(serd.Statement(serd.blank("s"), serd.uri("http://example.org/p"), serd.uri("http://example.org/o"), serd.uri("http://example.org/g")))', + ) + + self.assertEqual( + repr( + serd.Event.statement( + statement, + serd.StatementFlags.EMPTY_S | serd.StatementFlags.ANON_O, + ) + ), + 'serd.Event.statement(serd.Statement(serd.blank("s"), serd.uri("http://example.org/p"), serd.uri("http://example.org/o"), serd.uri("http://example.org/g")), serd.StatementFlags.EMPTY_S | serd.StatementFlags.ANON_O)', + ) + + self.assertEqual( + repr(serd.Event.end(s)), 'serd.Event.end(serd.blank("s"))' + ) + + class ReaderTests(unittest.TestCase): def setUp(self): self.world = serd.World() -- cgit v1.2.1