Add OVERWRITE_ sentinels for different overwrite techniques.

This commit is contained in:
voussoir 2022-01-04 13:07:16 -08:00
parent 31156aa67c
commit c1886ba536
No known key found for this signature in database
GPG key ID: 5F7554F8C26DACCB

View file

@ -24,6 +24,9 @@ BAIL = sentinel.Sentinel('BAIL')
YIELD_STYLE_FLAT = sentinel.Sentinel('yield style flat') YIELD_STYLE_FLAT = sentinel.Sentinel('yield style flat')
YIELD_STYLE_NESTED = sentinel.Sentinel('yield style nested') YIELD_STYLE_NESTED = sentinel.Sentinel('yield style nested')
OVERWRITE_ALL = sentinel.Sentinel('overwrite all files')
OVERWRITE_OLD = sentinel.Sentinel('overwrite old files')
# Number of bytes to read and write at a time # Number of bytes to read and write at a time
CHUNK_SIZE = 2 * bytestring.MIBIBYTE CHUNK_SIZE = 2 * bytestring.MIBIBYTE
@ -95,7 +98,7 @@ def copy_directory(
exclude_filenames=None, exclude_filenames=None,
files_per_second=None, files_per_second=None,
hash_class=None, hash_class=None,
overwrite_old=True, overwrite=OVERWRITE_OLD,
precalcsize=False, precalcsize=False,
skip_symlinks=True, skip_symlinks=True,
stop_event=None, stop_event=None,
@ -176,8 +179,8 @@ def copy_directory(
hash_class: hash_class:
Passed into each `copy_file` as `hash_class`. Passed into each `copy_file` as `hash_class`.
overwrite_old: overwrite:
Passed into each `copy_file` as `overwrite_old`. Passed into each `copy_file` as `overwrite`.
precalcsize: precalcsize:
If True, calculate the size of source before beginning the copy. If True, calculate the size of source before beginning the copy.
@ -313,7 +316,7 @@ def copy_directory(
chunk_size=chunk_size, chunk_size=chunk_size,
dry_run=dry_run, dry_run=dry_run,
hash_class=hash_class, hash_class=hash_class,
overwrite_old=overwrite_old, overwrite=overwrite,
verify_hash=verify_hash, verify_hash=verify_hash,
) )
@ -356,7 +359,7 @@ def copy_file(
chunk_size='dynamic', chunk_size='dynamic',
dry_run=False, dry_run=False,
hash_class=None, hash_class=None,
overwrite_old=True, overwrite=OVERWRITE_OLD,
verify_hash=False, verify_hash=False,
): ):
''' '''
@ -418,10 +421,13 @@ def copy_file(
needing overwrite, this won't be set, so be prepared to handle None. needing overwrite, this won't be set, so be prepared to handle None.
If None, the hash will not be calculated. If None, the hash will not be calculated.
overwrite_old: overwrite:
If True, overwrite the destination file if the source file This option decides what to do when the destination file already exists.
has a more recent "last modified" timestamp. If OVERWRITE_ALL, the file will be overwritten.
If False, existing files will be skipped no matter what. If OVERWRITE_OLD, the file will be overwritten if the source file
has a more recent "last modified" timestamp (i.e. stat.mtime).
If any other value, the file will not be overwritten. False or None
would be good values to pass.
verify_hash: verify_hash:
If True, the copied file will be read back after the copy is complete, If True, the copied file will be read back after the copy is complete,
@ -466,17 +472,17 @@ def copy_file(
default=None, default=None,
) )
# Determine overwrite # I'm putting the overwrite_all test first since an `is` is faster and
if destination.exists: # cheaper than the dest.exists which will invoke a stat check.
if not overwrite_old: should_overwrite = (
(overwrite is OVERWRITE_ALL) or
(not destination.exists) or
(overwrite is OVERWRITE_OLD and source.stat.st_mtime > destination.stat.st_mtime)
)
if not should_overwrite:
return results return results
source_modtime = source.stat.st_mtime
destination_modtime = destination.stat.st_mtime
if source_modtime == destination_modtime:
return results
# Copy
if dry_run: if dry_run:
if callback_progress is not None: if callback_progress is not None:
callback_progress(destination, 0, 0) callback_progress(destination, 0, 0)
@ -500,8 +506,9 @@ def copy_file(
else: else:
raise raise
log.debug('Opening handles.') log.loud('Opening source handle.')
source_handle = handlehelper(source, 'rb') source_handle = handlehelper(source, 'rb')
log.loud('Opening dest handle.')
destination_handle = handlehelper(destination, 'wb') destination_handle = handlehelper(destination, 'wb')
if source_handle is None and destination_handle: if source_handle is None and destination_handle:
@ -558,9 +565,9 @@ def copy_file(
callback_progress(destination, results.written_bytes, source_bytes) callback_progress(destination, results.written_bytes, source_bytes)
# Fin # Fin
log.debug('Closing source handle.') log.loud('Closing source handle.')
source_handle.close() source_handle.close()
log.debug('Closing dest handle.') log.loud('Closing dest handle.')
destination_handle.close() destination_handle.close()
log.debug('Copying metadata.') log.debug('Copying metadata.')
shutil.copystat(source, destination) shutil.copystat(source, destination)