def test_copy_file_hard_link(self):
with open(self.source, 'w') as f:
f.write('some content')
st = os.stat(self.source)
copy_file(self.source, self.target, link='hard')
st2 = os.stat(self.source)
st3 = os.stat(self.target)
self.assertTrue(os.path.samestat(st, st2), (st, st2))
self.assertTrue(os.path.samestat(st2, st3), (st2, st3))
with open(self.source, 'r') as f:
self.assertEqual(f.read(), 'some content')
python类copy_file()的实例源码
def copydir_run_2to3(src, dest, template=None, fixer_names=None,
options=None, explicit=None):
"""Recursively copy a directory, only copying new and changed files,
running run_2to3 over all newly copied Python modules afterward.
If you give a template string, it's parsed like a MANIFEST.in.
"""
from distutils.dir_util import mkpath
from distutils.file_util import copy_file
from distutils.filelist import FileList
filelist = FileList()
curdir = os.getcwd()
os.chdir(src)
try:
filelist.findall()
finally:
os.chdir(curdir)
filelist.files[:] = filelist.allfiles
if template:
for line in template.splitlines():
line = line.strip()
if not line: continue
filelist.process_template_line(line)
copied = []
for filename in filelist.files:
outname = os.path.join(dest, filename)
mkpath(os.path.dirname(outname))
res = copy_file(os.path.join(src, filename), outname, update=1)
if res[1]: copied.append(outname)
run_2to3([fn for fn in copied if fn.lower().endswith('.py')],
fixer_names=fixer_names, options=options, explicit=explicit)
return copied
def copy_file(self, infile, outfile,
preserve_mode=1, preserve_times=1, link=None, level=1):
"""Copy a file respecting verbose, dry-run and force flags. (The
former two default to whatever is in the Distribution object, and
the latter defaults to false for commands that don't define it.)"""
return file_util.copy_file(
infile, outfile,
preserve_mode, preserve_times,
not self.force,
link,
dry_run=self.dry_run)
def _copy_files(self, filelist):
self.outfiles = []
if not filelist:
return
self.mkpath(self.install_dir)
for f in filelist:
self.copy_file(f, self.install_dir)
self.outfiles.append(os.path.join(self.install_dir, f))
def copy_file(self, infile, outfile,
preserve_mode=1, preserve_times=1, link=None, level=1):
"""Copy a file respecting verbose, dry-run and force flags. (The
former two default to whatever is in the Distribution object, and
the latter defaults to false for commands that don't define it.)"""
return file_util.copy_file(
infile, outfile,
preserve_mode, preserve_times,
not self.force,
link,
dry_run=self.dry_run)
def _copy_files(self, filelist):
self.outfiles = []
if not filelist:
return
self.mkpath(self.install_dir)
for f in filelist:
self.copy_file(f, self.install_dir)
self.outfiles.append(os.path.join(self.install_dir, f))
def copy_file(self, infile, outfile, preserve_mode=1, preserve_times=1,
link=None, level=1):
"""Copy a file respecting verbose, dry-run and force flags. (The
former two default to whatever is in the Distribution object, and
the latter defaults to false for commands that don't define it.)"""
return file_util.copy_file(infile, outfile, preserve_mode,
preserve_times, not self.force, link,
dry_run=self.dry_run)
def _copy_files(self, filelist):
self.outfiles = []
if not filelist:
return
self.mkpath(self.install_dir)
for f in filelist:
self.copy_file(f, self.install_dir)
self.outfiles.append(os.path.join(self.install_dir, f))
def copydir_run_2to3(src, dest, template=None, fixer_names=None,
options=None, explicit=None):
"""Recursively copy a directory, only copying new and changed files,
running run_2to3 over all newly copied Python modules afterward.
If you give a template string, it's parsed like a MANIFEST.in.
"""
from distutils.dir_util import mkpath
from distutils.file_util import copy_file
from distutils.filelist import FileList
filelist = FileList()
curdir = os.getcwd()
os.chdir(src)
try:
filelist.findall()
finally:
os.chdir(curdir)
filelist.files[:] = filelist.allfiles
if template:
for line in template.splitlines():
line = line.strip()
if not line: continue
filelist.process_template_line(line)
copied = []
for filename in filelist.files:
outname = os.path.join(dest, filename)
mkpath(os.path.dirname(outname))
res = copy_file(os.path.join(src, filename), outname, update=1)
if res[1]: copied.append(outname)
run_2to3([fn for fn in copied if fn.lower().endswith('.py')],
fixer_names=fixer_names, options=options, explicit=explicit)
return copied
def run(self):
self.mkpath(self.install_dir)
for f in self.data_files:
dir, files = f
dir = util.convert_path(dir)
if not os.path.isabs(dir):
dir = os.path.join(self.install_dir, dir)
elif self.root:
dir = change_root(self.root, dir)
self.mkpath(dir)
if not files:
self.outfiles.append(dir)
else:
for file in files:
if isinstance(file, six.string_types):
infile = file
outfile = os.path.join(dir,
os.path.basename(file))
else:
infile, outfile = file
infile = util.convert_path(infile)
outfile = util.convert_path(outfile)
if os.path.sep not in outfile:
outfile = os.path.join(dir,
outfile)
self.copy_file(infile, outfile)
self.outfiles.append(outfile)
def run(self):
dest_file = os.path.join(self.dest, os.path.basename(self.file))
ret = self.copy_file(self.file, dest_file)
os.chmod(dest_file, self.mode)
os.utime(dest_file, None)
return ret
def setup_python3():
# Taken from "distribute" setup.py
from distutils.filelist import FileList
from distutils import dir_util, file_util, util, log
from os.path import join, exists
tmp_src = join("build", "src")
# Not covered by "setup.py clean --all", so explicit deletion required.
if exists(tmp_src):
dir_util.remove_tree(tmp_src)
# log.set_verbosity(1)
fl = FileList()
for line in open("MANIFEST.in"):
if not line.strip():
continue
fl.process_template_line(line)
dir_util.create_tree(tmp_src, fl.files)
outfiles_2to3 = []
for f in fl.files:
outf, copied = file_util.copy_file(f, join(tmp_src, f), update=1)
if copied and outf.endswith(".py"):
outfiles_2to3.append(outf)
util.run_2to3(outfiles_2to3)
# arrange setup to use the copy
sys.path.insert(0, tmp_src)
return tmp_src
def run(self):
"""At the end of the install function, we need to rename some
files because distutils provides no way to rename files as they
are placed in their install locations.
"""
_install.run(self)
for o_src, o_dest in hardlink_modules:
for e in [".py", ".pyc"]:
src = util.change_root(self.root_dir, o_src + e)
dest = util.change_root(
self.root_dir, o_dest + e)
if ostype == "posix":
if os.path.exists(dest) and \
os.stat(src)[stat.ST_INO] != \
os.stat(dest)[stat.ST_INO]:
os.remove(dest)
file_util.copy_file(src, dest,
link="hard", update=1)
else:
file_util.copy_file(src, dest, update=1)
# XXX Uncomment it when we need to deliver python 3.4 version
# of modules.
# Don't install the scripts for python 3.4.
if py_version == '3.4':
return
for d, files in six.iteritems(scripts[osname]):
for (srcname, dstname) in files:
dst_dir = util.change_root(self.root_dir, d)
dst_path = util.change_root(self.root_dir,
os.path.join(d, dstname))
dir_util.mkpath(dst_dir, verbose=True)
file_util.copy_file(srcname, dst_path,
update=True)
# make scripts executable
os.chmod(dst_path,
os.stat(dst_path).st_mode
| stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)
for target, o_dest in symlink_modules:
dest = util.change_root(self.root_dir, o_dest)
dir_util.mkpath(os.path.dirname(dest), verbose=True)
try:
os.unlink(dest)
except Exception:
pass
os.symlink(target, dest)
def copy_file(self, infile, outfile, preserve_mode=1, preserve_times=1,
link=None, level=1):
# If the timestamp on the source file (coming from mercurial if
# unchanged, or from the filesystem if changed) doesn't match
# the filesystem timestamp on the destination, then force the
# copy to make sure the right data is in place.
try:
dst_mtime = os.stat(outfile).st_mtime
except OSError as e:
if e.errno != errno.ENOENT:
raise
dst_mtime = time.time()
# The timestamp for __init__.py is the timestamp for the
# workspace itself.
if outfile.endswith("/pkg/__init__.py"):
src_mtime = self.timestamps[b"."]
else:
src_mtime = self.timestamps.get(
os.path.join("src", infile), self.timestamps[b"."])
# Force a copy of the file if the source timestamp is different
# from that of the destination, not just if it's newer. This
# allows timestamps in the working directory to regress (for
# instance, following the reversion of a change).
if dst_mtime != src_mtime:
f = self.force
self.force = True
dst, copied = _build_py.copy_file(self, infile, outfile,
preserve_mode, preserve_times, link, level)
self.force = f
else:
dst, copied = outfile, 0
# If we copied the file, then we need to go and readjust the
# timestamp on the file to match what we have in our database.
# Save the filename aside for our version of install_lib.
if copied and dst.endswith(".py"):
os.utime(dst, (src_mtime, src_mtime))
self.copied.append(dst)
return dst, copied