isinstance() not recognizing an instance correctly (python bug?)
Fernando Pérez
fperez528 at yahoo.com
Wed May 8 13:56:36 EDT 2002
Martin v. Löwis wrote:
> Fernando Perez <fperez528 at yahoo.com> writes:
>
>> So both the user-defined one and the internal one have been imported
>> via the same statement. Note however that as I said, the interactive
>> user code is run in a closed namespace, which is what (I think)
>> causes the behavior. I could well be confused though.
>
> I guess you need to explain in more detail what a "closed namespace"
> is. Does it share sys.modules with the rest of the interpreter?
>
> If not, that would indeed explain the problem.
>
> You should compute and print the id of class Struct at both places,
> and see whether they are identical. If not, it is not surprising that
> the isinstance check fails - you would have two different classes that
> just happen to have the same name.
Here's the output. Indeed they have a different id for the Struct class, but
the funny thing is that sys.modules shows the same id both for the
interactive and internal sides.
[python]> ip
Python 2.2 (#1, Feb 24 2002, 16:21:58)
Type "copyright", "credits" or "license" for more information.
IPython 0.2.12pre13 -- An enhanced Interactive Python.
? -> Introduction to IPython's features.
@magic -> Information about IPython's 'magic' @ functions.
help -> Python's own help system.
object? -> Details about 'object'. ?object also works, ?? prints more.
In [1]: from Struct import Struct
In [2]: s=Struct(a=1)
In [3]: print id(Struct)
136214948
In [4]: print id(sys.modules )
134532788
In [5]: s
Out[5]:
Argument passed belongs to class: Struct.Struct
Is arg a Struct (via isinstance)? 0
id of Struct class: 135905636
id of sys.modules : 134532788
Struct({'a': 1})
By 'in a closed namespace' I mean that all user input is executed via the
following code (my shell is a subclass of the code.py stuff, the code below
is copied from code.py):
def runcode(self, code):
"""Execute a code object.
When an exception occurs, self.showtraceback() is called to
display a traceback. All exceptions are caught except
SystemExit, which is reraised.
A note about KeyboardInterrupt: this exception may occur
elsewhere in this code, and may not always be caught. The
caller should be prepared to deal with it.
"""
try:
exec code in self.locals
except SystemExit:
raise
except:
self.showtraceback()
else:
if softspace(sys.stdout, 0):
print
The locals dict referenced by this is given in the the following constructor
in my class:
code.InteractiveConsole.__init__(self,locals = user_ns)
where user_ns is initially an almost empty dict. So all user code is executed
in user_ns, not in __main__. But looking at code.py, a similar thing is done
if you don't specify locals (a new dict is created for user execution), so I
guess this problem will happen to anyone subclassing InteractiveConsole.
If you really need, I can try to write a new simple subclass of
InteractiveConsole showing the problem, which I'm getting more and more
convinced should at least be documented as a failure mode of isinstance().
Thanks for the help,
f.
More information about the Python-list
mailing list