This issue tracker has been migrated to GitHub ,
and is currently read-only.
For more information,
see the GitHub FAQs in the Python's Developer Guide.
Created on 2011年03月19日 02:13 by terry.reedy, last changed 2022年04月11日 14:57 by admin. This issue is now closed.
| Messages (7) | |||
|---|---|---|---|
| msg131381 - (view) | Author: Terry J. Reedy (terry.reedy) * (Python committer) | Date: 2011年03月19日 02:13 | |
People occasionally ask on python-list about the following error message when trying to create a class:
> TypeError: Error when calling the metaclass bases
> module.__init__() takes at most 2 arguments (3 given)
It is a bit cryptic. It is also accidental: if module.__init__ happened to take 3 args instead of 2, the exception would be delayed until ???
The cause is using a module as a superclass, as in
import UserDict
class MyDict(UserDict): pass
This seems to happen mostly because of duplicate (or only case-different) module/class names.
Suggestion: insert a specific module type check for bases in type_new() in typeobject.c. In Python:
if basetype is module: # where 'module' is the module class
raise TypeError('Cannot subclass module')
I see 2 possible places to put the check:
1. for all bases - after
tmp = PyTuple_GET_ITEM(bases, i);
tmptype = Py_TYPE(tmp);
Advantage: can add (name of) tmp to the error message.
2. Before the return call in
if (winner != metatype) {
if (winner->tp_new != type_new) /* Pass it to the winner */
return winner->tp_new(winner, args, kwds);
Advantage: only add extra check when module is the winner and are about to call it as a metaclass, which raises the current error.
Any test would be CPython specific and would require checking something about the message text.
I am only suggesting a check for module because the is the only mistake I remember anyone reporting. Passing a number as a base class gives a similar message, but no one does that. And as far as I know, there is no way in general to detect whether a callable works as a metaclass except by calling it with name, bases, and dict.
|
|||
| msg131397 - (view) | Author: ysj.ray (ysj.ray) | Date: 2011年03月19日 06:22 | |
> I am only suggesting a check for module because the is the only mistake > I remember anyone reporting. Passing a number as a base class gives a > > similar message, but no one does that. And as far as I know, there is > no way in general to detect whether a callable works as a metaclass > except by calling it with name, bases, and dict. Since 3.x all the module names became lower-case and can be easily differ from class names, so I don't think this problem will present much in 3.x, right? |
|||
| msg131493 - (view) | Author: Éric Araujo (eric.araujo) * (Python committer) | Date: 2011年03月20日 13:34 | |
> raise TypeError('Cannot subclass module')
It is possible to subclass module.
Ray: right, but 2.x still has a long life ahead of it, so we still want to improve its doc.
|
|||
| msg131522 - (view) | Author: Terry J. Reedy (terry.reedy) * (Python committer) | Date: 2011年03月20日 17:46 | |
Whoops. That should be 'Cannot subclass a module' or 'Cannot subclass module %s' % modulename. Types.ModuleType can indeed by subclassed. I agree that this is not a pressing issue, but it will at least provide an answer to anyone searching the tracker for the current message. |
|||
| msg140268 - (view) | Author: Éric Araujo (eric.araujo) * (Python committer) | Date: 2011年07月13日 15:18 | |
I don’t know if this should be left to lint tools or addressed by CPython itself. Raymond, do you have an opinion? |
|||
| msg381160 - (view) | Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) | Date: 2020年11月16日 21:27 | |
Special cases aren't special enough to break the rules. I think this issue should be closed. This is not common user error, especially in Python 3. I can even imagine that you can subclass module, if it is an instance of special ModuleType subclass. It is a feature of Python that you can subclass any objects, not only classes, if they provide the particular interface. |
|||
| msg381208 - (view) | Author: Terry J. Reedy (terry.reedy) * (Python committer) | Date: 2020年11月17日 06:27 | |
I cannot anymore remember seeing this. So closing. |
|||
| History | |||
|---|---|---|---|
| Date | User | Action | Args |
| 2022年04月11日 14:57:15 | admin | set | github: 55813 |
| 2020年11月17日 06:27:44 | terry.reedy | set | status: pending -> closed resolution: out of date messages: + msg381208 stage: test needed -> resolved |
| 2020年11月16日 21:27:23 | serhiy.storchaka | set | status: open -> pending nosy: + serhiy.storchaka messages: + msg381160 |
| 2020年11月16日 20:00:11 | iritkatriel | set | keywords:
+ newcomer friendly versions: + Python 3.9, Python 3.10, - Python 3.3 |
| 2011年07月13日 15:18:39 | eric.araujo | set | nosy:
+ rhettinger messages: + msg140268 |
| 2011年03月20日 17:46:32 | terry.reedy | set | nosy:
terry.reedy, eric.araujo, ysj.ray messages: + msg131522 |
| 2011年03月20日 13:34:16 | eric.araujo | set | nosy:
+ eric.araujo messages: + msg131493 |
| 2011年03月19日 06:22:29 | ysj.ray | set | nosy:
+ ysj.ray messages: + msg131397 |
| 2011年03月19日 02:13:57 | terry.reedy | create | |