Recursion error in metaclass
Steven D'Aprano
steve+comp.lang.python at pearwood.info
Fri Jun 10 23:34:42 EDT 2011
I have a metaclass in Python 3.1:
class MC1(type):
@staticmethod
def get_mro(bases):
print('get_mro called')
return type('K', bases, {}).__mro__[1:]
def __new__(cls, name, bases, dict):
mro = None
docstring = dict.get('__doc__')
if docstring == 'ham':
mro = cls.get_mro(bases)
dict['__doc__'] = "spam spam spam"
# Create the class we want, and return it.
K = super().__new__(cls, name, bases, dict)
if mro:
assert K.__mro__ == (K,) + mro
return K
It seems to work fine:
>>> class A(metaclass=MC1):
... pass
...
>>> class B(A):
... 'ham'
...
get_mro called
>>> assert B.__doc__ == 'spam spam spam'
>>>
But if I move the call to get_mro outside of the if block, it works fine
at first, and then blows up with RecursionError:
class MC2(type):
@staticmethod
def get_mro(bases):
print('get_mro called')
return type('K', bases, {}).__mro__[1:]
def __new__(cls, name, bases, dict):
mro = None
docstring = dict.get('__doc__')
mro = cls.get_mro(bases)
if docstring == 'ham':
dict['__doc__'] = "spam spam spam"
# Create the class we want, and return it.
K = super().__new__(cls, name, bases, dict)
if mro:
assert K.__mro__ == (K,) + mro
return K
>>> class C(metaclass=MC2):
... pass
...
get_mro called
>>>
>>> sys.setrecursionlimit(15)
>>> class D(C):
... 'ham'
...
get_mro called
get_mro called
get_mro called
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 9, in __new__
File "<stdin>", line 5, in get_mro
File "<stdin>", line 9, in __new__
File "<stdin>", line 5, in get_mro
File "<stdin>", line 9, in __new__
File "<stdin>", line 4, in get_mro
RuntimeError: maximum recursion depth exceeded while calling a Python
object
I am utterly perplexed. What's going on here?
--
Steven
More information about the Python-list
mailing list