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 2008年12月08日 21:25 by terry.reedy, last changed 2022年04月11日 14:56 by admin. This issue is now closed.
| Files | ||||
|---|---|---|---|---|
| File name | Uploaded | Description | Edit | |
| 4600.diff | jonash, 2011年02月27日 18:00 | |||
| Messages (6) | |||
|---|---|---|---|
| msg77343 - (view) | Author: Terry J. Reedy (terry.reedy) * (Python committer) | Date: 2008年12月08日 21:25 | |
ob.__class__ = ob2 gives some confusing TypeError messages. >>> c.__class__ = 1 Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: __class__ must be set to new-style class, not 'int' object Problem: 'new-style' is obsolete in 3.0. It is also too inclusive... >>> c.__class__ = object Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: __class__ assignment: only for heap types object *is* 'new-style'. I presume 'heap type' means 'class defined by class statement'. If so, let us say so, since beginning programmers may not know what a 'heap type' is. If the above is incorrect, then this experienced programmer also does not know what it means in Python context ;-). Proposal: when someone tries to set __class__ to an inappropriate object, give similar error message for instances and heap classes. TypeError: __class__ must be set to a class defined by a class statement, not 'xxx' [object]. where 'object', without the brackets, is added for non-classes, as it is today. >>> c.__class__ = object Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: __class__ assignment: only for heap types C, the class of c, *is* a heap type. The different problem, the target being an instance of heap class, should get a different message. 'Heap' is still possibly confusing. Proposal: TypeError: __class__ assignment: only for instances of classes defined by class statements. |
|||
| msg77381 - (view) | Author: Terry J. Reedy (terry.reedy) * (Python committer) | Date: 2008年12月09日 00:59 | |
Related issue that applies to recent 2.x. Language/data model/Objects, values, and types says 'An object’s type is also unchangeable.'. This should be changed or deleted. |
|||
| msg129643 - (view) | Author: Jonas H. (jonash) * | Date: 2011年02月27日 18:00 | |
Here comes a patch, changing the behaviour to: ./python -q >>> class C: ... pass ... >>> (1).__class__ = 1 Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: __class__ must be set to a class defined by a class statement, not 'int' object >>> (1).__class__ = object Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: class__ must be set to a class defined by a class statement, not 'object' >>> (1).__class__ = C Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: __class__ assignment: only for instances of classes defined by class statements |
|||
| msg129646 - (view) | Author: Benjamin Peterson (benjamin.peterson) * (Python committer) | Date: 2011年02月27日 18:25 | |
This is not really accurate: >>> class x(int): pass ... >>> class y(object): pass ... >>> x().__class__ = y Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: __class__ assignment: 'x' object layout differs from 'y' >>> y().__class__ = x Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: __class__ assignment: 'y' object layout differs from 'x' |
|||
| msg396989 - (view) | Author: Irit Katriel (iritkatriel) * (Python committer) | Date: 2021年07月05日 13:35 | |
The error messages are different now: >>> class C: pass ... >>> c = C() >>> c.__class__ = 1 Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: __class__ must be set to a class, not 'int' object >>> c.__class__ = object Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: __class__ assignment only supported for mutable types or ModuleType subclasses >>> |
|||
| msg397017 - (view) | Author: Terry J. Reedy (terry.reedy) * (Python committer) | Date: 2021年07月05日 19:15 | |
I neglected to mention above what c is. I Irit guessed right as
>>> class C: pass
...
>>> c = C()
is what I (also) usually do for examples and testing.
Removing "new-style" elsewhere solved the issue with the error message for "ob.__class__ = non_class_object". The new error message for "ob.__class__ = someclass" replaces 'heap' with 'mutable'. But it can still be confusing as the qualification in
__class__ assignment only supported for mutable types or ModuleType subclasses
applies to both type(ob) and someclass and the same error is given if either does not qualify. The use of the plural 'types' allows but does not mandate this interpretation. Also, "mutable types" means that the types are mutable, not their instances. Although 'list' is sometimes referred to as a 'mutable type' because its instances are, 'list' itself is not mutable and does not qualify here.
I am closing this issue, which is about the error message, because the new message is accurate when understood. I cannot think of any better one-line message. Explaining the background needed to understand should be done elsewhere.
Andre, I nosied you in case the above would help you improve Friendly's explanation of this error. I was a bit confused myself until I did more experiments.
Note: Even when type(ob) and someclass both 'qualify', the assignment will fail if instances are 'incompatible'. Let M be a subclass of types.ModuleType.
c.__class__ = M # fails with
TypeError: __class__ assignment: 'M' object layout differs from 'C'
The difference is obvious by looking as dir(c) and dir(M('somename')).
|
|||
| History | |||
|---|---|---|---|
| Date | User | Action | Args |
| 2022年04月11日 14:56:42 | admin | set | github: 48850 |
| 2021年07月05日 19:15:08 | terry.reedy | set | nosy:
+ aroberge title: __class__ assignment: new-style? heap? == confusing -> __class__ assignment error message confusing messages: + msg397017 versions: + Python 3.11, - Python 3.3 |
| 2021年07月05日 17:46:03 | terry.reedy | set | status: open -> closed resolution: out of date stage: resolved |
| 2021年07月05日 13:35:46 | iritkatriel | set | nosy:
+ iritkatriel messages: + msg396989 |
| 2012年04月17日 17:12:08 | flox | set | nosy:
+ flox |
| 2011年05月23日 11:32:59 | eric.araujo | set | assignee: docs@python -> nosy: - docs@python |
| 2011年05月23日 11:32:37 | eric.araujo | set | nosy:
+ eric.araujo versions: + Python 3.3, - Python 3.0 |
| 2011年02月27日 18:25:42 | benjamin.peterson | set | nosy:
+ benjamin.peterson messages: + msg129646 |
| 2011年02月27日 18:00:31 | jonash | set | files:
+ 4600.diff nosy: + jonash messages: + msg129643 keywords: + patch |
| 2011年02月27日 16:14:25 | Trundle | set | nosy:
+ Trundle |
| 2011年02月27日 16:04:58 | stutzbach | set | nosy:
+ stutzbach |
| 2010年08月01日 06:40:22 | georg.brandl | set | assignee: docs@python nosy: + docs@python |
| 2008年12月09日 00:59:47 | terry.reedy | set | messages: + msg77381 |
| 2008年12月08日 21:25:22 | terry.reedy | create | |