Attempting a on-demand resolution of datatypes references, so we don't need to call resolve_references anymore. It works with python 2, but not yet python 3 (some weakref issues)
This commit is contained in:
parent
520341238e
commit
938c6f5e13
1
tox.ini
1
tox.ini
@ -32,6 +32,7 @@ deps=
|
|||||||
webtest
|
webtest
|
||||||
coverage
|
coverage
|
||||||
simplejson
|
simplejson
|
||||||
|
zope.interface<=3.8.99
|
||||||
transaction<=1.1.1
|
transaction<=1.1.1
|
||||||
|
|
||||||
[testenv:sphinxext]
|
[testenv:sphinxext]
|
||||||
|
@ -117,7 +117,6 @@ class WSRoot(object):
|
|||||||
:rtype: list of (path, :class:`FunctionDefinition`)
|
:rtype: list of (path, :class:`FunctionDefinition`)
|
||||||
"""
|
"""
|
||||||
if self._api is None:
|
if self._api is None:
|
||||||
self.__registry__.resolve_references()
|
|
||||||
self._api = [i for i in scan_api(self)]
|
self._api = [i for i in scan_api(self)]
|
||||||
return self._api
|
return self._api
|
||||||
|
|
||||||
|
@ -287,6 +287,15 @@ class TestTypes(unittest.TestCase):
|
|||||||
|
|
||||||
types.register_type(A)
|
types.register_type(A)
|
||||||
types.register_type(B)
|
types.register_type(B)
|
||||||
types.registry.resolve_references()
|
|
||||||
|
|
||||||
assert A.b.datatype is B
|
assert A.b.datatype is B
|
||||||
|
|
||||||
|
def test_base(self):
|
||||||
|
class B1(types.Base):
|
||||||
|
b2 = types.wsattr('B2')
|
||||||
|
|
||||||
|
class B2(types.Base):
|
||||||
|
b2 = types.wsattr('B2')
|
||||||
|
|
||||||
|
assert B1.b2.datatype is B2, repr(B1.b2.datatype)
|
||||||
|
assert B2.b2.datatype is B2
|
||||||
|
@ -203,13 +203,15 @@ class wsattr(object):
|
|||||||
#: The attribute name on the public of the api.
|
#: The attribute name on the public of the api.
|
||||||
#: Defaults to :attr:`key`
|
#: Defaults to :attr:`key`
|
||||||
self.name = name
|
self.name = name
|
||||||
self._datatype = datatype
|
self._datatype = (datatype,)
|
||||||
#: True if the attribute is mandatory
|
#: True if the attribute is mandatory
|
||||||
self.mandatory = mandatory
|
self.mandatory = mandatory
|
||||||
#: Default value. The attribute will return this instead
|
#: Default value. The attribute will return this instead
|
||||||
#: of :data:`Unset` if no value has been set.
|
#: of :data:`Unset` if no value has been set.
|
||||||
self.default = default
|
self.default = default
|
||||||
|
|
||||||
|
self.complextype = None
|
||||||
|
|
||||||
def __get__(self, instance, owner):
|
def __get__(self, instance, owner):
|
||||||
if instance is None:
|
if instance is None:
|
||||||
return self
|
return self
|
||||||
@ -231,6 +233,9 @@ class wsattr(object):
|
|||||||
self.__set__(instance, Unset)
|
self.__set__(instance, Unset)
|
||||||
|
|
||||||
def _get_datatype(self):
|
def _get_datatype(self):
|
||||||
|
if isinstance(self._datatype, tuple):
|
||||||
|
self._datatype = \
|
||||||
|
self.complextype().__registry__.resolve_type(self._datatype[0])
|
||||||
if isinstance(self._datatype, weakref.ref):
|
if isinstance(self._datatype, weakref.ref):
|
||||||
return self._datatype()
|
return self._datatype()
|
||||||
return self._datatype
|
return self._datatype
|
||||||
@ -320,6 +325,7 @@ def inspect_class(class_):
|
|||||||
attrdef.key = name
|
attrdef.key = name
|
||||||
if attrdef.name is None:
|
if attrdef.name is None:
|
||||||
attrdef.name = name
|
attrdef.name = name
|
||||||
|
attrdef.complextype = weakref.ref(class_)
|
||||||
attributes.append(attrdef)
|
attributes.append(attrdef)
|
||||||
setattr(class_, name, attrdef)
|
setattr(class_, name, attrdef)
|
||||||
|
|
||||||
@ -378,6 +384,7 @@ class Registry(object):
|
|||||||
class_._wsme_attributes = None
|
class_._wsme_attributes = None
|
||||||
class_._wsme_attributes = inspect_class(class_)
|
class_._wsme_attributes = inspect_class(class_)
|
||||||
|
|
||||||
|
class_.__registry__ = self
|
||||||
self.complex_types.append(weakref.ref(class_))
|
self.complex_types.append(weakref.ref(class_))
|
||||||
|
|
||||||
def lookup(self, typename):
|
def lookup(self, typename):
|
||||||
@ -402,15 +409,25 @@ class Registry(object):
|
|||||||
}
|
}
|
||||||
return type_
|
return type_
|
||||||
|
|
||||||
def resolve_references(self):
|
|
||||||
for ct in self.complex_types:
|
|
||||||
ct = ct()
|
|
||||||
for attr in list_attributes(ct):
|
|
||||||
attr.datatype = self.resolve_type(attr.datatype)
|
|
||||||
|
|
||||||
# Default type registry
|
# Default type registry
|
||||||
registry = Registry()
|
registry = Registry()
|
||||||
|
|
||||||
|
|
||||||
def register_type(class_):
|
def register_type(class_):
|
||||||
return registry.register(class_)
|
return registry.register(class_)
|
||||||
|
|
||||||
|
|
||||||
|
class BaseMeta(type):
|
||||||
|
def __new__(cls, name, bases, dct):
|
||||||
|
r = type.__new__(cls, name, bases, dct)
|
||||||
|
if bases[0] is object:
|
||||||
|
return r
|
||||||
|
if getattr(r, '__registry__', None) is None:
|
||||||
|
registry.register(r)
|
||||||
|
else:
|
||||||
|
r.__registry__.register(r)
|
||||||
|
return r
|
||||||
|
|
||||||
|
|
||||||
|
class Base(object):
|
||||||
|
__metaclass__ = BaseMeta
|
||||||
|
Loading…
x
Reference in New Issue
Block a user