Fix response objects not referencing parents correctly

Fixes #103
This commit is contained in:
Jason Paryani 2016-06-17 13:50:42 -07:00
parent e4c128de61
commit 5ffe7eb2f6
3 changed files with 55 additions and 2 deletions

View file

@ -1019,7 +1019,7 @@ cdef class _DynamicStructReader:
return self
cpdef _get(self, field):
return to_python_reader(self.thisptr.get(field), self._parent)
return to_python_reader(self.thisptr.get(field), self)
def __getattr__(self, field):
try:
@ -1028,7 +1028,7 @@ cdef class _DynamicStructReader:
raise e._to_python(), None, _sys.exc_info()[2]
cpdef _get_by_field(self, _StructSchemaField field):
return to_python_reader(self.thisptr.getByField(field.thisptr), self._parent)
return to_python_reader(self.thisptr.getByField(field.thisptr), self)
cpdef _has(self, field):
return self.thisptr.has(field)

13
test/test_response.capnp Normal file
View file

@ -0,0 +1,13 @@
@0x84249be5c3bff005;
interface Foo {
foo @0 () -> (val :UInt32);
}
struct Bar {
foo @0 :Foo;
}
interface Baz {
grault @0 () -> (bar: Bar);
}

40
test/test_response.py Normal file
View file

@ -0,0 +1,40 @@
import pytest
import capnp
import os
import time
import test_response_capnp
class FooServer(test_response_capnp.Foo.Server):
def __init__(self, val=1):
self.val = val
def foo(self, **kwargs):
return 1
class BazServer(test_response_capnp.Baz.Server):
def __init__(self, val=1):
self.val = val
def grault(self, **kwargs):
return {"foo": FooServer()}
def test_response_reference():
baz = test_response_capnp.Baz._new_client(BazServer())
bar = baz.grault().wait().bar
foo = bar.foo
# This used to cause an exception about invalid pointers because the response got garbage collected
foo.foo().wait()
def test_response_reference2():
baz = test_response_capnp.Baz._new_client(BazServer())
bar = baz.grault().wait().bar
# This always worked since it saved the intermediate response object
response = baz.grault().wait()
bar = response.bar
foo = bar.foo
foo.foo().wait()