difference 2.3 versus 2.2

2 visualizzazioni
Passa al primo messaggio da leggere

Michele Simionato

da leggere,
22 gen 2003, 17:25:4522/01/03
a
I have found a difference of behaviour between Python 2.2 and 2.3.

$ python
Python 2.2 (#1, Apr 12 2002, 15:29:57)
[GCC 2.96 20000731 (Red Hat Linux 7.2 2.96-109)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> class Meta(type): pass
...
>>> class C(object): pass
...
>>> C.__class__=Meta
>>> C.__class__
<class '__main__.Meta'>

Therefore I can change the metaclass of C on Python 2.2.
However on Python 2.3:

$ p23a
Python 2.3a1 (#1, Jan 6 2003, 10:31:14)
[GCC 2.96 20000731 (Red Hat Linux 7.2 2.96-108.7.2)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> class Meta(type): pass
...
>>> class C(object): pass
...
>>> C.__class__=Meta
Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: __class__ assignment: only for heap types

Can somebody put some light on this TypeError ?
It looks like intentional.

I can change class of a normal object, why not the class of a class ?

Bye,

Michele

"Martin v. Löwis"

da leggere,
23 gen 2003, 03:05:1623/01/03
a
Michele Simionato wrote:
> TypeError: __class__ assignment: only for heap types
>
> Can somebody put some light on this TypeError ?
> It looks like intentional.
>
> I can change class of a normal object, why not the class of a class ?

You can't change the class of arbitrary normal objects:

>>> (2).__class__=float


Traceback (most recent call last):

File "<interactive input>", line 1, in ?
TypeError: __class__ assignment: 'float' object layout differs from 'int'

In 2.3, this rules was tightened that not only the layout must be
compatible, but both old and new type must be "heap types", i.e. created
through a class statement. Without this restriction, 2.3 would have
allowed to write

(2).__class__ = bool

which would have cheated the constructor of the bool type.

In your example, the old type of the object is TypeType, which is not a
heap type.

Regards,
Martin

Michele Simionato

da leggere,
23 gen 2003, 11:00:4523/01/03
a
"Martin v. Löwis" <mar...@v.loewis.de> wrote in message news:<b0o7nr$t1l$07$1...@news.t-online.com>...

>>Michele Simionato wrote:
>>$ p23a
>>Python 2.3a1 (#1, Jan 6 2003, 10:31:14)
>>[GCC 2.96 20000731 (Red Hat Linux 7.2 2.96-108.7.2)] on linux2
>>Type "help", "copyright", "credits" or "license" for more information.
>>>> class Meta(type): pass ...
>>>> class C(object): pass ...
>>>> C.__class__=Meta

Thanks, Martin.

Therefore, if I understand correctly, 'heap type' means 'user-defined type',
as opposed to built-in typ). For instance, I see that I *can* change the
metaclass from Meta1 to Meta1 if both Meta1 and Meta2 are user-defined:

>>> class Meta1(type): pass
>>> class Meta2(type): pass
>>> C=Meta1('C',(),{})
>>> C.__class__
<class '__main__.Meta1'>
>>> C.__class__=Meta2
>>> C.__class__
<class '__main__.Meta2'>

This restriction (i.e. it is possible to change the __class__ attribute
only for heap types) should be reported in "What's new in Python 2.3",
since it is a change that breaks old code. I will send a copy of the
present mail to pytho...@python.org.

Thanks again,

Michele

Martin v. Löwis

da leggere,
24 gen 2003, 04:46:0424/01/03
a
mi...@pitt.edu (Michele Simionato) writes:

> Therefore, if I understand correctly, 'heap type' means 'user-defined type',
> as opposed to built-in typ).

Roughly, yes. You can define a heap type using the C API if you want,
but they are typically defined through a class statement.

> This restriction (i.e. it is possible to change the __class__ attribute
> only for heap types) should be reported in "What's new in Python 2.3",
> since it is a change that breaks old code. I will send a copy of the
> present mail to pytho...@python.org.

It would be much better if you posted a documentation patch to
sf.net/projects/python.

I don't think this change is major enough to find mentioning in
"What's new"; I really doubt any real application will be affected by
that. It is listed in the NEWS file, as

- Assignment to __class__ is disallowed if either the old or the new
class is a statically allocated type object (such as defined by an
extension module). This prevents anomalies like 2.__class__ = bool.

Regards,
Martin

Rispondi a tutti
Rispondi all'autore
Inoltra
0 nuovi messaggi