aboutsummaryrefslogtreecommitdiffstats
path: root/bindings/python
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2020-10-13 19:33:18 +0200
committerDavid Robillard <d@drobilla.net>2020-10-27 13:13:59 +0100
commit9c9effab183be6333fc5f67add4ccc52fd3c16fe (patch)
tree2756340cd12b298eead634e92309aa65e27b10ee /bindings/python
parent2986435c28a4a8b0a6cbf1bb462e628a1f830be0 (diff)
downloadserd-9c9effab183be6333fc5f67add4ccc52fd3c16fe.tar.gz
serd-9c9effab183be6333fc5f67add4ccc52fd3c16fe.tar.bz2
serd-9c9effab183be6333fc5f67add4ccc52fd3c16fe.zip
fixup! WIP: Add Python bindings
Diffstat (limited to 'bindings/python')
-rw-r--r--bindings/python/serd.pyx84
-rw-r--r--bindings/python/test_serd.py30
2 files changed, 56 insertions, 58 deletions
diff --git a/bindings/python/serd.pyx b/bindings/python/serd.pyx
index 8c0bfe1b..2363420f 100644
--- a/bindings/python/serd.pyx
+++ b/bindings/python/serd.pyx
@@ -677,7 +677,12 @@ class EventType(enum.IntEnum):
# Private Python Bindings Utilities
cdef SerdNode* _unwrap_node(node: Node):
- return (<Node>node)._ptr if type(node) == Node else NULL
+ if node is None:
+ return NULL
+ elif type(node) == Node:
+ return (<Node>node)._ptr
+
+ raise TypeError("Expected Node, got %s" % type(node))
def _uri_from_param(param) -> Node:
@@ -1289,7 +1294,7 @@ cdef class Reader:
cdef SerdReader* _ptr
cdef __ByteSource _byte_source
- cdef SinkBase _sink
+ cdef _SinkBase _sink
cdef object _callback
@staticmethod
@@ -1307,17 +1312,17 @@ cdef class Reader:
flags: ReaderFlags,
sink,
stack_size: int = 4096):
- if isinstance(sink, SinkBase):
+ if isinstance(sink, _SinkBase):
self._sink = sink
else:
self._callback = sink
self._sink = Sink(func=self._callback)
- assert isinstance(self._sink, SinkBase)
+ assert isinstance(self._sink, _SinkBase)
assert self._sink._cptr is not NULL
self._ptr = serd_reader_new(
- world._ptr, syntax, flags, (<SinkBase>self._sink)._cptr, stack_size
+ world._ptr, syntax, flags, (<_SinkBase>self._sink)._cptr, stack_size
)
def __dealloc__(self):
@@ -1545,15 +1550,15 @@ cdef class Model:
def __iter__(self):
if self.size() == 0:
- return Iter._end()
+ return _Iter._end()
- return Iter._manage(serd_model_begin(self._ptr))
+ return _Iter._manage(serd_model_begin(self._ptr))
def __contains__(self, statement):
- return self.find(Statement._from_param(statement)) != self.end()
+ return self._find(Statement._from_param(statement)) != self._end()
def __delitem__(self, statement):
- i = self.find(statement)
+ i = self._find(statement)
if i is not None:
self.erase(i)
@@ -1583,11 +1588,13 @@ cdef class Model:
return serd_model_empty(self._ptr)
def inserter(self, env: Env, default_graph: Node = None) -> Sink:
+ """Return a sink that will insert into this model when written to."""
return Sink._manage(serd_inserter_new(
self._ptr, env._ptr, _unwrap_node(default_graph)
))
def insert(self, arg) -> None:
+ """Insert a Statement or Range into this model."""
if type(arg) == Range:
return Status(serd_model_add_range(self._ptr, (<Range>arg)._ptr))
@@ -1605,13 +1612,14 @@ cdef class Model:
_ensure_success(
serd_model_erase_range(self._ptr, (<Range>arg)._ptr),
"Failed to erase range")
- elif type(arg) == Iter:
+ elif type(arg) == _Iter:
+ # FIXME: remove?
_ensure_success(
- serd_model_erase(self._ptr, (<Iter>arg)._ptr),
+ serd_model_erase(self._ptr, (<_Iter>arg)._ptr),
"Failed to erase iterator")
elif type(arg) == Statement:
- i = self.find(arg)
- if i == self.end():
+ i = self._find(arg)
+ if i == self._end():
raise ValueError("serd.Model.erase(): statement not in model")
self.erase(i)
@@ -1620,17 +1628,17 @@ cdef class Model:
else:
raise TypeError("Bad argument type for Model.erase: %s" % type(arg))
- def begin(self) -> Iter:
- return Iter._manage(serd_model_begin(self._ptr))
+ # def begin(self) -> _Iter:
+ # return _Iter._manage(serd_model_begin(self._ptr))
- def end(self) -> Iter:
- return Iter._wrap(serd_model_end(self._ptr))
+ def _end(self) -> _Iter:
+ return _Iter._wrap(serd_model_end(self._ptr))
def all(self) -> Range:
"""Return a range that contains all statements in the model."""
return Range._manage(serd_model_all(self._ptr))
- def find(self, statement) -> Iter:
+ def _find(self, statement) -> _Iter:
statement = Statement._from_param(statement)
s = statement.subject()
p = statement.predicate()
@@ -1645,9 +1653,10 @@ cdef class Model:
_unwrap_node(g)
)
- return Iter._manage(c_iter) if c_iter else self.end()
+ return _Iter._manage(c_iter) if c_iter else self._end()
def range(self, pattern) -> Range:
+ """Return a range of statements that match a pattern."""
assert type(pattern) == tuple
assert len(pattern) == 3 or len(pattern) == 4
@@ -1898,14 +1907,14 @@ cdef class Statement:
return Cursor._wrap(serd_statement_cursor(self._ptr))
-cdef class Iter:
+cdef class _Iter:
"""An iterator that points to a statement in a model."""
cdef SerdIter* _ptr
cdef bint _is_end
@staticmethod
cdef _end():
- cdef Iter wrapper = Iter.__new__(Iter)
+ cdef _Iter wrapper = _Iter.__new__(_Iter)
wrapper._ptr = NULL
wrapper._is_end = True
@@ -1914,7 +1923,7 @@ cdef class Iter:
@staticmethod
cdef _manage(SerdIter* ptr):
- cdef Iter wrapper = Iter.__new__(Iter)
+ cdef _Iter wrapper = _Iter.__new__(_Iter)
if ptr is NULL:
wrapper._ptr = NULL
@@ -1927,10 +1936,10 @@ cdef class Iter:
@staticmethod
cdef _wrap(const SerdIter* ptr):
- return Iter._manage(serd_iter_copy(ptr))
+ return _Iter._manage(serd_iter_copy(ptr))
- def __init__(self, iter: Iter):
- assert type(iter) == Iter
+ def __init__(self, iter: _Iter):
+ assert type(iter) == _Iter
self._is_end = False
self._ptr = serd_iter_copy(iter._ptr)
@@ -1941,7 +1950,7 @@ cdef class Iter:
self._ptr = NULL
def __eq__(self, rhs):
- return type(rhs) == Iter and serd_iter_equals(self._ptr, (<Iter>rhs)._ptr)
+ return type(rhs) == _Iter and serd_iter_equals(self._ptr, (<_Iter>rhs)._ptr)
def __next__(self):
"""Move to and return the next item."""
@@ -1969,9 +1978,6 @@ cdef class Range:
print(statement)
A range is "truthy" if it is non-empty.
-
- There are also methods that expose the underlying iterators, as in the C
- API, but these are not typically used in Pythonic code.
"""
cdef SerdRange* _ptr
@@ -2004,9 +2010,9 @@ cdef class Range:
def __iter__(self):
if self.empty():
- return Iter._end()
+ return _Iter._end()
- return Iter._wrap(serd_range_begin(self._ptr))
+ return _Iter._wrap(serd_range_begin(self._ptr))
def front(self) -> Statement:
"""Return the first statement in this range, or None."""
@@ -2016,15 +2022,7 @@ cdef class Range:
"""Return true iff there are no statements in this range."""
return serd_range_empty(self._ptr)
- def begin(self) -> Iter:
- """Return an iterator to the start of this range."""
- return Iter._wrap(serd_range_begin(self._ptr))
-
- def end(self) -> Iter:
- """Return an iterator to the exclusive end of this range."""
- return Iter._wrap(serd_range_end(self._ptr))
-
- def serialise(self, sink: SinkBase, flags: SerialisationFlags) -> Status:
+ def serialise(self, sink: _SinkBase, flags: SerialisationFlags) -> Status:
"""Write this range to `sink`.
The serialisation style can be controlled with `flags`. The default is
@@ -2226,11 +2224,11 @@ cdef class Event:
return "None"
-cdef class SinkBase:
+cdef class _SinkBase:
cdef const SerdSink* _cptr
-cdef class SinkView(SinkBase):
+cdef class SinkView(_SinkBase):
@staticmethod
cdef SinkView _wrap(const SerdSink* cptr):
if cptr is NULL:
@@ -2241,7 +2239,7 @@ cdef class SinkView(SinkBase):
return wrapper
-cdef class Sink(SinkBase):
+cdef class Sink(_SinkBase):
cdef SerdSink* _ptr
cdef Env _env
cdef object _func
diff --git a/bindings/python/test_serd.py b/bindings/python/test_serd.py
index 712c21e5..898f4af4 100644
--- a/bindings/python/test_serd.py
+++ b/bindings/python/test_serd.py
@@ -513,25 +513,25 @@ class ModelTests(unittest.TestCase):
self.assertEqual(len(model), 0)
self.assertTrue(model.empty())
- def testBeginEnd(self):
- s, p, o, g = self.s, self.p, self.o, self.g
- model = serd.Model(self.world, serd.ModelFlags.INDEX_SPO)
+ # def testBeginEnd(self):
+ # s, p, o, g = self.s, self.p, self.o, self.g
+ # model = serd.Model(self.world, serd.ModelFlags.INDEX_SPO)
- self.assertEqual(model.begin(), model.end())
+ # self.assertEqual(model.begin(), model.end())
- model.insert((s, p, o, g))
- self.assertNotEqual(model.begin(), model.end())
+ # model.insert((s, p, o, g))
+ # self.assertNotEqual(model.begin(), model.end())
- def testFind(self):
- s, p, o, g, x = self.s, self.p, self.o, self.g, self.x
- flags = serd.ModelFlags.INDEX_SPO | serd.ModelFlags.INDEX_GRAPHS
- model = serd.Model(self.world, flags)
- in_statement = serd.Statement(s, p, o, g)
- out_statement = serd.Statement(x, p, o, g)
+ # def testFind(self):
+ # s, p, o, g, x = self.s, self.p, self.o, self.g, self.x
+ # flags = serd.ModelFlags.INDEX_SPO | serd.ModelFlags.INDEX_GRAPHS
+ # model = serd.Model(self.world, flags)
+ # in_statement = serd.Statement(s, p, o, g)
+ # out_statement = serd.Statement(x, p, o, g)
- model += in_statement
- self.assertEqual(model.find(out_statement), model.end())
- self.assertNotEqual(model.find(in_statement), model.end())
+ # model += in_statement
+ # self.assertEqual(model.find(out_statement), model.end())
+ # self.assertNotEqual(model.find(in_statement), model.end())
def testGet(self):
s, p, o, g = self.s, self.p, self.o, self.g