Anyone who is a reasonably competent Windows/Python programmer can help me out here. (At least) two functions in the distutils.util module need help: 'mkpath()' and 'move_file()'. Actually, 'mkpath()' might be working fine now, but I'd like some of you Windows folks to take a look at it, beat on it, make sure it'll really work. Here's the code: ------------------------------------------------------------------------ # cache for by mkpath() -- in addition to cheapening redundant calls, # eliminates redundant "creating /foo/bar/baz" messages in dry-run mode PATH_CREATED = {} # I don't use os.makedirs because a) it's new to Python 1.5.2, and # b) it blows up if the directory already exists (I want to silently # succeed in that case). def mkpath (name, mode=0777, verbose=0, dry_run=0): """Create a directory and any missing ancestor directories. If the directory already exists, return silently. Raise DistutilsFileError if unable to create some directory along the way (eg. some sub-path exists, but is a file rather than a directory). If 'verbose' is true, print a one-line summary of each mkdir to stdout.""" global PATH_CREATED # XXX what's the better way to handle verbosity? print as we create # each directory in the path (the current behaviour), or only announce # the creation of the whole path? (quite easy to do the latter since # we're not using a recursive algorithm) name = os.path.normpath (name) if os.path.isdir (name): return if PATH_CREATED.get (name): return (head, tail) = os.path.split (name) tails = [tail] # stack of lone dirs to create while head and tail and not os.path.isdir (head): #print "splitting '%s': " % head, (head, tail) = os.path.split (head) #print "to ('%s','%s')" % (head, tail) tails.insert (0, tail) # push next higher dir onto stack #print "stack of tails:", tails # now 'head' contains the deepest directory that already exists # (that is, the child of 'head' in 'name' is the highest directory # that does *not* exist) for d in tails: #print "head = %s, d = %s: " % (head, d), head = os.path.join (head, d) if PATH_CREATED.get (head): continue if verbose: print "creating", head if not dry_run: try: os.mkdir (head) except os.error, (errno, errstr): raise DistutilsFileError, "%s: %s" % (head, errstr) PATH_CREATED[head] = 1 # mkpath () ------------------------------------------------------------------------ The other one, 'move_file()', almost certainly has portability problems. Please read it, bash on it, and help me fix it! Here's the code for it: ------------------------------------------------------------------------ def move_file (src, dst, verbose=0, dry_run=0): """Move a file 'src' to 'dst'. If 'dst' is a directory, the file will be moved into it with the same name; otherwise, 'src' is just renamed to 'dst'. Return the new full name of the file. Handles cross-device moves on Unix using 'copy_file()'. What about other systems???""" from os.path import exists, isfile, isdir, basename, dirname if verbose: print "moving %s -> %s" % (src, dst) if dry_run: return dst if not isfile (src): raise DistutilsFileError, \ "can't move '%s': not a regular file" % src if isdir (dst): dst = os.path.join (dst, basename (src)) elif exists (dst): raise DistutilsFileError, \ "can't move '%s': destination '%s' already exists" % \ (src, dst) if not isdir (dirname (dst)): raise DistutilsFileError, \ "can't move '%s': destination '%s' not a valid path" % \ (src, dst) copy_it = 0 try: os.rename (src, dst) except os.error, (num, msg): if num == errno.EXDEV: copy_it = 1 else: raise DistutilsFileError, \ "couldn't move '%s' to '%s': %s" % (src, dst, msg) if copy_it: copy_file (src, dst) try: os.unlink (src) except os.error, (num, msg): try: os.unlink (dst) except os.error: pass raise DistutilsFileError, \ ("couldn't move '%s' to '%s' by copy/delete: " + "delete '%s' failed: %s") % \ (src, dst, src, msg) return dst # move_file () ------------------------------------------------------------------------ Thanks! Greg -- Greg Ward - software developer gward@cnri.reston.va.us Corporation for National Research Initiatives 1895 Preston White Drive voice: +1-703-620-8990 Reston, Virginia, USA 20191-5434 fax: +1-703-620-0913
participants (1)
-
Greg Ward