Commit b6b517ee authored by Xiaowu Zhang's avatar Xiaowu Zhang

portal_type_class: possible to overwrite methods or properties in mixin

Before this change, class hierarchy is like this when using mixin:
```
class MyClass(BaseClass, Mixin1....)
```
which is usually ok when classes don't override each other's

But if we want to overwrite BaseClass's method by using mixin to do more thing,

For example:
```
class BaseClass(object):
  def test(self):
    print 'base test'

class Mixin1(object):
  def test(self):
    super(Mixin,self).test()
    print 'mixin'
```
I want to display 'mixin base test' when call test, but it doesn't work

since priority of how methods are resolved is from left

to right: BaseClass----->Mixin1, it only display 'base test'

So the correct way to use mixin should be in reverse order:
```
class MyClass(Mixin1, BaseClass)
```

/reviewed-on nexedi/erp5!935
parent 0d996b48
......@@ -285,7 +285,7 @@ def generatePortalTypeClass(site, portal_type_name):
mixin_class_list.append(mixin_class)
base_class_list = [klass] + accessor_holder_list + mixin_class_list + [
base_class_list = mixin_class_list + [klass] + accessor_holder_list + [
# _getAcquireLocalRoles is accessed by security machinery, so it needs to
# be fast: make it a ConstantGetter while we have access to portal_type
# configuration.
......
......@@ -2559,15 +2559,18 @@ class TestZodbMixinComponent(TestZodbInterfaceComponent):
"""
Return 42
"""
def getTitle(self, **kw):
return "Test Mixin"
''' % class_name
def testAssignToPortalTypeClass(self):
"""
Create a new Document Component inheriting from Person Document and try to
assign it to Person Portal Type, then create a new Person and check
whether it has been successfully added to its Portal Type class bases and
that the newly-defined function on ZODB Component can be called as well as
methods from Person Document
assign it to Person Portal Type, in this Component, define getTitle method,
then create a new Person and check whether it has been successfully added
to its Portal Type class bases and that the newly-defined function
on ZODB Component can be called as well as methods from Person Document,also
check getTitle method overwrite the original one
"""
import erp5.portal_type
person_type = self.portal.portal_types.Person
......@@ -2588,6 +2591,9 @@ class TestZodbMixinComponent(TestZodbInterfaceComponent):
person_type_class_mro_list = person_type_class.__mro__
self.assertFalse(TestPortalTypeMixin in person_type_class_mro_list)
person_original_mixin_type_list = list(person_type.getTypeMixinList())
person_module = self.portal.person_module
person = person_module.newContent(id='Mixin', portal_type='Person')
original_title = person.getTitle()
try:
person_type.setTypeMixinList(person_original_mixin_type_list +
['TestPortalTypeMixin'])
......@@ -2598,6 +2604,8 @@ class TestZodbMixinComponent(TestZodbInterfaceComponent):
person_type_class_mro_list = person_type_class.__mro__
from erp5.component.mixin.TestPortalTypeMixin import TestPortalTypeMixin
self.assertTrue(TestPortalTypeMixin in person_type_class_mro_list)
self.assertEqual('Test Mixin', person.getTitle())
self.assertNotEqual(original_title, person.getTitle())
finally:
person_type.setTypeMixinList(person_original_mixin_type_list)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment