No os.copy()? Why not?

Steve Howell showell30 at yahoo.com
Wed Apr 4 11:15:54 EDT 2012


On Apr 4, 1:37 am, Chris Angelico <ros... at gmail.com> wrote:
> On Wed, Apr 4, 2012 at 3:53 PM, Steven D'Aprano
>
> <steve+comp.lang.pyt... at pearwood.info> wrote:
> > On Tue, 03 Apr 2012 15:46:31 -0400, D'Arcy Cain wrote:
>
> >> def cp(infile, outfile):
> >>    open(outfile, "w").write(open(infile).read())
>
> > Because your cp doesn't copy the FILE, it copies the file's CONTENTS,
> > which are not the same thing.
>
> And, as a subtle point: This method can't create the file "at size". I
> don't know how it'll end up allocating space, but certainly there's no
> opportunity to announce to the OS at file open/create time "please
> allocate X bytes for this file". That may be an utterly trivial point,
> or a crucially vital one.
>
> ChrisA

FWIW shutil.py doesn't do anything particularly fancy with respect to
creating files "at size", unless I'm missing something:

     http://hg.python.org/cpython/file/2.7/Lib/shutil.py

Only one level away from copyfile, you have copyfileobj, which is a
read/write loop:

    46 def copyfileobj(fsrc, fdst, length=16*1024):
    47     """copy data from file-like object fsrc to file-like object
fdst"""
    48     while 1:
    49         buf = fsrc.read(length)
    50         if not buf:
    51             break
    52         fdst.write(buf)

...and that gets called by copyfile, which only does a little bit of
"os"-related stuff:

    66 def copyfile(src, dst):
    67     """Copy data from src to dst"""
    68     if _samefile(src, dst):
    69         raise Error("`%s` and `%s` are the same file" % (src,
dst))
    70
    71     for fn in [src, dst]:
    72         try:
    73             st = os.stat(fn)
    74         except OSError:
    75             # File most likely does not exist
    76             pass
    77         else:
    78             # XXX What about other special files? (sockets,
devices...)
    79             if stat.S_ISFIFO(st.st_mode):
    80                 raise SpecialFileError("`%s` is a named pipe" %
fn)
    81
    82     with open(src, 'rb') as fsrc:
    83         with open(dst, 'wb') as fdst:
    84             copyfileobj(fsrc, fdst)

The "value add" vs. a simple read/write loop depends on whether you
want OSError suppressed.  The _samefile guard is nice to have, but
probably unnecessary for many apps.

I'm sure shutil.copyfile() makes perfect sense for most use cases, and
it's nice that you can see what it does under the covers pretty
easily, but it's not rocket science.





More information about the Python-list mailing list