Issue 4843: make distutils use shutil (original) (raw)
In one sentence:
Let's enhance shutil.copytree so we can drop distutils.[dir_util/file_util]
In details:
I am currently studying what could be removed from Distutils in order to rely on what is available in the standard library.
I have a concern about distutils.dir_util and distutils.file_util modules.
Distutils implements its own file and directory copy functions there, that could be replaced by shutil ones, except four small features:
- verbose : each time a file is copied a "source -> target" is displayed in the output.
- dry_run : nothing is really copied
- update : each file will only be copied if they don't exist in the target path or if they are newer
- the copy_tree function returns the list of files copied (or that should have been copied when dry_run is True).
I think shutil could benefit from these small features, and
distutils code could be refactored to use them.
Here's a small proposal for distutils.copytree::
copytree(src, dst, symlinks=False, ignore=None) -> None
becomes:
copytree(src, dst, symlinks=False, ignore=None, update=False,
verbose=False, dry_run=False, logger=None) -> list of
copied files
where:
update
if False, copytree behaves as usual: if os.path.samefile(source, target) is True it raise an error
if True, the file is copied only if it's newer or doesn't exists, otherwise it doesn't raise
logger
- if None, logger is set to logging.info
verbose: if True, a logger.info("source -> target") call is made on each copy
dry_run: if True, the files are not really copied
Last, the function returns a tuple of copied files.
From there, distutils can work with shutil.copytree, shutil.copyfile and shutil.copy2
Pro's:
- distutils can rely on this function and its specialized modules dissapear
- shutil.copytree becomes more powerful
- less redundancy in the sdtlib
Con's:
- the API signature is getting a bit complex
- distutils use case might not be common enough
I suggest a more generic and powerful API change:
copytree(src, dst, symlinks=False, ignore=None) -> None
becomes:
copytree(src, dst, symlinks=False, ignore=None, callback=None) -> None
where callback, if not None, is called with each (filename, src_dir, dst_dir) and can return either True or False depending on whether the copy must really occur or not.
Then you should be able implement the four distutils option in terms of the callback.