0

System: Python 2.6 on Windows 7 64 bit

Recently I did a lot of path formatting in Python. Since the string modifications are always dangerous I started to do it the proper way by using the 'os.path' module.

The first question is if this is the right way to to handle incoming paths? Or can I somehow optimize this?

sCleanPath = sRawPath.replace('\n', '')
sCleanPath = sCleanPath.replace('\\', '/')
sCleanPythonPath = os.path.normpath(sCleanPath)

For formatting the 'sCleanPythonPath' now I use only functions from the 'os.path' module. This works very nice and I didn't had any problems so far.

There is only one exception. I have to change paths so they point not longer on a network storage but on a local drive. Is started to use 'os.path.splitunc()' in conjunction with 'os.path.join()'.

aUncSplit = os.path.splitunc(sCleanPythonUncPath)
sLocalDrive = os.path.normpath('X:/mount')
sCleanPythonLocalPath = (os.path.join(sLocalDrive, aUncSplit[1]))

Unfortunately this doesn't work due to the nature of how absolute paths are handled using 'os.path.join()'. All the solutions I found in the web are using string replacements again which I want to avoid by using the 'os.path' module. Have I overseen anything? Is there another, maybe a better way to do this?

All comments on this are very welcome!

Mr. Dice
  • 61
  • 2
  • 7
  • What are you getting with os.path.join and what do would you like to get? I dont see what you need to use regex for. – Mahdi Yusuf Feb 07 '13 at 19:33
  • @myusuf3: Let's say `sCleanPythonUncPath` is `//host/mount/folder/file.ext` then I would like to get `X:/mount/folder/file.ext`. Unfortunately `os.path.join()` only returns `/folder/file.ext`, because it handles it like an absolute path. What regex calls do you mean? The calls of `replace()`? – Mr. Dice Feb 07 '13 at 19:44
  • Sometimes ``\`` is valid as in ``C:\Program\ Files`` to be careful and always check. – sotapme Feb 07 '13 at 19:50
  • So would I do the replacement of the backslashes with a regular expression which excludes escape characters? – Mr. Dice Feb 07 '13 at 20:17

1 Answers1

0

You could optimize the first part slightly by removing the replace() call because on Windows normpath() converts forward slashes to backward slashes:

sCleanPath = sRawPath.replace('\n', '')
sCleanPythonPath = os.path.normpath(sCleanPath)

Here's something that would make the second part of your question work without doing a string replacement:

sSharedFolder = os.path.relpath(os.path.splitunc(sCleanPythonUncPath)[1], os.sep)
sLocalDrive = os.path.normpath('X:/mount')  # why not hardcode the result?
sCleanPythonLocalPath = os.path.join(sLocalDrive, sSharedFolder)
martineau
  • 119,623
  • 25
  • 170
  • 301
  • This is a very smart approach. Unfortunately it returns `X:\mount\..\testfolder\version\file.ext` for `sCleanPythonLocalPath` on my side. I have to play around with it a little more. The `replace()` call is meant to handle paths with the typical windows structure like `C:\mount\folder\..`. I just realized that it doesn't work on escape character like combination which you can see in the following example `C:\mount\testfolder\version\newfile.ext`. I guess I have to go with regular expressions if I want to cover all occurrences. – Mr. Dice Feb 07 '13 at 22:21
  • Works fine for me with `'\\host\mount\folder\file.ext'`. Make sure you've got the `os.path.relpath()` call right (it needs the second parameter passed to it). – martineau Feb 07 '13 at 22:51
  • Yeah, I use the call in the right way. I just copied and pasted your example. I send `\folder\file.ext` and get `..\folder\file.ext` back. – Mr. Dice Feb 07 '13 at 23:29
  • `>>> os.path.relpath(r'\folder\file.ext', os.sep)` returns `'folder\\file.ext'` on my Windows system. – martineau Feb 07 '13 at 23:56
  • Which version of Python are you using? With 2.7.3 I get the same result like you, but with 2.6.4 I get the leading '..\'. – Mr. Dice Feb 08 '13 at 00:12
  • Oops, sorry, I am using 2.7.3 and forgot about what you said in your question -- even so, I'm surprised it matters. They must have fixed a bug since the function was first introduced in version 2.6. If you can't upgrade for some reason, perhaps you could just replace the `ntpath` module you have with version 2.7.3's. – martineau Feb 08 '13 at 00:56
  • The source for v2.7.3's `ntpath.py` is [here](http://hg.python.org/cpython/file/18a3528f661d/Lib/ntpath.py). – martineau Feb 08 '13 at 01:09
  • I think I found the [2.7 patch](http://bugs.python.org/issue5117) that changed/fixed it. – martineau Feb 08 '13 at 01:29