isinstance() bug

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Michal Vitecek

    isinstance() bug

    hello,

    please consider the following situation:

    under the current directory there's a subdirectory 'package' with two
    files: __init__.py and module.py

    ./package:
    __init__.py
    module.py

    module.py contains:

    class A(object):
    pass

    aModule = A()


    now, let's do:

    current directory:
    [color=blue][color=green][color=darkred]
    >>> import package.module
    >>> type(package.mo dule.aModule)[/color][/color][/color]
    <class 'package.module .A'>[color=blue][color=green][color=darkred]
    >>> isinstance(pack age.module.aMod ule, package.module. A) # so far good[/color][/color][/color]
    1[color=blue][color=green][color=darkred]
    >>> a = package.module. A()
    >>> isinstance(a, package.module. A) # so far good
    >>> import sys
    >>> sys.path.append ('package')
    >>> import module
    >>> a = module.A()
    >>> isinstance(a, package.module. A) # will return 0 !!![/color][/color][/color]
    0[color=blue][color=green][color=darkred]
    >>> isinstance(pack age.module.aMod ule, module.A) # will return 0 !!![/color][/color][/color]
    0[color=blue][color=green][color=darkred]
    >>>[/color][/color][/color]

    how is it possible that it IS important how you imported a class
    definition for isinstance() to work? it's insane!

    --
    fuf (fuf@mageo.cz)

  • Sidharth Kuruvila

    #2
    Re: isinstance() bug


    "Michal Vitecek" <fuf@mageo.cz > wrote in message
    news:mailman.90 7.1075296157.12 720.python-list@python.org ...[color=blue]
    > hello,
    >
    > please consider the following situation:
    >
    > under the current directory there's a subdirectory 'package' with two
    > files: __init__.py and module.py
    >
    > ./package:
    > __init__.py
    > module.py
    >
    > module.py contains:
    >
    > class A(object):
    > pass
    >
    > aModule = A()
    >
    >
    > now, let's do:
    >
    > current directory:
    >[color=green][color=darkred]
    > >>> import package.module
    > >>> type(package.mo dule.aModule)[/color][/color]
    > <class 'package.module .A'>[color=green][color=darkred]
    > >>> isinstance(pack age.module.aMod ule, package.module. A) # so far good[/color][/color]
    > 1[color=green][color=darkred]
    > >>> a = package.module. A()
    > >>> isinstance(a, package.module. A) # so far good
    > >>> import sys
    > >>> sys.path.append ('package')
    > >>> import module
    > >>> a = module.A()
    > >>> isinstance(a, package.module. A) # will return 0 !!![/color][/color]
    > 0[color=green][color=darkred]
    > >>> isinstance(pack age.module.aMod ule, module.A) # will return 0 !!![/color][/color]
    > 0[color=green][color=darkred]
    > >>>[/color][/color]
    >
    > how is it possible that it IS important how you imported a class
    > definition for isinstance() to work? it's insane!
    >
    > --
    > fuf (fuf@mageo.cz)
    >[/color]

    its got to do with how python imports modules.
    both imports are treated as seperate modules because the relative paths are
    diferent.
    python is a dynamic language it figures out where modules are located at run
    time, it would be expensive to check all paths to see if they ended up at
    the same file.


    Comment

    • Skip Montanaro

      #3
      Re: isinstance() bug


      Sidharth> python is a dynamic language it figures out where modules are
      Sidharth> located at run time, it would be expensive to check all paths
      Sidharth> to see if they ended up at the same file.

      Maybe not:

      Help on function abspath in module posixpath:

      abspath(path)
      Return an absolute path.

      Considering all the other stuff import has to do, this seems like only a
      small extra bit of work.

      Skip

      Comment

      • Sidharth Kuruvila

        #4
        Re: isinstance() bug

        i dont know unix.
        how does abs path work with sym-links.



        Comment

        • Sidharth Kuruvila

          #5
          Re: isinstance() bug

          Stupid post must be ignored at all costs

          "Sidharth Kuruvila" <sidharthk@hotm ail.com> wrote in message
          news:bv8qhc$ph1 mk$1@ID-223265.news.uni-berlin.de...[color=blue]
          > i dont know unix.
          > how does abs path work with sym-links.
          >
          >
          >[/color]


          Comment

          • Skip Montanaro

            #6
            Re: isinstance() bug


            Sidharth> i dont know unix.
            Sidharth> how does abs path work with sym-links.

            Not well. Seems that os.path.realpat h does the right thing though:

            % ls -l /etc/rc2.d
            lrwxrwxrwx 1 root root 10 May 21 2002 /etc/rc2.d -> rc.d/rc2.d/
            % python
            Python 2.2.3 (#1, Jun 21 2003, 08:08:22)
            [GCC 3.0.1] on linux2
            Type "help", "copyright" , "credits" or "license" for more information.[color=blue][color=green][color=darkred]
            >>> import os
            >>> os.path.abspath ("/etc/rc2.d")[/color][/color][/color]
            '/etc/rc2.d'[color=blue][color=green][color=darkred]
            >>> os.path.realpat h("/etc/rc2.d")[/color][/color][/color]
            '/etc/rc.d/rc2.d'

            As someone else pointed out, the issue of multiple hard links to the same
            file is a bit tougher nut to crack.

            % cd ~/tmp
            % cat > a.py
            class A: pass
            % ln a.py b.py
            % python
            Python 2.2.3 (#1, Jun 21 2003, 08:08:22)
            [GCC 3.0.1] on linux2
            Type "help", "copyright" , "credits" or "license" for more information.[color=blue][color=green][color=darkred]
            >>> import a
            >>> import b
            >>> a.A == b.A[/color][/color][/color]
            0

            You need to compare inode numbers to see if you have the same or different
            files.
            [color=blue][color=green][color=darkred]
            >>> import stat
            >>> os.stat(a.__fil e__)[stat.ST_INO][/color][/color][/color]
            37041L[color=blue][color=green][color=darkred]
            >>> os.stat(b.__fil e__)[stat.ST_INO][/color][/color][/color]
            37041L

            Skip

            Comment

            • Jeff Epler

              #7
              posixpath.abspa th and symlinks

              On Wed, Jan 28, 2004 at 10:37:39PM +0530, Sidharth Kuruvila wrote:[color=blue]
              > i dont know unix.
              > how does abs path work with sym-links.[/color]


              os.abspath does not check whether any components are symlinks. In the
              presence of symlinks,
              /a/../b
              and
              /b
              can refer to separate files if /a is a symlink to a directory. As far as
              I know, posixpath.abspa th normalizes the first into the second anyway.

              Similarly, if you have a symlink
              /a -> c
              then posixpath.abspa th("a") doesn't return /c, it still returns /a

              You can use os.readlink() on posix systems to get the thing a symlink
              points to:[color=blue][color=green][color=darkred]
              >>> os.readlink("/proc/self")[/color][/color][/color]
              '14717'[color=blue][color=green][color=darkred]
              >>> os.readlink("/")[/color][/color][/color]
              OSError: [Errno 22] Invalid argument: '/'

              Jeff

              Comment

              Working...