185
187
return dict((k, getattr(obj, k))
186
188
for k in attrnames if not k.startswith('_'))
190
def safe_rmtree(path, ignore_errors=False, onerror=None):
191
"""Recursively delete a directory tree.
193
Copied from shutil.rmtree from Python 2.6, which does not follow symbolic
194
links (it is otherwise unsafe to call as root on untrusted directories; do
195
not use shutil.rmtree in this case, as you may be running Python 2.5).
197
If ignore_errors is set, errors are ignored; otherwise, if onerror
198
is set, it is called to handle the error with arguments (func,
199
path, exc_info) where func is os.listdir, os.remove, or os.rmdir;
200
path is the argument to that function that caused it to fail; and
201
exc_info is a tuple returned by sys.exc_info(). If ignore_errors
202
is false and onerror is None, an exception is raised.
208
elif onerror is None:
212
if os.path.islink(path):
213
# symlinks to directories are forbidden, see bug #1669
214
raise OSError("Cannot call safe_rmtree on a symbolic link")
216
onerror(os.path.islink, path, sys.exc_info())
217
# can't continue even if onerror hook returns
221
names = os.listdir(path)
222
except os.error, err:
223
onerror(os.listdir, path, sys.exc_info())
225
fullname = os.path.join(path, name)
227
mode = os.lstat(fullname).st_mode
230
if stat.S_ISDIR(mode):
231
safe_rmtree(fullname, ignore_errors, onerror)
235
except os.error, err:
236
onerror(os.remove, fullname, sys.exc_info())
240
onerror(os.rmdir, path, sys.exc_info())