[ python-Bugs-1164631 ] super(...).__new__( ... ) behaves
"unexpected"
SourceForge.net
noreply at sourceforge.net
Sat Mar 19 01:17:16 CET 2005
Bugs item #1164631, was opened at 2005-03-17 03:07
Message generated for change (Comment added) made by ncoghlan
You can respond by visiting:
https://sourceforge.net/tracker/?func=detail&atid=105470&aid=1164631&group_id=5470
Category: Type/class unification
Group: Python 2.4
Status: Open
Resolution: None
Priority: 5
Submitted By: Dirk Brenckmann (brenck)
Assigned to: Nobody/Anonymous (nobody)
Summary: super(...).__new__( ... ) behaves "unexpected"
Initial Comment:
Hello there,
python code and trace output enclosed.
What I did:
1. Metaclass inheritence:
type <-- MA <-- MB <-- MC
2. Created Class A using __metaclass__= MC
3. Create Class B(A) using __metaclass__= MB
...although this might seem strange, it should work...
When taking a look at the trace, you will notice one line
that goes like:
'-------> why does super( MA, metacls ).__new__ call MC.
__new__ in next line ????????????????????'
if you run the code, you will find it three times. That's ok.
In my trace I just replaced two occurences of that line by
">>" to enable focussing on the Problem...
What I would expect the code to do is the following:
1. Create a Class A which is of type MC
2. Create a Class B(A) which is of type MB
What the interpreter does is different:
1. Create a Class A which is type MC
2.1 Nearly create a Class B which is of type MB.
2.2 In type.__new__( ... ) change it's mind.
2.3 Due to the superclass A<MC> of B, create some
class A which is of type MC as well. Although B
contains a __metaclass__ = MB statement.
Well - that's what I experienced is "the way windows
works", so I ran the code on Solaris again but the
behaviour remains reproduceable...
I would consider it a bug therefor. If it's not a bug, I would
expect an Exception which tells me where I did wrong...
Thanx for your time and efforts
----------------------------------------------------------------------
Comment By: Nick Coghlan (ncoghlan)
Date: 2005-03-19 10:17
Message:
Logged In: YES
user_id=1038590
To address the documentation side, the following text from
Guido's descrintro essay could be added to the official
documentation:
"""For new-style metaclasses, there is a constraint that the
chosen metaclass is equal to, or a subclass of, each of the
metaclasses of the bases. Consider a class C with two base
classes, B1 and B2. Let's say M = C.__class__, M1 =
B1.__class__, M2 = B2.__class__. Then we require
issubclass(M, M1) and issubclass(M, M2). (This is because a
method of B1 should be able to call a meta-method defined in
M1 on self.__class__, even when self is an instance of a
subclass of B1.)"""
----------------------------------------------------------------------
Comment By: Nick Coghlan (ncoghlan)
Date: 2005-03-19 10:14
Message:
Logged In: YES
user_id=1038590
Minimal case that should throw an exception on C3, but
doesn't (instead, it silently replaces the explicitly
requested metaclass M1 with its subclass M2):
class M1(type):
pass
class M2(M1):
pass
class C1(object):
__metaclass__ = M1
class C2(C1):
__metaclass__ = M2
class C3(C2):
__metaclass__ = M1
----------------------------------------------------------------------
Comment By: Jim Jewett (jimjjewett)
Date: 2005-03-19 05:14
Message:
Logged In: YES
user_id=764593
Yes, it is intentional.
class Derived(Base): ...
should mean that you can use an instance of Derived
anywhere you need an instance of Base.
There are ways to break this, but it isn't a good idea.
Letting Derived ignore part of the metaclass (and creation
instructions) of Base would make it much easier to create an
invalid Derived by accident -- and the error could show up as
memory corruption, instead of something meaningful.
----------------------------------------------------------------------
Comment By: Dirk Brenckmann (brenck)
Date: 2005-03-19 01:48
Message:
Logged In: YES
user_id=360037
Ok - I think I found the reason for the behaviour I explained
above ...
typeobject.c:
function type_new(...)
[...]
/* Determine the proper [...]
<line 1611, 1612, 1613>
if (PyType_IsSubtype(tmptype, winner)) {
winner = tmptype;
continue;
}
These three lines mean, it would never be possible to create a
subclass using a (metatype which is a subclass of the
metatype) of it's superclass.
In such cases, (even) a metaclass (explictly set by a
programmer) is ignored and replaced by a metaclass which
python decides...
... do you really want this to be that way????
This means, one always ends up in a (meta-)class hierarchy
that is fixed. Programmers dynamically can't decide anymore,
if there should be a level in their class hierarchy which should
*NOT* use the 'highest subclassed metaclass' in their class
hierarchy.
I would consider this a problem, because the use of
__metaclasses__ will be implicitly restricted
----------------------------------------------------------------------
Comment By: Dirk Brenckmann (brenck)
Date: 2005-03-19 00:41
Message:
Logged In: YES
user_id=360037
Ok - I think I found the reason for the behaviour I explained
above ...
typeobject.c:
function type_new(...)
[...]
/* Determine the proper [...]
<line 1611, 1612, 1613>
if (PyType_IsSubtype(tmptype, winner)) {
winner = tmptype;
continue;
}
These three lines mean, it would never be possible to create a
subclass using a (metatype which is a subclass of the
metatype) of it's superclass.
In such cases, (even) a metaclass (explictly set by a
programmer) is ignored and replaced by a metaclass which
python decides...
... do you really want this to be that way????
This means, one always ends up in a (meta-)class hierarchy
that is fixed. Programmers dynamically can't decide anymore,
if there should be a level in their class hierarchy which should
*NOT* use the 'highest subclassed metaclass' in their class
hierarchy.
I would consider this a problem, because the use of
__metaclasses__ will be implicitly restricted
----------------------------------------------------------------------
Comment By: Dirk Brenckmann (brenck)
Date: 2005-03-19 00:13
Message:
Logged In: YES
user_id=360037
Ok - I think I found the reason for the behaviour I explained
above ...
typeobject.c:
function type_new(...)
[...]
/* Determine the proper [...]
<line 1611, 1612, 1613>
if (PyType_IsSubtype(tmptype, winner)) {
winner = tmptype;
continue;
}
These three lines mean, it would never be possible to create a
subclass using a (metatype which is a subclass of the
metatype) of it's superclass.
In such cases, (even) a metaclass (explictly set by a
programmer) is ignored and replaced by a metaclass which
python decides...
... do you really want this to be that way????
This means, one always ends up in a (meta-)class hierarchy
that is fixed. Programmers dynamically can't decide anymore,
if there should be a level in their class hierarchy which should
*NOT* use the 'highest subclassed metaclass' in their class
hierarchy.
I would consider this a problem, because the use of
__metaclasses__ will be implicitly restricted
----------------------------------------------------------------------
Comment By: Dirk Brenckmann (brenck)
Date: 2005-03-18 20:38
Message:
Logged In: YES
user_id=360037
Ok - I think I found the reason for the behaviour I explained
above ...
typeobject.c:
function type_new(...)
[...]
/* Determine the proper [...]
<line 1611, 1612, 1613>
if (PyType_IsSubtype(tmptype, winner)) {
winner = tmptype;
continue;
}
These three lines mean, it would never be possible to create a
subclass using a (metatype which is a subclass of the
metatype) of it's superclass.
In such cases, (even) a metaclass (explictly set by a
programmer) is ignored and replaced by a metaclass which
python decides...
... do you really want this to be that way????
This means, one always ends up in a (meta-)class hierarchy
that is fixed. Programmers dynamically can't decide anymore,
if there should be a level in their class hierarchy which should
*NOT* use the 'highest subclassed metaclass' in their class
hierarchy.
I would consider this a problem, because the use of
__metaclasses__ will be implicitly restricted
----------------------------------------------------------------------
Comment By: Dirk Brenckmann (brenck)
Date: 2005-03-17 03:11
Message:
Logged In: YES
user_id=360037
Sorry - 2.3 must be corrected:
2.3 Due to the superclass A<MC> of B, create some
class B which is of type MC as well. Although B
contains a __metaclass__ = MB statement.
----------------------------------------------------------------------
You can respond by visiting:
https://sourceforge.net/tracker/?func=detail&atid=105470&aid=1164631&group_id=5470
More information about the Python-bugs-list
mailing list