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:
Christophe de Vienne 2012-06-04 19:22:32 +02:00
parent 520341238e
commit 938c6f5e13
4 changed files with 35 additions and 9 deletions

View File

@ -32,6 +32,7 @@ deps=
webtest
coverage
simplejson
zope.interface<=3.8.99
transaction<=1.1.1
[testenv:sphinxext]

View File

@ -117,7 +117,6 @@ class WSRoot(object):
:rtype: list of (path, :class:`FunctionDefinition`)
"""
if self._api is None:
self.__registry__.resolve_references()
self._api = [i for i in scan_api(self)]
return self._api

View File

@ -287,6 +287,15 @@ class TestTypes(unittest.TestCase):
types.register_type(A)
types.register_type(B)
types.registry.resolve_references()
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

View File

@ -203,13 +203,15 @@ class wsattr(object):
#: The attribute name on the public of the api.
#: Defaults to :attr:`key`
self.name = name
self._datatype = datatype
self._datatype = (datatype,)
#: True if the attribute is mandatory
self.mandatory = mandatory
#: Default value. The attribute will return this instead
#: of :data:`Unset` if no value has been set.
self.default = default
self.complextype = None
def __get__(self, instance, owner):
if instance is None:
return self
@ -231,6 +233,9 @@ class wsattr(object):
self.__set__(instance, Unset)
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):
return self._datatype()
return self._datatype
@ -320,6 +325,7 @@ def inspect_class(class_):
attrdef.key = name
if attrdef.name is None:
attrdef.name = name
attrdef.complextype = weakref.ref(class_)
attributes.append(attrdef)
setattr(class_, name, attrdef)
@ -378,6 +384,7 @@ class Registry(object):
class_._wsme_attributes = None
class_._wsme_attributes = inspect_class(class_)
class_.__registry__ = self
self.complex_types.append(weakref.ref(class_))
def lookup(self, typename):
@ -402,15 +409,25 @@ class Registry(object):
}
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
registry = Registry()
def register_type(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