From 754fcc21e6ca9de82ff6d2837841c4300aeb941f Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 9 Mar 2025 13:35:09 -0400 Subject: [PATCH] Remove 'dry run' functionality throughout. --- distutils/archive_util.py | 64 +++++++++++------------- distutils/cmd.py | 31 +++--------- distutils/command/bdist_dumb.py | 2 +- distutils/command/bdist_rpm.py | 47 +++++++++--------- distutils/command/build_clib.py | 4 +- distutils/command/build_ext.py | 1 - distutils/command/build_py.py | 5 +- distutils/command/build_scripts.py | 36 +++++--------- distutils/command/clean.py | 15 +++--- distutils/command/config.py | 12 +---- distutils/command/install_egg_info.py | 7 ++- distutils/command/install_lib.py | 2 - distutils/command/install_scripts.py | 9 ++-- distutils/command/sdist.py | 4 +- distutils/compilers/C/base.py | 24 +++------ distutils/compilers/C/cygwin.py | 8 +-- distutils/compilers/C/msvc.py | 4 +- distutils/compilers/C/zos.py | 4 +- distutils/dir_util.py | 36 +++++--------- distutils/dist.py | 4 +- distutils/file_util.py | 14 ++---- distutils/spawn.py | 6 +-- distutils/tests/test_archive_util.py | 11 ----- distutils/util.py | 70 +++++++++++---------------- 24 files changed, 150 insertions(+), 270 deletions(-) diff --git a/distutils/archive_util.py b/distutils/archive_util.py index d860f552..4a7fb9c9 100644 --- a/distutils/archive_util.py +++ b/distutils/archive_util.py @@ -61,7 +61,6 @@ def make_tarball( base_dir: str | os.PathLike[str], compress: Literal["gzip", "bzip2", "xz"] | None = "gzip", verbose: bool = False, - dry_run: bool = False, owner: str | None = None, group: str | None = None, ) -> str: @@ -96,7 +95,7 @@ def make_tarball( archive_name = base_name + '.tar' archive_name += compress_ext.get(compress, '') - mkpath(os.path.dirname(archive_name), dry_run=dry_run) + mkpath(os.path.dirname(archive_name)) # creating the tarball import tarfile # late import so Python build itself doesn't break @@ -115,21 +114,19 @@ def _set_uid_gid(tarinfo): tarinfo.uname = owner return tarinfo - if not dry_run: - tar = tarfile.open(archive_name, f'w|{tar_compression[compress]}') - try: - tar.add(base_dir, filter=_set_uid_gid) - finally: - tar.close() + tar = tarfile.open(archive_name, f'w|{tar_compression[compress]}') + try: + tar.add(base_dir, filter=_set_uid_gid) + finally: + tar.close() return archive_name -def make_zipfile( # noqa: C901 +def make_zipfile( base_name: str, base_dir: str | os.PathLike[str], verbose: bool = False, - dry_run: bool = False, ) -> str: """Create a zip file from all the files under 'base_dir'. @@ -140,7 +137,7 @@ def make_zipfile( # noqa: C901 file. """ zip_filename = base_name + ".zip" - mkpath(os.path.dirname(zip_filename), dry_run=dry_run) + mkpath(os.path.dirname(zip_filename)) # If zipfile module is not available, try spawning an external # 'zip' command. @@ -151,7 +148,7 @@ def make_zipfile( # noqa: C901 zipoptions = "-rq" try: - spawn(["zip", zipoptions, zip_filename, base_dir], dry_run=dry_run) + spawn(["zip", zipoptions, zip_filename, base_dir]) except DistutilsExecError: # XXX really should distinguish between "couldn't find # external 'zip' command" and "zip failed". @@ -164,29 +161,26 @@ def make_zipfile( # noqa: C901 else: log.info("creating '%s' and adding '%s' to it", zip_filename, base_dir) - if not dry_run: - try: - zip = zipfile.ZipFile( - zip_filename, "w", compression=zipfile.ZIP_DEFLATED - ) - except RuntimeError: - zip = zipfile.ZipFile(zip_filename, "w", compression=zipfile.ZIP_STORED) - - with zip: - if base_dir != os.curdir: - path = os.path.normpath(os.path.join(base_dir, '')) + try: + zip = zipfile.ZipFile(zip_filename, "w", compression=zipfile.ZIP_DEFLATED) + except RuntimeError: + zip = zipfile.ZipFile(zip_filename, "w", compression=zipfile.ZIP_STORED) + + with zip: + if base_dir != os.curdir: + path = os.path.normpath(os.path.join(base_dir, '')) + zip.write(path, path) + log.info("adding '%s'", path) + for dirpath, dirnames, filenames in os.walk(base_dir): + for name in dirnames: + path = os.path.normpath(os.path.join(dirpath, name, '')) zip.write(path, path) log.info("adding '%s'", path) - for dirpath, dirnames, filenames in os.walk(base_dir): - for name in dirnames: - path = os.path.normpath(os.path.join(dirpath, name, '')) + for name in filenames: + path = os.path.normpath(os.path.join(dirpath, name)) + if os.path.isfile(path): zip.write(path, path) log.info("adding '%s'", path) - for name in filenames: - path = os.path.normpath(os.path.join(dirpath, name)) - if os.path.isfile(path): - zip.write(path, path) - log.info("adding '%s'", path) return zip_filename @@ -219,7 +213,6 @@ def make_archive( root_dir: str | os.PathLike[str] | bytes | os.PathLike[bytes] | None = None, base_dir: str | None = None, verbose: bool = False, - dry_run: bool = False, owner: str | None = None, group: str | None = None, ) -> str: ... @@ -230,7 +223,6 @@ def make_archive( root_dir: str | os.PathLike[str] | bytes | os.PathLike[bytes], base_dir: str | None = None, verbose: bool = False, - dry_run: bool = False, owner: str | None = None, group: str | None = None, ) -> str: ... @@ -240,7 +232,6 @@ def make_archive( root_dir: str | os.PathLike[str] | bytes | os.PathLike[bytes] | None = None, base_dir: str | None = None, verbose: bool = False, - dry_run: bool = False, owner: str | None = None, group: str | None = None, ) -> str: @@ -264,13 +255,12 @@ def make_archive( if root_dir is not None: log.debug("changing into '%s'", root_dir) base_name = os.path.abspath(base_name) - if not dry_run: - os.chdir(root_dir) + os.chdir(root_dir) if base_dir is None: base_dir = os.curdir - kwargs = {'dry_run': dry_run} + kwargs: dict[str, bool | None] = {} try: format_info = ARCHIVE_FORMATS[format] diff --git a/distutils/cmd.py b/distutils/cmd.py index 241621bd..530cc108 100644 --- a/distutils/cmd.py +++ b/distutils/cmd.py @@ -91,13 +91,8 @@ def __init__(self, dist: Distribution) -> None: # Per-command versions of the global flags, so that the user can # customize Distutils' behaviour command-by-command and let some - # commands fall back on the Distribution's behaviour. None means - # "not defined, check self.distribution's copy", while 0 or 1 mean - # false and true (duh). Note that this means figuring out the real - # value of each flag is a touch complicated -- hence "self._dry_run" - # will be handled by __getattr__, below. - # XXX This needs to be fixed. - self._dry_run = None + # commands fall back on the Distribution's behaviour. None means + # "not defined, check self.distribution's copy". # verbose is largely ignored, but needs to be set for # backwards compatibility (I think)? @@ -119,17 +114,6 @@ def __init__(self, dist: Distribution) -> None: # always calls 'finalize_options()', to respect/update it. self.finalized = False - # XXX A more explicit way to customize dry_run would be better. - def __getattr__(self, attr): - if attr == 'dry_run': - myval = getattr(self, "_" + attr) - if myval is None: - return getattr(self.distribution, attr) - else: - return myval - else: - raise AttributeError(attr) - def ensure_finalized(self) -> None: if not self.finalized: self.finalize_options() @@ -381,10 +365,10 @@ def execute( msg: object = None, level: int = 1, ) -> None: - util.execute(func, args, msg, dry_run=self.dry_run) + util.execute(func, args, msg) def mkpath(self, name: str, mode: int = 0o777) -> None: - dir_util.mkpath(name, mode, dry_run=self.dry_run) + dir_util.mkpath(name, mode) @overload def copy_file( @@ -425,7 +409,6 @@ def copy_file( preserve_times, not self.force, link, - dry_run=self.dry_run, ) def copy_tree( @@ -447,7 +430,6 @@ def copy_tree( preserve_times, preserve_symlinks, not self.force, - dry_run=self.dry_run, ) @overload @@ -465,7 +447,7 @@ def move_file( level: int = 1, ) -> str | os.PathLike[str] | bytes | os.PathLike[bytes]: """Move a file respecting dry-run flag.""" - return file_util.move_file(src, dst, dry_run=self.dry_run) + return file_util.move_file(src, dst) def spawn( self, cmd: MutableSequence[str], search_path: bool = True, level: int = 1 @@ -473,7 +455,7 @@ def spawn( """Spawn an external command respecting dry-run flag.""" from distutils.spawn import spawn - spawn(cmd, search_path, dry_run=self.dry_run) + spawn(cmd, search_path) @overload def make_archive( @@ -509,7 +491,6 @@ def make_archive( format, root_dir, base_dir, - dry_run=self.dry_run, owner=owner, group=group, ) diff --git a/distutils/command/bdist_dumb.py b/distutils/command/bdist_dumb.py index ccad66f4..c49ef253 100644 --- a/distutils/command/bdist_dumb.py +++ b/distutils/command/bdist_dumb.py @@ -138,4 +138,4 @@ def run(self): self.distribution.dist_files.append(('bdist_dumb', pyversion, filename)) if not self.keep_temp: - remove_tree(self.bdist_dir, dry_run=self.dry_run) + remove_tree(self.bdist_dir) diff --git a/distutils/command/bdist_rpm.py b/distutils/command/bdist_rpm.py index 357b4e86..dfa5f99d 100644 --- a/distutils/command/bdist_rpm.py +++ b/distutils/command/bdist_rpm.py @@ -378,30 +378,29 @@ def run(self) -> None: # noqa: C901 self.spawn(rpm_cmd) - if not self.dry_run: - if self.distribution.has_ext_modules(): - pyversion = get_python_version() - else: - pyversion = 'any' - - if not self.binary_only: - srpm = os.path.join(rpm_dir['SRPMS'], source_rpm) - assert os.path.exists(srpm) - self.move_file(srpm, self.dist_dir) - filename = os.path.join(self.dist_dir, source_rpm) - self.distribution.dist_files.append(('bdist_rpm', pyversion, filename)) - - if not self.source_only: - for rpm in binary_rpms: - rpm = os.path.join(rpm_dir['RPMS'], rpm) - if os.path.exists(rpm): - self.move_file(rpm, self.dist_dir) - filename = os.path.join(self.dist_dir, os.path.basename(rpm)) - self.distribution.dist_files.append(( - 'bdist_rpm', - pyversion, - filename, - )) + if self.distribution.has_ext_modules(): + pyversion = get_python_version() + else: + pyversion = 'any' + + if not self.binary_only: + srpm = os.path.join(rpm_dir['SRPMS'], source_rpm) + assert os.path.exists(srpm) + self.move_file(srpm, self.dist_dir) + filename = os.path.join(self.dist_dir, source_rpm) + self.distribution.dist_files.append(('bdist_rpm', pyversion, filename)) + + if not self.source_only: + for rpm in binary_rpms: + rpm = os.path.join(rpm_dir['RPMS'], rpm) + if os.path.exists(rpm): + self.move_file(rpm, self.dist_dir) + filename = os.path.join(self.dist_dir, os.path.basename(rpm)) + self.distribution.dist_files.append(( + 'bdist_rpm', + pyversion, + filename, + )) def _dist_path(self, path): return os.path.join(self.dist_dir, os.path.basename(path)) diff --git a/distutils/command/build_clib.py b/distutils/command/build_clib.py index 8b65b3d8..8de5df23 100644 --- a/distutils/command/build_clib.py +++ b/distutils/command/build_clib.py @@ -88,9 +88,7 @@ def run(self) -> None: if not self.libraries: return - self.compiler = new_compiler( - compiler=self.compiler, dry_run=self.dry_run, force=self.force - ) + self.compiler = new_compiler(compiler=self.compiler, force=self.force) customize_compiler(self.compiler) if self.include_dirs is not None: diff --git a/distutils/command/build_ext.py b/distutils/command/build_ext.py index ec45b440..df623d7e 100644 --- a/distutils/command/build_ext.py +++ b/distutils/command/build_ext.py @@ -326,7 +326,6 @@ def run(self) -> None: # noqa: C901 self.compiler = new_compiler( compiler=self.compiler, verbose=self.verbose, - dry_run=self.dry_run, force=self.force, ) customize_compiler(self.compiler) diff --git a/distutils/command/build_py.py b/distutils/command/build_py.py index a20b076f..d6ec7d10 100644 --- a/distutils/command/build_py.py +++ b/distutils/command/build_py.py @@ -394,14 +394,11 @@ def byte_compile(self, files) -> None: # method of the "install_lib" command, except for the determination # of the 'prefix' string. Hmmm. if self.compile: - byte_compile( - files, optimize=0, force=self.force, prefix=prefix, dry_run=self.dry_run - ) + byte_compile(files, optimize=0, force=self.force, prefix=prefix) if self.optimize > 0: byte_compile( files, optimize=self.optimize, force=self.force, prefix=prefix, - dry_run=self.dry_run, ) diff --git a/distutils/command/build_scripts.py b/distutils/command/build_scripts.py index 127c51d8..56a1be0e 100644 --- a/distutils/command/build_scripts.py +++ b/distutils/command/build_scripts.py @@ -87,30 +87,24 @@ def _copy_script(self, script, outfiles, updated_files): # Always open the file, but ignore failures in dry-run mode # in order to attempt to copy directly. - try: - f = tokenize.open(script) - except OSError: - if not self.dry_run: - raise - f = None - else: - first_line = f.readline() - if not first_line: - self.warn(f"{script} is an empty file (skipping)") - return + f = tokenize.open(script) + + first_line = f.readline() + if not first_line: + self.warn(f"{script} is an empty file (skipping)") + return - shebang_match = shebang_pattern.match(first_line) + shebang_match = shebang_pattern.match(first_line) updated_files.append(outfile) if shebang_match: log.info("copying and adjusting %s -> %s", script, self.build_dir) - if not self.dry_run: - post_interp = shebang_match.group(1) or '' - shebang = f"#!python{post_interp}\n" - self._validate_shebang(shebang, f.encoding) - with open(outfile, "w", encoding=f.encoding) as outf: - outf.write(shebang) - outf.writelines(f.readlines()) + post_interp = shebang_match.group(1) or '' + shebang = f"#!python{post_interp}\n" + self._validate_shebang(shebang, f.encoding) + with open(outfile, "w", encoding=f.encoding) as outf: + outf.write(shebang) + outf.writelines(f.readlines()) if f: f.close() else: @@ -126,10 +120,6 @@ def _change_modes(self, outfiles): self._change_mode(file) def _change_mode(self, file): - if self.dry_run: - log.info("changing mode of %s", file) - return - oldmode = os.stat(file)[ST_MODE] & 0o7777 newmode = (oldmode | 0o555) & 0o7777 if newmode != oldmode: diff --git a/distutils/command/clean.py b/distutils/command/clean.py index 23427aba..fc1711be 100644 --- a/distutils/command/clean.py +++ b/distutils/command/clean.py @@ -55,7 +55,7 @@ def run(self): # remove the build/temp. directory (unless it's already # gone) if os.path.exists(self.build_temp): - remove_tree(self.build_temp, dry_run=self.dry_run) + remove_tree(self.build_temp) else: log.debug("'%s' does not exist -- can't clean it", self.build_temp) @@ -63,15 +63,14 @@ def run(self): # remove build directories for directory in (self.build_lib, self.bdist_base, self.build_scripts): if os.path.exists(directory): - remove_tree(directory, dry_run=self.dry_run) + remove_tree(directory) else: log.warning("'%s' does not exist -- can't clean it", directory) # just for the heck of it, try to remove the base build directory: # we might have emptied it right now, but if not we don't care - if not self.dry_run: - try: - os.rmdir(self.build_base) - log.info("removing '%s'", self.build_base) - except OSError: - pass + try: + os.rmdir(self.build_base) + log.info("removing '%s'", self.build_base) + except OSError: + pass diff --git a/distutils/command/config.py b/distutils/command/config.py index 44df8233..4d43ca0d 100644 --- a/distutils/command/config.py +++ b/distutils/command/config.py @@ -92,9 +92,7 @@ def _check_compiler(self): # We do this late, and only on-demand, because this is an expensive # import. if not isinstance(self.compiler, CCompiler): - self.compiler = new_compiler( - compiler=self.compiler, dry_run=self.dry_run, force=True - ) + self.compiler = new_compiler(compiler=self.compiler, force=True) customize_compiler(self.compiler) if self.include_dirs: self.compiler.set_include_dirs(self.include_dirs) @@ -159,14 +157,6 @@ def _clean(self, *filenames): except OSError: pass - # XXX these ignore the dry-run flag: what to do, what to do? even if - # you want a dry-run build, you still need some sort of configuration - # info. My inclination is to make it up to the real config command to - # consult 'dry_run', and assume a default (minimal) configuration if - # true. The problem with trying to do it here is that you'd have to - # return either true or false from all the 'try' methods, neither of - # which is correct. - # XXX need access to the header search path and maybe default macros. def try_cpp(self, body=None, headers=None, include_dirs=None, lang="c"): diff --git a/distutils/command/install_egg_info.py b/distutils/command/install_egg_info.py index 230e94ab..6840b34e 100644 --- a/distutils/command/install_egg_info.py +++ b/distutils/command/install_egg_info.py @@ -44,7 +44,7 @@ def finalize_options(self): def run(self): target = self.target if os.path.isdir(target) and not os.path.islink(target): - dir_util.remove_tree(target, dry_run=self.dry_run) + dir_util.remove_tree(target) elif os.path.exists(target): self.execute(os.unlink, (self.target,), "Removing " + target) elif not os.path.isdir(self.install_dir): @@ -52,9 +52,8 @@ def run(self): os.makedirs, (self.install_dir,), "Creating " + self.install_dir ) log.info("Writing %s", target) - if not self.dry_run: - with open(target, 'w', encoding='UTF-8') as f: - self.distribution.metadata.write_pkg_file(f) + with open(target, 'w', encoding='UTF-8') as f: + self.distribution.metadata.write_pkg_file(f) def get_outputs(self): return self.outputs diff --git a/distutils/command/install_lib.py b/distutils/command/install_lib.py index 2aababf8..9909a617 100644 --- a/distutils/command/install_lib.py +++ b/distutils/command/install_lib.py @@ -142,7 +142,6 @@ def byte_compile(self, files) -> None: optimize=0, force=self.force, prefix=install_root, - dry_run=self.dry_run, ) if self.optimize > 0: byte_compile( @@ -151,7 +150,6 @@ def byte_compile(self, files) -> None: force=self.force, prefix=install_root, verbose=self.verbose, - dry_run=self.dry_run, ) # -- Utility methods ----------------------------------------------- diff --git a/distutils/command/install_scripts.py b/distutils/command/install_scripts.py index 92e86941..33d235d9 100644 --- a/distutils/command/install_scripts.py +++ b/distutils/command/install_scripts.py @@ -48,12 +48,9 @@ def run(self) -> None: # Set the executable bits (owner, group, and world) on # all the scripts we just installed. for file in self.get_outputs(): - if self.dry_run: - log.info("changing mode of %s", file) - else: - mode = ((os.stat(file)[ST_MODE]) | 0o555) & 0o7777 - log.info("changing mode of %s to %o", file, mode) - os.chmod(file, mode) + mode = ((os.stat(file)[ST_MODE]) | 0o555) & 0o7777 + log.info("changing mode of %s to %o", file, mode) + os.chmod(file, mode) def get_inputs(self): return self.distribution.scripts or [] diff --git a/distutils/command/sdist.py b/distutils/command/sdist.py index b3bf0c32..e64cc829 100644 --- a/distutils/command/sdist.py +++ b/distutils/command/sdist.py @@ -450,7 +450,7 @@ def make_release_tree(self, base_dir, files) -> None: # put 'files' there; the 'mkpath()' is just so we don't die # if the manifest happens to be empty. self.mkpath(base_dir) - dir_util.create_tree(base_dir, files, dry_run=self.dry_run) + dir_util.create_tree(base_dir, files) # And walk over the list of files, either making a hard link (if # os.link exists) to each one that doesn't already exist in its @@ -508,7 +508,7 @@ def make_distribution(self) -> None: self.archive_files = archive_files if not self.keep_temp: - dir_util.remove_tree(base_dir, dry_run=self.dry_run) + dir_util.remove_tree(base_dir) def get_archive_files(self): """Return the list of archive files created when the command diff --git a/distutils/compilers/C/base.py b/distutils/compilers/C/base.py index 5efd2a39..ea6b5458 100644 --- a/distutils/compilers/C/base.py +++ b/distutils/compilers/C/base.py @@ -130,10 +130,7 @@ class Compiler: library dirs specific to this compiler class """ - def __init__( - self, verbose: bool = False, dry_run: bool = False, force: bool = False - ) -> None: - self.dry_run = dry_run + def __init__(self, verbose: bool = False, force: bool = False) -> None: self.force = force self.verbose = verbose @@ -531,12 +528,8 @@ def _need_link(self, objects, output_file): """ if self.force: return True - else: - if self.dry_run: - newer = newer_group(objects, output_file, missing='newer') - else: - newer = newer_group(objects, output_file) - return newer + newer = newer_group(objects, output_file) + return newer def detect_language(self, sources: str | list[str]) -> str | None: """Detect the language of a given file, or list of files. Uses @@ -1150,12 +1143,12 @@ def execute( msg: object = None, level: int = 1, ) -> None: - execute(func, args, msg, self.dry_run) + execute(func, args, msg) def spawn( self, cmd: MutableSequence[bytes | str | os.PathLike[str]], **kwargs ) -> None: - spawn(cmd, dry_run=self.dry_run, **kwargs) + spawn(cmd, **kwargs) @overload def move_file( @@ -1170,10 +1163,10 @@ def move_file( src: str | os.PathLike[str] | bytes | os.PathLike[bytes], dst: str | os.PathLike[str] | bytes | os.PathLike[bytes], ) -> str | os.PathLike[str] | bytes | os.PathLike[bytes]: - return move_file(src, dst, dry_run=self.dry_run) + return move_file(src, dst) def mkpath(self, name, mode=0o777): - mkpath(name, mode, dry_run=self.dry_run) + mkpath(name, mode) # Map a sys.platform/os.name ('posix', 'nt') to the default compiler @@ -1262,7 +1255,6 @@ def new_compiler( plat: str | None = None, compiler: str | None = None, verbose: bool = False, - dry_run: bool = False, force: bool = False, ) -> Compiler: """Generate an instance of some CCompiler subclass for the supplied @@ -1307,7 +1299,7 @@ def new_compiler( # XXX The None is necessary to preserve backwards compatibility # with classes that expect verbose to be the first positional # argument. - return klass(None, dry_run, force) + return klass(None, force=force) def gen_preprocess_options( diff --git a/distutils/compilers/C/cygwin.py b/distutils/compilers/C/cygwin.py index bfabbb30..f349e9de 100644 --- a/distutils/compilers/C/cygwin.py +++ b/distutils/compilers/C/cygwin.py @@ -52,8 +52,8 @@ class Compiler(unix.Compiler): dylib_lib_format = "cyg%s%s" exe_extension = ".exe" - def __init__(self, verbose=False, dry_run=False, force=False): - super().__init__(verbose, dry_run, force) + def __init__(self, verbose=False, force=False): + super().__init__(verbose, force=force) status, details = check_config_h() self.debug_print(f"Python's GCC status: {status} (details: {details})") @@ -246,8 +246,8 @@ class MinGW32Compiler(Compiler): compiler_type = 'mingw32' - def __init__(self, verbose=False, dry_run=False, force=False): - super().__init__(verbose, dry_run, force) + def __init__(self, verbose=False, force=False): + super().__init__(verbose, force) shared_option = "-shared" diff --git a/distutils/compilers/C/msvc.py b/distutils/compilers/C/msvc.py index 6db062a9..1f50fa50 100644 --- a/distutils/compilers/C/msvc.py +++ b/distutils/compilers/C/msvc.py @@ -260,8 +260,8 @@ class Compiler(base.Compiler): static_lib_format = shared_lib_format = '%s%s' exe_extension = '.exe' - def __init__(self, verbose=False, dry_run=False, force=False) -> None: - super().__init__(verbose, dry_run, force) + def __init__(self, verbose=False, force=False) -> None: + super().__init__(verbose, force=force) # target platform (.plat_name is consistent with 'bdist') self.plat_name = None self.initialized = False diff --git a/distutils/compilers/C/zos.py b/distutils/compilers/C/zos.py index 82d017fc..681c6316 100644 --- a/distutils/compilers/C/zos.py +++ b/distutils/compilers/C/zos.py @@ -136,8 +136,8 @@ def _get_zos_compiler_name(self): return zos_compilers.get(zos_compiler_names[0], 'ibm-openxl') - def __init__(self, verbose=False, dry_run=False, force=False): - super().__init__(verbose, dry_run, force) + def __init__(self, verbose=False, force=False): + super().__init__(verbose, force=force) self.zos_compiler = self._get_zos_compiler_name() sysconfig.customize_compiler(self) diff --git a/distutils/dir_util.py b/distutils/dir_util.py index d9782602..61b4575a 100644 --- a/distutils/dir_util.py +++ b/distutils/dir_util.py @@ -45,7 +45,7 @@ def wrapper(path, *args, **kwargs): @functools.singledispatch @wrapper -def mkpath(name: pathlib.Path, mode=0o777, verbose=True, dry_run=False) -> None: +def mkpath(name: pathlib.Path, mode=0o777, verbose=True) -> None: """Create a directory and any missing ancestor directories. If the directory already exists (or if 'name' is the empty string, which @@ -58,7 +58,7 @@ def mkpath(name: pathlib.Path, mode=0o777, verbose=True, dry_run=False) -> None: log.info("creating %s", name) try: - dry_run or name.mkdir(mode=mode, parents=True, exist_ok=True) + name.mkdir(mode=mode, parents=True, exist_ok=True) except OSError as exc: raise DistutilsFileError(f"could not create '{name}': {exc.args[-1]}") @@ -76,22 +76,22 @@ def _(name: None, *args, **kwargs): raise DistutilsInternalError(f"mkpath: 'name' must be a string (got {name!r})") -def create_tree(base_dir, files, mode=0o777, verbose=True, dry_run=False): +def create_tree(base_dir, files, mode=0o777, verbose=True): """Create all the empty directories under 'base_dir' needed to put 'files' there. 'base_dir' is just the name of a directory which doesn't necessarily exist yet; 'files' is a list of filenames to be interpreted relative to 'base_dir'. 'base_dir' + the directory portion of every file in 'files' - will be created if it doesn't already exist. 'mode', 'verbose' and - 'dry_run' flags are as for 'mkpath()'. + will be created if it doesn't already exist. 'mode' and 'verbose' + flags are as for 'mkpath()'. """ # First get the list of directories to create need_dir = set(os.path.join(base_dir, os.path.dirname(file)) for file in files) # Now create them for dir in sorted(need_dir): - mkpath(dir, mode, verbose=verbose, dry_run=dry_run) + mkpath(dir, mode, verbose=verbose) def copy_tree( @@ -102,7 +102,6 @@ def copy_tree( preserve_symlinks=False, update=False, verbose=True, - dry_run=False, ): """Copy an entire directory tree 'src' to a new location 'dst'. @@ -112,7 +111,7 @@ def copy_tree( file in 'src' is copied to 'dst', and directories under 'src' are recursively copied to 'dst'. Return the list of files that were copied or might have been copied, using their output name. The - return value is unaffected by 'update' or 'dry_run': it is simply + return value is unaffected by 'update': it is simply the list of all files under 'src', with the names changed to be under 'dst'. @@ -123,18 +122,14 @@ def copy_tree( (the default), the destination of the symlink will be copied. 'update' and 'verbose' are the same as for 'copy_file'. """ - if not dry_run and not os.path.isdir(src): + if not os.path.isdir(src): raise DistutilsFileError(f"cannot copy tree '{src}': not a directory") try: names = os.listdir(src) except OSError as e: - if dry_run: - names = [] - else: - raise DistutilsFileError(f"error listing files in '{src}': {e.strerror}") + raise DistutilsFileError(f"error listing files in '{src}': {e.strerror}") - if not dry_run: - mkpath(dst, verbose=verbose) + mkpath(dst, verbose=verbose) copy_one = functools.partial( _copy_one, @@ -142,7 +137,6 @@ def copy_tree( dst=dst, preserve_symlinks=preserve_symlinks, verbose=verbose, - dry_run=dry_run, preserve_mode=preserve_mode, preserve_times=preserve_times, update=update, @@ -157,7 +151,6 @@ def _copy_one( dst, preserve_symlinks, verbose, - dry_run, preserve_mode, preserve_times, update, @@ -173,8 +166,7 @@ def _copy_one( link_dest = os.readlink(src_name) if verbose >= 1: log.info("linking %s -> %s", dst_name, link_dest) - if not dry_run: - os.symlink(link_dest, dst_name) + os.symlink(link_dest, dst_name) yield dst_name elif os.path.isdir(src_name): @@ -186,7 +178,6 @@ def _copy_one( preserve_symlinks, update, verbose=verbose, - dry_run=dry_run, ) else: file_util.copy_file( @@ -196,7 +187,6 @@ def _copy_one( preserve_times, update, verbose=verbose, - dry_run=dry_run, ) yield dst_name @@ -212,7 +202,7 @@ def _build_cmdtuple(path, cmdtuples): cmdtuples.append((os.rmdir, path)) -def remove_tree(directory, verbose=True, dry_run=False): +def remove_tree(directory, verbose=True): """Recursively remove an entire directory tree. Any errors are ignored (apart from being reported to stdout if 'verbose' @@ -220,8 +210,6 @@ def remove_tree(directory, verbose=True, dry_run=False): """ if verbose >= 1: log.info("removing '%s' (and everything under it)", directory) - if dry_run: - return cmdtuples = [] _build_cmdtuple(directory, cmdtuples) for cmd in cmdtuples: diff --git a/distutils/dist.py b/distutils/dist.py index 37b788df..e04e487b 100644 --- a/distutils/dist.py +++ b/distutils/dist.py @@ -99,7 +99,6 @@ class Distribution: global_options: ClassVar[_OptionsList] = [ ('verbose', 'v', "run verbosely (default)", 1), ('quiet', 'q', "run quietly (turns verbosity off)"), - ('dry-run', 'n', "don't actually do anything"), ('help', 'h', "show detailed help message"), ('no-user-cfg', None, 'ignore pydistutils.cfg in your home directory'), ] @@ -164,7 +163,6 @@ def __init__(self, attrs: MutableMapping[str, Any] | None = None) -> None: # no # Default values for our command-line options self.verbose = True - self.dry_run = False self.help = False for attr in self.display_option_names: setattr(self, attr, False) @@ -446,7 +444,7 @@ def parse_config_files(self, filenames=None): # noqa: C901 try: if alias: setattr(self, alias, not strtobool(val)) - elif opt in ('verbose', 'dry_run'): # ugh! + elif opt in ('verbose',): # ugh! setattr(self, opt, strtobool(val)) else: setattr(self, opt, val) diff --git a/distutils/file_util.py b/distutils/file_util.py index 0acc8cb8..a9724b17 100644 --- a/distutils/file_util.py +++ b/distutils/file_util.py @@ -68,7 +68,6 @@ def copy_file( # noqa: C901 update=False, link=None, verbose=True, - dry_run=False, ): """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 @@ -91,8 +90,7 @@ def copy_file( # noqa: C901 other systems, uses '_copy_file_contents()' to copy file contents. Return a tuple (dest_name, copied): 'dest_name' is the actual name of - the output file, and 'copied' is true if the file was copied (or would - have been copied, if 'dry_run' true). + the output file, and 'copied' is true if the file was copied. """ # XXX if the destination file already exists, we clobber it if # copying, but blow up if linking. Hmmm. And I don't know what @@ -131,12 +129,9 @@ def copy_file( # noqa: C901 else: log.info("%s %s -> %s", action, src, dst) - if dry_run: - return (dst, True) - # If linking (hard or symbolic), use the appropriate system call # (Unix only, of course, but that's the caller's responsibility) - elif link == 'hard': + if link == 'hard': if not (os.path.exists(dst) and os.path.samefile(src, dst)): try: os.link(src, dst) @@ -169,7 +164,7 @@ def copy_file( # noqa: C901 # XXX I suspect this is Unix-specific -- need porting help! -def move_file(src, dst, verbose=True, dry_run=False): # noqa: C901 +def move_file(src, dst, verbose=True): # noqa: C901 """Move a file 'src' to 'dst'. If 'dst' is a directory, the file will be moved into it with the same name; otherwise, 'src' is just renamed to 'dst'. Return the new full name of the file. @@ -183,9 +178,6 @@ def move_file(src, dst, verbose=True, dry_run=False): # noqa: C901 if verbose >= 1: log.info("moving %s -> %s", src, dst) - if dry_run: - return dst - if not isfile(src): raise DistutilsFileError(f"can't move '{src}': not a regular file") diff --git a/distutils/spawn.py b/distutils/spawn.py index 973668f2..e47f1d19 100644 --- a/distutils/spawn.py +++ b/distutils/spawn.py @@ -56,7 +56,6 @@ def spawn( cmd: MutableSequence[bytes | str | os.PathLike[str]], search_path: bool = True, verbose: bool = False, - dry_run: bool = False, env: _ENV | None = None, ) -> None: """Run another program, specified as a command list 'cmd', in a new process. @@ -68,15 +67,12 @@ def spawn( If 'search_path' is true (the default), the system's executable search path will be used to find the program; otherwise, cmd[0] - must be the exact path to the executable. If 'dry_run' is true, - the command will not actually be run. + must be the exact path to the executable. Raise DistutilsExecError if running the program fails in any way; just return on success. """ log.info(subprocess.list2cmdline(cmd)) - if dry_run: - return if search_path: executable = shutil.which(cmd[0]) diff --git a/distutils/tests/test_archive_util.py b/distutils/tests/test_archive_util.py index 3e4ed75a..a9cc5eb0 100644 --- a/distutils/tests/test_archive_util.py +++ b/distutils/tests/test_archive_util.py @@ -177,17 +177,6 @@ def test_tarfile_vs_tar(self): tarball = base_name + '.tar' assert os.path.exists(tarball) - # now for a dry_run - base_name = os.path.join(tmpdir2, 'archive') - old_dir = os.getcwd() - os.chdir(tmpdir) - try: - make_tarball(base_name, 'dist', compress=None, dry_run=True) - finally: - os.chdir(old_dir) - tarball = base_name + '.tar' - assert os.path.exists(tarball) - @pytest.mark.usefixtures('needs_zlib') def test_make_zipfile(self): zipfile = pytest.importorskip('zipfile') diff --git a/distutils/util.py b/distutils/util.py index 6dbe049f..47bb5af5 100644 --- a/distutils/util.py +++ b/distutils/util.py @@ -313,16 +313,11 @@ def execute( args: tuple[Unpack[_Ts]], msg: object = None, verbose: bool = False, - dry_run: bool = False, ) -> None: """ Perform some action that affects the outside world (e.g. by - writing to the filesystem). Such actions are special because they - are disabled by the 'dry_run' flag. This method handles that - complication; simply supply the - function to call and an argument tuple for it (to embody the - "external action" being performed) and an optional message to - emit. + writing to the filesystem). Was previously used to deal with + "dry run" operations, but now runs unconditionally. """ if msg is None: msg = f"{func.__name__}{args!r}" @@ -330,8 +325,7 @@ def execute( msg = msg[0:-2] + ')' log.info(msg) - if not dry_run: - func(*args) + func(*args) def strtobool(val: str) -> bool: @@ -357,7 +351,6 @@ def byte_compile( # noqa: C901 prefix: str | None = None, base_dir: str | None = None, verbose: bool = True, - dry_run: bool = False, direct: bool | None = None, ) -> None: """Byte-compile a collection of Python source files to .pyc @@ -377,9 +370,6 @@ def byte_compile( # noqa: C901 prepended (after 'prefix' is stripped). You can supply either or both (or neither) of 'prefix' and 'base_dir', as you wish. - If 'dry_run' is true, doesn't actually do anything that would - affect the filesystem. - Byte-compilation is either done directly in this interpreter process with the standard py_compile module, or indirectly by writing a temporary script and executing it. Normally, you should let @@ -411,42 +401,41 @@ def byte_compile( # noqa: C901 if not direct: (script_fd, script_name) = tempfile.mkstemp(".py") log.info("writing byte-compilation script '%s'", script_name) - if not dry_run: - script = os.fdopen(script_fd, "w", encoding='utf-8') + script = os.fdopen(script_fd, "w", encoding='utf-8') - with script: - script.write( - """\ + with script: + script.write( + """\ from distutils.util import byte_compile files = [ """ - ) - - # XXX would be nice to write absolute filenames, just for - # safety's sake (script should be more robust in the face of - # chdir'ing before running it). But this requires abspath'ing - # 'prefix' as well, and that breaks the hack in build_lib's - # 'byte_compile()' method that carefully tacks on a trailing - # slash (os.sep really) to make sure the prefix here is "just - # right". This whole prefix business is rather delicate -- the - # problem is that it's really a directory, but I'm treating it - # as a dumb string, so trailing slashes and so forth matter. - - script.write(",\n".join(map(repr, py_files)) + "]\n") - script.write( - f""" + ) + + # XXX would be nice to write absolute filenames, just for + # safety's sake (script should be more robust in the face of + # chdir'ing before running it). But this requires abspath'ing + # 'prefix' as well, and that breaks the hack in build_lib's + # 'byte_compile()' method that carefully tacks on a trailing + # slash (os.sep really) to make sure the prefix here is "just + # right". This whole prefix business is rather delicate -- the + # problem is that it's really a directory, but I'm treating it + # as a dumb string, so trailing slashes and so forth matter. + + script.write(",\n".join(map(repr, py_files)) + "]\n") + script.write( + f""" byte_compile(files, optimize={optimize!r}, force={force!r}, - prefix={prefix!r}, base_dir={base_dir!r}, - verbose={verbose!r}, dry_run=False, - direct=True) + prefix={prefix!r}, base_dir={base_dir!r}, + verbose={verbose!r}, + direct=True) """ - ) + ) cmd = [sys.executable] cmd.extend(subprocess._optim_args_from_interpreter_flags()) cmd.append(script_name) - spawn(cmd, dry_run=dry_run) - execute(os.remove, (script_name,), f"removing {script_name}", dry_run=dry_run) + spawn(cmd) + execute(os.remove, (script_name,), f"removing {script_name}") # "Direct" byte-compilation: use the py_compile module to compile # right here, right now. Note that the script generated in indirect @@ -483,8 +472,7 @@ def byte_compile( # noqa: C901 if direct: if force or newer(file, cfile): log.info("byte-compiling %s to %s", file, cfile_base) - if not dry_run: - compile(file, cfile, dfile) + compile(file, cfile, dfile) else: log.debug("skipping byte-compilation of %s to %s", file, cfile_base)