isinstance() not recognizing an instance correctly (python bug?)

Fernando Perez fperez528 at yahoo.com
Wed May 8 02:02:32 EDT 2002


Martin v. Loewis wrote:

> Fernando Perez <fperez528 at yahoo.com> writes:
> 
>> I've found a rather unpleasant situation where isinstance(obj,cls)==0, even
>> though obj _is_ indeed a cls() instance. I don't know if this should be
>> considered a bug or just an unavoidable consequence of the circumstances
>> where it happens.
> 
> That's really hard to believe. Can you demonstrate it in a small,
> self-contained example (including instructions like what Python
> version to use, on what operating system, and what commands to execute
> in what order)?

I've enclosed below the code which produces the problem, but it's part of a 
large enough system that it doesn't work on its own. This is a full-blown 
interactive interpreter, and it would take me a couple of hours to 
disassemble enough of it to have only a few lines which work on their own and 
still show the problem. But if you want I can post on the web a tarball of a 
version with the problem activated and tell  you exactly where it  is in the 
code.


>> Well,  when 's' above is passed to display(), it fails to identify that s
>> is indeed an instance of someclass(). The reason, I think, is that the
>> interactive code is executed in a separate namespace than the display code,
>> and therefore someclass exists with two different memory addresses.
> 
> This is very unlikely. When somemodule is imported the second time,
> sys.modules is checked to see whether it is already imported, and if
> so, the existing module is re-used. In turn, somemodule.someclass
> ought to be the same module all the time.
> 
> One possible cause is that you import the same code both as a
> submodule of a package, and as a top-level module
> (i.e. somepackage.somemodule vs. somemodule). In that case, those two
> copies will indeed have distinct definitions of someclass.
> 
> In any case, without seeing further details, I'm unwilling to believe
> that what you report actually happened.

Well, here's a 'screenshot' of an interactive session with the problem:

----------------------------------------------------
[python]> ipython
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]: s
Out[3]: is arg a Struct? 0
arg class Struct.Struct
Struct({'a': 1})

In [4]: print s.__class__
Struct.Struct
----------------------------------------------------


The display code which is called at printing time is below (with the special 
mods which produce those messages):

    def _display(self,arg):
        """Default printer method, uses pprint.

        This can be over-ridden by the users to implement special formatting
        of certain types of output."""

        if self.Pprint:
            try:
                print 'is arg a Struct?',isinstance(arg,Struct)
                print 'arg class',arg.__class__
                if isinstance(arg,Struct):
                    print 'STRUCT DETECTED!!!'
                    out = '<Struct>:\n%s' % pformat(arg.dict())
                else:
                    out = pformat(arg)
            except:
                out = pformat(arg)
            if '\n' in out:
                print
            print out
        else:
            print arg

At the top of the module where the display code is located I have:
from Struct import Struct

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.

Cheers,

f.



More information about the Python-list mailing list