isinstance() bug

Jeff Epler jepler at unpythonic.net
Thu Jan 29 12:00:38 EST 2004


On Wed, Jan 28, 2004 at 09:08:00PM +0100, Michs Vitecek wrote:
> On Wed, 28 Jan 2004 11:32:19 -0600 Skip Montanaro <skip at pobox.com> wrote:
> >You need to compare inode numbers to see if you have the same or different
> >files. 
> >
> >    >>> import stat
> >    >>> os.stat(a.__file__)[stat.ST_INO]
> >    37041L
> >    >>> os.stat(b.__file__)[stat.ST_INO]
> >    37041L
> >
> 
> this could also be used to verify whether the imported module, class etc. 
> comes from the same file without messing with the absolute path and 
> problems related to it. really a good idea, Skip.

I'd have to come out on the -1 side.

First, because it adds complications to the interpreter simply to notify
a programmer of an avoidable problem that should be caught by testing.

Second, I'm not convinced that you won't create some other kind of
problem through cleverness.  For instance, it's perfectly legitimate to
use module-level variables to hold state, and it's perfectly legitimate
for two packages to both contain the same sub-package (for instance, of
modules A and B both use the same non-standard module, they can bundle
it inside their respective namespaces).  But on systems with a small
read-only filesystem, it's also perfectly legitimate to make these two
copies of the same file actually hard-links to the same file.  You've
just broken this arrangement.

Third, I'm not convinced that using inode numbers is guaranteed to work.
In Unix, it at least needs to be the tuple (inode, device), because the
same inode number can appear on multiple devices.  Are you sure that
Python will *never* encounter a system with a bug or limitation that can
make two different files return the same inode number from os.stat()?
(for instance, if an NFS server uses a 64-bit-inode filesystem but must
generate 32-bit inodes for clients because of NFS protocol limitations;
or if a filesystem doesn't really have the concept of an inode number,
like FAT/VFAT filesystems)

Fourth, what is the "inode" or "device" of a module loaded from a ZIP
archive (possible in Python today), or from a URL (possible with the
right import hook, though probably a bad idea)?

Fifth, will it work right if the 'a.m' and 'm' refer to the same file,
but the sequence of actions look like this in the interactive console:

>>> import a.m
# edit m.py in an editor, save
>>> import m

The editor session might change the inode of m.py, meaning that m is not
a.m.  Or, if not, then it will see that a.m is the same as m, so the
imported m will not contain the changes from the editor session.

Sixth, will it work right in the presence of reload()?

>>> import a.m
>>> import m
# edit m.py here, and assume there is no inode number change
>>> reload(a.m)

Is m reloaded too?  What is "correct" in this case?

So I guess that makes me at least -6 if I get a vote for each problem
I can imagine.

Jeff




More information about the Python-list mailing list