classification
Title: type() returns incorrect type for nested classes
Type: behavior Stage:
Components: Interpreter Core Versions: Python 3.4
process
Status: closed Resolution: duplicate
Dependencies: Superseder: Integrate pickle protocol version 4 GSoC work by Stefan Mihaila
View: 15642
Assigned To: Nosy List: daniel.urban, pitrou, pwil3058, r.david.murray, serhiy.storchaka
Priority: normal Keywords:

Created on 2011-07-01 05:25 by pwil3058, last changed 2012-12-04 12:08 by pitrou. This issue is now closed.

Files
File name Uploaded Description Edit
nested_class_bug.py pwil3058, 2011-07-01 05:25 Short code snippet to demonstrate the problem.
confusion.py pwil3058, 2011-07-02 00:26 Demonstration of type namimg confusion
Messages (8)
msg139542 - (view) Author: Peter Williams (pwil3058) Date: 2011-07-01 05:25
The built in type() function returns incorrect type names for nested classes which in turn causes pickle to crash when used with nested classes as it cannot find the nested class definitions from the using the string returned by type().

e.g. if I have an instance "inner" of class Inner which is defined inside (nested in) the class Outer:

type(inner) returns <class '__main__.Inner'> instead of <class '__main__.Outer.Inner'>

The isinstance() function, as expected, returns True for isinstance(inner, Outer.Inner) and raises a NameError exception for isinstance(inner, Inner).

However, isinstance(inner, type(inner)) returns True which indicates the core functionality is OK and this conforms to the fact that no problems were encountered until I tried to pickle an object containing nested classes.

My system is Fedora 15 x86_64 and Python versions are 2.7.1 and 3.2.

A short program illustrating the problem is attached.
msg139550 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2011-07-01 07:35
Inner classes can't be pickled (see the pickle docs for what can be pickled).

Whether or not there is a bug in the repr of the inner class is an interesting question.
msg139622 - (view) Author: Peter Williams (pwil3058) Date: 2011-07-02 00:26
The class I was pickling was a top level class but a field inside that class had an instance of a nested class set as its value.  The error message produced indicated that the reason for failure was the inability of pickle to find the class definition and (I think) that was caused by the problem with type()'s returned value.

Perhaps fixing the problem with type() would allow the restriction on pickling nested classes to be removed?  Was that restriction a deliberate design decision (illogical) or the result of not being able to get it to work?

Re whether the behaviour of type() is a problem:  I believe it is as, in addition to the inconsistencies between type() and isinstance() that I described in my original report, there is the confusion that arises if two separate classes have nested classes with the same name (see mini program confusion.py as an example).  This seems to compromise the whole purpose of namespaces and is inconsistent with the way modules are treated in determining the name reported by type().
msg172924 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2012-10-14 21:54
There is no crash. I don't think this is a bug. It looks as feature request and this feature already implemented in 3.3 (PEP 3155).
msg176286 - (view) Author: Daniel Urban (daniel.urban) * (Python triager) Date: 2012-11-24 14:17
Also, it seems, that pickling inner classes will by supported by pickle protocol version 4 (see PEP 3154). There is already an issue for the implementation: issue15642.
msg176897 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2012-12-04 11:37
Should it be closed?
msg176900 - (view) Author: Daniel Urban (daniel.urban) * (Python triager) Date: 2012-12-04 12:06
I don't know what is the protocol for duplicates when the superseder is still open. If they should be closed, then I think yes, this should be closed.
msg176903 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2012-12-04 12:08
The "naming confusion" was fixed in 3.3:
http://docs.python.org/dev/whatsnew/3.3.html#pep-3155-qualified-name-for-classes-and-functions

As for pickle, it indeed depends on protocol version 4 as proposed in PEP 3154.
History
Date User Action Args
2012-12-04 12:08:43pitrousetstatus: open -> closed

nosy: + pitrou
messages: + msg176903

stage: needs patch ->
2012-12-04 12:06:38daniel.urbansetmessages: + msg176900
2012-12-04 11:37:44serhiy.storchakasetmessages: + msg176897
2012-11-24 14:18:01daniel.urbansetsuperseder: Integrate pickle protocol version 4 GSoC work by Stefan Mihaila
resolution: duplicate
2012-11-24 14:17:20daniel.urbansetmessages: + msg176286
versions: + Python 3.4, - Python 2.7, Python 3.2
2012-10-14 21:54:39serhiy.storchakasetnosy: + serhiy.storchaka
messages: + msg172924

components: + Interpreter Core, - None
type: crash -> behavior
stage: needs patch
2011-07-02 00:26:24pwil3058setfiles: + confusion.py
type: behavior -> crash
messages: + msg139622
2011-07-01 16:43:38daniel.urbansetnosy: + daniel.urban
2011-07-01 07:35:42r.david.murraysettype: crash -> behavior

messages: + msg139550
nosy: + r.david.murray
2011-07-01 05:25:40pwil3058create