classification
Title: metaclass can't derive from ABC
Type: behavior Stage:
Components: Library (Lib) Versions: Python 3.1, Python 3.2, Python 2.7
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: Nosy List: benjamin.peterson, daniel.urban, eric.araujo, r.david.murray, roalddevries, terry.reedy
Priority: normal Keywords:

Created on 2010-08-06 10:33 by roalddevries, last changed 2010-10-02 17:53 by benjamin.peterson. This issue is now closed.

Files
File name Uploaded Description Edit
bug.py roalddevries, 2010-08-06 10:33 source file leading to the exception in the comment
Messages (5)
msg113094 - (view) Author: Roald de Vries (roalddevries) Date: 2010-08-06 10:33
Exception raised::

  Traceback (most recent call last):
    File "bug.py", line 5, in <module>
      class derived(type, Sized):
    File "/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/abc.py", line 85, in __new__
      for name in getattr(base, "__abstractmethods__", set()):
  TypeError: Error when calling the metaclass bases
      'getset_descriptor' object is not iterable
msg114025 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2010-08-15 23:22
+- same traceback in 3.1
Since ABCmeta is not used (by name) its import is not needed.
I have no opinion on whether this should work.
msg117802 - (view) Author: Daniel Urban (daniel.urban) * (Python triager) Date: 2010-10-01 14:10
If we create a new class, which is a metaclass, and also inherits an ABC, we create a new instance of ABCMeta.

When ABCMeta.__new__ creates the __abstractmethods__ attribute of the new class, it iterates over the __abstractmethods__ attribute of every base class (and checks every name in it, if it's abstract in the new class). One of the base classes of a metaclass is of course type. The type.__abstractmethods__ object is a getset descriptor (its __set__ switches some flags in tp_flags), which isn't iterable, so it raises the exception. 

Ideas for possible solutions:
1. In ABCMeta.__new__ special case type (do not check its __abstractmethods__attribute). 
2. In ABCMeta.__new__ check if the __abstractmethods__ attribute is in fact an iterable, before we try to iterate over it. (I don't think this would be a very good solution, because if a base class' __abstractmethods__ isn't iterable, it should be an error, except if the base class is type itself. So we should special case type anyway.)

I can't come up with a use case for this right now, but I don't see why it shouldn't work.
msg117880 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2010-10-02 14:18
Does the "fix" for issue 10006 affect this?  (I imagine that question is why Antoine made Benjamin nosy on this issue).
msg117891 - (view) Author: Benjamin Peterson (benjamin.peterson) * (Python committer) Date: 2010-10-02 17:53
You can now create metaclass abcs. However, having __abstractmethods__ does not prevent instance creation. This is a problem with a builtins, though.
History
Date User Action Args
2010-10-02 17:53:46benjamin.petersonsetstatus: open -> closed
resolution: fixed
messages: + msg117891
2010-10-02 14:18:09r.david.murraysetnosy: + r.david.murray
messages: + msg117880
2010-10-02 12:23:01pitrousetnosy: + benjamin.peterson
2010-10-01 14:10:04daniel.urbansetnosy: terry.reedy, eric.araujo, daniel.urban, roalddevries
messages: + msg117802
components: + Library (Lib)
2010-09-20 22:59:29eric.araujosetnosy: + eric.araujo
2010-08-15 23:22:51terry.reedysetnosy: + terry.reedy

messages: + msg114025
versions: + Python 3.1, Python 2.7, Python 3.2, - Python 2.6
2010-08-06 16:07:36daniel.urbansetnosy: + daniel.urban
type: compile error -> behavior
2010-08-06 10:33:37roalddevriescreate