From 03faa0e18b03b2387a472468b8131854b84a4b10 Mon Sep 17 00:00:00 2001 From: Jason Paryani Date: Fri, 18 Apr 2014 18:18:54 -0700 Subject: [PATCH] Get inheritance working for simple version capabilities --- capnp/lib/capnp.pyx | 33 +++++++++++++++++++++++---------- test/test_capability.py | 15 +++++++++++++++ 2 files changed, 38 insertions(+), 10 deletions(-) diff --git a/capnp/lib/capnp.pyx b/capnp/lib/capnp.pyx index ef6c824..610feb1 100644 --- a/capnp/lib/capnp.pyx +++ b/capnp/lib/capnp.pyx @@ -1731,7 +1731,7 @@ cdef class _DynamicCapabilityServer: cdef class _DynamicCapabilityClient: cdef C_DynamicCapability.Client thisptr - cdef public object _server, _parent, _methods_set + cdef public object _server, _parent, _cached_schema cdef _init(self, C_DynamicCapability.Client other, object parent): self.thisptr = other @@ -1801,11 +1801,11 @@ cdef class _DynamicCapabilityClient: def __getattr__(self, name): if name.endswith('_request'): short_name = name[:-8] - if short_name not in self._method_names: + if short_name not in self.schema.method_names_inherited: raise AttributeError('Method named %s not found' % short_name) return _partial(self._request, short_name) - if name not in self._method_names: + if name not in self.schema.method_names_inherited: raise AttributeError('Method named %s not found' % name) return _partial(self._send, name) @@ -1829,13 +1829,9 @@ cdef class _DynamicCapabilityClient: property schema: """A property that returns the _InterfaceSchema object matching this client""" def __get__(self): - return _InterfaceSchema()._init(self.thisptr.getSchema()) - - property _method_names: - def __get__(self): - if self._methods_set is None: - self._methods_set = set(self.schema.method_names) - return self._methods_set + if self._cached_schema is None: + self._cached_schema = _InterfaceSchema()._init(self.thisptr.getSchema()) + return self._cached_schema def __dir__(self): return list(self.schema._method_names) @@ -2201,6 +2197,23 @@ cdef class _InterfaceSchema: for i in xrange(nfields)) return self.__method_names + property method_names_inherited: + """A set of the function names in the interface, including inherited methods""" + def __get__(self): + fieldlist = self.thisptr.getMethods() + nfields = fieldlist.size() + ret = set(fieldlist[i].getProto().getName().cStr() + for i in xrange(nfields)) + for interface in self.extends: + ret |= interface.method_names_inherited + + return ret + + property extends: + """A list of interfaces that this interface extends""" + def __get__(self): + return [self.get_dependency(i).as_interface() for i in self.node.interface.extends] + property node: """The raw schema node""" def __get__(self): diff --git a/test/test_capability.py b/test/test_capability.py index 8c646f9..71203bb 100644 --- a/test/test_capability.py +++ b/test/test_capability.py @@ -328,3 +328,18 @@ def test_then_args(): with pytest.raises(ValueError): client.foo(i=5).then(lambda x, y: 1) + + +class ExtendsServer(Server): + def qux(self, **kwargs): + pass + + +def test_inheritance(): + client = capability.TestExtends._new_client(ExtendsServer()) + client.qux().wait() + + remote = client.foo(i=5) + response = remote.wait() + + assert response.x == '26'