Skip to content
Snippets Groups Projects
Commit 15f7b56e authored by Piotr Maślanka's avatar Piotr Maślanka
Browse files

v2.2.9

parent a7bd7074
No related branches found
No related tags found
No related merge requests found
# v2.2.9 # v2.2.9
* fixed `metaclass_maker`
* `self.assertEquals` -> `self.assertEqual` due to deprecation * `self.assertEquals` -> `self.assertEqual` due to deprecation
# v2.2.8 # v2.2.8
......
...@@ -26,11 +26,11 @@ Now, give the following type structure: ...@@ -26,11 +26,11 @@ Now, give the following type structure:
class MetaB(type): class MetaB(type):
pass pass
class A: class A(metaclass=MetaA):
__metaclass__ = MetaA pass
class B: class B(metaclass=MetaB):
__metaclass__ = MetaB pass
You just can't construct the following class You just can't construct the following class
......
# coding=UTF-8 # coding=UTF-8
__version__ = '2.2.9a2' __version__ = '2.2.9'
...@@ -4,7 +4,7 @@ import types ...@@ -4,7 +4,7 @@ import types
Taken from http://code.activestate.com/recipes/204197-solving-the-metaclass-conflict/ Taken from http://code.activestate.com/recipes/204197-solving-the-metaclass-conflict/
""" """
__all__ = ['metaclass_maker'] __all__ = ['metaclass_maker_f']
def skip_redundant(iterable, skipset=None): def skip_redundant(iterable, skipset=None):
...@@ -17,7 +17,7 @@ def skip_redundant(iterable, skipset=None): ...@@ -17,7 +17,7 @@ def skip_redundant(iterable, skipset=None):
def remove_redundant(metaclasses): def remove_redundant(metaclasses):
skipset = set([types.ClassType]) skipset = set([type])
for meta in metaclasses: # determines the metaclasses to be skipped for meta in metaclasses: # determines the metaclasses to be skipped
skipset.update(inspect.getmro(meta)[1:]) skipset.update(inspect.getmro(meta)[1:])
return tuple(skip_redundant(metaclasses, skipset)) return tuple(skip_redundant(metaclasses, skipset))
...@@ -46,19 +46,24 @@ def get_noconflict_metaclass(bases, left_metas, right_metas): ...@@ -46,19 +46,24 @@ def get_noconflict_metaclass(bases, left_metas, right_metas):
raise TypeError("Incompatible root metatypes", needed_metas) raise TypeError("Incompatible root metatypes", needed_metas)
else: # gotta work ... else: # gotta work ...
metaname = '_' + ''.join([m.__name__ for m in needed_metas]) metaname = '_' + ''.join([m.__name__ for m in needed_metas])
meta = metaclass_maker()(metaname, needed_metas, {}) meta = metaclass_maker_f()(metaname, needed_metas, {})
memoized_metaclasses_map[needed_metas] = meta memoized_metaclasses_map[needed_metas] = meta
return meta return meta
def metaclass_maker(left_metas=(), right_metas=()): def metaclass_maker_f(left_metas=(), right_metas=()):
"""
Automatically construct a compatible meta-class like interface. Use like:
>>> class C(A, B):
>>> __metaclass__ = metaclass_maker()
"""
def make_class(name, bases, adict): def make_class(name, bases, adict):
metaclass = get_noconflict_metaclass(bases, left_metas, right_metas) metaclass = get_noconflict_metaclass(bases, left_metas, right_metas)
return metaclass(name, bases, adict) return metaclass(name, bases, adict)
return make_class return make_class
def metaclass_maker(name, bases, adict):
"""
Automatically construct a compatible meta-class like interface. Use like:
>>> class C(A, B, metaclass=metaclass_maker):
>>> pass
"""
metaclass = get_noconflict_metaclass(bases, (), ())
return metaclass(name, bases, adict)
...@@ -2,22 +2,27 @@ import unittest ...@@ -2,22 +2,27 @@ import unittest
from satella.coding import metaclass_maker from satella.coding import metaclass_maker
class TestMetaclasses(unittest.TestCase): class MetaA(type):
def test_metaclasses(self): pass
class MetaA(type):
pass
class MetaB(type):
pass
class MetaB(type): class A(metaclass=MetaA):
pass pass
class A:
__metaclass__ = MetaA
class B: class B(metaclass=MetaB):
__metaclass__ = MetaB pass
class AB(A, B):
__metaclass__ = metaclass_maker()
class AB(A, B, metaclass=metaclass_maker):
pass
class TestMetaclasses(unittest.TestCase):
def test_metaclasses(self):
a = AB() a = AB()
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment