Various fixups to the RPC api.
* change how restorer works * fix join_promises * add incref's all around to make sure we aren't freeing objects early * make it so we return PyPromises everywhere and make chains collapsible
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
from .capnp.includes cimport capnp_cpp as capnp
|
||||
from .capnp.includes cimport schema_cpp
|
||||
from .capnp.includes.capnp_cpp cimport Schema as C_Schema, StructSchema as C_StructSchema, InterfaceSchema as C_InterfaceSchema, DynamicStruct as C_DynamicStruct, DynamicValue as C_DynamicValue, Type as C_Type, DynamicList as C_DynamicList, SchemaParser as C_SchemaParser, ParsedSchema as C_ParsedSchema, VOID, ArrayPtr, StringPtr, String, StringTree, DynamicOrphan as C_DynamicOrphan, AnyPointer as C_DynamicObject, DynamicCapability as C_DynamicCapability, Request, Response, RemotePromise, PyPromise, VoidPromise, CallContext, PyRestorer, RpcSystem, makeRpcServer, makeRpcClient, Capability as C_Capability, TwoPartyVatNetwork as C_TwoPartyVatNetwork, Side, AsyncIoStream, Own, makeTwoPartyVatNetwork, PromiseFulfillerPair as C_PromiseFulfillerPair, copyPromiseFulfillerPair, newPromiseAndFulfiller
|
||||
from .capnp.includes.capnp_cpp cimport Schema as C_Schema, StructSchema as C_StructSchema, InterfaceSchema as C_InterfaceSchema, DynamicStruct as C_DynamicStruct, DynamicValue as C_DynamicValue, Type as C_Type, DynamicList as C_DynamicList, SchemaParser as C_SchemaParser, ParsedSchema as C_ParsedSchema, VOID, ArrayPtr, StringPtr, String, StringTree, DynamicOrphan as C_DynamicOrphan, AnyPointer as C_DynamicObject, DynamicCapability as C_DynamicCapability, Request, Response, RemotePromise, PyPromise, VoidPromise, CallContext, PyRestorer, RpcSystem, makeRpcServer, makeRpcClient, Capability as C_Capability, TwoPartyVatNetwork as C_TwoPartyVatNetwork, Side, AsyncIoStream, Own, makeTwoPartyVatNetwork, PromiseFulfillerPair as C_PromiseFulfillerPair, copyPromiseFulfillerPair, newPromiseAndFulfiller, PyArray
|
||||
from .capnp.includes.schema_cpp cimport Node as C_Node, EnumNode as C_EnumNode
|
||||
from .capnp.includes.types cimport *
|
||||
from .capnp.helpers.non_circular cimport reraise_kj_exception
|
||||
|
||||
@@ -17,6 +17,7 @@ from types import ModuleType as _ModuleType
|
||||
import os as _os
|
||||
import sys as _sys
|
||||
import imp as _imp
|
||||
import traceback as _traceback
|
||||
from functools import partial as _partial
|
||||
import warnings as _warnings
|
||||
import inspect as _inspect
|
||||
@@ -26,12 +27,14 @@ from operator import attrgetter as _attrgetter
|
||||
cdef public object wrap_dynamic_struct_reader(C_DynamicStruct.Reader & reader):
|
||||
return _DynamicStructReader()._init(reader, None)
|
||||
|
||||
cdef public void wrap_remote_call(PyObject * func, Response & r) except *:
|
||||
cdef public PyObject * wrap_remote_call(PyObject * func, Response & r) except *:
|
||||
response = _Response()._init_childptr(new Response(moveResponse(r)), None)
|
||||
|
||||
func_obj = <object>func
|
||||
# TODO: decref func?
|
||||
func_obj(response)
|
||||
ret = func_obj(response)
|
||||
Py_INCREF(ret)
|
||||
return <PyObject *>ret
|
||||
|
||||
cdef _find_field_order(struct_node):
|
||||
return [f.name for f in sorted(struct_node.fields, key=_attrgetter('codeOrder'))]
|
||||
@@ -44,24 +47,29 @@ cdef public VoidPromise * call_server_method(PyObject * _server, char * _method_
|
||||
func = getattr(server, method_name+'_context', None)
|
||||
if func is not None:
|
||||
ret = func(context)
|
||||
Py_INCREF(ret) #TODO: stop leaking this
|
||||
if ret is not None:
|
||||
if type(ret) is _VoidPromise:
|
||||
return new VoidPromise(moveVoidPromise(deref((<_VoidPromise>ret).thisptr)))
|
||||
elif type(ret) is Promise:
|
||||
return new VoidPromise(helpers.convert_to_voidpromise(deref((<Promise>ret).thisptr)))
|
||||
else:
|
||||
try:
|
||||
warning_msg = 'Server function (%s) returned a value that was not a VoidPromise: return = %s' % (method_name, str(ret))
|
||||
warning_msg = 'Server function (%s) returned a value that was not a Promise: return = %s' % (method_name, str(ret))
|
||||
except:
|
||||
warning_msg = 'Server function (%s) returned a value that was not a VoidPromise' % (method_name)
|
||||
warning_msg = 'Server function (%s) returned a value that was not a Promise' % (method_name)
|
||||
_warnings.warn_explicit(warning_msg, UserWarning, _inspect.getsourcefile(func), _inspect.getsourcelines(func)[1])
|
||||
|
||||
if ret is not None:
|
||||
if type(ret) is _VoidPromise:
|
||||
return new VoidPromise(moveVoidPromise(deref((<_VoidPromise>ret).thisptr)))
|
||||
if type(ret) is Promise:
|
||||
return new VoidPromise(helpers.convert_to_voidpromise(deref((<Promise>ret).thisptr)))
|
||||
elif type(ret) is Promise:
|
||||
return new VoidPromise(helpers.convert_to_voidpromise(deref((<Promise>ret).thisptr)))
|
||||
else:
|
||||
try:
|
||||
warning_msg = 'Server function (%s) returned a value that was not a VoidPromise: return = %s' % (method_name, str(ret))
|
||||
warning_msg = 'Server function (%s) returned a value that was not a Promise: return = %s' % (method_name, str(ret))
|
||||
except:
|
||||
warning_msg = 'Server function (%s) returned a value that was not a VoidPromise' % (method_name)
|
||||
warning_msg = 'Server function (%s) returned a value that was not a Promise' % (method_name)
|
||||
_warnings.warn_explicit(warning_msg, UserWarning, _inspect.getsourcefile(func), _inspect.getsourcelines(func)[1])
|
||||
else:
|
||||
func = getattr(server, method_name) # will raise if no function found
|
||||
@@ -69,10 +77,13 @@ cdef public VoidPromise * call_server_method(PyObject * _server, char * _method_
|
||||
params_dict = {name : getattr(params, name) for name in params.schema.fieldnames}
|
||||
params_dict['_context'] = context
|
||||
ret = func(**params_dict)
|
||||
Py_INCREF(ret) #TODO: stop leaking this
|
||||
|
||||
if ret is not None:
|
||||
if type(ret) is _VoidPromise:
|
||||
return new VoidPromise(moveVoidPromise(deref((<_VoidPromise>ret).thisptr)))
|
||||
elif type(ret) is Promise:
|
||||
return new VoidPromise(helpers.convert_to_voidpromise(deref((<Promise>ret).thisptr)))
|
||||
if not isinstance(ret, tuple):
|
||||
ret = (ret,)
|
||||
names = _find_field_order(context.results.schema.node.struct)
|
||||
@@ -85,16 +96,29 @@ cdef public VoidPromise * call_server_method(PyObject * _server, char * _method_
|
||||
|
||||
return NULL
|
||||
|
||||
cdef public C_Capability.Client * call_py_restorer(PyObject * _restorer, C_DynamicStruct.Reader & _reader) except *:
|
||||
cdef public C_Capability.Client * call_py_restorer(PyObject * _restorer, C_DynamicObject.Reader & _reader) except *:
|
||||
restorer = <object>_restorer
|
||||
reader = _DynamicStructReader()._init(_reader, None)
|
||||
reader = _DynamicObjectReader()._init(_reader, None)
|
||||
|
||||
ret = restorer.restore(reader)
|
||||
ret = restorer._restore(reader)
|
||||
cdef _DynamicCapabilityServer server = ret
|
||||
cdef _InterfaceSchema schema = ret.schema
|
||||
|
||||
return new C_Capability.Client(helpers.server_to_client(schema.thisptr, <PyObject *>server))
|
||||
|
||||
|
||||
cdef public convert_array_pyobject(PyArray & arr):
|
||||
return [<object>arr[i] for i in range(arr.size())]
|
||||
|
||||
cdef public PyPromise * extract_promise(object obj):
|
||||
if type(obj) is Promise:
|
||||
promise = <Promise>obj
|
||||
promise.is_consumed = True
|
||||
Py_INCREF(promise) # TODO: fix leak
|
||||
return promise.thisptr
|
||||
|
||||
return NULL
|
||||
|
||||
cdef extern from "<kj/string.h>" namespace " ::kj":
|
||||
String strStructReader" ::kj::str"(C_DynamicStruct.Reader)
|
||||
String strStructBuilder" ::kj::str"(C_DynamicStruct.Builder)
|
||||
@@ -234,8 +258,8 @@ ctypedef fused _DynamicSetterClasses:
|
||||
C_DynamicStruct.Builder
|
||||
Request
|
||||
|
||||
ctypedef fused _PromiseTypes:
|
||||
_Promise
|
||||
ctypedef fused PromiseTypes:
|
||||
Promise
|
||||
_RemotePromise
|
||||
_VoidPromise
|
||||
PromiseFulfillerPair
|
||||
@@ -637,7 +661,7 @@ cdef _setDynamicField(_DynamicSetterClasses thisptr, field, value, parent):
|
||||
elif value_type is _DynamicCapabilityServer or isinstance(value, _DynamicCapabilityServer):
|
||||
thisptr.set(field, _extract_dynamic_server(value))
|
||||
else:
|
||||
raise ValueError("Non primitive type")
|
||||
raise ValueError("Tried to set field: '{}' with a value of: '{}' which is an unsupported type: '{}'".format(field, str(value), str(type(value))))
|
||||
|
||||
cdef _setDynamicFieldPtr(_DynamicSetterClasses * thisptr, field, value, parent):
|
||||
cdef C_DynamicValue.Reader temp
|
||||
@@ -672,7 +696,7 @@ cdef _setDynamicFieldPtr(_DynamicSetterClasses * thisptr, field, value, parent):
|
||||
elif value_type is _DynamicCapabilityClient:
|
||||
thisptr.set(field, _extract_dynamic_client(value))
|
||||
else:
|
||||
raise ValueError("Non primitive type")
|
||||
raise ValueError("Tried to set field: '{}' with a value of: '{}' which is an unsupported type: '{}'".format(field, str(value), str(type(value))))
|
||||
|
||||
cdef _to_dict(msg, bint verbose):
|
||||
msg_type = type(msg)
|
||||
@@ -1108,7 +1132,7 @@ cdef class _DynamicObjectReader:
|
||||
self._parent = parent
|
||||
return self
|
||||
|
||||
cpdef as_struct(self, schema):
|
||||
cpdef as_struct(self, schema) except +reraise_kj_exception:
|
||||
cdef _StructSchema s
|
||||
if hasattr(schema, 'schema'):
|
||||
s = schema.schema
|
||||
@@ -1117,6 +1141,9 @@ cdef class _DynamicObjectReader:
|
||||
|
||||
return _DynamicStructReader()._init(self.thisptr.getAs(s.thisptr), self._parent)
|
||||
|
||||
cpdef as_text(self) except +reraise_kj_exception:
|
||||
return (<char*>self.thisptr.getAsText().cStr())[:]
|
||||
|
||||
cdef class _DynamicObjectBuilder:
|
||||
cdef C_DynamicObject.Builder * thisptr
|
||||
cdef public object _parent
|
||||
@@ -1129,7 +1156,7 @@ cdef class _DynamicObjectBuilder:
|
||||
def __dealloc__(self):
|
||||
del self.thisptr
|
||||
|
||||
cpdef as_struct(self, schema):
|
||||
cpdef as_struct(self, schema) except +reraise_kj_exception:
|
||||
cdef _StructSchema s
|
||||
if hasattr(schema, 'schema'):
|
||||
s = schema.schema
|
||||
@@ -1141,6 +1168,9 @@ cdef class _DynamicObjectBuilder:
|
||||
cpdef set_as_text(self, text):
|
||||
self.thisptr.setAsText(text)
|
||||
|
||||
cpdef as_text(self) except +reraise_kj_exception:
|
||||
return (<char*>self.thisptr.getAsText().cStr())[:]
|
||||
|
||||
cdef class _EventLoop:
|
||||
cdef capnp.AsyncIoContext * thisptr
|
||||
|
||||
@@ -1164,6 +1194,11 @@ cdef class _EventLoop:
|
||||
|
||||
cdef _EventLoop C_DEFAULT_EVENT_LOOP = _EventLoop()
|
||||
|
||||
cpdef reset_event_loop():
|
||||
global C_DEFAULT_EVENT_LOOP
|
||||
C_DEFAULT_EVENT_LOOP._remove()
|
||||
C_DEFAULT_EVENT_LOOP = _EventLoop()
|
||||
|
||||
cdef class _CallContext:
|
||||
cdef CallContext * thisptr
|
||||
|
||||
@@ -1192,18 +1227,28 @@ cdef class _CallContext:
|
||||
self.thisptr.allowCancellation()
|
||||
|
||||
cpdef tail_call(self, _Request tailRequest):
|
||||
return _VoidPromise()._init(self.thisptr.tailCall(moveRequest(deref(tailRequest.thisptr_child))))
|
||||
promise = _VoidPromise()._init(self.thisptr.tailCall(moveRequest(deref(tailRequest.thisptr_child))))
|
||||
promise.is_consumed = True
|
||||
return promise
|
||||
|
||||
cdef class _Promise:
|
||||
cdef class Promise:
|
||||
cdef PyPromise * thisptr
|
||||
cdef public bint is_consumed
|
||||
cdef public object _parent, _obj
|
||||
|
||||
def __init__(self):
|
||||
self.is_consumed = True
|
||||
def __init__(self, obj=None):
|
||||
if obj is None:
|
||||
self.is_consumed = True
|
||||
else:
|
||||
self.is_consumed = False
|
||||
self._obj = obj
|
||||
Py_INCREF(obj) # TODO: fix this
|
||||
self.thisptr = new PyPromise(<PyObject *>obj)
|
||||
|
||||
cdef _init(self, PyPromise other):
|
||||
cdef _init(self, PyPromise other, parent=None):
|
||||
self.is_consumed = False
|
||||
self.thisptr = new PyPromise(movePromise(other))
|
||||
self._parent = parent
|
||||
return self
|
||||
|
||||
def __dealloc__(self):
|
||||
@@ -1225,7 +1270,7 @@ cdef class _Promise:
|
||||
Py_INCREF(func)
|
||||
Py_INCREF(error_func)
|
||||
|
||||
return _Promise()._init(helpers.then(deref(self.thisptr), <PyObject *>func, <PyObject *>error_func))
|
||||
return Promise()._init(helpers.then(deref(self.thisptr), <PyObject *>func, <PyObject *>error_func), self)
|
||||
|
||||
cdef class _VoidPromise:
|
||||
cdef VoidPromise * thisptr
|
||||
@@ -1257,7 +1302,12 @@ cdef class _VoidPromise:
|
||||
Py_INCREF(func)
|
||||
Py_INCREF(error_func)
|
||||
|
||||
return _Promise()._init(helpers.then(deref(self.thisptr), <PyObject *>func, <PyObject *>error_func))
|
||||
return Promise()._init(helpers.then(deref(self.thisptr), <PyObject *>func, <PyObject *>error_func), self)
|
||||
|
||||
cpdef as_pypromise(self) except +reraise_kj_exception:
|
||||
if self.is_consumed:
|
||||
raise RuntimeError('Promise was already used in a consuming operation. You can no longer use this Promise object')
|
||||
Promise()._init(helpers.convert_to_pypromise(deref(self.thisptr)), self)
|
||||
|
||||
cdef class _RemotePromise:
|
||||
cdef RemotePromise * thisptr
|
||||
@@ -1273,8 +1323,8 @@ cdef class _RemotePromise:
|
||||
self._parent = parent
|
||||
return self
|
||||
|
||||
def __dealloc__(self):
|
||||
del self.thisptr
|
||||
# def __dealloc__(self):
|
||||
# del self.thisptr
|
||||
|
||||
cpdef wait(self) except +reraise_kj_exception:
|
||||
if self.is_consumed:
|
||||
@@ -1286,7 +1336,9 @@ cdef class _RemotePromise:
|
||||
return ret
|
||||
|
||||
cpdef as_pypromise(self) except +reraise_kj_exception:
|
||||
_Promise()._init(helpers.convert_to_pypromise(deref(self.thisptr)))
|
||||
if self.is_consumed:
|
||||
raise RuntimeError('Promise was already used in a consuming operation. You can no longer use this Promise object')
|
||||
Promise()._init(helpers.convert_to_pypromise(deref(self.thisptr)), self)
|
||||
|
||||
cpdef then(self, func, error_func=None) except +reraise_kj_exception:
|
||||
if self.is_consumed:
|
||||
@@ -1295,7 +1347,7 @@ cdef class _RemotePromise:
|
||||
Py_INCREF(func)
|
||||
Py_INCREF(error_func)
|
||||
|
||||
return _VoidPromise()._init(helpers.then(deref(self.thisptr), <PyObject *>func, <PyObject *>error_func))
|
||||
return Promise()._init(helpers.then(deref(self.thisptr), <PyObject *>func, <PyObject *>error_func), self)
|
||||
|
||||
cpdef _get(self, field) except +reraise_kj_exception:
|
||||
cdef int type = (<C_DynamicValue.Pipeline>self.thisptr.get(field)).getType()
|
||||
@@ -1322,6 +1374,26 @@ cdef class _RemotePromise:
|
||||
def to_dict(self, verbose=False):
|
||||
return _to_dict(self, verbose)
|
||||
|
||||
cpdef join_promises(promises) except +reraise_kj_exception:
|
||||
heap = capnp.heapArrayBuilderPyPromise(len(promises))
|
||||
|
||||
new_promises = []
|
||||
new_promises_append = new_promises.append
|
||||
|
||||
for promise in promises:
|
||||
promise_type = type(promise)
|
||||
if promise_type is Promise:
|
||||
pyPromise = <Promise>promise
|
||||
elif promise_type is _RemotePromise or promise_type is _VoidPromise:
|
||||
pyPromise = <Promise>promise.as_pypromise()
|
||||
new_promises_append(pyPromise)
|
||||
else:
|
||||
raise ValueError('One of the promises passed to `join_promises` had a non promise value of: ' + str(promise))
|
||||
heap.add(movePromise(deref(pyPromise.thisptr)))
|
||||
pyPromise.is_consumed = True
|
||||
|
||||
return Promise()._init(helpers.then(capnp.joinPromises(heap.finish())))
|
||||
|
||||
cdef class _Request(_DynamicStructBuilder):
|
||||
cdef Request * thisptr_child
|
||||
|
||||
@@ -1330,6 +1402,7 @@ cdef class _Request(_DynamicStructBuilder):
|
||||
self._init(<C_DynamicStruct.Builder>deref(self.thisptr_child), parent)
|
||||
return self
|
||||
|
||||
#TODO: dealloc
|
||||
cpdef send(self):
|
||||
return _RemotePromise()._init(self.thisptr_child.send(), self._parent)
|
||||
|
||||
@@ -1341,6 +1414,7 @@ cdef class _Response(_DynamicStructReader):
|
||||
self._init(<C_DynamicStruct.Reader>deref(self.thisptr_child), parent)
|
||||
return self
|
||||
|
||||
#TODO: dealloc
|
||||
cdef _init_childptr(self, Response * other, parent):
|
||||
self.thisptr_child = other
|
||||
self._init(<C_DynamicStruct.Reader>deref(self.thisptr_child), parent)
|
||||
@@ -1483,26 +1557,20 @@ cdef class _CapabilityClient:
|
||||
s = schema
|
||||
return _DynamicCapabilityClient()._init(self.thisptr.castAs(s.thisptr), self._parent)
|
||||
|
||||
cdef class Restorer:
|
||||
cdef class _Restorer:
|
||||
cdef PyRestorer * thisptr
|
||||
cdef C_StructSchema schema
|
||||
|
||||
cdef public object restore
|
||||
|
||||
def __init__(self, schema, restore_func):
|
||||
cdef _StructSchema s
|
||||
if hasattr(schema, 'schema'):
|
||||
s = schema.schema
|
||||
else:
|
||||
s = schema
|
||||
|
||||
self.schema = s.thisptr
|
||||
self.restore = restore_func
|
||||
self.thisptr = new PyRestorer(<PyObject*>self, self.schema)
|
||||
def __init__(self, restore):
|
||||
self.thisptr = new PyRestorer(<PyObject*>self)
|
||||
self.restore = restore
|
||||
|
||||
def __dealloc__(self):
|
||||
del self.thisptr
|
||||
|
||||
def _restore(self, obj):
|
||||
return self.restore(obj)
|
||||
|
||||
cdef class _TwoPartyVatNetwork:
|
||||
cdef Own[C_TwoPartyVatNetwork] thisptr
|
||||
|
||||
@@ -1510,21 +1578,34 @@ cdef class _TwoPartyVatNetwork:
|
||||
self.thisptr = makeTwoPartyVatNetwork(stream, side)
|
||||
return self
|
||||
|
||||
cdef class RpcClient:
|
||||
cdef _Restorer _convert_restorer(restorer):
|
||||
if isinstance(restorer, _RestorerImpl):
|
||||
return _Restorer(restorer._restore)
|
||||
elif type(restorer) is _Restorer:
|
||||
return restorer
|
||||
elif hasattr(restorer, 'restore'):
|
||||
return _Restorer(restorer.restore)
|
||||
elif callable(restorer):
|
||||
return _Restorer(restorer)
|
||||
else:
|
||||
raise ValueError("Restorer object ({}) isn't able to be used as a restore".format(str(restorer)))
|
||||
|
||||
cdef class TwoPartyClient:
|
||||
cdef RpcSystem * thisptr
|
||||
cdef public _TwoPartyVatNetwork network
|
||||
cdef public object restorer, _stream
|
||||
cdef public object _stream
|
||||
cdef public _Restorer restorer
|
||||
cdef public _FdAsyncIoStream stream
|
||||
|
||||
def __init__(self, stream, Restorer restorer=None):
|
||||
def __init__(self, stream, restorer=None):
|
||||
self._stream = stream
|
||||
self.stream = _FdAsyncIoStream(stream.fileno())
|
||||
self.network = _TwoPartyVatNetwork()._init(deref(self.stream.thisptr), capnp.CLIENT)
|
||||
if restorer is None:
|
||||
self.thisptr = new RpcSystem(makeRpcClient(deref(self.network.thisptr)))
|
||||
else:
|
||||
self.restorer = restorer
|
||||
self.thisptr = new RpcSystem(makeRpcClientWithRestorer(deref(self.network.thisptr), deref(restorer.thisptr)))
|
||||
self.restorer = _convert_restorer(restorer)
|
||||
self.thisptr = new RpcSystem(makeRpcClientWithRestorer(deref(self.network.thisptr), deref(self.restorer.thisptr)))
|
||||
|
||||
def __dealloc__(self):
|
||||
del self.thisptr
|
||||
@@ -1568,18 +1649,23 @@ cdef class RpcClient:
|
||||
|
||||
return self.restore(ref.objectId)
|
||||
|
||||
cdef class RpcServer:
|
||||
cdef class TwoPartyServer:
|
||||
cdef RpcSystem * thisptr
|
||||
cdef public _TwoPartyVatNetwork network
|
||||
cdef public object restorer, _stream
|
||||
cdef public object _stream
|
||||
cdef public _Restorer restorer
|
||||
cdef public _FdAsyncIoStream stream
|
||||
|
||||
def __init__(self, stream, Restorer restorer):
|
||||
def __init__(self, stream, restorer):
|
||||
self._stream = stream
|
||||
self.stream = _FdAsyncIoStream(stream.fileno())
|
||||
self.restorer = restorer
|
||||
Py_INCREF(self._stream)
|
||||
Py_INCREF(self.stream) # TODO: attach this to onDrained, also figure out what's leaking
|
||||
self.restorer = _convert_restorer(restorer)
|
||||
self.network = _TwoPartyVatNetwork()._init(deref(self.stream.thisptr), capnp.SERVER)
|
||||
self.thisptr = new RpcSystem(makeRpcServer(deref(self.network.thisptr), deref(restorer.thisptr)))
|
||||
self.thisptr = new RpcSystem(makeRpcServer(deref(self.network.thisptr), deref(self.restorer.thisptr)))
|
||||
Py_INCREF(self.restorer) # TODO: attach this to onDrained, also figure out what's leaking
|
||||
Py_INCREF(self.network) # TODO: attach this to onDrained, also figure out what's leaking
|
||||
|
||||
def __dealloc__(self):
|
||||
del self.thisptr
|
||||
@@ -1751,9 +1837,17 @@ cdef _new_message(self, kwargs):
|
||||
_from_dict(msg, kwargs)
|
||||
return msg
|
||||
|
||||
class _RestorerImpl(object):
|
||||
pass
|
||||
|
||||
class _StructModule(object):
|
||||
def __init__(self, schema):
|
||||
def __init__(self, schema, name):
|
||||
def blank_init(server_self):
|
||||
pass
|
||||
def _restore(self, obj):
|
||||
return self.restore(obj.as_struct(self.schema))
|
||||
self.schema = schema
|
||||
self.Restorer = type(name + '.Restorer', (_RestorerImpl,), {'schema':schema, '_restore':_restore})
|
||||
|
||||
def read(self, file, traversal_limit_in_words = None, nesting_limit = None):
|
||||
"""Returns a Reader for the unpacked object read from file.
|
||||
@@ -1876,7 +1970,7 @@ class _InterfaceModule(object):
|
||||
def server_init(server_self):
|
||||
pass
|
||||
self.schema = schema
|
||||
self.Server = type(name, (_DynamicCapabilityServer,), {'__init__': server_init, 'schema':schema})
|
||||
self.Server = type(name + '.Server', (_DynamicCapabilityServer,), {'__init__': server_init, 'schema':schema})
|
||||
|
||||
def _new_client(self, server):
|
||||
return _DynamicCapabilityClient()._init_vals(self.schema, server)
|
||||
@@ -1955,7 +2049,7 @@ cdef class SchemaParser:
|
||||
schema = nodeSchema.get_nested(node.name)
|
||||
proto = schema.get_proto()
|
||||
if proto.isStruct:
|
||||
local_module = _StructModule(schema.as_struct())
|
||||
local_module = _StructModule(schema.as_struct(), node.name)
|
||||
class Reader(_DynamicStructReader):
|
||||
"""An abstract base class. Readers are 'instances' of this class."""
|
||||
__metaclass__ = _StructABCMeta
|
||||
|
||||
Reference in New Issue
Block a user