Copy a file 'src' to 'dst'. If 'dst' is a directory, then 'src' is copied there with the same name; otherwise, it must be a filename. (If the file exists, it will be ruthlessly clobbered.) If 'preserve_mode' is true (the default), the file's mode (type and permission bits, or
(src, dst, preserve_mode=1, preserve_times=1, update=0,
link=None, verbose=1, dry_run=0)
| 65 | fsrc.close() |
| 66 | |
| 67 | def copy_file(src, dst, preserve_mode=1, preserve_times=1, update=0, |
| 68 | link=None, verbose=1, dry_run=0): |
| 69 | """Copy a file 'src' to 'dst'. If 'dst' is a directory, then 'src' is |
| 70 | copied there with the same name; otherwise, it must be a filename. (If |
| 71 | the file exists, it will be ruthlessly clobbered.) If 'preserve_mode' |
| 72 | is true (the default), the file's mode (type and permission bits, or |
| 73 | whatever is analogous on the current platform) is copied. If |
| 74 | 'preserve_times' is true (the default), the last-modified and |
| 75 | last-access times are copied as well. If 'update' is true, 'src' will |
| 76 | only be copied if 'dst' does not exist, or if 'dst' does exist but is |
| 77 | older than 'src'. |
| 78 | |
| 79 | 'link' allows you to make hard links (os.link) or symbolic links |
| 80 | (os.symlink) instead of copying: set it to "hard" or "sym"; if it is |
| 81 | None (the default), files are copied. Don't set 'link' on systems that |
| 82 | don't support it: 'copy_file()' doesn't check if hard or symbolic |
| 83 | linking is available. If hardlink fails, falls back to |
| 84 | _copy_file_contents(). |
| 85 | |
| 86 | Under Mac OS, uses the native file copy function in macostools; on |
| 87 | other systems, uses '_copy_file_contents()' to copy file contents. |
| 88 | |
| 89 | Return a tuple (dest_name, copied): 'dest_name' is the actual name of |
| 90 | the output file, and 'copied' is true if the file was copied (or would |
| 91 | have been copied, if 'dry_run' true). |
| 92 | """ |
| 93 | # XXX if the destination file already exists, we clobber it if |
| 94 | # copying, but blow up if linking. Hmmm. And I don't know what |
| 95 | # macostools.copyfile() does. Should definitely be consistent, and |
| 96 | # should probably blow up if destination exists and we would be |
| 97 | # changing it (ie. it's not already a hard/soft link to src OR |
| 98 | # (not update) and (src newer than dst). |
| 99 | |
| 100 | from distutils.dep_util import newer |
| 101 | from stat import ST_ATIME, ST_MTIME, ST_MODE, S_IMODE |
| 102 | |
| 103 | if not os.path.isfile(src): |
| 104 | raise DistutilsFileError( |
| 105 | "can't copy '%s': doesn't exist or not a regular file" % src) |
| 106 | |
| 107 | if os.path.isdir(dst): |
| 108 | dir = dst |
| 109 | dst = os.path.join(dst, os.path.basename(src)) |
| 110 | else: |
| 111 | dir = os.path.dirname(dst) |
| 112 | |
| 113 | if update and not newer(src, dst): |
| 114 | if verbose >= 1: |
| 115 | log.debug("not copying %s (output up-to-date)", src) |
| 116 | return (dst, 0) |
| 117 | |
| 118 | try: |
| 119 | action = _copy_action[link] |
| 120 | except KeyError: |
| 121 | raise ValueError("invalid value '%s' for 'link' argument" % link) |
| 122 | |
| 123 | if verbose >= 1: |
| 124 | if os.path.basename(dst) == os.path.basename(src): |