/[thuban]/branches/WIP-pyshapelib-bramz/Thuban/Lib/fileutil.py
ViewVC logotype

Annotation of /branches/WIP-pyshapelib-bramz/Thuban/Lib/fileutil.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 339 - (hide annotations)
Fri Sep 20 17:27:36 2002 UTC (22 years, 5 months ago) by bh
Original Path: trunk/thuban/Thuban/Lib/fileutil.py
File MIME type: text/x-python
File size: 6435 byte(s)
Fixup some whitespace and typos

1 bh 339 # Copyright (c) 2001, 2002 by Intevation GmbH
2 bh 6 # Authors:
3     # Bernhard Herzog <[email protected]>
4     #
5     # This program is free software under the GPL (>=v2)
6     # Read the file COPYING coming with Thuban for details.
7    
8     """
9     Functions to deal with filenames
10     """
11    
12     __version__ = "$Revision$"
13    
14     import os.path
15     from string import split, join
16    
17    
18     def relative_filename_common(dir, absname, sep):
19     """Return a filename relative to dir for the absolute file name absname.
20     This is part the posix and nt versions have in common. Both dir and
21     absname are assumed to be normalized (as done with os.normpath)
22     absolute filenames without drive letters. sep is the platform
23     specific directory separator.
24     """
25    
26     # split the filenames into their components. remove the first item
27     # since it will be always empty because both names are absolute.
28     dir_parts = split(dir, sep)[1:]
29     absname_parts = split(absname, sep)[1:]
30    
31     # count the number of common parts at the start of dir_parts and
32     # absname_parts
33     max_common = min(len(dir_parts), len(absname_parts))
34     common = 0
35     while common < max_common and dir_parts[common] == absname_parts[common]:
36     common = common + 1
37    
38     # If the common part is the root directory, return absname
39     if common == 0:
40     return absname
41    
42     # for each directory under the common part prepend a '..'.
43     rel_parts = (len(dir_parts) - common) * ['..'] + absname_parts[common:]
44     return join(rel_parts, sep)
45    
46    
47     def relative_filename_posix(dir, absname):
48     """Return a filename relative to dir for the absolute file name absname.
49    
50     If absname is already a relative filename, return it unchanged. If
51     the common directory of dir and absname is /, return absname
52     unchanged. If dir is not an absolute name, raise TypeError.
53    
54     This is the posix specific version of relative_filename.
55    
56     Example:
57     >>> from fileutil import relative_filename_posix
58     >>> relative_filename_posix("/usr/local/lib/", "/usr/local/lib/python")
59     'python'
60     >>> relative_filename_posix("/usr/local/lib/", "/usr/local/bin/python")
61     '../bin/python'
62     >>> relative_filename_posix("/usr/local/lib/", "/usr/bin/python")
63     '../../bin/python'
64     >>> relative_filename_posix("/usr/local/lib/", "/var/spool/mail")
65     '/var/spool/mail'
66     >>> relative_filename_posix("/home/", "xyzzy")
67     'xyzzy'
68     >>> relative_filename_posix("home/", "/xyzzy")
69     Traceback (most recent call last):
70     File "<stdin>", line 1, in ?
71     File "fileutil.py", line 42, in relative_filename_posix
72     raise TypeError("first argument must be an absolute filename")
73     TypeError: first argument must be an absolute filename
74     """
75     # for posix, the common part does exactly what we need, except for
76     # the special cases and input checking. Import posixpath explicitly
77     # for that to faciliate testing
78     import posixpath
79     if not posixpath.isabs(absname):
80 bh 339 return absname
81 bh 6
82     if not posixpath.isabs(dir):
83     raise TypeError("first argument must be an absolute filename")
84    
85     dir = posixpath.normpath(dir)
86     absname = posixpath.normpath(absname)
87    
88     return relative_filename_common(dir, absname, "/")
89    
90     def relative_filename_nt(dir, absname):
91     r"""Return a filename relative to dir for the absolute file name absname.
92    
93     If absname is already a relative filename or if dir and absname are
94     on different drives, return absname. If the common directory of dir
95     and absname is the drive's root directory, return absname. If dir is
96     not an absolute name or either name doesn't have a drive letter,
97     raise TypeError.
98    
99     This is the nt specific version of relative_filename.
100    
101     Example:
102     >>> from fileutil import relative_filename_nt
103     >>> relative_filename_nt(r"C:\Programme\Python", r"C:\Programme\Thuban")
104     '..\\Thuban'
105     >>> relative_filename_nt(r"C:\Programme\Python", r"D:\Programme\Thuban")
106     'D:\\Programme\\Thuban'
107     >>> relative_filename_nt(r"C:\Programme\Python", r"C:Programme")
108     'C:Programme'
109     >>> relative_filename_nt(r"C:Programme\Python", r"C:Programme")
110     Traceback (most recent call last):
111     File "<stdin>", line 1, in ?
112     File "fileutil.py", line 123, in relative_filename_nt
113     raise TypeError("first argument must be an absolute filename")
114     TypeError: first argument must be an absolute filename
115     >>> relative_filename_nt(r"\Programme\Python", r"\Programme")
116     Traceback (most recent call last):
117     File "<stdin>", line 1, in ?
118     File "fileutil.py", line 120, in relative_filename_nt
119     raise TypeError("Both parameters must have a drive letter")
120     TypeError: Both parameters must have a drive letter
121     """
122     # first check the parameters. Imort ntpath directly to facilitate
123     # testing on non-nt systems.
124     import ntpath
125    
126     dir = ntpath.normpath(dir)
127     absname = ntpath.normpath(absname)
128    
129     dir_drive, dir_rest = ntpath.splitdrive(dir)
130     absname_drive, absname_rest = ntpath.splitdrive(absname)
131     #print dir_drive, dir_rest
132     #print absname_drive, absname_rest
133     if not dir_drive or not absname_drive:
134     raise TypeError("Both parameters must have a drive letter")
135    
136     if not ntpath.isabs(dir_rest):
137     raise TypeError("first argument must be an absolute filename")
138    
139     # handle some special cases
140     if not ntpath.isabs(absname_rest):
141 bh 339 return absname
142 bh 6
143     if dir_drive != absname_drive:
144     return absname
145    
146     # Now both dir_rest and absname_rest are absolute filenames without
147     # drive letter. We can now use the common part to determine the
148     # relative name
149     return relative_filename_common(dir_rest, absname_rest, "\\")
150    
151    
152 bh 339 # bind the appropriate version of relative_filename for the platform
153     # we're currently running on.
154 bh 6 if os.name == "posix":
155     relative_filename = relative_filename_posix
156     elif os.name == "nt":
157     relative_filename = relative_filename_nt
158     else:
159     raise RuntimeError("No implementation of relative_filename"
160     " available for platform" + os.name)
161    
162     __test__ = {"relative_filename_posix": relative_filename_posix,
163     "relative_filename_nt": relative_filename_nt}
164    
165     # if run as a script, run doctest
166     def _test():
167     import doctest, fileutil
168     # Pass an isprivate function that always returns true so that only
169     # items in __test__ are tested
170     return doctest.testmod(fileutil, isprivate = lambda *args: 1)
171    
172     if __name__ == "__main__":
173     _test()

Properties

Name Value
svn:eol-style native
svn:keywords Author Date Id Revision

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26