97
95
return tuple(splitpath)
99
def relpath(path, start=os.path.curdir):
100
"""Return a relative version of a path.
101
XXX Backported from Python 2.6 posixpath.py.
105
raise ValueError("no path specified")
107
start_list = os.path.abspath(start).split(os.path.sep)
108
path_list = os.path.abspath(path).split(os.path.sep)
110
# Work out how much of the filepath is shared by start and path.
111
i = len(os.path.commonprefix([start_list, path_list]))
113
rel_list = [os.path.pardir] * (len(start_list)-i) + path_list[i:]
115
return os.path.curdir
116
return os.path.join(*rel_list)
118
97
def incomplete_utf8_sequence(byteseq):
119
98
"""Calculate the completeness of a UTF-8 encoded string.
206
185
return dict((k, getattr(obj, k))
207
186
for k in attrnames if not k.startswith('_'))
209
def safe_rmtree(path, ignore_errors=False, onerror=None):
210
"""Recursively delete a directory tree.
212
Copied from shutil.rmtree from Python 2.6, which does not follow symbolic
213
links (it is otherwise unsafe to call as root on untrusted directories; do
214
not use shutil.rmtree in this case, as you may be running Python 2.5).
216
If ignore_errors is set, errors are ignored; otherwise, if onerror
217
is set, it is called to handle the error with arguments (func,
218
path, exc_info) where func is os.listdir, os.remove, or os.rmdir;
219
path is the argument to that function that caused it to fail; and
220
exc_info is a tuple returned by sys.exc_info(). If ignore_errors
221
is false and onerror is None, an exception is raised.
227
elif onerror is None:
231
if os.path.islink(path):
232
# symlinks to directories are forbidden, see bug #1669
233
raise OSError("Cannot call safe_rmtree on a symbolic link")
235
onerror(os.path.islink, path, sys.exc_info())
236
# can't continue even if onerror hook returns
240
names = os.listdir(path)
241
except os.error, err:
242
onerror(os.listdir, path, sys.exc_info())
244
fullname = os.path.join(path, name)
246
mode = os.lstat(fullname).st_mode
249
if stat.S_ISDIR(mode):
250
safe_rmtree(fullname, ignore_errors, onerror)
254
except os.error, err:
255
onerror(os.remove, fullname, sys.exc_info())
259
onerror(os.rmdir, path, sys.exc_info())