views:

140

answers:

3

Is there a simple way to get the "real" case sensitive path from a all lower case path. Like the reverse of os.path.normcase.

For example, consider the directory:

c:\StackOverFlow

If I have the following snippet, how to obtain d_real?

>>> import os
>>> d = os.path.normcase('C:\\StackOverFlow') # convert to lower case
>>> d
'c:\\stackoverflow'
>>> d_real = ... # should give 'C:\StackOverFlow' with the correct case
A: 

Dirty hack approach,

import glob
...
if os.path.exists(d):
    d_real = glob.glob(d + '*')[0][:len(d)]
Nick D
glob.glob(d+'*') returns an empty list on Windows (at least for me)
jhwist
@jhwist, I tested it on Windows and it works. What did you use for `d`?
Nick D
Hmmm, could be some mixup of cygwin-style paths, my `d = "c:/existing_file"`
jhwist
+1  A: 

Hi,
I wouldn't consider this solution simple, but what you can to is:

import os
d = os.path.normcase('C:\\StackOverFlow')
files = os.listdir(os.path.dirname(d))
for f in files:
  if not d.endswith(f.lower()):
    continue
  else
    real_d = os.path.join(os.path.dirname(d), f)

It's probably not efficient (depending on the number of files in the directory). It needs tweaking for the path-components (my solution really only corrects the case of the file name and doesn't care about the directory names). Also, maybe os.walk could be helpful to traverse down the tree.

jhwist
A: 

Definitely ugly, but fun:

def getRealDirPath(path):
    try:
        open(path)
    except IOError, e:
        return str(e).split("'")[-2]

Of course:

  • works only with dirs
  • will be buggy if dir cannot be open for another reason

But can still be useful if you don't need it for "life or death" kind of code.

Tried to grep the standard lib to find how they found the real path but couldn't find it. Must be in C.

That was the dirty hack of the day, next time we will use a regexp on the stacktrace just because we can :-)

e-satis