name lookup failure using metaclasses with unittests
Ulrich Eckhardt
ulrich.eckhardt at dominolaser.com
Thu Apr 11 02:43:58 EDT 2013
Am 10.04.2013 11:52, schrieb Peter Otten:
> Ulrich Eckhardt wrote:
[...]
> It looks like this particular invocation relies on class attribute and
> function __name__ being identical.
>
> Please file a bug report.
Thanks for confirming this and reducing the test case even more.
>> Now, concerning Python 3, it fails to detect any test case at all! My
>> guess is that the unittest library was changed to use metaclasses itself
>> in order to detect classes derived from unittest.TestCase. Therefore,
>> overriding the metaclass breaks test case discovery. My question in that
>> context is how do I extend metaclasses instead of overriding it? In
>> other words, what is the equivalent to super() for class creation?
>
> Python 3 does not recognize the __metaclass__ attribute as the metaclass.
> You need to provide it like so:
>
> def __metaclass__(name, bases, dict):
> ...
>
> class X(unittest.TestCase, metaclass=__metaclass__):
> pass
:|
Doing some research[0, 1] on metaclasses in 2 and 3, I have a few more
questions...
The first thing I was wondering was why Python doesn't complain about a
class property that is marked as special (leading and trailing double
underscores) but that it knows nothing about. Worse, Python 3 should be
aware of its legacy and recognize the Python 2 metaclass syntax, even if
only to reject it loudly. I'm pretty sure there is a reason for that,
The second question that came up was if there is a way to keep a
metaclass defined inside the class or if the only way is to provide it
externally. The reason I like this in-class definition is that for my
case of autogenerated test functions, everything is in one place which
used to be in a loop that modified the class after its creation. Maybe
I'm just too brainwashed by static languages though.
To get the Python2 feeling back, I have a hack in mind that involves
creating a baseclass which in turn provides a metaclass that invokes a
specific function to post-initialize the class, similar to the way
Python 2 does it automatically, but I'm wondering if there isn't
anything better. Also PEP 3115 "Metaclasses in Python 3000"[2] seems to
consider postprocessing of a class definition as better handled by a
class decorator, which is something I haven't looked at yet.
Greetings from Hamburg!
Uli
[0] http://mikewatkins.ca/2008/11/29/python-2-and-3-metaclasses/
[1] http://www.artima.com/weblogs/viewpost.jsp?thread=236234
[2] http://www.python.org/dev/peps/pep-3115/
More information about the Python-list
mailing list