simplify metaclass logic, punt on trying to divine intent in multiple inheritance case
This commit is contained in:
@@ -1917,6 +1917,7 @@ class _SchemaNode(object):
|
||||
class _SchemaMeta(type):
|
||||
def __init__(cls, name, bases, clsattrs):
|
||||
nodes = []
|
||||
|
||||
for name, value in clsattrs.items():
|
||||
if isinstance(value, _SchemaNode):
|
||||
delattr(cls, name)
|
||||
@@ -1925,16 +1926,15 @@ class _SchemaMeta(type):
|
||||
if value.raw_title is _marker:
|
||||
value.title = name.replace('_', ' ').title()
|
||||
nodes.append((value._order, value))
|
||||
cls.__class_schema_nodes__ = nodes
|
||||
# Combine all attrs from this class and its subclasses.
|
||||
extended = []
|
||||
for i, c in enumerate(reversed(cls.__mro__)):
|
||||
|
||||
nodes.sort()
|
||||
cls.__class_schema_nodes__ = [ n[1] for n in nodes ]
|
||||
|
||||
# Combine all attrs from this class and its _SchemaNode superclasses.
|
||||
cls.__all_schema_nodes__ = []
|
||||
for c in reversed(cls.__mro__):
|
||||
csn = getattr(c, '__class_schema_nodes__', [])
|
||||
extended.extend([(i, x, y) for x, y in csn])
|
||||
# Sort the attrs to maintain the order as defined, and assign to the
|
||||
# class.
|
||||
extended.sort()
|
||||
cls.__all_schema_nodes__ = [x[2] for x in extended]
|
||||
cls.__all_schema_nodes__.extend(csn)
|
||||
|
||||
# metaclass spelling compatibility across Python 2 and Python 3
|
||||
SchemaNode = _SchemaMeta(
|
||||
|
||||
@@ -2631,6 +2631,56 @@ class TestMappingSchemaInheritance(unittest.TestCase):
|
||||
]
|
||||
)
|
||||
|
||||
def test_single_inheritance2(self):
|
||||
import colander
|
||||
class One(colander.Schema):
|
||||
a = colander.SchemaNode(
|
||||
colander.Int(),
|
||||
id='a1',
|
||||
)
|
||||
b = colander.SchemaNode(
|
||||
colander.Int(),
|
||||
id='b1',
|
||||
)
|
||||
d = colander.SchemaNode(
|
||||
colander.Int(),
|
||||
id='d1',
|
||||
)
|
||||
|
||||
class Two(One):
|
||||
a = colander.SchemaNode(
|
||||
colander.String(),
|
||||
id='a2',
|
||||
)
|
||||
c = colander.SchemaNode(
|
||||
colander.String(),
|
||||
id='c2',
|
||||
)
|
||||
e = colander.SchemaNode(
|
||||
colander.String(),
|
||||
id='e2',
|
||||
)
|
||||
|
||||
class Three(Two):
|
||||
b = colander.SchemaNode(
|
||||
colander.Bool(),
|
||||
id='b3',
|
||||
)
|
||||
d = colander.SchemaNode(
|
||||
colander.Bool(),
|
||||
id='d3',
|
||||
)
|
||||
f = colander.SchemaNode(
|
||||
colander.Bool(),
|
||||
id='f3',
|
||||
)
|
||||
|
||||
inst = Three()
|
||||
c = inst.children
|
||||
self.assertEqual(len(c), 6)
|
||||
result = [ x.id for x in c ]
|
||||
self.assertEqual(result, ['a2', 'b3', 'd3', 'c2', 'e2', 'f3'])
|
||||
|
||||
def test_multiple_inheritance(self):
|
||||
import colander
|
||||
class One(colander.Schema):
|
||||
@@ -2661,7 +2711,7 @@ class TestMappingSchemaInheritance(unittest.TestCase):
|
||||
id='e2',
|
||||
)
|
||||
|
||||
class Three(One, Two):
|
||||
class Three(Two, One):
|
||||
b = colander.SchemaNode(
|
||||
colander.Bool(),
|
||||
id='b3',
|
||||
@@ -2676,13 +2726,10 @@ class TestMappingSchemaInheritance(unittest.TestCase):
|
||||
)
|
||||
|
||||
inst = Three()
|
||||
self.assertEqual(len(inst.children), 6)
|
||||
self.assertEqual(inst.children[0].id, 'a1')
|
||||
self.assertEqual(inst.children[1].id, 'b3')
|
||||
self.assertEqual(inst.children[2].id, 'd3')
|
||||
self.assertEqual(inst.children[3].id, 'c2')
|
||||
self.assertEqual(inst.children[4].id, 'e2')
|
||||
self.assertEqual(inst.children[5].id, 'f3')
|
||||
c = inst.children
|
||||
self.assertEqual(len(c), 6)
|
||||
result = [ x.id for x in c ]
|
||||
self.assertEqual(result, ['a2', 'b3', 'd3', 'c2', 'e2', 'f3'])
|
||||
|
||||
def test_insert_before_failure(self):
|
||||
import colander
|
||||
|
||||
Reference in New Issue
Block a user