tags:

views:

294

answers:

4

Hi,

How can I check whether two file paths point to the same file in Python?

+3  A: 

You want to use os.path.abspath(path) to normalize each path for comparison.

os.path.abspath(foo) == os.path.abspath(bar)
Andrew Hare
+2  A: 

A simple string compare should work:

import os
print os.path.abspath(first) == os.path.abspath(second)

Credit to Andrew, he corrected my initial post which included a call to os.path.normpath: this is unneeded because the implementation of os.path.abspath does it for you.

jkp
You don't need to call `normpath` first.
Andrew Hare
Andrew: if you were just going to compare the strings you may end up with different paths pointing to the same file in some cases. os.abspath doesnt do anything clever, it only adds a prefix.
jkp
@Andrew: no i take it back! You were right, for *nix at least the implementation does that for you. Every day is a schoolday :)
jkp
I disagree, from http://docs.python.org/library/os.path.html: Return a normalized absolutized version of the pathname path. On most platforms, this is equivalent to normpath(join(os.getcwd(), path)).
Andrew Hare
@jkp - Haha!! No worries - I live and learn as well! :)
Andrew Hare
+13  A: 
$ touch foo
$ ln -s foo bar
$ python
Python 2.5.1 (r251:54863, Feb  6 2009, 19:02:12) 
[GCC 4.0.1 (Apple Inc. build 5465)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> help(os.path.samefile)
Help on function samefile in module posixpath:

samefile(f1, f2)
    Test whether two pathnames reference the same actual file

>>> os.path.samefile("foo", "bar")
True
Stefano Borini
Nice answer. I didn not know about this method!
jkp
Note that this is documented as only available on Unix. It is not present on Windows, at least in Python 2.6.
Weeble
A: 

On Windows systems, there is no samefile function and you also have to worry about case. The normcase function from os.path can be combined with abspath to handle this case.

from os.path import abspath, normcase

def are_paths_equivalent(path1, path2):
    return normcase(abspath(path1)) == normcase(abspath(path2))

This will consider "C:\SPAM\Eggs.txt" to be equivalent to "c:\spam\eggs.txt" on Windows.

Note that unlike samefile, all methods based on normalizing and comparing paths will not be aware of cases where completely different paths refer to the same file. On Windows, this means that if you use SUBST, MKLINK or mounted network shares to create multiple distinct paths to the same file, none of these solutions will be able to say "that's the same file". Hopefully that's not too much of a problem most of the time.

Weeble