From: Gelonida on 11 Jul 2010 09:37 Hi, I wanted to figure out whether a given path name is below another path name. Surprisingly this turned out to be more difficult than initially anticipated: Let's assume I want to find out, whether path1 is below path2 First I thought about checking whether path1 starts with path2 For this I had to - convert path1 / path2 to absolute paths - I had to normalize the path name Further this would still fail for path1='/tmp/dir11' and path2='/tmp/dir1' next option would be to split both absolute and normalized paths by os.sep and check whether the path2's split list starts with path1's split list. That should work but is also not really nice. finally I came up with: ################################################# import os def is_below_dir(fname,topdir): relpath = os.path.relpath(fname,topdir) return not relpath.startswith('..'+os.sep) print is_below_dir(path1,path2) ################################################# The basic idea is, if the path name of path1 relative to path2 does NOT start with '..', then it must be below path2 Does anybody see pitfalls with that solution? Is there by any chance a function, that I overlooked, which does already what I'd like to do?
From: Thomas Jollans on 11 Jul 2010 09:52 On 07/11/2010 03:37 PM, Gelonida wrote: > ################################################# > import os > def is_below_dir(fname,topdir): > relpath = os.path.relpath(fname,topdir) > return not relpath.startswith('..'+os.sep) > > print is_below_dir(path1,path2) > ################################################# > The basic idea is, if the path name of path1 > relative to path2 does NOT start with '..', then > it must be below path2 > > > Does anybody see pitfalls with that solution? > Is there by any chance a function, that I overlooked, > which does already what I'd like to do? It probably won't work on Windows because it isolates volumes (drive letters). What does, for example, os.path.relpath do when you pass r'c:\foo\bar', r'y:\drive\letters\are\silly' ? I see two reasonably correct options: either raise an exception (there is no relative path) or return the absolute path, which doesn't start with .. On UNIX, the only potential problem I see is that it may or may not do what you expect when symlinks are involved somewhere.
From: Gelonida on 11 Jul 2010 10:34 Hi Thomas, Thomas Jollans wrote: > On 07/11/2010 03:37 PM, Gelonida wrote: >> ################################################# >> import os >> def is_below_dir(fname,topdir): >> relpath = os.path.relpath(fname,topdir) >> return not relpath.startswith('..'+os.sep) >> >> print is_below_dir(path1,path2) >> ################################################# >> The basic idea is, if the path name of path1 >> relative to path2 does NOT start with '..', then >> it must be below path2 >> >> >> Does anybody see pitfalls with that solution? >> Is there by any chance a function, that I overlooked, >> which does already what I'd like to do? > > It probably won't work on Windows because it isolates volumes (drive > letters). What does, for example, os.path.relpath do when > you pass r'c:\foo\bar', r'y:\drive\letters\are\silly' ? I see two > reasonably correct options: Thanks, Indeed. different drives raise an ecception. I could catch the ValueError and let it just return False > > either raise an exception (there is no relative path) or return the > absolute path, which doesn't start with .. > > On UNIX, the only potential problem I see is that it may or may not do > what you expect when symlinks are involved somewhere. Also true. In my case I'd prefer it would not follow, but it doesn't really matter. So my function in order to be portable had now to look like: ################################################# import os def is_below_dir(fname,topdir): try: relpath = os.path.relpath(fname,topdir) except ValueError: return False return not relpath.startswith('..'+os.sep) print is_below_dir(path1,path2) ################################################# if I wanted to folow symlinks, then had to apply os.path.realpath() on fname AND on topdir
|
Pages: 1 Prev: getting the variable type Next: I wish for a tool named "2to6". |