summaryrefslogtreecommitdiff
path: root/setuptools/_distutils/command
diff options
context:
space:
mode:
authorJason R. Coombs <jaraco@jaraco.com>2022-06-12 18:05:03 -0400
committerJason R. Coombs <jaraco@jaraco.com>2022-06-12 18:05:03 -0400
commit423f1829b5e8b2213492e4f023f26a7c26f0b287 (patch)
tree14a73d41f42c5d3a3effce1dd47ee3af3c07d689 /setuptools/_distutils/command
parent48adabe567806c808fdede5afc8c57f68c4f9755 (diff)
parent75ed79d1ad1bfbb30dd684cd3cc55cb1139dc31b (diff)
downloadpython-setuptools-git-423f1829b5e8b2213492e4f023f26a7c26f0b287.tar.gz
Merge pypa/distutils@75ed79d
Diffstat (limited to 'setuptools/_distutils/command')
-rw-r--r--setuptools/_distutils/command/__init__.py53
-rw-r--r--setuptools/_distutils/command/bdist.py106
-rw-r--r--setuptools/_distutils/command/bdist_dumb.py115
-rw-r--r--setuptools/_distutils/command/bdist_msi.py923
-rw-r--r--setuptools/_distutils/command/bdist_rpm.py406
-rw-r--r--setuptools/_distutils/command/bdist_wininst.py213
-rw-r--r--setuptools/_distutils/command/build.py88
-rw-r--r--setuptools/_distutils/command/build_clib.py107
-rw-r--r--setuptools/_distutils/command/build_ext.py247
-rw-r--r--setuptools/_distutils/command/build_py.py95
-rw-r--r--setuptools/_distutils/command/build_scripts.py33
-rw-r--r--setuptools/_distutils/command/check.py68
-rw-r--r--setuptools/_distutils/command/clean.py52
-rw-r--r--setuptools/_distutils/command/config.py140
-rw-r--r--setuptools/_distutils/command/install.py343
-rw-r--r--setuptools/_distutils/command/install_data.py33
-rw-r--r--setuptools/_distutils/command/install_egg_info.py17
-rw-r--r--setuptools/_distutils/command/install_headers.py16
-rw-r--r--setuptools/_distutils/command/install_lib.py93
-rw-r--r--setuptools/_distutils/command/install_scripts.py13
-rw-r--r--setuptools/_distutils/command/py37compat.py3
-rw-r--r--setuptools/_distutils/command/register.py133
-rw-r--r--setuptools/_distutils/command/sdist.py191
-rw-r--r--setuptools/_distutils/command/upload.py39
24 files changed, 2093 insertions, 1434 deletions
diff --git a/setuptools/_distutils/command/__init__.py b/setuptools/_distutils/command/__init__.py
index 481eea9f..d199c242 100644
--- a/setuptools/_distutils/command/__init__.py
+++ b/setuptools/_distutils/command/__init__.py
@@ -3,29 +3,30 @@
Package containing implementation of all the standard Distutils
commands."""
-__all__ = ['build',
- 'build_py',
- 'build_ext',
- 'build_clib',
- 'build_scripts',
- 'clean',
- 'install',
- 'install_lib',
- 'install_headers',
- 'install_scripts',
- 'install_data',
- 'sdist',
- 'register',
- 'bdist',
- 'bdist_dumb',
- 'bdist_rpm',
- 'bdist_wininst',
- 'check',
- 'upload',
- # These two are reserved for future use:
- #'bdist_sdux',
- #'bdist_pkgtool',
- # Note:
- # bdist_packager is not included because it only provides
- # an abstract base class
- ]
+__all__ = [
+ 'build',
+ 'build_py',
+ 'build_ext',
+ 'build_clib',
+ 'build_scripts',
+ 'clean',
+ 'install',
+ 'install_lib',
+ 'install_headers',
+ 'install_scripts',
+ 'install_data',
+ 'sdist',
+ 'register',
+ 'bdist',
+ 'bdist_dumb',
+ 'bdist_rpm',
+ 'bdist_wininst',
+ 'check',
+ 'upload',
+ # These two are reserved for future use:
+ #'bdist_sdux',
+ #'bdist_pkgtool',
+ # Note:
+ # bdist_packager is not included because it only provides
+ # an abstract base class
+]
diff --git a/setuptools/_distutils/command/bdist.py b/setuptools/_distutils/command/bdist.py
index 014871d2..2a639761 100644
--- a/setuptools/_distutils/command/bdist.py
+++ b/setuptools/_distutils/command/bdist.py
@@ -10,13 +10,12 @@ from distutils.util import get_platform
def show_formats():
- """Print list of available formats (arguments to "--format" option).
- """
+ """Print list of available formats (arguments to "--format" option)."""
from distutils.fancy_getopt import FancyGetopt
+
formats = []
for format in bdist.format_commands:
- formats.append(("formats=" + format, None,
- bdist.format_command[format][1]))
+ formats.append(("formats=" + format, None, bdist.format_command[format][1]))
pretty_printer = FancyGetopt(formats)
pretty_printer.print_help("List of available distribution formats:")
@@ -25,58 +24,71 @@ class bdist(Command):
description = "create a built (binary) distribution"
- user_options = [('bdist-base=', 'b',
- "temporary directory for creating built distributions"),
- ('plat-name=', 'p',
- "platform name to embed in generated filenames "
- "(default: %s)" % get_platform()),
- ('formats=', None,
- "formats for distribution (comma-separated list)"),
- ('dist-dir=', 'd',
- "directory to put final built distributions in "
- "[default: dist]"),
- ('skip-build', None,
- "skip rebuilding everything (for testing/debugging)"),
- ('owner=', 'u',
- "Owner name used when creating a tar file"
- " [default: current user]"),
- ('group=', 'g',
- "Group name used when creating a tar file"
- " [default: current group]"),
- ]
+ user_options = [
+ ('bdist-base=', 'b', "temporary directory for creating built distributions"),
+ (
+ 'plat-name=',
+ 'p',
+ "platform name to embed in generated filenames "
+ "(default: %s)" % get_platform(),
+ ),
+ ('formats=', None, "formats for distribution (comma-separated list)"),
+ (
+ 'dist-dir=',
+ 'd',
+ "directory to put final built distributions in " "[default: dist]",
+ ),
+ ('skip-build', None, "skip rebuilding everything (for testing/debugging)"),
+ (
+ 'owner=',
+ 'u',
+ "Owner name used when creating a tar file" " [default: current user]",
+ ),
+ (
+ 'group=',
+ 'g',
+ "Group name used when creating a tar file" " [default: current group]",
+ ),
+ ]
boolean_options = ['skip-build']
help_options = [
- ('help-formats', None,
- "lists available distribution formats", show_formats),
- ]
+ ('help-formats', None, "lists available distribution formats", show_formats),
+ ]
# The following commands do not take a format option from bdist
no_format_option = ('bdist_rpm',)
# This won't do in reality: will need to distinguish RPM-ish Linux,
# Debian-ish Linux, Solaris, FreeBSD, ..., Windows, Mac OS.
- default_format = {'posix': 'gztar',
- 'nt': 'zip'}
+ default_format = {'posix': 'gztar', 'nt': 'zip'}
# Establish the preferred order (for the --help-formats option).
- format_commands = ['rpm', 'gztar', 'bztar', 'xztar', 'ztar', 'tar',
- 'wininst', 'zip', 'msi']
+ format_commands = [
+ 'rpm',
+ 'gztar',
+ 'bztar',
+ 'xztar',
+ 'ztar',
+ 'tar',
+ 'wininst',
+ 'zip',
+ 'msi',
+ ]
# And the real information.
- format_command = {'rpm': ('bdist_rpm', "RPM distribution"),
- 'gztar': ('bdist_dumb', "gzip'ed tar file"),
- 'bztar': ('bdist_dumb', "bzip2'ed tar file"),
- 'xztar': ('bdist_dumb', "xz'ed tar file"),
- 'ztar': ('bdist_dumb', "compressed tar file"),
- 'tar': ('bdist_dumb', "tar file"),
- 'wininst': ('bdist_wininst',
- "Windows executable installer"),
- 'zip': ('bdist_dumb', "ZIP file"),
- 'msi': ('bdist_msi', "Microsoft Installer")
- }
-
+ format_command = {
+ 'rpm': ('bdist_rpm', "RPM distribution"),
+ 'gztar': ('bdist_dumb', "gzip'ed tar file"),
+ 'bztar': ('bdist_dumb', "bzip2'ed tar file"),
+ 'xztar': ('bdist_dumb', "xz'ed tar file"),
+ 'ztar': ('bdist_dumb', "compressed tar file"),
+ 'tar': ('bdist_dumb', "tar file"),
+ 'wininst': ('bdist_wininst', "Windows executable installer"),
+ 'zip': ('bdist_dumb', "ZIP file"),
+ 'msi': ('bdist_msi', "Microsoft Installer"),
+ }
def initialize_options(self):
self.bdist_base = None
@@ -100,8 +112,7 @@ class bdist(Command):
# "build/bdist.<plat>/dumb", "build/bdist.<plat>/rpm", etc.)
if self.bdist_base is None:
build_base = self.get_finalized_command('build').build_base
- self.bdist_base = os.path.join(build_base,
- 'bdist.' + self.plat_name)
+ self.bdist_base = os.path.join(build_base, 'bdist.' + self.plat_name)
self.ensure_string_list('formats')
if self.formats is None:
@@ -109,8 +120,9 @@ class bdist(Command):
self.formats = [self.default_format[os.name]]
except KeyError:
raise DistutilsPlatformError(
- "don't know how to create built distributions "
- "on platform %s" % os.name)
+ "don't know how to create built distributions "
+ "on platform %s" % os.name
+ )
if self.dist_dir is None:
self.dist_dir = "dist"
@@ -138,6 +150,6 @@ class bdist(Command):
# If we're going to need to run this command again, tell it to
# keep its temporary files around so subsequent runs go faster.
- if cmd_name in commands[i+1:]:
+ if cmd_name in commands[i + 1 :]:
sub_cmd.keep_temp = 1
self.run_command(cmd_name)
diff --git a/setuptools/_distutils/command/bdist_dumb.py b/setuptools/_distutils/command/bdist_dumb.py
index f0d6b5b8..3c387828 100644
--- a/setuptools/_distutils/command/bdist_dumb.py
+++ b/setuptools/_distutils/command/bdist_dumb.py
@@ -12,40 +12,52 @@ from distutils.errors import *
from distutils.sysconfig import get_python_version
from distutils import log
+
class bdist_dumb(Command):
description = "create a \"dumb\" built distribution"
- user_options = [('bdist-dir=', 'd',
- "temporary directory for creating the distribution"),
- ('plat-name=', 'p',
- "platform name to embed in generated filenames "
- "(default: %s)" % get_platform()),
- ('format=', 'f',
- "archive format to create (tar, gztar, bztar, xztar, "
- "ztar, zip)"),
- ('keep-temp', 'k',
- "keep the pseudo-installation tree around after " +
- "creating the distribution archive"),
- ('dist-dir=', 'd',
- "directory to put final built distributions in"),
- ('skip-build', None,
- "skip rebuilding everything (for testing/debugging)"),
- ('relative', None,
- "build the archive using relative paths "
- "(default: false)"),
- ('owner=', 'u',
- "Owner name used when creating a tar file"
- " [default: current user]"),
- ('group=', 'g',
- "Group name used when creating a tar file"
- " [default: current group]"),
- ]
+ user_options = [
+ ('bdist-dir=', 'd', "temporary directory for creating the distribution"),
+ (
+ 'plat-name=',
+ 'p',
+ "platform name to embed in generated filenames "
+ "(default: %s)" % get_platform(),
+ ),
+ (
+ 'format=',
+ 'f',
+ "archive format to create (tar, gztar, bztar, xztar, " "ztar, zip)",
+ ),
+ (
+ 'keep-temp',
+ 'k',
+ "keep the pseudo-installation tree around after "
+ + "creating the distribution archive",
+ ),
+ ('dist-dir=', 'd', "directory to put final built distributions in"),
+ ('skip-build', None, "skip rebuilding everything (for testing/debugging)"),
+ (
+ 'relative',
+ None,
+ "build the archive using relative paths " "(default: false)",
+ ),
+ (
+ 'owner=',
+ 'u',
+ "Owner name used when creating a tar file" " [default: current user]",
+ ),
+ (
+ 'group=',
+ 'g',
+ "Group name used when creating a tar file" " [default: current group]",
+ ),
+ ]
boolean_options = ['keep-temp', 'skip-build', 'relative']
- default_format = { 'posix': 'gztar',
- 'nt': 'zip' }
+ default_format = {'posix': 'gztar', 'nt': 'zip'}
def initialize_options(self):
self.bdist_dir = None
@@ -68,13 +80,16 @@ class bdist_dumb(Command):
self.format = self.default_format[os.name]
except KeyError:
raise DistutilsPlatformError(
- "don't know how to create dumb built distributions "
- "on platform %s" % os.name)
+ "don't know how to create dumb built distributions "
+ "on platform %s" % os.name
+ )
- self.set_undefined_options('bdist',
- ('dist_dir', 'dist_dir'),
- ('plat_name', 'plat_name'),
- ('skip_build', 'skip_build'))
+ self.set_undefined_options(
+ 'bdist',
+ ('dist_dir', 'dist_dir'),
+ ('plat_name', 'plat_name'),
+ ('skip_build', 'skip_build'),
+ )
def run(self):
if not self.skip_build:
@@ -90,34 +105,38 @@ class bdist_dumb(Command):
# And make an archive relative to the root of the
# pseudo-installation tree.
- archive_basename = "%s.%s" % (self.distribution.get_fullname(),
- self.plat_name)
+ archive_basename = "%s.%s" % (self.distribution.get_fullname(), self.plat_name)
pseudoinstall_root = os.path.join(self.dist_dir, archive_basename)
if not self.relative:
archive_root = self.bdist_dir
else:
- if (self.distribution.has_ext_modules() and
- (install.install_base != install.install_platbase)):
+ if self.distribution.has_ext_modules() and (
+ install.install_base != install.install_platbase
+ ):
raise DistutilsPlatformError(
- "can't make a dumb built distribution where "
- "base and platbase are different (%s, %s)"
- % (repr(install.install_base),
- repr(install.install_platbase)))
+ "can't make a dumb built distribution where "
+ "base and platbase are different (%s, %s)"
+ % (repr(install.install_base), repr(install.install_platbase))
+ )
else:
- archive_root = os.path.join(self.bdist_dir,
- ensure_relative(install.install_base))
+ archive_root = os.path.join(
+ self.bdist_dir, ensure_relative(install.install_base)
+ )
# Make the archive
- filename = self.make_archive(pseudoinstall_root,
- self.format, root_dir=archive_root,
- owner=self.owner, group=self.group)
+ filename = self.make_archive(
+ pseudoinstall_root,
+ self.format,
+ root_dir=archive_root,
+ owner=self.owner,
+ group=self.group,
+ )
if self.distribution.has_ext_modules():
pyversion = get_python_version()
else:
pyversion = 'any'
- self.distribution.dist_files.append(('bdist_dumb', pyversion,
- filename))
+ self.distribution.dist_files.append(('bdist_dumb', pyversion, filename))
if not self.keep_temp:
remove_tree(self.bdist_dir, dry_run=self.dry_run)
diff --git a/setuptools/_distutils/command/bdist_msi.py b/setuptools/_distutils/command/bdist_msi.py
index 56c4b988..2f292c96 100644
--- a/setuptools/_distutils/command/bdist_msi.py
+++ b/setuptools/_distutils/command/bdist_msi.py
@@ -20,17 +20,19 @@ import msilib
from msilib import schema, sequence, text
from msilib import Directory, Feature, Dialog, add_data
+
class PyDialog(Dialog):
"""Dialog class with a fixed layout: controls at the top, then a ruler,
then a list of buttons: back, next, cancel. Optionally a bitmap at the
left."""
+
def __init__(self, *args, **kw):
"""Dialog(database, name, x, y, w, h, attributes, title, first,
default, cancel, bitmap=true)"""
super().__init__(*args)
ruler = self.h - 36
- bmwidth = 152*ruler/328
- #if kw.get("bitmap", True):
+ bmwidth = 152 * ruler / 328
+ # if kw.get("bitmap", True):
# self.bitmap("Bitmap", 0, 0, bmwidth, ruler, "PythonWin")
self.line("BottomLine", 0, ruler, self.w, 0)
@@ -38,41 +40,40 @@ class PyDialog(Dialog):
"Set the title text of the dialog at the top."
# name, x, y, w, h, flags=Visible|Enabled|Transparent|NoPrefix,
# text, in VerdanaBold10
- self.text("Title", 15, 10, 320, 60, 0x30003,
- r"{\VerdanaBold10}%s" % title)
+ self.text("Title", 15, 10, 320, 60, 0x30003, r"{\VerdanaBold10}%s" % title)
- def back(self, title, next, name = "Back", active = 1):
+ def back(self, title, next, name="Back", active=1):
"""Add a back button with a given title, the tab-next button,
its name in the Control table, possibly initially disabled.
Return the button, so that events can be associated"""
if active:
- flags = 3 # Visible|Enabled
+ flags = 3 # Visible|Enabled
else:
- flags = 1 # Visible
- return self.pushbutton(name, 180, self.h-27 , 56, 17, flags, title, next)
+ flags = 1 # Visible
+ return self.pushbutton(name, 180, self.h - 27, 56, 17, flags, title, next)
- def cancel(self, title, next, name = "Cancel", active = 1):
+ def cancel(self, title, next, name="Cancel", active=1):
"""Add a cancel button with a given title, the tab-next button,
its name in the Control table, possibly initially disabled.
Return the button, so that events can be associated"""
if active:
- flags = 3 # Visible|Enabled
+ flags = 3 # Visible|Enabled
else:
- flags = 1 # Visible
- return self.pushbutton(name, 304, self.h-27, 56, 17, flags, title, next)
+ flags = 1 # Visible
+ return self.pushbutton(name, 304, self.h - 27, 56, 17, flags, title, next)
- def next(self, title, next, name = "Next", active = 1):
+ def next(self, title, next, name="Next", active=1):
"""Add a Next button with a given title, the tab-next button,
its name in the Control table, possibly initially disabled.
Return the button, so that events can be associated"""
if active:
- flags = 3 # Visible|Enabled
+ flags = 3 # Visible|Enabled
else:
- flags = 1 # Visible
- return self.pushbutton(name, 236, self.h-27, 56, 17, flags, title, next)
+ flags = 1 # Visible
+ return self.pushbutton(name, 236, self.h - 27, 56, 17, flags, title, next)
def xbutton(self, name, title, next, xpos):
"""Add a button with a given title, the tab-next button,
@@ -80,55 +81,96 @@ class PyDialog(Dialog):
y-position is aligned with the other buttons.
Return the button, so that events can be associated"""
- return self.pushbutton(name, int(self.w*xpos - 28), self.h-27, 56, 17, 3, title, next)
+ return self.pushbutton(
+ name, int(self.w * xpos - 28), self.h - 27, 56, 17, 3, title, next
+ )
+
class bdist_msi(Command):
description = "create a Microsoft Installer (.msi) binary distribution"
- user_options = [('bdist-dir=', None,
- "temporary directory for creating the distribution"),
- ('plat-name=', 'p',
- "platform name to embed in generated filenames "
- "(default: %s)" % get_platform()),
- ('keep-temp', 'k',
- "keep the pseudo-installation tree around after " +
- "creating the distribution archive"),
- ('target-version=', None,
- "require a specific python version" +
- " on the target system"),
- ('no-target-compile', 'c',
- "do not compile .py to .pyc on the target system"),
- ('no-target-optimize', 'o',
- "do not compile .py to .pyo (optimized) "
- "on the target system"),
- ('dist-dir=', 'd',
- "directory to put final built distributions in"),
- ('skip-build', None,
- "skip rebuilding everything (for testing/debugging)"),
- ('install-script=', None,
- "basename of installation script to be run after "
- "installation or before deinstallation"),
- ('pre-install-script=', None,
- "Fully qualified filename of a script to be run before "
- "any files are installed. This script need not be in the "
- "distribution"),
- ]
-
- boolean_options = ['keep-temp', 'no-target-compile', 'no-target-optimize',
- 'skip-build']
-
- all_versions = ['2.0', '2.1', '2.2', '2.3', '2.4',
- '2.5', '2.6', '2.7', '2.8', '2.9',
- '3.0', '3.1', '3.2', '3.3', '3.4',
- '3.5', '3.6', '3.7', '3.8', '3.9']
+ user_options = [
+ ('bdist-dir=', None, "temporary directory for creating the distribution"),
+ (
+ 'plat-name=',
+ 'p',
+ "platform name to embed in generated filenames "
+ "(default: %s)" % get_platform(),
+ ),
+ (
+ 'keep-temp',
+ 'k',
+ "keep the pseudo-installation tree around after "
+ + "creating the distribution archive",
+ ),
+ (
+ 'target-version=',
+ None,
+ "require a specific python version" + " on the target system",
+ ),
+ ('no-target-compile', 'c', "do not compile .py to .pyc on the target system"),
+ (
+ 'no-target-optimize',
+ 'o',
+ "do not compile .py to .pyo (optimized) " "on the target system",
+ ),
+ ('dist-dir=', 'd', "directory to put final built distributions in"),
+ ('skip-build', None, "skip rebuilding everything (for testing/debugging)"),
+ (
+ 'install-script=',
+ None,
+ "basename of installation script to be run after "
+ "installation or before deinstallation",
+ ),
+ (
+ 'pre-install-script=',
+ None,
+ "Fully qualified filename of a script to be run before "
+ "any files are installed. This script need not be in the "
+ "distribution",
+ ),
+ ]
+
+ boolean_options = [
+ 'keep-temp',
+ 'no-target-compile',
+ 'no-target-optimize',
+ 'skip-build',
+ ]
+
+ all_versions = [
+ '2.0',
+ '2.1',
+ '2.2',
+ '2.3',
+ '2.4',
+ '2.5',
+ '2.6',
+ '2.7',
+ '2.8',
+ '2.9',
+ '3.0',
+ '3.1',
+ '3.2',
+ '3.3',
+ '3.4',
+ '3.5',
+ '3.6',
+ '3.7',
+ '3.8',
+ '3.9',
+ ]
other_version = 'X'
def __init__(self, *args, **kw):
super().__init__(*args, **kw)
- warnings.warn("bdist_msi command is deprecated since Python 3.9, "
- "use bdist_wheel (wheel packages) instead",
- DeprecationWarning, 2)
+ warnings.warn(
+ "bdist_msi command is deprecated since Python 3.9, "
+ "use bdist_wheel (wheel packages) instead",
+ DeprecationWarning,
+ 2,
+ )
def initialize_options(self):
self.bdist_dir = None
@@ -156,22 +198,28 @@ class bdist_msi(Command):
if self.target_version:
self.versions = [self.target_version]
- if not self.skip_build and self.distribution.has_ext_modules()\
- and self.target_version != short_version:
+ if (
+ not self.skip_build
+ and self.distribution.has_ext_modules()
+ and self.target_version != short_version
+ ):
raise DistutilsOptionError(
- "target version can only be %s, or the '--skip-build'"
- " option must be specified" % (short_version,))
+ "target version can only be %s, or the '--skip-build'"
+ " option must be specified" % (short_version,)
+ )
else:
self.versions = list(self.all_versions)
- self.set_undefined_options('bdist',
- ('dist_dir', 'dist_dir'),
- ('plat_name', 'plat_name'),
- )
+ self.set_undefined_options(
+ 'bdist',
+ ('dist_dir', 'dist_dir'),
+ ('plat_name', 'plat_name'),
+ )
if self.pre_install_script:
raise DistutilsOptionError(
- "the pre-install-script feature is not yet implemented")
+ "the pre-install-script feature is not yet implemented"
+ )
if self.install_script:
for script in self.distribution.scripts:
@@ -179,8 +227,8 @@ class bdist_msi(Command):
break
else:
raise DistutilsOptionError(
- "install_script '%s' not found in scripts"
- % self.install_script)
+ "install_script '%s' not found in scripts" % self.install_script
+ )
self.install_script_key = None
def run(self):
@@ -210,8 +258,7 @@ class bdist_msi(Command):
target_version = '%d.%d' % sys.version_info[:2]
plat_specifier = ".%s-%s" % (self.plat_name, target_version)
build = self.get_finalized_command('build')
- build.build_lib = os.path.join(build.build_base,
- 'lib' + plat_specifier)
+ build.build_lib = os.path.join(build.build_base, 'lib' + plat_specifier)
log.info("installing to %s", self.bdist_dir)
install.ensure_finalized()
@@ -228,7 +275,8 @@ class bdist_msi(Command):
fullname = self.distribution.get_fullname()
installer_name = self.get_installer_filename(fullname)
installer_name = os.path.abspath(installer_name)
- if os.path.exists(installer_name): os.unlink(installer_name)
+ if os.path.exists(installer_name):
+ os.unlink(installer_name)
metadata = self.distribution.metadata
author = metadata.author or metadata.maintainer
@@ -244,9 +292,9 @@ class bdist_msi(Command):
product_name = "Python %s %s" % (self.target_version, fullname)
else:
product_name = "Python %s" % (fullname)
- self.db = msilib.init_database(installer_name, schema,
- product_name, msilib.gen_uuid(),
- sversion, author)
+ self.db = msilib.init_database(
+ installer_name, schema, product_name, msilib.gen_uuid(), sversion, author
+ )
msilib.add_tables(self.db, sequence)
props = [('DistVersion', version)]
email = metadata.author_email or metadata.maintainer_email
@@ -276,8 +324,7 @@ class bdist_msi(Command):
rootdir = os.path.abspath(self.bdist_dir)
root = Directory(db, cab, None, rootdir, "TARGETDIR", "SourceDir")
- f = Feature(db, "Python", "Python", "Everything",
- 0, 1, directory="TARGETDIR")
+ f = Feature(db, "Python", "Python", "Everything", 0, 1, directory="TARGETDIR")
items = [(f, root, '')]
for version in self.versions + [self.other_version]:
@@ -312,15 +359,27 @@ class bdist_msi(Command):
dir.start_component(dir.logical, feature, 0)
if afile not in seen:
key = seen[afile] = dir.add_file(file)
- if file==self.install_script:
+ if file == self.install_script:
if self.install_script_key:
raise DistutilsOptionError(
- "Multiple files with name %s" % file)
+ "Multiple files with name %s" % file
+ )
self.install_script_key = '[#%s]' % key
else:
key = seen[afile]
- add_data(self.db, "DuplicateFile",
- [(key + version, dir.component, key, None, dir.logical)])
+ add_data(
+ self.db,
+ "DuplicateFile",
+ [
+ (
+ key + version,
+ dir.component,
+ key,
+ None,
+ dir.logical,
+ )
+ ],
+ )
db.Commit()
cab.commit(db)
@@ -349,32 +408,60 @@ class bdist_msi(Command):
exe_prop = "PYTHON" + ver
if msilib.Win64:
# type: msidbLocatorTypeRawValue + msidbLocatorType64bit
- Type = 2+16
+ Type = 2 + 16
else:
Type = 2
- add_data(self.db, "RegLocator",
- [(machine_reg, 2, install_path, None, Type),
- (user_reg, 1, install_path, None, Type)])
- add_data(self.db, "AppSearch",
- [(machine_prop, machine_reg),
- (user_prop, user_reg)])
- add_data(self.db, "CustomAction",
- [(machine_action, 51+256, target_dir_prop, "[" + machine_prop + "]"),
- (user_action, 51+256, target_dir_prop, "[" + user_prop + "]"),
- (exe_action, 51+256, exe_prop, "[" + target_dir_prop + "]\\python.exe"),
- ])
- add_data(self.db, "InstallExecuteSequence",
- [(machine_action, machine_prop, start),
- (user_action, user_prop, start + 1),
- (exe_action, None, start + 2),
- ])
- add_data(self.db, "InstallUISequence",
- [(machine_action, machine_prop, start),
- (user_action, user_prop, start + 1),
- (exe_action, None, start + 2),
- ])
- add_data(self.db, "Condition",
- [("Python" + ver, 0, "NOT TARGETDIR" + ver)])
+ add_data(
+ self.db,
+ "RegLocator",
+ [
+ (machine_reg, 2, install_path, None, Type),
+ (user_reg, 1, install_path, None, Type),
+ ],
+ )
+ add_data(
+ self.db,
+ "AppSearch",
+ [(machine_prop, machine_reg), (user_prop, user_reg)],
+ )
+ add_data(
+ self.db,
+ "CustomAction",
+ [
+ (
+ machine_action,
+ 51 + 256,
+ target_dir_prop,
+ "[" + machine_prop + "]",
+ ),
+ (user_action, 51 + 256, target_dir_prop, "[" + user_prop + "]"),
+ (
+ exe_action,
+ 51 + 256,
+ exe_prop,
+ "[" + target_dir_prop + "]\\python.exe",
+ ),
+ ],
+ )
+ add_data(
+ self.db,
+ "InstallExecuteSequence",
+ [
+ (machine_action, machine_prop, start),
+ (user_action, user_prop, start + 1),
+ (exe_action, None, start + 2),
+ ],
+ )
+ add_data(
+ self.db,
+ "InstallUISequence",
+ [
+ (machine_action, machine_prop, start),
+ (user_action, user_prop, start + 1),
+ (exe_action, None, start + 2),
+ ],
+ )
+ add_data(self.db, "Condition", [("Python" + ver, 0, "NOT TARGETDIR" + ver)])
start += 4
assert start < 500
@@ -384,10 +471,16 @@ class bdist_msi(Command):
for ver in self.versions + [self.other_version]:
install_action = "install_script." + ver
exe_prop = "PYTHON" + ver
- add_data(self.db, "CustomAction",
- [(install_action, 50, exe_prop, self.install_script_key)])
- add_data(self.db, "InstallExecuteSequence",
- [(install_action, "&Python%s=3" % ver, start)])
+ add_data(
+ self.db,
+ "CustomAction",
+ [(install_action, 50, exe_prop, self.install_script_key)],
+ )
+ add_data(
+ self.db,
+ "InstallExecuteSequence",
+ [(install_action, "&Python%s=3" % ver, start)],
+ )
start += 1
# XXX pre-install scripts are currently refused in finalize_options()
# but if this feature is completed, it will also need to add
@@ -406,15 +499,13 @@ class bdist_msi(Command):
f.write('rem ="""\n%1 %0\nexit\n"""\n')
with open(self.pre_install_script) as fin:
f.write(fin.read())
- add_data(self.db, "Binary",
- [("PreInstall", msilib.Binary(scriptfn))
- ])
- add_data(self.db, "CustomAction",
- [("PreInstall", 2, "PreInstall", None)
- ])
- add_data(self.db, "InstallExecuteSequence",
- [("PreInstall", "NOT Installed", 450)])
-
+ add_data(self.db, "Binary", [("PreInstall", msilib.Binary(scriptfn))])
+ add_data(self.db, "CustomAction", [("PreInstall", 2, "PreInstall", None)])
+ add_data(
+ self.db,
+ "InstallExecuteSequence",
+ [("PreInstall", "NOT Installed", 450)],
+ )
def add_ui(self):
db = self.db
@@ -424,168 +515,322 @@ class bdist_msi(Command):
title = "[ProductName] Setup"
# see "Dialog Style Bits"
- modal = 3 # visible | modal
- modeless = 1 # visible
+ modal = 3 # visible | modal
+ modeless = 1 # visible
track_disk_space = 32
# UI customization properties
- add_data(db, "Property",
- # See "DefaultUIFont Property"
- [("DefaultUIFont", "DlgFont8"),
- # See "ErrorDialog Style Bit"
- ("ErrorDialog", "ErrorDlg"),
- ("Progress1", "Install"), # modified in maintenance type dlg
- ("Progress2", "installs"),
- ("MaintenanceForm_Action", "Repair"),
- # possible values: ALL, JUSTME
- ("WhichUsers", "ALL")
- ])
+ add_data(
+ db,
+ "Property",
+ # See "DefaultUIFont Property"
+ [
+ ("DefaultUIFont", "DlgFont8"),
+ # See "ErrorDialog Style Bit"
+ ("ErrorDialog", "ErrorDlg"),
+ ("Progress1", "Install"), # modified in maintenance type dlg
+ ("Progress2", "installs"),
+ ("MaintenanceForm_Action", "Repair"),
+ # possible values: ALL, JUSTME
+ ("WhichUsers", "ALL"),
+ ],
+ )
# Fonts, see "TextStyle Table"
- add_data(db, "TextStyle",
- [("DlgFont8", "Tahoma", 9, None, 0),
- ("DlgFontBold8", "Tahoma", 8, None, 1), #bold
- ("VerdanaBold10", "Verdana", 10, None, 1),
- ("VerdanaRed9", "Verdana", 9, 255, 0),
- ])
+ add_data(
+ db,
+ "TextStyle",
+ [
+ ("DlgFont8", "Tahoma", 9, None, 0),
+ ("DlgFontBold8", "Tahoma", 8, None, 1), # bold
+ ("VerdanaBold10", "Verdana", 10, None, 1),
+ ("VerdanaRed9", "Verdana", 9, 255, 0),
+ ],
+ )
# UI Sequences, see "InstallUISequence Table", "Using a Sequence Table"
# Numbers indicate sequence; see sequence.py for how these action integrate
- add_data(db, "InstallUISequence",
- [("PrepareDlg", "Not Privileged or Windows9x or Installed", 140),
- ("WhichUsersDlg", "Privileged and not Windows9x and not Installed", 141),
- # In the user interface, assume all-users installation if privileged.
- ("SelectFeaturesDlg", "Not Installed", 1230),
- # XXX no support for resume installations yet
- #("ResumeDlg", "Installed AND (RESUME OR Preselected)", 1240),
- ("MaintenanceTypeDlg", "Installed AND NOT RESUME AND NOT Preselected", 1250),
- ("ProgressDlg", None, 1280)])
+ add_data(
+ db,
+ "InstallUISequence",
+ [
+ ("PrepareDlg", "Not Privileged or Windows9x or Installed", 140),
+ (
+ "WhichUsersDlg",
+ "Privileged and not Windows9x and not Installed",
+ 141,
+ ),
+ # In the user interface, assume all-users installation if privileged.
+ ("SelectFeaturesDlg", "Not Installed", 1230),
+ # XXX no support for resume installations yet
+ # ("ResumeDlg", "Installed AND (RESUME OR Preselected)", 1240),
+ (
+ "MaintenanceTypeDlg",
+ "Installed AND NOT RESUME AND NOT Preselected",
+ 1250,
+ ),
+ ("ProgressDlg", None, 1280),
+ ],
+ )
add_data(db, 'ActionText', text.ActionText)
add_data(db, 'UIText', text.UIText)
#####################################################################
# Standard dialogs: FatalError, UserExit, ExitDialog
- fatal=PyDialog(db, "FatalError", x, y, w, h, modal, title,
- "Finish", "Finish", "Finish")
+ fatal = PyDialog(
+ db, "FatalError", x, y, w, h, modal, title, "Finish", "Finish", "Finish"
+ )
fatal.title("[ProductName] Installer ended prematurely")
- fatal.back("< Back", "Finish", active = 0)
- fatal.cancel("Cancel", "Back", active = 0)
- fatal.text("Description1", 15, 70, 320, 80, 0x30003,
- "[ProductName] setup ended prematurely because of an error. Your system has not been modified. To install this program at a later time, please run the installation again.")
- fatal.text("Description2", 15, 155, 320, 20, 0x30003,
- "Click the Finish button to exit the Installer.")
- c=fatal.next("Finish", "Cancel", name="Finish")
+ fatal.back("< Back", "Finish", active=0)
+ fatal.cancel("Cancel", "Back", active=0)
+ fatal.text(
+ "Description1",
+ 15,
+ 70,
+ 320,
+ 80,
+ 0x30003,
+ "[ProductName] setup ended prematurely because of an error. Your system has not been modified. To install this program at a later time, please run the installation again.",
+ )
+ fatal.text(
+ "Description2",
+ 15,
+ 155,
+ 320,
+ 20,
+ 0x30003,
+ "Click the Finish button to exit the Installer.",
+ )
+ c = fatal.next("Finish", "Cancel", name="Finish")
c.event("EndDialog", "Exit")
- user_exit=PyDialog(db, "UserExit", x, y, w, h, modal, title,
- "Finish", "Finish", "Finish")
+ user_exit = PyDialog(
+ db, "UserExit", x, y, w, h, modal, title, "Finish", "Finish", "Finish"
+ )
user_exit.title("[ProductName] Installer was interrupted")
- user_exit.back("< Back", "Finish", active = 0)
- user_exit.cancel("Cancel", "Back", active = 0)
- user_exit.text("Description1", 15, 70, 320, 80, 0x30003,
- "[ProductName] setup was interrupted. Your system has not been modified. "
- "To install this program at a later time, please run the installation again.")
- user_exit.text("Description2", 15, 155, 320, 20, 0x30003,
- "Click the Finish button to exit the Installer.")
+ user_exit.back("< Back", "Finish", active=0)
+ user_exit.cancel("Cancel", "Back", active=0)
+ user_exit.text(
+ "Description1",
+ 15,
+ 70,
+ 320,
+ 80,
+ 0x30003,
+ "[ProductName] setup was interrupted. Your system has not been modified. "
+ "To install this program at a later time, please run the installation again.",
+ )
+ user_exit.text(
+ "Description2",
+ 15,
+ 155,
+ 320,
+ 20,
+ 0x30003,
+ "Click the Finish button to exit the Installer.",
+ )
c = user_exit.next("Finish", "Cancel", name="Finish")
c.event("EndDialog", "Exit")
- exit_dialog = PyDialog(db, "ExitDialog", x, y, w, h, modal, title,
- "Finish", "Finish", "Finish")
+ exit_dialog = PyDialog(
+ db, "ExitDialog", x, y, w, h, modal, title, "Finish", "Finish", "Finish"
+ )
exit_dialog.title("Completing the [ProductName] Installer")
- exit_dialog.back("< Back", "Finish", active = 0)
- exit_dialog.cancel("Cancel", "Back", active = 0)
- exit_dialog.text("Description", 15, 235, 320, 20, 0x30003,
- "Click the Finish button to exit the Installer.")
+ exit_dialog.back("< Back", "Finish", active=0)
+ exit_dialog.cancel("Cancel", "Back", active=0)
+ exit_dialog.text(
+ "Description",
+ 15,
+ 235,
+ 320,
+ 20,
+ 0x30003,
+ "Click the Finish button to exit the Installer.",
+ )
c = exit_dialog.next("Finish", "Cancel", name="Finish")
c.event("EndDialog", "Return")
#####################################################################
# Required dialog: FilesInUse, ErrorDlg
- inuse = PyDialog(db, "FilesInUse",
- x, y, w, h,
- 19, # KeepModeless|Modal|Visible
- title,
- "Retry", "Retry", "Retry", bitmap=False)
- inuse.text("Title", 15, 6, 200, 15, 0x30003,
- r"{\DlgFontBold8}Files in Use")
- inuse.text("Description", 20, 23, 280, 20, 0x30003,
- "Some files that need to be updated are currently in use.")
- inuse.text("Text", 20, 55, 330, 50, 3,
- "The following applications are using files that need to be updated by this setup. Close these applications and then click Retry to continue the installation or Cancel to exit it.")
- inuse.control("List", "ListBox", 20, 107, 330, 130, 7, "FileInUseProcess",
- None, None, None)
- c=inuse.back("Exit", "Ignore", name="Exit")
+ inuse = PyDialog(
+ db,
+ "FilesInUse",
+ x,
+ y,
+ w,
+ h,
+ 19, # KeepModeless|Modal|Visible
+ title,
+ "Retry",
+ "Retry",
+ "Retry",
+ bitmap=False,
+ )
+ inuse.text("Title", 15, 6, 200, 15, 0x30003, r"{\DlgFontBold8}Files in Use")
+ inuse.text(
+ "Description",
+ 20,
+ 23,
+ 280,
+ 20,
+ 0x30003,
+ "Some files that need to be updated are currently in use.",
+ )
+ inuse.text(
+ "Text",
+ 20,
+ 55,
+ 330,
+ 50,
+ 3,
+ "The following applications are using files that need to be updated by this setup. Close these applications and then click Retry to continue the installation or Cancel to exit it.",
+ )
+ inuse.control(
+ "List",
+ "ListBox",
+ 20,
+ 107,
+ 330,
+ 130,
+ 7,
+ "FileInUseProcess",
+ None,
+ None,
+ None,
+ )
+ c = inuse.back("Exit", "Ignore", name="Exit")
c.event("EndDialog", "Exit")
- c=inuse.next("Ignore", "Retry", name="Ignore")
+ c = inuse.next("Ignore", "Retry", name="Ignore")
c.event("EndDialog", "Ignore")
- c=inuse.cancel("Retry", "Exit", name="Retry")
- c.event("EndDialog","Retry")
+ c = inuse.cancel("Retry", "Exit", name="Retry")
+ c.event("EndDialog", "Retry")
# See "Error Dialog". See "ICE20" for the required names of the controls.
- error = Dialog(db, "ErrorDlg",
- 50, 10, 330, 101,
- 65543, # Error|Minimize|Modal|Visible
- title,
- "ErrorText", None, None)
- error.text("ErrorText", 50,9,280,48,3, "")
- #error.control("ErrorIcon", "Icon", 15, 9, 24, 24, 5242881, None, "py.ico", None, None)
- error.pushbutton("N",120,72,81,21,3,"No",None).event("EndDialog","ErrorNo")
- error.pushbutton("Y",240,72,81,21,3,"Yes",None).event("EndDialog","ErrorYes")
- error.pushbutton("A",0,72,81,21,3,"Abort",None).event("EndDialog","ErrorAbort")
- error.pushbutton("C",42,72,81,21,3,"Cancel",None).event("EndDialog","ErrorCancel")
- error.pushbutton("I",81,72,81,21,3,"Ignore",None).event("EndDialog","ErrorIgnore")
- error.pushbutton("O",159,72,81,21,3,"Ok",None).event("EndDialog","ErrorOk")
- error.pushbutton("R",198,72,81,21,3,"Retry",None).event("EndDialog","ErrorRetry")
+ error = Dialog(
+ db,
+ "ErrorDlg",
+ 50,
+ 10,
+ 330,
+ 101,
+ 65543, # Error|Minimize|Modal|Visible
+ title,
+ "ErrorText",
+ None,
+ None,
+ )
+ error.text("ErrorText", 50, 9, 280, 48, 3, "")
+ # error.control("ErrorIcon", "Icon", 15, 9, 24, 24, 5242881, None, "py.ico", None, None)
+ error.pushbutton("N", 120, 72, 81, 21, 3, "No", None).event(
+ "EndDialog", "ErrorNo"
+ )
+ error.pushbutton("Y", 240, 72, 81, 21, 3, "Yes", None).event(
+ "EndDialog", "ErrorYes"
+ )
+ error.pushbutton("A", 0, 72, 81, 21, 3, "Abort", None).event(
+ "EndDialog", "ErrorAbort"
+ )
+ error.pushbutton("C", 42, 72, 81, 21, 3, "Cancel", None).event(
+ "EndDialog", "ErrorCancel"
+ )
+ error.pushbutton("I", 81, 72, 81, 21, 3, "Ignore", None).event(
+ "EndDialog", "ErrorIgnore"
+ )
+ error.pushbutton("O", 159, 72, 81, 21, 3, "Ok", None).event(
+ "EndDialog", "ErrorOk"
+ )
+ error.pushbutton("R", 198, 72, 81, 21, 3, "Retry", None).event(
+ "EndDialog", "ErrorRetry"
+ )
#####################################################################
# Global "Query Cancel" dialog
- cancel = Dialog(db, "CancelDlg", 50, 10, 260, 85, 3, title,
- "No", "No", "No")
- cancel.text("Text", 48, 15, 194, 30, 3,
- "Are you sure you want to cancel [ProductName] installation?")
- #cancel.control("Icon", "Icon", 15, 15, 24, 24, 5242881, None,
+ cancel = Dialog(db, "CancelDlg", 50, 10, 260, 85, 3, title, "No", "No", "No")
+ cancel.text(
+ "Text",
+ 48,
+ 15,
+ 194,
+ 30,
+ 3,
+ "Are you sure you want to cancel [ProductName] installation?",
+ )
+ # cancel.control("Icon", "Icon", 15, 15, 24, 24, 5242881, None,
# "py.ico", None, None)
- c=cancel.pushbutton("Yes", 72, 57, 56, 17, 3, "Yes", "No")
+ c = cancel.pushbutton("Yes", 72, 57, 56, 17, 3, "Yes", "No")
c.event("EndDialog", "Exit")
- c=cancel.pushbutton("No", 132, 57, 56, 17, 3, "No", "Yes")
+ c = cancel.pushbutton("No", 132, 57, 56, 17, 3, "No", "Yes")
c.event("EndDialog", "Return")
#####################################################################
# Global "Wait for costing" dialog
- costing = Dialog(db, "WaitForCostingDlg", 50, 10, 260, 85, modal, title,
- "Return", "Return", "Return")
- costing.text("Text", 48, 15, 194, 30, 3,
- "Please wait while the installer finishes determining your disk space requirements.")
+ costing = Dialog(
+ db,
+ "WaitForCostingDlg",
+ 50,
+ 10,
+ 260,
+ 85,
+ modal,
+ title,
+ "Return",
+ "Return",
+ "Return",
+ )
+ costing.text(
+ "Text",
+ 48,
+ 15,
+ 194,
+ 30,
+ 3,
+ "Please wait while the installer finishes determining your disk space requirements.",
+ )
c = costing.pushbutton("Return", 102, 57, 56, 17, 3, "Return", None)
c.event("EndDialog", "Exit")
#####################################################################
# Preparation dialog: no user input except cancellation
- prep = PyDialog(db, "PrepareDlg", x, y, w, h, modeless, title,
- "Cancel", "Cancel", "Cancel")
- prep.text("Description", 15, 70, 320, 40, 0x30003,
- "Please wait while the Installer prepares to guide you through the installation.")
+ prep = PyDialog(
+ db, "PrepareDlg", x, y, w, h, modeless, title, "Cancel", "Cancel", "Cancel"
+ )
+ prep.text(
+ "Description",
+ 15,
+ 70,
+ 320,
+ 40,
+ 0x30003,
+ "Please wait while the Installer prepares to guide you through the installation.",
+ )
prep.title("Welcome to the [ProductName] Installer")
- c=prep.text("ActionText", 15, 110, 320, 20, 0x30003, "Pondering...")
+ c = prep.text("ActionText", 15, 110, 320, 20, 0x30003, "Pondering...")
c.mapping("ActionText", "Text")
- c=prep.text("ActionData", 15, 135, 320, 30, 0x30003, None)
+ c = prep.text("ActionData", 15, 135, 320, 30, 0x30003, None)
c.mapping("ActionData", "Text")
prep.back("Back", None, active=0)
prep.next("Next", None, active=0)
- c=prep.cancel("Cancel", None)
+ c = prep.cancel("Cancel", None)
c.event("SpawnDialog", "CancelDlg")
#####################################################################
# Feature (Python directory) selection
- seldlg = PyDialog(db, "SelectFeaturesDlg", x, y, w, h, modal, title,
- "Next", "Next", "Cancel")
+ seldlg = PyDialog(
+ db, "SelectFeaturesDlg", x, y, w, h, modal, title, "Next", "Next", "Cancel"
+ )
seldlg.title("Select Python Installations")
- seldlg.text("Hint", 15, 30, 300, 20, 3,
- "Select the Python locations where %s should be installed."
- % self.distribution.get_fullname())
+ seldlg.text(
+ "Hint",
+ 15,
+ 30,
+ 300,
+ 20,
+ 3,
+ "Select the Python locations where %s should be installed."
+ % self.distribution.get_fullname(),
+ )
seldlg.back("< Back", None, active=0)
c = seldlg.next("Next >", "Cancel")
@@ -593,30 +838,56 @@ class bdist_msi(Command):
c.event("[TARGETDIR]", "[SourceDir]", ordering=order)
for version in self.versions + [self.other_version]:
order += 1
- c.event("[TARGETDIR]", "[TARGETDIR%s]" % version,
- "FEATURE_SELECTED AND &Python%s=3" % version,
- ordering=order)
+ c.event(
+ "[TARGETDIR]",
+ "[TARGETDIR%s]" % version,
+ "FEATURE_SELECTED AND &Python%s=3" % version,
+ ordering=order,
+ )
c.event("SpawnWaitDialog", "WaitForCostingDlg", ordering=order + 1)
c.event("EndDialog", "Return", ordering=order + 2)
c = seldlg.cancel("Cancel", "Features")
c.event("SpawnDialog", "CancelDlg")
- c = seldlg.control("Features", "SelectionTree", 15, 60, 300, 120, 3,
- "FEATURE", None, "PathEdit", None)
+ c = seldlg.control(
+ "Features",
+ "SelectionTree",
+ 15,
+ 60,
+ 300,
+ 120,
+ 3,
+ "FEATURE",
+ None,
+ "PathEdit",
+ None,
+ )
c.event("[FEATURE_SELECTED]", "1")
ver = self.other_version
install_other_cond = "FEATURE_SELECTED AND &Python%s=3" % ver
dont_install_other_cond = "FEATURE_SELECTED AND &Python%s<>3" % ver
- c = seldlg.text("Other", 15, 200, 300, 15, 3,
- "Provide an alternate Python location")
+ c = seldlg.text(
+ "Other", 15, 200, 300, 15, 3, "Provide an alternate Python location"
+ )
c.condition("Enable", install_other_cond)
c.condition("Show", install_other_cond)
c.condition("Disable", dont_install_other_cond)
c.condition("Hide", dont_install_other_cond)
- c = seldlg.control("PathEdit", "PathEdit", 15, 215, 300, 16, 1,
- "TARGETDIR" + ver, None, "Next", None)
+ c = seldlg.control(
+ "PathEdit",
+ "PathEdit",
+ 15,
+ 215,
+ 300,
+ 16,
+ 1,
+ "TARGETDIR" + ver,
+ None,
+ "Next",
+ None,
+ )
c.condition("Enable", install_other_cond)
c.condition("Show", install_other_cond)
c.condition("Disable", dont_install_other_cond)
@@ -624,20 +895,47 @@ class bdist_msi(Command):
#####################################################################
# Disk cost
- cost = PyDialog(db, "DiskCostDlg", x, y, w, h, modal, title,
- "OK", "OK", "OK", bitmap=False)
- cost.text("Title", 15, 6, 200, 15, 0x30003,
- r"{\DlgFontBold8}Disk Space Requirements")
- cost.text("Description", 20, 20, 280, 20, 0x30003,
- "The disk space required for the installation of the selected features.")
- cost.text("Text", 20, 53, 330, 60, 3,
- "The highlighted volumes (if any) do not have enough disk space "
- "available for the currently selected features. You can either "
- "remove some files from the highlighted volumes, or choose to "
- "install less features onto local drive(s), or select different "
- "destination drive(s).")
- cost.control("VolumeList", "VolumeCostList", 20, 100, 330, 150, 393223,
- None, "{120}{70}{70}{70}{70}", None, None)
+ cost = PyDialog(
+ db, "DiskCostDlg", x, y, w, h, modal, title, "OK", "OK", "OK", bitmap=False
+ )
+ cost.text(
+ "Title", 15, 6, 200, 15, 0x30003, r"{\DlgFontBold8}Disk Space Requirements"
+ )
+ cost.text(
+ "Description",
+ 20,
+ 20,
+ 280,
+ 20,
+ 0x30003,
+ "The disk space required for the installation of the selected features.",
+ )
+ cost.text(
+ "Text",
+ 20,
+ 53,
+ 330,
+ 60,
+ 3,
+ "The highlighted volumes (if any) do not have enough disk space "
+ "available for the currently selected features. You can either "
+ "remove some files from the highlighted volumes, or choose to "
+ "install less features onto local drive(s), or select different "
+ "destination drive(s).",
+ )
+ cost.control(
+ "VolumeList",
+ "VolumeCostList",
+ 20,
+ 100,
+ 330,
+ 150,
+ 393223,
+ None,
+ "{120}{70}{70}{70}{70}",
+ None,
+ None,
+ )
cost.xbutton("OK", "Ok", None, 0.5).event("EndDialog", "Return")
#####################################################################
@@ -651,12 +949,26 @@ class bdist_msi(Command):
# On Windows9x, the ALLUSERS property is ignored on the command line
# and in the Property table, but installer fails according to the documentation
# if a dialog attempts to set ALLUSERS.
- whichusers = PyDialog(db, "WhichUsersDlg", x, y, w, h, modal, title,
- "AdminInstall", "Next", "Cancel")
- whichusers.title("Select whether to install [ProductName] for all users of this computer.")
+ whichusers = PyDialog(
+ db,
+ "WhichUsersDlg",
+ x,
+ y,
+ w,
+ h,
+ modal,
+ title,
+ "AdminInstall",
+ "Next",
+ "Cancel",
+ )
+ whichusers.title(
+ "Select whether to install [ProductName] for all users of this computer."
+ )
# A radio group with two options: allusers, justme
- g = whichusers.radiogroup("AdminInstall", 15, 60, 260, 50, 3,
- "WhichUsers", "", "Next")
+ g = whichusers.radiogroup(
+ "AdminInstall", 15, 60, 260, 50, 3, "WhichUsers", "", "Next"
+ )
g.add("ALL", 0, 5, 150, 20, "Install for all users")
g.add("JUSTME", 0, 25, 150, 20, "Install just for me")
@@ -664,30 +976,67 @@ class bdist_msi(Command):
c = whichusers.next("Next >", "Cancel")
c.event("[ALLUSERS]", "1", 'WhichUsers="ALL"', 1)
- c.event("EndDialog", "Return", ordering = 2)
+ c.event("EndDialog", "Return", ordering=2)
c = whichusers.cancel("Cancel", "AdminInstall")
c.event("SpawnDialog", "CancelDlg")
#####################################################################
# Installation Progress dialog (modeless)
- progress = PyDialog(db, "ProgressDlg", x, y, w, h, modeless, title,
- "Cancel", "Cancel", "Cancel", bitmap=False)
- progress.text("Title", 20, 15, 200, 15, 0x30003,
- r"{\DlgFontBold8}[Progress1] [ProductName]")
- progress.text("Text", 35, 65, 300, 30, 3,
- "Please wait while the Installer [Progress2] [ProductName]. "
- "This may take several minutes.")
+ progress = PyDialog(
+ db,
+ "ProgressDlg",
+ x,
+ y,
+ w,
+ h,
+ modeless,
+ title,
+ "Cancel",
+ "Cancel",
+ "Cancel",
+ bitmap=False,
+ )
+ progress.text(
+ "Title",
+ 20,
+ 15,
+ 200,
+ 15,
+ 0x30003,
+ r"{\DlgFontBold8}[Progress1] [ProductName]",
+ )
+ progress.text(
+ "Text",
+ 35,
+ 65,
+ 300,
+ 30,
+ 3,
+ "Please wait while the Installer [Progress2] [ProductName]. "
+ "This may take several minutes.",
+ )
progress.text("StatusLabel", 35, 100, 35, 20, 3, "Status:")
- c=progress.text("ActionText", 70, 100, w-70, 20, 3, "Pondering...")
+ c = progress.text("ActionText", 70, 100, w - 70, 20, 3, "Pondering...")
c.mapping("ActionText", "Text")
- #c=progress.text("ActionData", 35, 140, 300, 20, 3, None)
- #c.mapping("ActionData", "Text")
-
- c=progress.control("ProgressBar", "ProgressBar", 35, 120, 300, 10, 65537,
- None, "Progress done", None, None)
+ # c=progress.text("ActionData", 35, 140, 300, 20, 3, None)
+ # c.mapping("ActionData", "Text")
+
+ c = progress.control(
+ "ProgressBar",
+ "ProgressBar",
+ 35,
+ 120,
+ 300,
+ 10,
+ 65537,
+ None,
+ "Progress done",
+ None,
+ None,
+ )
c.mapping("SetProgress", "Progress")
progress.back("< Back", "Next", active=False)
@@ -696,23 +1045,40 @@ class bdist_msi(Command):
###################################################################
# Maintenance type: repair/uninstall
- maint = PyDialog(db, "MaintenanceTypeDlg", x, y, w, h, modal, title,
- "Next", "Next", "Cancel")
+ maint = PyDialog(
+ db, "MaintenanceTypeDlg", x, y, w, h, modal, title, "Next", "Next", "Cancel"
+ )
maint.title("Welcome to the [ProductName] Setup Wizard")
- maint.text("BodyText", 15, 63, 330, 42, 3,
- "Select whether you want to repair or remove [ProductName].")
- g=maint.radiogroup("RepairRadioGroup", 15, 108, 330, 60, 3,
- "MaintenanceForm_Action", "", "Next")
- #g.add("Change", 0, 0, 200, 17, "&Change [ProductName]")
+ maint.text(
+ "BodyText",
+ 15,
+ 63,
+ 330,
+ 42,
+ 3,
+ "Select whether you want to repair or remove [ProductName].",
+ )
+ g = maint.radiogroup(
+ "RepairRadioGroup",
+ 15,
+ 108,
+ 330,
+ 60,
+ 3,
+ "MaintenanceForm_Action",
+ "",
+ "Next",
+ )
+ # g.add("Change", 0, 0, 200, 17, "&Change [ProductName]")
g.add("Repair", 0, 18, 200, 17, "&Repair [ProductName]")
g.add("Remove", 0, 36, 200, 17, "Re&move [ProductName]")
maint.back("< Back", None, active=False)
- c=maint.next("Finish", "Cancel")
+ c = maint.next("Finish", "Cancel")
# Change installation: Change progress dialog to "Change", then ask
# for feature selection
- #c.event("[Progress1]", "Change", 'MaintenanceForm_Action="Change"', 1)
- #c.event("[Progress2]", "changes", 'MaintenanceForm_Action="Change"', 2)
+ # c.event("[Progress1]", "Change", 'MaintenanceForm_Action="Change"', 1)
+ # c.event("[Progress2]", "changes", 'MaintenanceForm_Action="Change"', 2)
# Reinstall: Change progress dialog to "Repair", then invoke reinstall
# Also set list of reinstalled features to "ALL"
@@ -730,15 +1096,18 @@ class bdist_msi(Command):
# Close dialog when maintenance action scheduled
c.event("EndDialog", "Return", 'MaintenanceForm_Action<>"Change"', 20)
- #c.event("NewDialog", "SelectFeaturesDlg", 'MaintenanceForm_Action="Change"', 21)
+ # c.event("NewDialog", "SelectFeaturesDlg", 'MaintenanceForm_Action="Change"', 21)
maint.cancel("Cancel", "RepairRadioGroup").event("SpawnDialog", "CancelDlg")
def get_installer_filename(self, fullname):
# Factored out to allow overriding in subclasses
if self.target_version:
- base_name = "%s.%s-py%s.msi" % (fullname, self.plat_name,
- self.target_version)
+ base_name = "%s.%s-py%s.msi" % (
+ fullname,
+ self.plat_name,
+ self.target_version,
+ )
else:
base_name = "%s.%s.msi" % (fullname, self.plat_name)
installer_name = os.path.join(self.dist_dir, base_name)
diff --git a/setuptools/_distutils/command/bdist_rpm.py b/setuptools/_distutils/command/bdist_rpm.py
index a2a9e8e5..cf4b9525 100644
--- a/setuptools/_distutils/command/bdist_rpm.py
+++ b/setuptools/_distutils/command/bdist_rpm.py
@@ -11,126 +11,137 @@ from distutils.errors import *
from distutils.sysconfig import get_python_version
from distutils import log
+
class bdist_rpm(Command):
description = "create an RPM distribution"
user_options = [
- ('bdist-base=', None,
- "base directory for creating built distributions"),
- ('rpm-base=', None,
- "base directory for creating RPMs (defaults to \"rpm\" under "
- "--bdist-base; must be specified for RPM 2)"),
- ('dist-dir=', 'd',
- "directory to put final RPM files in "
- "(and .spec files if --spec-only)"),
- ('python=', None,
- "path to Python interpreter to hard-code in the .spec file "
- "(default: \"python\")"),
- ('fix-python', None,
- "hard-code the exact path to the current Python interpreter in "
- "the .spec file"),
- ('spec-only', None,
- "only regenerate spec file"),
- ('source-only', None,
- "only generate source RPM"),
- ('binary-only', None,
- "only generate binary RPM"),
- ('use-bzip2', None,
- "use bzip2 instead of gzip to create source distribution"),
-
+ ('bdist-base=', None, "base directory for creating built distributions"),
+ (
+ 'rpm-base=',
+ None,
+ "base directory for creating RPMs (defaults to \"rpm\" under "
+ "--bdist-base; must be specified for RPM 2)",
+ ),
+ (
+ 'dist-dir=',
+ 'd',
+ "directory to put final RPM files in " "(and .spec files if --spec-only)",
+ ),
+ (
+ 'python=',
+ None,
+ "path to Python interpreter to hard-code in the .spec file "
+ "(default: \"python\")",
+ ),
+ (
+ 'fix-python',
+ None,
+ "hard-code the exact path to the current Python interpreter in "
+ "the .spec file",
+ ),
+ ('spec-only', None, "only regenerate spec file"),
+ ('source-only', None, "only generate source RPM"),
+ ('binary-only', None, "only generate binary RPM"),
+ ('use-bzip2', None, "use bzip2 instead of gzip to create source distribution"),
# More meta-data: too RPM-specific to put in the setup script,
# but needs to go in the .spec file -- so we make these options
# to "bdist_rpm". The idea is that packagers would put this
# info in setup.cfg, although they are of course free to
# supply it on the command line.
- ('distribution-name=', None,
- "name of the (Linux) distribution to which this "
- "RPM applies (*not* the name of the module distribution!)"),
- ('group=', None,
- "package classification [default: \"Development/Libraries\"]"),
- ('release=', None,
- "RPM release number"),
- ('serial=', None,
- "RPM serial number"),
- ('vendor=', None,
- "RPM \"vendor\" (eg. \"Joe Blow <joe@example.com>\") "
- "[default: maintainer or author from setup script]"),
- ('packager=', None,
- "RPM packager (eg. \"Jane Doe <jane@example.net>\") "
- "[default: vendor]"),
- ('doc-files=', None,
- "list of documentation files (space or comma-separated)"),
- ('changelog=', None,
- "RPM changelog"),
- ('icon=', None,
- "name of icon file"),
- ('provides=', None,
- "capabilities provided by this package"),
- ('requires=', None,
- "capabilities required by this package"),
- ('conflicts=', None,
- "capabilities which conflict with this package"),
- ('build-requires=', None,
- "capabilities required to build this package"),
- ('obsoletes=', None,
- "capabilities made obsolete by this package"),
- ('no-autoreq', None,
- "do not automatically calculate dependencies"),
-
+ (
+ 'distribution-name=',
+ None,
+ "name of the (Linux) distribution to which this "
+ "RPM applies (*not* the name of the module distribution!)",
+ ),
+ ('group=', None, "package classification [default: \"Development/Libraries\"]"),
+ ('release=', None, "RPM release number"),
+ ('serial=', None, "RPM serial number"),
+ (
+ 'vendor=',
+ None,
+ "RPM \"vendor\" (eg. \"Joe Blow <joe@example.com>\") "
+ "[default: maintainer or author from setup script]",
+ ),
+ (
+ 'packager=',
+ None,
+ "RPM packager (eg. \"Jane Doe <jane@example.net>\") " "[default: vendor]",
+ ),
+ ('doc-files=', None, "list of documentation files (space or comma-separated)"),
+ ('changelog=', None, "RPM changelog"),
+ ('icon=', None, "name of icon file"),
+ ('provides=', None, "capabilities provided by this package"),
+ ('requires=', None, "capabilities required by this package"),
+ ('conflicts=', None, "capabilities which conflict with this package"),
+ ('build-requires=', None, "capabilities required to build this package"),
+ ('obsoletes=', None, "capabilities made obsolete by this package"),
+ ('no-autoreq', None, "do not automatically calculate dependencies"),
# Actions to take when building RPM
- ('keep-temp', 'k',
- "don't clean up RPM build directory"),
- ('no-keep-temp', None,
- "clean up RPM build directory [default]"),
- ('use-rpm-opt-flags', None,
- "compile with RPM_OPT_FLAGS when building from source RPM"),
- ('no-rpm-opt-flags', None,
- "do not pass any RPM CFLAGS to compiler"),
- ('rpm3-mode', None,
- "RPM 3 compatibility mode (default)"),
- ('rpm2-mode', None,
- "RPM 2 compatibility mode"),
-
+ ('keep-temp', 'k', "don't clean up RPM build directory"),
+ ('no-keep-temp', None, "clean up RPM build directory [default]"),
+ (
+ 'use-rpm-opt-flags',
+ None,
+ "compile with RPM_OPT_FLAGS when building from source RPM",
+ ),
+ ('no-rpm-opt-flags', None, "do not pass any RPM CFLAGS to compiler"),
+ ('rpm3-mode', None, "RPM 3 compatibility mode (default)"),
+ ('rpm2-mode', None, "RPM 2 compatibility mode"),
# Add the hooks necessary for specifying custom scripts
- ('prep-script=', None,
- "Specify a script for the PREP phase of RPM building"),
- ('build-script=', None,
- "Specify a script for the BUILD phase of RPM building"),
-
- ('pre-install=', None,
- "Specify a script for the pre-INSTALL phase of RPM building"),
- ('install-script=', None,
- "Specify a script for the INSTALL phase of RPM building"),
- ('post-install=', None,
- "Specify a script for the post-INSTALL phase of RPM building"),
-
- ('pre-uninstall=', None,
- "Specify a script for the pre-UNINSTALL phase of RPM building"),
- ('post-uninstall=', None,
- "Specify a script for the post-UNINSTALL phase of RPM building"),
-
- ('clean-script=', None,
- "Specify a script for the CLEAN phase of RPM building"),
-
- ('verify-script=', None,
- "Specify a script for the VERIFY phase of the RPM build"),
-
+ ('prep-script=', None, "Specify a script for the PREP phase of RPM building"),
+ ('build-script=', None, "Specify a script for the BUILD phase of RPM building"),
+ (
+ 'pre-install=',
+ None,
+ "Specify a script for the pre-INSTALL phase of RPM building",
+ ),
+ (
+ 'install-script=',
+ None,
+ "Specify a script for the INSTALL phase of RPM building",
+ ),
+ (
+ 'post-install=',
+ None,
+ "Specify a script for the post-INSTALL phase of RPM building",
+ ),
+ (
+ 'pre-uninstall=',
+ None,
+ "Specify a script for the pre-UNINSTALL phase of RPM building",
+ ),
+ (
+ 'post-uninstall=',
+ None,
+ "Specify a script for the post-UNINSTALL phase of RPM building",
+ ),
+ ('clean-script=', None, "Specify a script for the CLEAN phase of RPM building"),
+ (
+ 'verify-script=',
+ None,
+ "Specify a script for the VERIFY phase of the RPM build",
+ ),
# Allow a packager to explicitly force an architecture
- ('force-arch=', None,
- "Force an architecture onto the RPM build process"),
-
- ('quiet', 'q',
- "Run the INSTALL phase of RPM building in quiet mode"),
- ]
-
- boolean_options = ['keep-temp', 'use-rpm-opt-flags', 'rpm3-mode',
- 'no-autoreq', 'quiet']
-
- negative_opt = {'no-keep-temp': 'keep-temp',
- 'no-rpm-opt-flags': 'use-rpm-opt-flags',
- 'rpm2-mode': 'rpm3-mode'}
-
+ ('force-arch=', None, "Force an architecture onto the RPM build process"),
+ ('quiet', 'q', "Run the INSTALL phase of RPM building in quiet mode"),
+ ]
+
+ boolean_options = [
+ 'keep-temp',
+ 'use-rpm-opt-flags',
+ 'rpm3-mode',
+ 'no-autoreq',
+ 'quiet',
+ ]
+
+ negative_opt = {
+ 'no-keep-temp': 'keep-temp',
+ 'no-rpm-opt-flags': 'use-rpm-opt-flags',
+ 'rpm2-mode': 'rpm3-mode',
+ }
def initialize_options(self):
self.bdist_base = None
@@ -181,8 +192,7 @@ class bdist_rpm(Command):
self.set_undefined_options('bdist', ('bdist_base', 'bdist_base'))
if self.rpm_base is None:
if not self.rpm3_mode:
- raise DistutilsOptionError(
- "you must specify --rpm-base in RPM 2 mode")
+ raise DistutilsOptionError("you must specify --rpm-base in RPM 2 mode")
self.rpm_base = os.path.join(self.bdist_base, "rpm")
if self.python is None:
@@ -192,14 +202,17 @@ class bdist_rpm(Command):
self.python = "python3"
elif self.fix_python:
raise DistutilsOptionError(
- "--python and --fix-python are mutually exclusive options")
+ "--python and --fix-python are mutually exclusive options"
+ )
if os.name != 'posix':
- raise DistutilsPlatformError("don't know how to create RPM "
- "distributions on platform %s" % os.name)
+ raise DistutilsPlatformError(
+ "don't know how to create RPM " "distributions on platform %s" % os.name
+ )
if self.binary_only and self.source_only:
raise DistutilsOptionError(
- "cannot supply both '--source-only' and '--binary-only'")
+ "cannot supply both '--source-only' and '--binary-only'"
+ )
# don't pass CFLAGS to pure python distributions
if not self.distribution.has_ext_modules():
@@ -210,9 +223,11 @@ class bdist_rpm(Command):
def finalize_package_data(self):
self.ensure_string('group', "Development/Libraries")
- self.ensure_string('vendor',
- "%s <%s>" % (self.distribution.get_contact(),
- self.distribution.get_contact_email()))
+ self.ensure_string(
+ 'vendor',
+ "%s <%s>"
+ % (self.distribution.get_contact(), self.distribution.get_contact_email()),
+ )
self.ensure_string('packager')
self.ensure_string_list('doc_files')
if isinstance(self.doc_files, list):
@@ -221,12 +236,12 @@ class bdist_rpm(Command):
self.doc_files.append(readme)
self.ensure_string('release', "1")
- self.ensure_string('serial') # should it be an int?
+ self.ensure_string('serial') # should it be an int?
self.ensure_string('distribution_name')
self.ensure_string('changelog')
- # Format changelog correctly
+ # Format changelog correctly
self.changelog = self._format_changelog(self.changelog)
self.ensure_filename('icon')
@@ -274,14 +289,12 @@ class bdist_rpm(Command):
# Spec file goes into 'dist_dir' if '--spec-only specified',
# build/rpm.<plat> otherwise.
- spec_path = os.path.join(spec_dir,
- "%s.spec" % self.distribution.get_name())
- self.execute(write_file,
- (spec_path,
- self._make_spec_file()),
- "writing '%s'" % spec_path)
-
- if self.spec_only: # stop if requested
+ spec_path = os.path.join(spec_dir, "%s.spec" % self.distribution.get_name())
+ self.execute(
+ write_file, (spec_path, self._make_spec_file()), "writing '%s'" % spec_path
+ )
+
+ if self.spec_only: # stop if requested
return
# Make a source distribution and copy to SOURCES directory with
@@ -303,14 +316,13 @@ class bdist_rpm(Command):
if os.path.exists(self.icon):
self.copy_file(self.icon, source_dir)
else:
- raise DistutilsFileError(
- "icon file '%s' does not exist" % self.icon)
+ raise DistutilsFileError("icon file '%s' does not exist" % self.icon)
# build package
log.info("building RPMs")
rpm_cmd = ['rpmbuild']
- if self.source_only: # what kind of RPMs?
+ if self.source_only: # what kind of RPMs?
rpm_cmd.append('-bs')
elif self.binary_only:
rpm_cmd.append('-bb')
@@ -318,8 +330,7 @@ class bdist_rpm(Command):
rpm_cmd.append('-ba')
rpm_cmd.extend(['--define', '__python %s' % self.python])
if self.rpm3_mode:
- rpm_cmd.extend(['--define',
- '_topdir %s' % os.path.abspath(self.rpm_base)])
+ rpm_cmd.extend(['--define', '_topdir %s' % os.path.abspath(self.rpm_base)])
if not self.keep_temp:
rpm_cmd.append('--clean')
@@ -335,7 +346,10 @@ class bdist_rpm(Command):
src_rpm = nvr_string + ".src.rpm"
non_src_rpm = "%{arch}/" + nvr_string + ".%{arch}.rpm"
q_cmd = r"rpm -q --qf '%s %s\n' --specfile '%s'" % (
- src_rpm, non_src_rpm, spec_path)
+ src_rpm,
+ non_src_rpm,
+ spec_path,
+ )
out = os.popen(q_cmd)
try:
@@ -346,7 +360,7 @@ class bdist_rpm(Command):
if not line:
break
l = line.strip().split()
- assert(len(l) == 2)
+ assert len(l) == 2
binary_rpms.append(l[1])
# The source rpm is named after the first entry in the spec file
if source_rpm is None:
@@ -369,21 +383,20 @@ class bdist_rpm(Command):
if not self.binary_only:
srpm = os.path.join(rpm_dir['SRPMS'], source_rpm)
- assert(os.path.exists(srpm))
+ 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))
+ 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))
+ filename = os.path.join(self.dist_dir, os.path.basename(rpm))
self.distribution.dist_files.append(
- ('bdist_rpm', pyversion, filename))
+ ('bdist_rpm', pyversion, filename)
+ )
def _dist_path(self, path):
return os.path.join(self.dist_dir, os.path.basename(path))
@@ -395,12 +408,12 @@ class bdist_rpm(Command):
# definitions and headers
spec_file = [
'%define name ' + self.distribution.get_name(),
- '%define version ' + self.distribution.get_version().replace('-','_'),
+ '%define version ' + self.distribution.get_version().replace('-', '_'),
'%define unmangled_version ' + self.distribution.get_version(),
- '%define release ' + self.release.replace('-','_'),
+ '%define release ' + self.release.replace('-', '_'),
'',
'Summary: ' + (self.distribution.get_description() or "UNKNOWN"),
- ]
+ ]
# Workaround for #14443 which affects some RPM based systems such as
# RHEL6 (and probably derivatives)
@@ -408,8 +421,9 @@ class bdist_rpm(Command):
# Generate a potential replacement value for __os_install_post (whilst
# normalizing the whitespace to simplify the test for whether the
# invocation of brp-python-bytecompile passes in __python):
- vendor_hook = '\n'.join([' %s \\' % line.strip()
- for line in vendor_hook.splitlines()])
+ vendor_hook = '\n'.join(
+ [' %s \\' % line.strip() for line in vendor_hook.splitlines()]
+ )
problem = "brp-python-bytecompile \\\n"
fixed = "brp-python-bytecompile %{__python} \\\n"
fixed_hook = vendor_hook.replace(problem, fixed)
@@ -420,14 +434,17 @@ class bdist_rpm(Command):
# put locale summaries into spec file
# XXX not supported for now (hard to put a dictionary
# in a config file -- arg!)
- #for locale in self.summaries.keys():
+ # for locale in self.summaries.keys():
# spec_file.append('Summary(%s): %s' % (locale,
# self.summaries[locale]))
- spec_file.extend([
- 'Name: %{name}',
- 'Version: %{version}',
- 'Release: %{release}',])
+ spec_file.extend(
+ [
+ 'Name: %{name}',
+ 'Version: %{version}',
+ 'Release: %{release}',
+ ]
+ )
# XXX yuck! this filename is available from the "sdist" command,
# but only after it has run: and we create the spec file before
@@ -437,33 +454,36 @@ class bdist_rpm(Command):
else:
spec_file.append('Source0: %{name}-%{unmangled_version}.tar.gz')
- spec_file.extend([
- 'License: ' + (self.distribution.get_license() or "UNKNOWN"),
- 'Group: ' + self.group,
- 'BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot',
- 'Prefix: %{_prefix}', ])
+ spec_file.extend(
+ [
+ 'License: ' + (self.distribution.get_license() or "UNKNOWN"),
+ 'Group: ' + self.group,
+ 'BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot',
+ 'Prefix: %{_prefix}',
+ ]
+ )
if not self.force_arch:
# noarch if no extension modules
if not self.distribution.has_ext_modules():
spec_file.append('BuildArch: noarch')
else:
- spec_file.append( 'BuildArch: %s' % self.force_arch )
-
- for field in ('Vendor',
- 'Packager',
- 'Provides',
- 'Requires',
- 'Conflicts',
- 'Obsoletes',
- ):
+ spec_file.append('BuildArch: %s' % self.force_arch)
+
+ for field in (
+ 'Vendor',
+ 'Packager',
+ 'Provides',
+ 'Requires',
+ 'Conflicts',
+ 'Obsoletes',
+ ):
val = getattr(self, field.lower())
if isinstance(val, list):
spec_file.append('%s: %s' % (field, ' '.join(val)))
elif val is not None:
spec_file.append('%s: %s' % (field, val))
-
if self.distribution.get_url():
spec_file.append('Url: ' + self.distribution.get_url())
@@ -471,8 +491,7 @@ class bdist_rpm(Command):
spec_file.append('Distribution: ' + self.distribution_name)
if self.build_requires:
- spec_file.append('BuildRequires: ' +
- ' '.join(self.build_requires))
+ spec_file.append('BuildRequires: ' + ' '.join(self.build_requires))
if self.icon:
spec_file.append('Icon: ' + os.path.basename(self.icon))
@@ -480,16 +499,18 @@ class bdist_rpm(Command):
if self.no_autoreq:
spec_file.append('AutoReq: 0')
- spec_file.extend([
- '',
- '%description',
- self.distribution.get_long_description() or "",
- ])
+ spec_file.extend(
+ [
+ '',
+ '%description',
+ self.distribution.get_long_description() or "",
+ ]
+ )
# put locale descriptions into spec file
# XXX again, suppressed because config file syntax doesn't
# easily support this ;-(
- #for locale in self.descriptions.keys():
+ # for locale in self.descriptions.keys():
# spec_file.extend([
# '',
# '%description -l ' + locale,
@@ -498,7 +519,7 @@ class bdist_rpm(Command):
# rpm scripts
# figure out default build script
- def_setup_call = "%s %s" % (self.python,os.path.basename(sys.argv[0]))
+ def_setup_call = "%s %s" % (self.python, os.path.basename(sys.argv[0]))
def_build = "%s build" % def_setup_call
if self.use_rpm_opt_flags:
def_build = 'env CFLAGS="$RPM_OPT_FLAGS" ' + def_build
@@ -509,8 +530,9 @@ class bdist_rpm(Command):
# that we open and interpolate into the spec file, but the defaults
# are just text that we drop in as-is. Hmmm.
- install_cmd = ('%s install -O1 --root=$RPM_BUILD_ROOT '
- '--record=INSTALLED_FILES') % def_setup_call
+ install_cmd = (
+ '%s install -O1 --root=$RPM_BUILD_ROOT ' '--record=INSTALLED_FILES'
+ ) % def_setup_call
script_options = [
('prep', 'prep_script', "%setup -n %{name}-%{unmangled_version}"),
@@ -529,37 +551,43 @@ class bdist_rpm(Command):
# use 'default' as contents of script
val = getattr(self, attr)
if val or default:
- spec_file.extend([
- '',
- '%' + rpm_opt,])
+ spec_file.extend(
+ [
+ '',
+ '%' + rpm_opt,
+ ]
+ )
if val:
with open(val) as f:
spec_file.extend(f.read().split('\n'))
else:
spec_file.append(default)
-
# files section
- spec_file.extend([
- '',
- '%files -f INSTALLED_FILES',
- '%defattr(-,root,root)',
- ])
+ spec_file.extend(
+ [
+ '',
+ '%files -f INSTALLED_FILES',
+ '%defattr(-,root,root)',
+ ]
+ )
if self.doc_files:
spec_file.append('%doc ' + ' '.join(self.doc_files))
if self.changelog:
- spec_file.extend([
- '',
- '%changelog',])
+ spec_file.extend(
+ [
+ '',
+ '%changelog',
+ ]
+ )
spec_file.extend(self.changelog)
return spec_file
def _format_changelog(self, changelog):
- """Format the changelog correctly and convert it to a list of strings
- """
+ """Format the changelog correctly and convert it to a list of strings"""
if not changelog:
return changelog
new_changelog = []
diff --git a/setuptools/_distutils/command/bdist_wininst.py b/setuptools/_distutils/command/bdist_wininst.py
index 0e9ddaa2..76b8a890 100644
--- a/setuptools/_distutils/command/bdist_wininst.py
+++ b/setuptools/_distutils/command/bdist_wininst.py
@@ -13,58 +13,88 @@ from distutils.errors import *
from distutils.sysconfig import get_python_version
from distutils import log
+
class bdist_wininst(Command):
description = "create an executable installer for MS Windows"
- user_options = [('bdist-dir=', None,
- "temporary directory for creating the distribution"),
- ('plat-name=', 'p',
- "platform name to embed in generated filenames "
- "(default: %s)" % get_platform()),
- ('keep-temp', 'k',
- "keep the pseudo-installation tree around after " +
- "creating the distribution archive"),
- ('target-version=', None,
- "require a specific python version" +
- " on the target system"),
- ('no-target-compile', 'c',
- "do not compile .py to .pyc on the target system"),
- ('no-target-optimize', 'o',
- "do not compile .py to .pyo (optimized) "
- "on the target system"),
- ('dist-dir=', 'd',
- "directory to put final built distributions in"),
- ('bitmap=', 'b',
- "bitmap to use for the installer instead of python-powered logo"),
- ('title=', 't',
- "title to display on the installer background instead of default"),
- ('skip-build', None,
- "skip rebuilding everything (for testing/debugging)"),
- ('install-script=', None,
- "basename of installation script to be run after "
- "installation or before deinstallation"),
- ('pre-install-script=', None,
- "Fully qualified filename of a script to be run before "
- "any files are installed. This script need not be in the "
- "distribution"),
- ('user-access-control=', None,
- "specify Vista's UAC handling - 'none'/default=no "
- "handling, 'auto'=use UAC if target Python installed for "
- "all users, 'force'=always use UAC"),
- ]
-
- boolean_options = ['keep-temp', 'no-target-compile', 'no-target-optimize',
- 'skip-build']
+ user_options = [
+ ('bdist-dir=', None, "temporary directory for creating the distribution"),
+ (
+ 'plat-name=',
+ 'p',
+ "platform name to embed in generated filenames "
+ "(default: %s)" % get_platform(),
+ ),
+ (
+ 'keep-temp',
+ 'k',
+ "keep the pseudo-installation tree around after "
+ + "creating the distribution archive",
+ ),
+ (
+ 'target-version=',
+ None,
+ "require a specific python version" + " on the target system",
+ ),
+ ('no-target-compile', 'c', "do not compile .py to .pyc on the target system"),
+ (
+ 'no-target-optimize',
+ 'o',
+ "do not compile .py to .pyo (optimized) " "on the target system",
+ ),
+ ('dist-dir=', 'd', "directory to put final built distributions in"),
+ (
+ 'bitmap=',
+ 'b',
+ "bitmap to use for the installer instead of python-powered logo",
+ ),
+ (
+ 'title=',
+ 't',
+ "title to display on the installer background instead of default",
+ ),
+ ('skip-build', None, "skip rebuilding everything (for testing/debugging)"),
+ (
+ 'install-script=',
+ None,
+ "basename of installation script to be run after "
+ "installation or before deinstallation",
+ ),
+ (
+ 'pre-install-script=',
+ None,
+ "Fully qualified filename of a script to be run before "
+ "any files are installed. This script need not be in the "
+ "distribution",
+ ),
+ (
+ 'user-access-control=',
+ None,
+ "specify Vista's UAC handling - 'none'/default=no "
+ "handling, 'auto'=use UAC if target Python installed for "
+ "all users, 'force'=always use UAC",
+ ),
+ ]
+
+ boolean_options = [
+ 'keep-temp',
+ 'no-target-compile',
+ 'no-target-optimize',
+ 'skip-build',
+ ]
# bpo-10945: bdist_wininst requires mbcs encoding only available on Windows
- _unsupported = (sys.platform != "win32")
+ _unsupported = sys.platform != "win32"
def __init__(self, *args, **kw):
super().__init__(*args, **kw)
- warnings.warn("bdist_wininst command is deprecated since Python 3.8, "
- "use bdist_wheel (wheel packages) instead",
- DeprecationWarning, 2)
+ warnings.warn(
+ "bdist_wininst command is deprecated since Python 3.8, "
+ "use bdist_wheel (wheel packages) instead",
+ DeprecationWarning,
+ 2,
+ )
def initialize_options(self):
self.bdist_dir = None
@@ -81,7 +111,6 @@ class bdist_wininst(Command):
self.pre_install_script = None
self.user_access_control = None
-
def finalize_options(self):
self.set_undefined_options('bdist', ('skip_build', 'skip_build'))
@@ -102,14 +131,16 @@ class bdist_wininst(Command):
short_version = get_python_version()
if self.target_version and self.target_version != short_version:
raise DistutilsOptionError(
- "target version can only be %s, or the '--skip-build'" \
- " option must be specified" % (short_version,))
+ "target version can only be %s, or the '--skip-build'"
+ " option must be specified" % (short_version,)
+ )
self.target_version = short_version
- self.set_undefined_options('bdist',
- ('dist_dir', 'dist_dir'),
- ('plat_name', 'plat_name'),
- )
+ self.set_undefined_options(
+ 'bdist',
+ ('dist_dir', 'dist_dir'),
+ ('plat_name', 'plat_name'),
+ )
if self.install_script:
for script in self.distribution.scripts:
@@ -117,16 +148,17 @@ class bdist_wininst(Command):
break
else:
raise DistutilsOptionError(
- "install_script '%s' not found in scripts"
- % self.install_script)
+ "install_script '%s' not found in scripts" % self.install_script
+ )
def run(self):
- if (sys.platform != "win32" and
- (self.distribution.has_ext_modules() or
- self.distribution.has_c_libraries())):
- raise DistutilsPlatformError \
- ("distribution contains extensions and/or C libraries; "
- "must be compiled on a Windows 32 platform")
+ if sys.platform != "win32" and (
+ self.distribution.has_ext_modules() or self.distribution.has_c_libraries()
+ ):
+ raise DistutilsPlatformError(
+ "distribution contains extensions and/or C libraries; "
+ "must be compiled on a Windows 32 platform"
+ )
if not self.skip_build:
self.run_command('build')
@@ -155,8 +187,7 @@ class bdist_wininst(Command):
target_version = '%d.%d' % sys.version_info[:2]
plat_specifier = ".%s-%s" % (self.plat_name, target_version)
build = self.get_finalized_command('build')
- build.build_lib = os.path.join(build.build_base,
- 'lib' + plat_specifier)
+ build.build_lib = os.path.join(build.build_base, 'lib' + plat_specifier)
# Use a custom scheme for the zip-file, because we have to decide
# at installation time which scheme to use.
@@ -164,9 +195,7 @@ class bdist_wininst(Command):
value = key.upper()
if key == 'headers':
value = value + '/Include/$dist_name'
- setattr(install,
- 'install_' + key,
- value)
+ setattr(install, 'install_' + key, value)
log.info("installing to %s", self.bdist_dir)
install.ensure_finalized()
@@ -182,18 +211,19 @@ class bdist_wininst(Command):
# And make an archive relative to the root of the
# pseudo-installation tree.
from tempfile import mktemp
+
archive_basename = mktemp()
fullname = self.distribution.get_fullname()
- arcname = self.make_archive(archive_basename, "zip",
- root_dir=self.bdist_dir)
+ arcname = self.make_archive(archive_basename, "zip", root_dir=self.bdist_dir)
# create an exe containing the zip-file
self.create_exe(arcname, fullname, self.bitmap)
if self.distribution.has_ext_modules():
pyversion = get_python_version()
else:
pyversion = 'any'
- self.distribution.dist_files.append(('bdist_wininst', pyversion,
- self.get_installer_filename(fullname)))
+ self.distribution.dist_files.append(
+ ('bdist_wininst', pyversion, self.get_installer_filename(fullname))
+ )
# remove the zip-file again
log.debug("removing temporary file '%s'", arcname)
os.remove(arcname)
@@ -217,12 +247,19 @@ class bdist_wininst(Command):
def escape(s):
return s.replace("\n", "\\n")
- for name in ["author", "author_email", "description", "maintainer",
- "maintainer_email", "name", "url", "version"]:
+ for name in [
+ "author",
+ "author_email",
+ "description",
+ "maintainer",
+ "maintainer_email",
+ "name",
+ "url",
+ "version",
+ ]:
data = getattr(metadata, name, "")
if data:
- info = info + ("\n %s: %s" % \
- (name.capitalize(), escape(data)))
+ info = info + ("\n %s: %s" % (name.capitalize(), escape(data)))
lines.append("%s=%s" % (name, escape(data)))
# The [setup] section contains entries controlling
@@ -242,8 +279,11 @@ class bdist_wininst(Command):
lines.append("title=%s" % escape(title))
import time
import distutils
- build_info = "Built %s with distutils-%s" % \
- (time.ctime(time.time()), distutils.__version__)
+
+ build_info = "Built %s with distutils-%s" % (
+ time.ctime(time.time()),
+ distutils.__version__,
+ )
lines.append("build_info=%s" % build_info)
return "\n".join(lines)
@@ -279,8 +319,7 @@ class bdist_wininst(Command):
# We need to normalize newlines, so we open in text mode and
# convert back to bytes. "latin-1" simply avoids any possible
# failures.
- with open(self.pre_install_script, "r",
- encoding="latin-1") as script:
+ with open(self.pre_install_script, "r", encoding="latin-1") as script:
script_data = script.read().encode("latin-1")
cfgdata = cfgdata + script_data + b"\n\0"
else:
@@ -293,11 +332,12 @@ class bdist_wininst(Command):
# expects. If the layout changes, increment that number, make
# the corresponding changes to the wininst.exe sources, and
# recompile them.
- header = struct.pack("<iii",
- 0x1234567B, # tag
- len(cfgdata), # length
- bitmaplen, # number of bytes in bitmap
- )
+ header = struct.pack(
+ "<iii",
+ 0x1234567B, # tag
+ len(cfgdata), # length
+ bitmaplen, # number of bytes in bitmap
+ )
file.write(header)
with open(arcname, "rb") as f:
file.write(f.read())
@@ -307,12 +347,14 @@ class bdist_wininst(Command):
if self.target_version:
# if we create an installer for a specific python version,
# it's better to include this in the name
- installer_name = os.path.join(self.dist_dir,
- "%s.%s-py%s.exe" %
- (fullname, self.plat_name, self.target_version))
+ installer_name = os.path.join(
+ self.dist_dir,
+ "%s.%s-py%s.exe" % (fullname, self.plat_name, self.target_version),
+ )
else:
- installer_name = os.path.join(self.dist_dir,
- "%s.%s.exe" % (fullname, self.plat_name))
+ installer_name = os.path.join(
+ self.dist_dir, "%s.%s.exe" % (fullname, self.plat_name)
+ )
return installer_name
def get_exe_bytes(self):
@@ -355,7 +397,6 @@ class bdist_wininst(Command):
major = CRT_ASSEMBLY_VERSION.partition('.')[0]
bv = major + '.0'
-
# wininst-x.y.exe is in the same directory as this file
directory = os.path.dirname(__file__)
# we must use a wininst-x.y.exe built with the same C compiler
diff --git a/setuptools/_distutils/command/build.py b/setuptools/_distutils/command/build.py
index 9606b81a..3aa7fac7 100644
--- a/setuptools/_distutils/command/build.py
+++ b/setuptools/_distutils/command/build.py
@@ -10,6 +10,7 @@ from distutils.util import get_platform
def show_compilers():
from distutils.ccompiler import show_compilers
+
show_compilers()
@@ -18,40 +19,35 @@ class build(Command):
description = "build everything needed to install"
user_options = [
- ('build-base=', 'b',
- "base directory for build library"),
- ('build-purelib=', None,
- "build directory for platform-neutral distributions"),
- ('build-platlib=', None,
- "build directory for platform-specific distributions"),
- ('build-lib=', None,
- "build directory for all distribution (defaults to either " +
- "build-purelib or build-platlib"),
- ('build-scripts=', None,
- "build directory for scripts"),
- ('build-temp=', 't',
- "temporary build directory"),
- ('plat-name=', 'p',
- "platform name to build for, if supported "
- "(default: %s)" % get_platform()),
- ('compiler=', 'c',
- "specify the compiler type"),
- ('parallel=', 'j',
- "number of parallel build jobs"),
- ('debug', 'g',
- "compile extensions and libraries with debugging information"),
- ('force', 'f',
- "forcibly build everything (ignore file timestamps)"),
- ('executable=', 'e',
- "specify final destination interpreter path (build.py)"),
- ]
+ ('build-base=', 'b', "base directory for build library"),
+ ('build-purelib=', None, "build directory for platform-neutral distributions"),
+ ('build-platlib=', None, "build directory for platform-specific distributions"),
+ (
+ 'build-lib=',
+ None,
+ "build directory for all distribution (defaults to either "
+ + "build-purelib or build-platlib",
+ ),
+ ('build-scripts=', None, "build directory for scripts"),
+ ('build-temp=', 't', "temporary build directory"),
+ (
+ 'plat-name=',
+ 'p',
+ "platform name to build for, if supported "
+ "(default: %s)" % get_platform(),
+ ),
+ ('compiler=', 'c', "specify the compiler type"),
+ ('parallel=', 'j', "number of parallel build jobs"),
+ ('debug', 'g', "compile extensions and libraries with debugging information"),
+ ('force', 'f', "forcibly build everything (ignore file timestamps)"),
+ ('executable=', 'e', "specify final destination interpreter path (build.py)"),
+ ]
boolean_options = ['debug', 'force']
help_options = [
- ('help-compiler', None,
- "list available compilers", show_compilers),
- ]
+ ('help-compiler', None, "list available compilers", show_compilers),
+ ]
def initialize_options(self):
self.build_base = 'build'
@@ -78,11 +74,11 @@ class build(Command):
# other platforms.
if os.name != 'nt':
raise DistutilsOptionError(
- "--plat-name only supported on Windows (try "
- "using './configure --help' on your platform)")
+ "--plat-name only supported on Windows (try "
+ "using './configure --help' on your platform)"
+ )
- plat_specifier = ".%s-%s" % (self.plat_name,
- sys.implementation.cache_tag)
+ plat_specifier = ".%s-%s" % (self.plat_name, sys.implementation.cache_tag)
# Make it so Python 2.x and Python 2.x with --with-pydebug don't
# share the same build directories. Doing so confuses the build
@@ -96,8 +92,7 @@ class build(Command):
if self.build_purelib is None:
self.build_purelib = os.path.join(self.build_base, 'lib')
if self.build_platlib is None:
- self.build_platlib = os.path.join(self.build_base,
- 'lib' + plat_specifier)
+ self.build_platlib = os.path.join(self.build_base, 'lib' + plat_specifier)
# 'build_lib' is the actual directory that we will use for this
# particular module distribution -- if user didn't supply it, pick
@@ -111,11 +106,11 @@ class build(Command):
# 'build_temp' -- temporary directory for compiler turds,
# "build/temp.<plat>"
if self.build_temp is None:
- self.build_temp = os.path.join(self.build_base,
- 'temp' + plat_specifier)
+ self.build_temp = os.path.join(self.build_base, 'temp' + plat_specifier)
if self.build_scripts is None:
- self.build_scripts = os.path.join(self.build_base,
- 'scripts-%d.%d' % sys.version_info[:2])
+ self.build_scripts = os.path.join(
+ self.build_base, 'scripts-%d.%d' % sys.version_info[:2]
+ )
if self.executable is None and sys.executable:
self.executable = os.path.normpath(sys.executable)
@@ -135,7 +130,6 @@ class build(Command):
for cmd_name in self.get_sub_commands():
self.run_command(cmd_name)
-
# -- Predicates for the sub-command list ---------------------------
def has_pure_modules(self):
@@ -150,9 +144,9 @@ class build(Command):
def has_scripts(self):
return self.distribution.has_scripts()
-
- sub_commands = [('build_py', has_pure_modules),
- ('build_clib', has_c_libraries),
- ('build_ext', has_ext_modules),
- ('build_scripts', has_scripts),
- ]
+ sub_commands = [
+ ('build_py', has_pure_modules),
+ ('build_clib', has_c_libraries),
+ ('build_ext', has_ext_modules),
+ ('build_scripts', has_scripts),
+ ]
diff --git a/setuptools/_distutils/command/build_clib.py b/setuptools/_distutils/command/build_clib.py
index 3e20ef23..003499fa 100644
--- a/setuptools/_distutils/command/build_clib.py
+++ b/setuptools/_distutils/command/build_clib.py
@@ -20,8 +20,10 @@ from distutils.errors import *
from distutils.sysconfig import customize_compiler
from distutils import log
+
def show_compilers():
from distutils.ccompiler import show_compilers
+
show_compilers()
@@ -30,24 +32,18 @@ class build_clib(Command):
description = "build C/C++ libraries used by Python extensions"
user_options = [
- ('build-clib=', 'b',
- "directory to build C/C++ libraries to"),
- ('build-temp=', 't',
- "directory to put temporary build by-products"),
- ('debug', 'g',
- "compile with debugging information"),
- ('force', 'f',
- "forcibly build everything (ignore file timestamps)"),
- ('compiler=', 'c',
- "specify the compiler type"),
- ]
+ ('build-clib=', 'b', "directory to build C/C++ libraries to"),
+ ('build-temp=', 't', "directory to put temporary build by-products"),
+ ('debug', 'g', "compile with debugging information"),
+ ('force', 'f', "forcibly build everything (ignore file timestamps)"),
+ ('compiler=', 'c', "specify the compiler type"),
+ ]
boolean_options = ['debug', 'force']
help_options = [
- ('help-compiler', None,
- "list available compilers", show_compilers),
- ]
+ ('help-compiler', None, "list available compilers", show_compilers),
+ ]
def initialize_options(self):
self.build_clib = None
@@ -64,19 +60,20 @@ class build_clib(Command):
self.force = 0
self.compiler = None
-
def finalize_options(self):
# This might be confusing: both build-clib and build-temp default
# to build-temp as defined by the "build" command. This is because
# I think that C libraries are really just temporary build
# by-products, at least from the point of view of building Python
# extensions -- but I want to keep my options open.
- self.set_undefined_options('build',
- ('build_temp', 'build_clib'),
- ('build_temp', 'build_temp'),
- ('compiler', 'compiler'),
- ('debug', 'debug'),
- ('force', 'force'))
+ self.set_undefined_options(
+ 'build',
+ ('build_temp', 'build_clib'),
+ ('build_temp', 'build_temp'),
+ ('compiler', 'compiler'),
+ ('debug', 'debug'),
+ ('force', 'force'),
+ )
self.libraries = self.distribution.libraries
if self.libraries:
@@ -90,23 +87,23 @@ class build_clib(Command):
# XXX same as for build_ext -- what about 'self.define' and
# 'self.undef' ?
-
def run(self):
if not self.libraries:
return
# Yech -- this is cut 'n pasted from build_ext.py!
from distutils.ccompiler import new_compiler
- self.compiler = new_compiler(compiler=self.compiler,
- dry_run=self.dry_run,
- force=self.force)
+
+ self.compiler = new_compiler(
+ compiler=self.compiler, dry_run=self.dry_run, force=self.force
+ )
customize_compiler(self.compiler)
if self.include_dirs is not None:
self.compiler.set_include_dirs(self.include_dirs)
if self.define is not None:
# 'define' option is a list of (name,value) tuples
- for (name,value) in self.define:
+ for (name, value) in self.define:
self.compiler.define_macro(name, value)
if self.undef is not None:
for macro in self.undef:
@@ -114,7 +111,6 @@ class build_clib(Command):
self.build_libraries(self.libraries)
-
def check_library_list(self, libraries):
"""Ensure that the list of libraries is valid.
@@ -126,30 +122,31 @@ class build_clib(Command):
just returns otherwise.
"""
if not isinstance(libraries, list):
- raise DistutilsSetupError(
- "'libraries' option must be a list of tuples")
+ raise DistutilsSetupError("'libraries' option must be a list of tuples")
for lib in libraries:
if not isinstance(lib, tuple) and len(lib) != 2:
- raise DistutilsSetupError(
- "each element of 'libraries' must a 2-tuple")
+ raise DistutilsSetupError("each element of 'libraries' must a 2-tuple")
name, build_info = lib
if not isinstance(name, str):
raise DistutilsSetupError(
- "first element of each tuple in 'libraries' "
- "must be a string (the library name)")
+ "first element of each tuple in 'libraries' "
+ "must be a string (the library name)"
+ )
if '/' in name or (os.sep != '/' and os.sep in name):
- raise DistutilsSetupError("bad library name '%s': "
- "may not contain directory separators" % lib[0])
+ raise DistutilsSetupError(
+ "bad library name '%s': "
+ "may not contain directory separators" % lib[0]
+ )
if not isinstance(build_info, dict):
raise DistutilsSetupError(
- "second element of each tuple in 'libraries' "
- "must be a dictionary (build info)")
-
+ "second element of each tuple in 'libraries' "
+ "must be a dictionary (build info)"
+ )
def get_library_names(self):
# Assume the library list is valid -- 'check_library_list()' is
@@ -162,7 +159,6 @@ class build_clib(Command):
lib_names.append(lib_name)
return lib_names
-
def get_source_files(self):
self.check_library_list(self.libraries)
filenames = []
@@ -170,22 +166,23 @@ class build_clib(Command):
sources = build_info.get('sources')
if sources is None or not isinstance(sources, (list, tuple)):
raise DistutilsSetupError(
- "in 'libraries' option (library '%s'), "
- "'sources' must be present and must be "
- "a list of source filenames" % lib_name)
+ "in 'libraries' option (library '%s'), "
+ "'sources' must be present and must be "
+ "a list of source filenames" % lib_name
+ )
filenames.extend(sources)
return filenames
-
def build_libraries(self, libraries):
for (lib_name, build_info) in libraries:
sources = build_info.get('sources')
if sources is None or not isinstance(sources, (list, tuple)):
raise DistutilsSetupError(
- "in 'libraries' option (library '%s'), "
- "'sources' must be present and must be "
- "a list of source filenames" % lib_name)
+ "in 'libraries' option (library '%s'), "
+ "'sources' must be present and must be "
+ "a list of source filenames" % lib_name
+ )
sources = list(sources)
log.info("building '%s' library", lib_name)
@@ -195,15 +192,17 @@ class build_clib(Command):
# files in a temporary build directory.)
macros = build_info.get('macros')
include_dirs = build_info.get('include_dirs')
- objects = self.compiler.compile(sources,
- output_dir=self.build_temp,
- macros=macros,
- include_dirs=include_dirs,
- debug=self.debug)
+ objects = self.compiler.compile(
+ sources,
+ output_dir=self.build_temp,
+ macros=macros,
+ include_dirs=include_dirs,
+ debug=self.debug,
+ )
# Now "link" the object files together into a static library.
# (On Unix at least, this isn't really linking -- it just
# builds an archive. Whatever.)
- self.compiler.create_static_lib(objects, lib_name,
- output_dir=self.build_clib,
- debug=self.debug)
+ self.compiler.create_static_lib(
+ objects, lib_name, output_dir=self.build_clib, debug=self.debug
+ )
diff --git a/setuptools/_distutils/command/build_ext.py b/setuptools/_distutils/command/build_ext.py
index 181671bf..1a6dd394 100644
--- a/setuptools/_distutils/command/build_ext.py
+++ b/setuptools/_distutils/command/build_ext.py
@@ -22,12 +22,12 @@ from site import USER_BASE
# An extension name is just a dot-separated list of Python NAMEs (ie.
# the same as a fully-qualified module name).
-extension_name_re = re.compile \
- (r'^[a-zA-Z_][a-zA-Z_0-9]*(\.[a-zA-Z_][a-zA-Z_0-9]*)*$')
+extension_name_re = re.compile(r'^[a-zA-Z_][a-zA-Z_0-9]*(\.[a-zA-Z_][a-zA-Z_0-9]*)*$')
-def show_compilers ():
+def show_compilers():
from distutils.ccompiler import show_compilers
+
show_compilers()
@@ -55,54 +55,50 @@ class build_ext(Command):
sep_by = " (separated by '%s')" % os.pathsep
user_options = [
- ('build-lib=', 'b',
- "directory for compiled extension modules"),
- ('build-temp=', 't',
- "directory for temporary files (build by-products)"),
- ('plat-name=', 'p',
- "platform name to cross-compile for, if supported "
- "(default: %s)" % get_platform()),
- ('inplace', 'i',
- "ignore build-lib and put compiled extensions into the source " +
- "directory alongside your pure Python modules"),
- ('include-dirs=', 'I',
- "list of directories to search for header files" + sep_by),
- ('define=', 'D',
- "C preprocessor macros to define"),
- ('undef=', 'U',
- "C preprocessor macros to undefine"),
- ('libraries=', 'l',
- "external C libraries to link with"),
- ('library-dirs=', 'L',
- "directories to search for external C libraries" + sep_by),
- ('rpath=', 'R',
- "directories to search for shared C libraries at runtime"),
- ('link-objects=', 'O',
- "extra explicit link objects to include in the link"),
- ('debug', 'g',
- "compile/link with debugging information"),
- ('force', 'f',
- "forcibly build everything (ignore file timestamps)"),
- ('compiler=', 'c',
- "specify the compiler type"),
- ('parallel=', 'j',
- "number of parallel build jobs"),
- ('swig-cpp', None,
- "make SWIG create C++ files (default is C)"),
- ('swig-opts=', None,
- "list of SWIG command line options"),
- ('swig=', None,
- "path to the SWIG executable"),
- ('user', None,
- "add user include, library and rpath")
- ]
+ ('build-lib=', 'b', "directory for compiled extension modules"),
+ ('build-temp=', 't', "directory for temporary files (build by-products)"),
+ (
+ 'plat-name=',
+ 'p',
+ "platform name to cross-compile for, if supported "
+ "(default: %s)" % get_platform(),
+ ),
+ (
+ 'inplace',
+ 'i',
+ "ignore build-lib and put compiled extensions into the source "
+ + "directory alongside your pure Python modules",
+ ),
+ (
+ 'include-dirs=',
+ 'I',
+ "list of directories to search for header files" + sep_by,
+ ),
+ ('define=', 'D', "C preprocessor macros to define"),
+ ('undef=', 'U', "C preprocessor macros to undefine"),
+ ('libraries=', 'l', "external C libraries to link with"),
+ (
+ 'library-dirs=',
+ 'L',
+ "directories to search for external C libraries" + sep_by,
+ ),
+ ('rpath=', 'R', "directories to search for shared C libraries at runtime"),
+ ('link-objects=', 'O', "extra explicit link objects to include in the link"),
+ ('debug', 'g', "compile/link with debugging information"),
+ ('force', 'f', "forcibly build everything (ignore file timestamps)"),
+ ('compiler=', 'c', "specify the compiler type"),
+ ('parallel=', 'j', "number of parallel build jobs"),
+ ('swig-cpp', None, "make SWIG create C++ files (default is C)"),
+ ('swig-opts=', None, "list of SWIG command line options"),
+ ('swig=', None, "path to the SWIG executable"),
+ ('user', None, "add user include, library and rpath"),
+ ]
boolean_options = ['inplace', 'debug', 'force', 'swig-cpp', 'user']
help_options = [
- ('help-compiler', None,
- "list available compilers", show_compilers),
- ]
+ ('help-compiler', None, "list available compilers", show_compilers),
+ ]
def initialize_options(self):
self.extensions = None
@@ -131,15 +127,16 @@ class build_ext(Command):
def finalize_options(self):
from distutils import sysconfig
- self.set_undefined_options('build',
- ('build_lib', 'build_lib'),
- ('build_temp', 'build_temp'),
- ('compiler', 'compiler'),
- ('debug', 'debug'),
- ('force', 'force'),
- ('parallel', 'parallel'),
- ('plat_name', 'plat_name'),
- )
+ self.set_undefined_options(
+ 'build',
+ ('build_lib', 'build_lib'),
+ ('build_temp', 'build_temp'),
+ ('compiler', 'compiler'),
+ ('debug', 'debug'),
+ ('force', 'force'),
+ ('parallel', 'parallel'),
+ ('plat_name', 'plat_name'),
+ )
if self.package is None:
self.package = self.distribution.ext_package
@@ -164,8 +161,7 @@ class build_ext(Command):
# any local include dirs take precedence.
self.include_dirs.extend(py_include.split(os.path.pathsep))
if plat_py_include != py_include:
- self.include_dirs.extend(
- plat_py_include.split(os.path.pathsep))
+ self.include_dirs.extend(plat_py_include.split(os.path.pathsep))
self.ensure_string_list('libraries')
self.ensure_string_list('link_objects')
@@ -220,9 +216,11 @@ class build_ext(Command):
if sys.platform[:6] == 'cygwin':
if not sysconfig.python_build:
# building third party extensions
- self.library_dirs.append(os.path.join(sys.prefix, "lib",
- "python" + get_python_version(),
- "config"))
+ self.library_dirs.append(
+ os.path.join(
+ sys.prefix, "lib", "python" + get_python_version(), "config"
+ )
+ )
else:
# building python standard extensions
self.library_dirs.append('.')
@@ -230,7 +228,7 @@ class build_ext(Command):
# For building extensions with a shared Python library,
# Python's library directory must be appended to library_dirs
# See Issues: #1600860, #4366
- if (sysconfig.get_config_var('Py_ENABLE_SHARED')):
+ if sysconfig.get_config_var('Py_ENABLE_SHARED'):
if not sysconfig.python_build:
# building third party extensions
self.library_dirs.append(sysconfig.get_config_var('LIBDIR'))
@@ -302,10 +300,12 @@ class build_ext(Command):
# Setup the CCompiler object that we'll use to do all the
# compiling and linking
- self.compiler = new_compiler(compiler=self.compiler,
- verbose=self.verbose,
- dry_run=self.dry_run,
- force=self.force)
+ self.compiler = new_compiler(
+ compiler=self.compiler,
+ verbose=self.verbose,
+ dry_run=self.dry_run,
+ force=self.force,
+ )
customize_compiler(self.compiler)
# If we are cross-compiling, init the compiler now (if we are not
# cross-compiling, init would not hurt, but people may rely on
@@ -350,34 +350,40 @@ class build_ext(Command):
"""
if not isinstance(extensions, list):
raise DistutilsSetupError(
- "'ext_modules' option must be a list of Extension instances")
+ "'ext_modules' option must be a list of Extension instances"
+ )
for i, ext in enumerate(extensions):
if isinstance(ext, Extension):
- continue # OK! (assume type-checking done
- # by Extension constructor)
+ continue # OK! (assume type-checking done
+ # by Extension constructor)
if not isinstance(ext, tuple) or len(ext) != 2:
raise DistutilsSetupError(
- "each element of 'ext_modules' option must be an "
- "Extension instance or 2-tuple")
+ "each element of 'ext_modules' option must be an "
+ "Extension instance or 2-tuple"
+ )
ext_name, build_info = ext
- log.warn("old-style (ext_name, build_info) tuple found in "
- "ext_modules for extension '%s' "
- "-- please convert to Extension instance", ext_name)
+ log.warn(
+ "old-style (ext_name, build_info) tuple found in "
+ "ext_modules for extension '%s' "
+ "-- please convert to Extension instance",
+ ext_name,
+ )
- if not (isinstance(ext_name, str) and
- extension_name_re.match(ext_name)):
+ if not (isinstance(ext_name, str) and extension_name_re.match(ext_name)):
raise DistutilsSetupError(
- "first element of each tuple in 'ext_modules' "
- "must be the extension name (a string)")
+ "first element of each tuple in 'ext_modules' "
+ "must be the extension name (a string)"
+ )
if not isinstance(build_info, dict):
raise DistutilsSetupError(
- "second element of each tuple in 'ext_modules' "
- "must be a dictionary (build info)")
+ "second element of each tuple in 'ext_modules' "
+ "must be a dictionary (build info)"
+ )
# OK, the (ext_name, build_info) dict is type-safe: convert it
# to an Extension instance.
@@ -385,9 +391,14 @@ class build_ext(Command):
# Easy stuff: one-to-one mapping from dict elements to
# instance attributes.
- for key in ('include_dirs', 'library_dirs', 'libraries',
- 'extra_objects', 'extra_compile_args',
- 'extra_link_args'):
+ for key in (
+ 'include_dirs',
+ 'library_dirs',
+ 'libraries',
+ 'extra_objects',
+ 'extra_compile_args',
+ 'extra_link_args',
+ ):
val = build_info.get(key)
if val is not None:
setattr(ext, key, val)
@@ -395,8 +406,7 @@ class build_ext(Command):
# Medium-easy stuff: same syntax/semantics, different names.
ext.runtime_library_dirs = build_info.get('rpath')
if 'def_file' in build_info:
- log.warn("'def_file' element of build info dict "
- "no longer supported")
+ log.warn("'def_file' element of build info dict " "no longer supported")
# Non-trivial stuff: 'macros' split into 'define_macros'
# and 'undef_macros'.
@@ -407,8 +417,9 @@ class build_ext(Command):
for macro in macros:
if not (isinstance(macro, tuple) and len(macro) in (1, 2)):
raise DistutilsSetupError(
- "'macros' element of build info dict "
- "must be 1- or 2-tuple")
+ "'macros' element of build info dict "
+ "must be 1- or 2-tuple"
+ )
if len(macro) == 1:
ext.undef_macros.append(macro[0])
elif len(macro) == 2:
@@ -461,8 +472,9 @@ class build_ext(Command):
return
with ThreadPoolExecutor(max_workers=workers) as executor:
- futures = [executor.submit(self.build_extension, ext)
- for ext in self.extensions]
+ futures = [
+ executor.submit(self.build_extension, ext) for ext in self.extensions
+ ]
for ext, fut in zip(self.extensions, futures):
with self._filter_build_errors(ext):
fut.result()
@@ -479,16 +491,16 @@ class build_ext(Command):
except (CCompilerError, DistutilsError, CompileError) as e:
if not ext.optional:
raise
- self.warn('building extension "%s" failed: %s' %
- (ext.name, e))
+ self.warn('building extension "%s" failed: %s' % (ext.name, e))
def build_extension(self, ext):
sources = ext.sources
if sources is None or not isinstance(sources, (list, tuple)):
raise DistutilsSetupError(
- "in 'ext_modules' option (extension '%s'), "
- "'sources' must be present and must be "
- "a list of source filenames" % ext.name)
+ "in 'ext_modules' option (extension '%s'), "
+ "'sources' must be present and must be "
+ "a list of source filenames" % ext.name
+ )
# sort to make the resulting .so file build reproducible
sources = sorted(sources)
@@ -525,13 +537,15 @@ class build_ext(Command):
for undef in ext.undef_macros:
macros.append((undef,))
- objects = self.compiler.compile(sources,
- output_dir=self.build_temp,
- macros=macros,
- include_dirs=ext.include_dirs,
- debug=self.debug,
- extra_postargs=extra_args,
- depends=ext.depends)
+ objects = self.compiler.compile(
+ sources,
+ output_dir=self.build_temp,
+ macros=macros,
+ include_dirs=ext.include_dirs,
+ debug=self.debug,
+ extra_postargs=extra_args,
+ depends=ext.depends,
+ )
# XXX outdated variable, kept here in case third-part code
# needs it.
@@ -548,7 +562,8 @@ class build_ext(Command):
language = ext.language or self.compiler.detect_language(sources)
self.compiler.link_shared_object(
- objects, ext_path,
+ objects,
+ ext_path,
libraries=self.get_libraries(ext),
library_dirs=ext.library_dirs,
runtime_library_dirs=ext.runtime_library_dirs,
@@ -556,7 +571,8 @@ class build_ext(Command):
export_symbols=self.get_export_symbols(ext),
debug=self.debug,
build_temp=self.build_temp,
- target_lang=language)
+ target_lang=language,
+ )
def swig_sources(self, sources, extension):
"""Walk the list of source files in 'sources', looking for SWIG
@@ -576,15 +592,18 @@ class build_ext(Command):
if self.swig_cpp:
log.warn("--swig-cpp is deprecated - use --swig-opts=-c++")
- if self.swig_cpp or ('-c++' in self.swig_opts) or \
- ('-c++' in extension.swig_opts):
+ if (
+ self.swig_cpp
+ or ('-c++' in self.swig_opts)
+ or ('-c++' in extension.swig_opts)
+ ):
target_ext = '.cpp'
else:
target_ext = '.c'
for source in sources:
(base, ext) = os.path.splitext(source)
- if ext == ".i": # SWIG interface file
+ if ext == ".i": # SWIG interface file
new_sources.append(base + '_wrap' + target_ext)
swig_sources.append(source)
swig_targets[source] = new_sources[-1]
@@ -631,8 +650,9 @@ class build_ext(Command):
return "swig.exe"
else:
raise DistutilsPlatformError(
- "I don't know how to find (much less run) SWIG "
- "on platform '%s'" % os.name)
+ "I don't know how to find (much less run) SWIG "
+ "on platform '%s'" % os.name
+ )
# -- Name generators -----------------------------------------------
# (extension names, filenames, whatever)
@@ -650,7 +670,7 @@ class build_ext(Command):
# no further work needed
# returning :
# build_dir/package/path/filename
- filename = os.path.join(*modpath[:-1]+[filename])
+ filename = os.path.join(*modpath[:-1] + [filename])
return os.path.join(self.build_lib, filename)
# the inplace option requires to find the package directory
@@ -678,6 +698,7 @@ class build_ext(Command):
"foo\bar.pyd").
"""
from distutils.sysconfig import get_config_var
+
ext_path = ext_name.split('.')
ext_suffix = get_config_var('EXT_SUFFIX')
return os.path.join(*ext_path) + ext_suffix
@@ -715,12 +736,15 @@ class build_ext(Command):
# Append '_d' to the python import library on debug builds.
if sys.platform == "win32":
from distutils._msvccompiler import MSVCCompiler
+
if not isinstance(self.compiler, MSVCCompiler):
template = "python%d%d"
if self.debug:
template = template + '_d'
- pythonlib = (template %
- (sys.hexversion >> 24, (sys.hexversion >> 16) & 0xff))
+ pythonlib = template % (
+ sys.hexversion >> 24,
+ (sys.hexversion >> 16) & 0xFF,
+ )
# don't extend ext.libraries, it may be shared with other
# extensions, it is a reference to the original list
return ext.libraries + [pythonlib]
@@ -734,6 +758,7 @@ class build_ext(Command):
# Windows like MinGW) it is simply necessary that all symbols in
# shared libraries are resolved at link time.
from distutils.sysconfig import get_config_var
+
link_libpython = False
if get_config_var('Py_ENABLE_SHARED'):
# A native build on an Android device or on Cygwin
diff --git a/setuptools/_distutils/command/build_py.py b/setuptools/_distutils/command/build_py.py
index 7ef9bcef..1b22004e 100644
--- a/setuptools/_distutils/command/build_py.py
+++ b/setuptools/_distutils/command/build_py.py
@@ -12,7 +12,8 @@ from distutils.errors import *
from distutils.util import convert_path
from distutils import log
-class build_py (Command):
+
+class build_py(Command):
description = "\"build\" pure Python modules (copy to build directory)"
@@ -20,14 +21,17 @@ class build_py (Command):
('build-lib=', 'd', "directory to \"build\" (copy) to"),
('compile', 'c', "compile .py to .pyc"),
('no-compile', None, "don't compile .py files [default]"),
- ('optimize=', 'O',
- "also compile with optimization: -O1 for \"python -O\", "
- "-O2 for \"python -OO\", and -O0 to disable [default: -O0]"),
+ (
+ 'optimize=',
+ 'O',
+ "also compile with optimization: -O1 for \"python -O\", "
+ "-O2 for \"python -OO\", and -O0 to disable [default: -O0]",
+ ),
('force', 'f', "forcibly build everything (ignore file timestamps)"),
- ]
+ ]
boolean_options = ['compile', 'force']
- negative_opt = {'no-compile' : 'compile'}
+ negative_opt = {'no-compile': 'compile'}
def initialize_options(self):
self.build_lib = None
@@ -40,9 +44,9 @@ class build_py (Command):
self.force = None
def finalize_options(self):
- self.set_undefined_options('build',
- ('build_lib', 'build_lib'),
- ('force', 'force'))
+ self.set_undefined_options(
+ 'build', ('build_lib', 'build_lib'), ('force', 'force')
+ )
# Get the distribution options that are aliases for build_py
# options -- list of packages and list of modules.
@@ -109,26 +113,26 @@ class build_py (Command):
# Length of path to strip from found files
plen = 0
if src_dir:
- plen = len(src_dir)+1
+ plen = len(src_dir) + 1
# Strip directory from globbed filenames
- filenames = [
- file[plen:] for file in self.find_data_files(package, src_dir)
- ]
+ filenames = [file[plen:] for file in self.find_data_files(package, src_dir)]
data.append((package, src_dir, build_dir, filenames))
return data
def find_data_files(self, package, src_dir):
"""Return filenames for package's data files in 'src_dir'"""
- globs = (self.package_data.get('', [])
- + self.package_data.get(package, []))
+ globs = self.package_data.get('', []) + self.package_data.get(package, [])
files = []
for pattern in globs:
# Each pattern has to be converted to a platform-specific path
- filelist = glob.glob(os.path.join(glob.escape(src_dir), convert_path(pattern)))
+ filelist = glob.glob(
+ os.path.join(glob.escape(src_dir), convert_path(pattern))
+ )
# Files that match more than one pattern are only added once
- files.extend([fn for fn in filelist if fn not in files
- and os.path.isfile(fn)])
+ files.extend(
+ [fn for fn in filelist if fn not in files and os.path.isfile(fn)]
+ )
return files
def build_package_data(self):
@@ -138,13 +142,14 @@ class build_py (Command):
for filename in filenames:
target = os.path.join(build_dir, filename)
self.mkpath(os.path.dirname(target))
- self.copy_file(os.path.join(src_dir, filename), target,
- preserve_mode=False)
+ self.copy_file(
+ os.path.join(src_dir, filename), target, preserve_mode=False
+ )
def get_package_dir(self, package):
"""Return the directory, relative to the top of the source
- distribution, where package 'package' should be found
- (at least according to the 'package_dir' option, if any)."""
+ distribution, where package 'package' should be found
+ (at least according to the 'package_dir' option, if any)."""
path = package.split('.')
if not self.package_dir:
@@ -188,11 +193,13 @@ class build_py (Command):
if package_dir != "":
if not os.path.exists(package_dir):
raise DistutilsFileError(
- "package directory '%s' does not exist" % package_dir)
+ "package directory '%s' does not exist" % package_dir
+ )
if not os.path.isdir(package_dir):
raise DistutilsFileError(
- "supposed package directory '%s' exists, "
- "but is not a directory" % package_dir)
+ "supposed package directory '%s' exists, "
+ "but is not a directory" % package_dir
+ )
# Require __init__.py for all but the "root package"
if package:
@@ -200,8 +207,10 @@ class build_py (Command):
if os.path.isfile(init_py):
return init_py
else:
- log.warn(("package init file '%s' not found " +
- "(or not a regular file)"), init_py)
+ log.warn(
+ ("package init file '%s' not found " + "(or not a regular file)"),
+ init_py,
+ )
# Either not in a package at all (__init__.py not expected), or
# __init__.py doesn't exist -- so don't return the filename.
@@ -313,17 +322,21 @@ class build_py (Command):
outputs.append(filename)
if include_bytecode:
if self.compile:
- outputs.append(importlib.util.cache_from_source(
- filename, optimization=''))
+ outputs.append(
+ importlib.util.cache_from_source(filename, optimization='')
+ )
if self.optimize > 0:
- outputs.append(importlib.util.cache_from_source(
- filename, optimization=self.optimize))
+ outputs.append(
+ importlib.util.cache_from_source(
+ filename, optimization=self.optimize
+ )
+ )
outputs += [
os.path.join(build_dir, filename)
for package, src_dir, build_dir, filenames in self.data_files
for filename in filenames
- ]
+ ]
return outputs
@@ -332,7 +345,8 @@ class build_py (Command):
package = package.split('.')
elif not isinstance(package, (list, tuple)):
raise TypeError(
- "'package' must be a string (dot-separated), list, or tuple")
+ "'package' must be a string (dot-separated), list, or tuple"
+ )
# Now put the module source file into the "build" area -- this is
# easy, we just copy it somewhere under self.build_lib (the build
@@ -377,6 +391,7 @@ class build_py (Command):
return
from distutils.util import byte_compile
+
prefix = self.build_lib
if prefix[-1] != os.sep:
prefix = prefix + os.sep
@@ -385,8 +400,14 @@ class build_py (Command):
# 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, dry_run=self.dry_run
+ )
if self.optimize > 0:
- byte_compile(files, optimize=self.optimize,
- force=self.force, prefix=prefix, dry_run=self.dry_run)
+ byte_compile(
+ files,
+ optimize=self.optimize,
+ force=self.force,
+ prefix=prefix,
+ dry_run=self.dry_run,
+ )
diff --git a/setuptools/_distutils/command/build_scripts.py b/setuptools/_distutils/command/build_scripts.py
index e56511da..17058dbf 100644
--- a/setuptools/_distutils/command/build_scripts.py
+++ b/setuptools/_distutils/command/build_scripts.py
@@ -29,7 +29,7 @@ class build_scripts(Command):
('build-dir=', 'd', "directory to \"build\" (copy) to"),
('force', 'f', "forcibly build everything (ignore file timestamps"),
('executable=', 'e', "specify final destination interpreter path"),
- ]
+ ]
boolean_options = ['force']
@@ -40,10 +40,12 @@ class build_scripts(Command):
self.executable = None
def finalize_options(self):
- self.set_undefined_options('build',
- ('build_scripts', 'build_dir'),
- ('force', 'force'),
- ('executable', 'executable'))
+ self.set_undefined_options(
+ 'build',
+ ('build_scripts', 'build_dir'),
+ ('force', 'force'),
+ ('executable', 'executable'),
+ )
self.scripts = self.distribution.scripts
def get_source_files(self):
@@ -101,17 +103,19 @@ class build_scripts(Command):
updated_files.append(outfile)
if shebang_match:
- log.info("copying and adjusting %s -> %s", script,
- self.build_dir)
+ log.info("copying and adjusting %s -> %s", script, self.build_dir)
if not self.dry_run:
if not sysconfig.python_build:
executable = self.executable
else:
executable = os.path.join(
sysconfig.get_config_var("BINDIR"),
- "python%s%s" % (
+ "python%s%s"
+ % (
sysconfig.get_config_var("VERSION"),
- sysconfig.get_config_var("EXE")))
+ sysconfig.get_config_var("EXE"),
+ ),
+ )
post_interp = shebang_match.group(1) or ''
shebang = "#!" + executable + post_interp + "\n"
self._validate_shebang(shebang, f.encoding)
@@ -140,8 +144,7 @@ class build_scripts(Command):
oldmode = os.stat(file)[ST_MODE] & 0o7777
newmode = (oldmode | 0o555) & 0o7777
if newmode != oldmode:
- log.info("changing mode of %s from %o to %o",
- file, oldmode, newmode)
+ log.info("changing mode of %s from %o to %o", file, oldmode, newmode)
os.chmod(file, newmode)
@staticmethod
@@ -155,8 +158,8 @@ class build_scripts(Command):
shebang.encode('utf-8')
except UnicodeEncodeError:
raise ValueError(
- "The shebang ({!r}) is not encodable "
- "to utf-8".format(shebang))
+ "The shebang ({!r}) is not encodable " "to utf-8".format(shebang)
+ )
# If the script is encoded to a custom encoding (use a
# #coding:xxx cookie), the shebang has to be encodable to
@@ -166,5 +169,5 @@ class build_scripts(Command):
except UnicodeEncodeError:
raise ValueError(
"The shebang ({!r}) is not encodable "
- "to the script encoding ({})"
- .format(shebang, encoding))
+ "to the script encoding ({})".format(shebang, encoding)
+ )
diff --git a/setuptools/_distutils/command/check.py b/setuptools/_distutils/command/check.py
index 8a02dbca..176a8b87 100644
--- a/setuptools/_distutils/command/check.py
+++ b/setuptools/_distutils/command/check.py
@@ -15,18 +15,26 @@ try:
from docutils import nodes
class SilentReporter(Reporter):
-
- def __init__(self, source, report_level, halt_level, stream=None,
- debug=0, encoding='ascii', error_handler='replace'):
+ def __init__(
+ self,
+ source,
+ report_level,
+ halt_level,
+ stream=None,
+ debug=0,
+ encoding='ascii',
+ error_handler='replace',
+ ):
self.messages = []
- super().__init__(source, report_level, halt_level, stream,
- debug, encoding, error_handler)
+ super().__init__(
+ source, report_level, halt_level, stream, debug, encoding, error_handler
+ )
def system_message(self, level, message, *children, **kwargs):
self.messages.append((level, message, children, kwargs))
- return nodes.system_message(message, level=level,
- type=self.levels[level],
- *children, **kwargs)
+ return nodes.system_message(
+ message, level=level, type=self.levels[level], *children, **kwargs
+ )
HAS_DOCUTILS = True
except Exception:
@@ -34,16 +42,23 @@ except Exception:
# indicate that docutils is not ported to Py3k.
HAS_DOCUTILS = False
+
class check(Command):
- """This command checks the meta-data of the package.
- """
- description = ("perform some checks on the package")
- user_options = [('metadata', 'm', 'Verify meta-data'),
- ('restructuredtext', 'r',
- ('Checks if long string meta-data syntax '
- 'are reStructuredText-compliant')),
- ('strict', 's',
- 'Will exit with an error if a check fails')]
+ """This command checks the meta-data of the package."""
+
+ description = "perform some checks on the package"
+ user_options = [
+ ('metadata', 'm', 'Verify meta-data'),
+ (
+ 'restructuredtext',
+ 'r',
+ (
+ 'Checks if long string meta-data syntax '
+ 'are reStructuredText-compliant'
+ ),
+ ),
+ ('strict', 's', 'Will exit with an error if a check fails'),
+ ]
boolean_options = ['metadata', 'restructuredtext', 'strict']
@@ -116,13 +131,15 @@ class check(Command):
settings.tab_width = 4
settings.pep_references = None
settings.rfc_references = None
- reporter = SilentReporter(source_path,
- settings.report_level,
- settings.halt_level,
- stream=settings.warning_stream,
- debug=settings.debug,
- encoding=settings.error_encoding,
- error_handler=settings.error_encoding_error_handler)
+ reporter = SilentReporter(
+ source_path,
+ settings.report_level,
+ settings.halt_level,
+ stream=settings.warning_stream,
+ debug=settings.debug,
+ encoding=settings.error_encoding,
+ error_handler=settings.error_encoding_error_handler,
+ )
document = nodes.document(settings, reporter, source=source_path)
document.note_source(source_path, -1)
@@ -130,6 +147,7 @@ class check(Command):
parser.parse(data, document)
except AttributeError as e:
reporter.messages.append(
- (-1, 'Could not finish the parsing: %s.' % e, '', {}))
+ (-1, 'Could not finish the parsing: %s.' % e, '', {})
+ )
return reporter.messages
diff --git a/setuptools/_distutils/command/clean.py b/setuptools/_distutils/command/clean.py
index 0cb27016..b731b606 100644
--- a/setuptools/_distutils/command/clean.py
+++ b/setuptools/_distutils/command/clean.py
@@ -9,22 +9,25 @@ from distutils.core import Command
from distutils.dir_util import remove_tree
from distutils import log
+
class clean(Command):
description = "clean up temporary files from 'build' command"
user_options = [
- ('build-base=', 'b',
- "base build directory (default: 'build.build-base')"),
- ('build-lib=', None,
- "build directory for all modules (default: 'build.build-lib')"),
- ('build-temp=', 't',
- "temporary build directory (default: 'build.build-temp')"),
- ('build-scripts=', None,
- "build directory for scripts (default: 'build.build-scripts')"),
- ('bdist-base=', None,
- "temporary directory for built distributions"),
- ('all', 'a',
- "remove all build output, not just temporary by-products")
+ ('build-base=', 'b', "base build directory (default: 'build.build-base')"),
+ (
+ 'build-lib=',
+ None,
+ "build directory for all modules (default: 'build.build-lib')",
+ ),
+ ('build-temp=', 't', "temporary build directory (default: 'build.build-temp')"),
+ (
+ 'build-scripts=',
+ None,
+ "build directory for scripts (default: 'build.build-scripts')",
+ ),
+ ('bdist-base=', None, "temporary directory for built distributions"),
+ ('all', 'a', "remove all build output, not just temporary by-products"),
]
boolean_options = ['all']
@@ -38,13 +41,14 @@ class clean(Command):
self.all = None
def finalize_options(self):
- self.set_undefined_options('build',
- ('build_base', 'build_base'),
- ('build_lib', 'build_lib'),
- ('build_scripts', 'build_scripts'),
- ('build_temp', 'build_temp'))
- self.set_undefined_options('bdist',
- ('bdist_base', 'bdist_base'))
+ self.set_undefined_options(
+ 'build',
+ ('build_base', 'build_base'),
+ ('build_lib', 'build_lib'),
+ ('build_scripts', 'build_scripts'),
+ ('build_temp', 'build_temp'),
+ )
+ self.set_undefined_options('bdist', ('bdist_base', 'bdist_base'))
def run(self):
# remove the build/temp.<plat> directory (unless it's already
@@ -52,19 +56,15 @@ class clean(Command):
if os.path.exists(self.build_temp):
remove_tree(self.build_temp, dry_run=self.dry_run)
else:
- log.debug("'%s' does not exist -- can't clean it",
- self.build_temp)
+ log.debug("'%s' does not exist -- can't clean it", self.build_temp)
if self.all:
# remove build directories
- for directory in (self.build_lib,
- self.bdist_base,
- self.build_scripts):
+ 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)
else:
- log.warn("'%s' does not exist -- can't clean it",
- directory)
+ log.warn("'%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
diff --git a/setuptools/_distutils/command/config.py b/setuptools/_distutils/command/config.py
index aeda408e..73de1d3e 100644
--- a/setuptools/_distutils/command/config.py
+++ b/setuptools/_distutils/command/config.py
@@ -18,32 +18,26 @@ from distutils import log
LANG_EXT = {"c": ".c", "c++": ".cxx"}
+
class config(Command):
description = "prepare to build"
user_options = [
- ('compiler=', None,
- "specify the compiler type"),
- ('cc=', None,
- "specify the compiler executable"),
- ('include-dirs=', 'I',
- "list of directories to search for header files"),
- ('define=', 'D',
- "C preprocessor macros to define"),
- ('undef=', 'U',
- "C preprocessor macros to undefine"),
- ('libraries=', 'l',
- "external C libraries to link with"),
- ('library-dirs=', 'L',
- "directories to search for external C libraries"),
-
- ('noisy', None,
- "show every action (compile, link, run, ...) taken"),
- ('dump-source', None,
- "dump generated source files before attempting to compile them"),
- ]
-
+ ('compiler=', None, "specify the compiler type"),
+ ('cc=', None, "specify the compiler executable"),
+ ('include-dirs=', 'I', "list of directories to search for header files"),
+ ('define=', 'D', "C preprocessor macros to define"),
+ ('undef=', 'U', "C preprocessor macros to undefine"),
+ ('libraries=', 'l', "external C libraries to link with"),
+ ('library-dirs=', 'L', "directories to search for external C libraries"),
+ ('noisy', None, "show every action (compile, link, run, ...) taken"),
+ (
+ 'dump-source',
+ None,
+ "dump generated source files before attempting to compile them",
+ ),
+ ]
# The three standard command methods: since the "config" command
# does nothing by default, these are empty.
@@ -93,9 +87,11 @@ class config(Command):
# We do this late, and only on-demand, because this is an expensive
# import.
from distutils.ccompiler import CCompiler, new_compiler
+
if not isinstance(self.compiler, CCompiler):
- self.compiler = new_compiler(compiler=self.compiler,
- dry_run=self.dry_run, force=1)
+ self.compiler = new_compiler(
+ compiler=self.compiler, dry_run=self.dry_run, force=1
+ )
customize_compiler(self.compiler)
if self.include_dirs:
self.compiler.set_include_dirs(self.include_dirs)
@@ -132,14 +128,16 @@ class config(Command):
self.compiler.compile([src], include_dirs=include_dirs)
return (src, obj)
- def _link(self, body, headers, include_dirs, libraries, library_dirs,
- lang):
+ def _link(self, body, headers, include_dirs, libraries, library_dirs, lang):
(src, obj) = self._compile(body, headers, include_dirs, lang)
prog = os.path.splitext(os.path.basename(src))[0]
- self.compiler.link_executable([obj], prog,
- libraries=libraries,
- library_dirs=library_dirs,
- target_lang=lang)
+ self.compiler.link_executable(
+ [obj],
+ prog,
+ libraries=libraries,
+ library_dirs=library_dirs,
+ target_lang=lang,
+ )
if self.compiler.exe_extension is not None:
prog = prog + self.compiler.exe_extension
@@ -158,7 +156,6 @@ class config(Command):
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
@@ -177,6 +174,7 @@ class config(Command):
('body' probably isn't of much use, but what the heck.)
"""
from distutils.ccompiler import CompileError
+
self._check_compiler()
ok = True
try:
@@ -187,8 +185,7 @@ class config(Command):
self._clean()
return ok
- def search_cpp(self, pattern, body=None, headers=None, include_dirs=None,
- lang="c"):
+ def search_cpp(self, pattern, body=None, headers=None, include_dirs=None, lang="c"):
"""Construct a source file (just like 'try_cpp()'), run it through
the preprocessor, and return true if any line of the output matches
'pattern'. 'pattern' should either be a compiled regex object or a
@@ -220,6 +217,7 @@ class config(Command):
Return true on success, false otherwise.
"""
from distutils.ccompiler import CompileError
+
self._check_compiler()
try:
self._compile(body, headers, include_dirs, lang)
@@ -231,17 +229,24 @@ class config(Command):
self._clean()
return ok
- def try_link(self, body, headers=None, include_dirs=None, libraries=None,
- library_dirs=None, lang="c"):
+ def try_link(
+ self,
+ body,
+ headers=None,
+ include_dirs=None,
+ libraries=None,
+ library_dirs=None,
+ lang="c",
+ ):
"""Try to compile and link a source file, built from 'body' and
'headers', to executable form. Return true on success, false
otherwise.
"""
from distutils.ccompiler import CompileError, LinkError
+
self._check_compiler()
try:
- self._link(body, headers, include_dirs,
- libraries, library_dirs, lang)
+ self._link(body, headers, include_dirs, libraries, library_dirs, lang)
ok = True
except (CompileError, LinkError):
ok = False
@@ -250,17 +255,26 @@ class config(Command):
self._clean()
return ok
- def try_run(self, body, headers=None, include_dirs=None, libraries=None,
- library_dirs=None, lang="c"):
+ def try_run(
+ self,
+ body,
+ headers=None,
+ include_dirs=None,
+ libraries=None,
+ library_dirs=None,
+ lang="c",
+ ):
"""Try to compile, link to an executable, and run a program
built from 'body' and 'headers'. Return true on success, false
otherwise.
"""
from distutils.ccompiler import CompileError, LinkError
+
self._check_compiler()
try:
- src, obj, exe = self._link(body, headers, include_dirs,
- libraries, library_dirs, lang)
+ src, obj, exe = self._link(
+ body, headers, include_dirs, libraries, library_dirs, lang
+ )
self.spawn([exe])
ok = True
except (CompileError, LinkError, DistutilsExecError):
@@ -270,13 +284,20 @@ class config(Command):
self._clean()
return ok
-
# -- High-level methods --------------------------------------------
# (these are the ones that are actually likely to be useful
# when implementing a real-world config command!)
- def check_func(self, func, headers=None, include_dirs=None,
- libraries=None, library_dirs=None, decl=0, call=0):
+ def check_func(
+ self,
+ func,
+ headers=None,
+ include_dirs=None,
+ libraries=None,
+ library_dirs=None,
+ decl=0,
+ call=0,
+ ):
"""Determine if function 'func' is available by constructing a
source file that refers to 'func', and compiles and links it.
If everything succeeds, returns true; otherwise returns false.
@@ -302,11 +323,16 @@ class config(Command):
body.append("}")
body = "\n".join(body) + "\n"
- return self.try_link(body, headers, include_dirs,
- libraries, library_dirs)
+ return self.try_link(body, headers, include_dirs, libraries, library_dirs)
- def check_lib(self, library, library_dirs=None, headers=None,
- include_dirs=None, other_libraries=[]):
+ def check_lib(
+ self,
+ library,
+ library_dirs=None,
+ headers=None,
+ include_dirs=None,
+ other_libraries=[],
+ ):
"""Determine if 'library' is available to be linked against,
without actually checking that any particular symbols are provided
by it. 'headers' will be used in constructing the source file to
@@ -316,17 +342,23 @@ class config(Command):
has symbols that depend on other libraries.
"""
self._check_compiler()
- return self.try_link("int main (void) { }", headers, include_dirs,
- [library] + other_libraries, library_dirs)
-
- def check_header(self, header, include_dirs=None, library_dirs=None,
- lang="c"):
+ return self.try_link(
+ "int main (void) { }",
+ headers,
+ include_dirs,
+ [library] + other_libraries,
+ library_dirs,
+ )
+
+ def check_header(self, header, include_dirs=None, library_dirs=None, lang="c"):
"""Determine if the system header file named by 'header_file'
exists and can be found by the preprocessor; return true if so,
false otherwise.
"""
- return self.try_cpp(body="/* No body */", headers=[header],
- include_dirs=include_dirs)
+ return self.try_cpp(
+ body="/* No body */", headers=[header], include_dirs=include_dirs
+ )
+
def dump_file(filename, head=None):
"""Dumps a file content into log.info.
diff --git a/setuptools/_distutils/command/install.py b/setuptools/_distutils/command/install.py
index 41c17d8a..0660406f 100644
--- a/setuptools/_distutils/command/install.py
+++ b/setuptools/_distutils/command/install.py
@@ -21,6 +21,7 @@ from .. import _collections
from site import USER_BASE
from site import USER_SITE
+
HAS_USER_SITE = True
WINDOWS_SCHEME = {
@@ -28,7 +29,7 @@ WINDOWS_SCHEME = {
'platlib': '{base}/Lib/site-packages',
'headers': '{base}/Include/{dist_name}',
'scripts': '{base}/Scripts',
- 'data' : '{base}',
+ 'data': '{base}',
}
INSTALL_SCHEMES = {
@@ -37,31 +38,31 @@ INSTALL_SCHEMES = {
'platlib': '{platbase}/{platlibdir}/{implementation_lower}{py_version_short}/site-packages',
'headers': '{base}/include/{implementation_lower}{py_version_short}{abiflags}/{dist_name}',
'scripts': '{base}/bin',
- 'data' : '{base}',
- },
+ 'data': '{base}',
+ },
'posix_home': {
'purelib': '{base}/lib/{implementation_lower}',
'platlib': '{base}/{platlibdir}/{implementation_lower}',
'headers': '{base}/include/{implementation_lower}/{dist_name}',
'scripts': '{base}/bin',
- 'data' : '{base}',
- },
+ 'data': '{base}',
+ },
'nt': WINDOWS_SCHEME,
'pypy': {
'purelib': '{base}/site-packages',
'platlib': '{base}/site-packages',
'headers': '{base}/include/{dist_name}',
'scripts': '{base}/bin',
- 'data' : '{base}',
- },
+ 'data': '{base}',
+ },
'pypy_nt': {
'purelib': '{base}/site-packages',
'platlib': '{base}/site-packages',
'headers': '{base}/include/{dist_name}',
'scripts': '{base}/Scripts',
- 'data' : '{base}',
- },
- }
+ 'data': '{base}',
+ },
+}
# user site schemes
if HAS_USER_SITE:
@@ -70,17 +71,16 @@ if HAS_USER_SITE:
'platlib': '{usersite}',
'headers': '{userbase}/{implementation}{py_version_nodot_plat}/Include/{dist_name}',
'scripts': '{userbase}/{implementation}{py_version_nodot_plat}/Scripts',
- 'data' : '{userbase}',
- }
+ 'data': '{userbase}',
+ }
INSTALL_SCHEMES['posix_user'] = {
'purelib': '{usersite}',
'platlib': '{usersite}',
- 'headers':
- '{userbase}/include/{implementation_lower}{py_version_short}{abiflags}/{dist_name}',
+ 'headers': '{userbase}/include/{implementation_lower}{py_version_short}{abiflags}/{dist_name}',
'scripts': '{userbase}/bin',
- 'data' : '{userbase}',
- }
+ 'data': '{userbase}',
+ }
# The keys to an installation scheme; if any new types of files are to be
# installed, be sure to add an entry to every installation scheme above,
@@ -128,11 +128,7 @@ def _remove_set(ob, attrs):
"""
Include only attrs that are None in ob.
"""
- return {
- key: value
- for key, value in attrs.items()
- if getattr(ob, key) is None
- }
+ return {key: value for key, value in attrs.items() if getattr(ob, key) is None}
def _resolve_scheme(name):
@@ -164,10 +160,7 @@ def _inject_headers(name, scheme):
def _scheme_attrs(scheme):
"""Resolve install directories by applying the install schemes."""
- return {
- f'install_{key}': scheme[key]
- for key in SCHEME_KEYS
- }
+ return {f'install_{key}': scheme[key] for key in SCHEME_KEYS}
def _pypy_hack(name):
@@ -184,72 +177,73 @@ class install(Command):
user_options = [
# Select installation scheme and set base director(y|ies)
- ('prefix=', None,
- "installation prefix"),
- ('exec-prefix=', None,
- "(Unix only) prefix for platform-specific files"),
- ('home=', None,
- "(Unix only) home directory to install under"),
-
+ ('prefix=', None, "installation prefix"),
+ ('exec-prefix=', None, "(Unix only) prefix for platform-specific files"),
+ ('home=', None, "(Unix only) home directory to install under"),
# Or, just set the base director(y|ies)
- ('install-base=', None,
- "base installation directory (instead of --prefix or --home)"),
- ('install-platbase=', None,
- "base installation directory for platform-specific files " +
- "(instead of --exec-prefix or --home)"),
- ('root=', None,
- "install everything relative to this alternate root directory"),
-
+ (
+ 'install-base=',
+ None,
+ "base installation directory (instead of --prefix or --home)",
+ ),
+ (
+ 'install-platbase=',
+ None,
+ "base installation directory for platform-specific files "
+ + "(instead of --exec-prefix or --home)",
+ ),
+ ('root=', None, "install everything relative to this alternate root directory"),
# Or, explicitly set the installation scheme
- ('install-purelib=', None,
- "installation directory for pure Python module distributions"),
- ('install-platlib=', None,
- "installation directory for non-pure module distributions"),
- ('install-lib=', None,
- "installation directory for all module distributions " +
- "(overrides --install-purelib and --install-platlib)"),
-
- ('install-headers=', None,
- "installation directory for C/C++ headers"),
- ('install-scripts=', None,
- "installation directory for Python scripts"),
- ('install-data=', None,
- "installation directory for data files"),
-
+ (
+ 'install-purelib=',
+ None,
+ "installation directory for pure Python module distributions",
+ ),
+ (
+ 'install-platlib=',
+ None,
+ "installation directory for non-pure module distributions",
+ ),
+ (
+ 'install-lib=',
+ None,
+ "installation directory for all module distributions "
+ + "(overrides --install-purelib and --install-platlib)",
+ ),
+ ('install-headers=', None, "installation directory for C/C++ headers"),
+ ('install-scripts=', None, "installation directory for Python scripts"),
+ ('install-data=', None, "installation directory for data files"),
# Byte-compilation options -- see install_lib.py for details, as
# these are duplicated from there (but only install_lib does
# anything with them).
('compile', 'c', "compile .py to .pyc [default]"),
('no-compile', None, "don't compile .py files"),
- ('optimize=', 'O',
- "also compile with optimization: -O1 for \"python -O\", "
- "-O2 for \"python -OO\", and -O0 to disable [default: -O0]"),
-
+ (
+ 'optimize=',
+ 'O',
+ "also compile with optimization: -O1 for \"python -O\", "
+ "-O2 for \"python -OO\", and -O0 to disable [default: -O0]",
+ ),
# Miscellaneous control options
- ('force', 'f',
- "force installation (overwrite any existing files)"),
- ('skip-build', None,
- "skip rebuilding everything (for testing/debugging)"),
-
+ ('force', 'f', "force installation (overwrite any existing files)"),
+ ('skip-build', None, "skip rebuilding everything (for testing/debugging)"),
# Where to install documentation (eventually!)
- #('doc-format=', None, "format of documentation to generate"),
- #('install-man=', None, "directory for Unix man pages"),
- #('install-html=', None, "directory for HTML documentation"),
- #('install-info=', None, "directory for GNU info files"),
-
- ('record=', None,
- "filename in which to record list of installed files"),
- ]
+ # ('doc-format=', None, "format of documentation to generate"),
+ # ('install-man=', None, "directory for Unix man pages"),
+ # ('install-html=', None, "directory for HTML documentation"),
+ # ('install-info=', None, "directory for GNU info files"),
+ ('record=', None, "filename in which to record list of installed files"),
+ ]
boolean_options = ['compile', 'force', 'skip-build']
if HAS_USER_SITE:
- user_options.append(('user', None,
- "install in user site-package '%s'" % USER_SITE))
+ user_options.append(
+ ('user', None, "install in user site-package '%s'" % USER_SITE)
+ )
boolean_options.append('user')
- negative_opt = {'no-compile' : 'compile'}
-
+ negative_opt = {'no-compile': 'compile'}
def initialize_options(self):
"""Initializes options."""
@@ -271,10 +265,10 @@ class install(Command):
# supplied by the user, they are filled in using the installation
# scheme implied by prefix/exec-prefix/home and the contents of
# that installation scheme.
- self.install_purelib = None # for pure module distributions
- self.install_platlib = None # non-pure (dists w/ extensions)
- self.install_headers = None # for C/C++ headers
- self.install_lib = None # set to either purelib or platlib
+ self.install_purelib = None # for pure module distributions
+ self.install_platlib = None # non-pure (dists w/ extensions)
+ self.install_headers = None # for C/C++ headers
+ self.install_lib = None # set to either purelib or platlib
self.install_scripts = None
self.install_data = None
self.install_userbase = USER_BASE
@@ -316,13 +310,12 @@ class install(Command):
# Not defined yet because we don't know anything about
# documentation yet.
- #self.install_man = None
- #self.install_html = None
- #self.install_info = None
+ # self.install_man = None
+ # self.install_html = None
+ # self.install_info = None
self.record = None
-
# -- Option finalizing methods -------------------------------------
# (This is rather more involved than for most commands,
# because this is where the policy for installing third-
@@ -345,20 +338,30 @@ class install(Command):
# Check for errors/inconsistencies in the options; first, stuff
# that's wrong on any platform.
- if ((self.prefix or self.exec_prefix or self.home) and
- (self.install_base or self.install_platbase)):
+ if (self.prefix or self.exec_prefix or self.home) and (
+ self.install_base or self.install_platbase
+ ):
raise DistutilsOptionError(
- "must supply either prefix/exec-prefix/home or " +
- "install-base/install-platbase -- not both")
+ "must supply either prefix/exec-prefix/home or "
+ + "install-base/install-platbase -- not both"
+ )
if self.home and (self.prefix or self.exec_prefix):
raise DistutilsOptionError(
- "must supply either home or prefix/exec-prefix -- not both")
+ "must supply either home or prefix/exec-prefix -- not both"
+ )
- if self.user and (self.prefix or self.exec_prefix or self.home or
- self.install_base or self.install_platbase):
- raise DistutilsOptionError("can't combine user with prefix, "
- "exec_prefix/home, or install_(plat)base")
+ if self.user and (
+ self.prefix
+ or self.exec_prefix
+ or self.home
+ or self.install_base
+ or self.install_platbase
+ ):
+ raise DistutilsOptionError(
+ "can't combine user with prefix, "
+ "exec_prefix/home, or install_(plat)base"
+ )
# Next, stuff that's wrong (or dubious) only on certain platforms.
if os.name != "posix":
@@ -423,7 +426,8 @@ class install(Command):
local_vars['usersite'] = self.install_usersite
self.config_vars = _collections.DictStack(
- [compat_vars, sysconfig.get_config_vars(), local_vars])
+ [compat_vars, sysconfig.get_config_vars(), local_vars]
+ )
self.expand_basedirs()
@@ -436,6 +440,7 @@ class install(Command):
if DEBUG:
from pprint import pprint
+
print("config vars:")
pprint(dict(self.config_vars))
@@ -454,17 +459,23 @@ class install(Command):
# module distribution is pure or not. Of course, if the user
# already specified install_lib, use their selection.
if self.install_lib is None:
- if self.distribution.has_ext_modules(): # has extensions: non-pure
+ if self.distribution.has_ext_modules(): # has extensions: non-pure
self.install_lib = self.install_platlib
else:
self.install_lib = self.install_purelib
-
# Convert directories from Unix /-separated syntax to the local
# convention.
- self.convert_paths('lib', 'purelib', 'platlib',
- 'scripts', 'data', 'headers',
- 'userbase', 'usersite')
+ self.convert_paths(
+ 'lib',
+ 'purelib',
+ 'platlib',
+ 'scripts',
+ 'data',
+ 'headers',
+ 'userbase',
+ 'usersite',
+ )
# Deprecated
# Well, we're not actually fully completely finalized yet: we still
@@ -472,21 +483,22 @@ class install(Command):
# non-packagized module distributions (hello, Numerical Python!) to
# get their own directories.
self.handle_extra_path()
- self.install_libbase = self.install_lib # needed for .pth file
+ self.install_libbase = self.install_lib # needed for .pth file
self.install_lib = os.path.join(self.install_lib, self.extra_dirs)
# If a new root directory was supplied, make all the installation
# dirs relative to it.
if self.root is not None:
- self.change_roots('libbase', 'lib', 'purelib', 'platlib',
- 'scripts', 'data', 'headers')
+ self.change_roots(
+ 'libbase', 'lib', 'purelib', 'platlib', 'scripts', 'data', 'headers'
+ )
self.dump_dirs("after prepending root")
# Find out the build directories, ie. where to install from.
- self.set_undefined_options('build',
- ('build_base', 'build_base'),
- ('build_lib', 'build_lib'))
+ self.set_undefined_options(
+ 'build', ('build_base', 'build_base'), ('build_lib', 'build_lib')
+ )
# Punt on doc directories for now -- after all, we're punting on
# documentation completely!
@@ -496,6 +508,7 @@ class install(Command):
if not DEBUG:
return
from distutils.fancy_getopt import longopt_xlate
+
log.debug(msg + ":")
for opt in self.user_options:
opt_name = opt[0]
@@ -515,24 +528,24 @@ class install(Command):
if self.install_base is not None or self.install_platbase is not None:
incomplete_scheme = (
(
- self.install_lib is None and
- self.install_purelib is None and
- self.install_platlib is None
- ) or
- self.install_headers is None or
- self.install_scripts is None or
- self.install_data is None
+ self.install_lib is None
+ and self.install_purelib is None
+ and self.install_platlib is None
+ )
+ or self.install_headers is None
+ or self.install_scripts is None
+ or self.install_data is None
)
if incomplete_scheme:
raise DistutilsOptionError(
- "install-base or install-platbase supplied, but "
- "installation scheme is incomplete")
+ "install-base or install-platbase supplied, but "
+ "installation scheme is incomplete"
+ )
return
if self.user:
if self.install_userbase is None:
- raise DistutilsPlatformError(
- "User base directory is not specified")
+ raise DistutilsPlatformError("User base directory is not specified")
self.install_base = self.install_platbase = self.install_userbase
self.select_scheme("posix_user")
elif self.home is not None:
@@ -542,15 +555,14 @@ class install(Command):
if self.prefix is None:
if self.exec_prefix is not None:
raise DistutilsOptionError(
- "must not supply exec-prefix without prefix")
+ "must not supply exec-prefix without prefix"
+ )
# Allow Fedora to add components to the prefix
_prefix_addition = getattr(sysconfig, '_prefix_addition', "")
- self.prefix = (
- os.path.normpath(sys.prefix) + _prefix_addition)
- self.exec_prefix = (
- os.path.normpath(sys.exec_prefix) + _prefix_addition)
+ self.prefix = os.path.normpath(sys.prefix) + _prefix_addition
+ self.exec_prefix = os.path.normpath(sys.exec_prefix) + _prefix_addition
else:
if self.exec_prefix is None:
@@ -564,8 +576,7 @@ class install(Command):
"""Finalizes options for non-posix platforms"""
if self.user:
if self.install_userbase is None:
- raise DistutilsPlatformError(
- "User base directory is not specified")
+ raise DistutilsPlatformError("User base directory is not specified")
self.install_base = self.install_platbase = self.install_userbase
self.select_scheme(os.name + "_user")
elif self.home is not None:
@@ -580,7 +591,8 @@ class install(Command):
self.select_scheme(os.name)
except KeyError:
raise DistutilsPlatformError(
- "I don't know how to install stuff on '%s'" % os.name)
+ "I don't know how to install stuff on '%s'" % os.name
+ )
def select_scheme(self, name):
_select_scheme(self, name)
@@ -601,9 +613,16 @@ class install(Command):
def expand_dirs(self):
"""Calls `os.path.expanduser` on install dirs."""
- self._expand_attrs(['install_purelib', 'install_platlib',
- 'install_lib', 'install_headers',
- 'install_scripts', 'install_data',])
+ self._expand_attrs(
+ [
+ 'install_purelib',
+ 'install_platlib',
+ 'install_lib',
+ 'install_headers',
+ 'install_scripts',
+ 'install_data',
+ ]
+ )
def convert_paths(self, *names):
"""Call `convert_path` over `names`."""
@@ -630,8 +649,9 @@ class install(Command):
path_file, extra_dirs = self.extra_path
else:
raise DistutilsOptionError(
- "'extra_path' option must be a list, tuple, or "
- "comma-separated string with 1 or 2 elements")
+ "'extra_path' option must be a list, tuple, or "
+ "comma-separated string with 1 or 2 elements"
+ )
# convert to local form in case Unix notation used (as it
# should be in setup scripts)
@@ -674,8 +694,7 @@ class install(Command):
# internally, and not to sys.path, so we don't check the platform
# matches what we are running.
if self.warn_dir and build_plat != get_platform():
- raise DistutilsPlatformError("Can't install when "
- "cross-compiling")
+ raise DistutilsPlatformError("Can't install when " "cross-compiling")
# Run all sub-commands (at least those that need to be run)
for cmd_name in self.get_sub_commands():
@@ -687,38 +706,43 @@ class install(Command):
# write list of installed files, if requested.
if self.record:
outputs = self.get_outputs()
- if self.root: # strip any package prefix
+ if self.root: # strip any package prefix
root_len = len(self.root)
for counter in range(len(outputs)):
outputs[counter] = outputs[counter][root_len:]
- self.execute(write_file,
- (self.record, outputs),
- "writing list of installed files to '%s'" %
- self.record)
+ self.execute(
+ write_file,
+ (self.record, outputs),
+ "writing list of installed files to '%s'" % self.record,
+ )
sys_path = map(os.path.normpath, sys.path)
sys_path = map(os.path.normcase, sys_path)
install_lib = os.path.normcase(os.path.normpath(self.install_lib))
- if (self.warn_dir and
- not (self.path_file and self.install_path_file) and
- install_lib not in sys_path):
- log.debug(("modules installed to '%s', which is not in "
- "Python's module search path (sys.path) -- "
- "you'll have to change the search path yourself"),
- self.install_lib)
+ if (
+ self.warn_dir
+ and not (self.path_file and self.install_path_file)
+ and install_lib not in sys_path
+ ):
+ log.debug(
+ (
+ "modules installed to '%s', which is not in "
+ "Python's module search path (sys.path) -- "
+ "you'll have to change the search path yourself"
+ ),
+ self.install_lib,
+ )
def create_path_file(self):
"""Creates the .pth file"""
- filename = os.path.join(self.install_libbase,
- self.path_file + ".pth")
+ filename = os.path.join(self.install_libbase, self.path_file + ".pth")
if self.install_path_file:
- self.execute(write_file,
- (filename, [self.extra_dirs]),
- "creating %s" % filename)
+ self.execute(
+ write_file, (filename, [self.extra_dirs]), "creating %s" % filename
+ )
else:
self.warn("path file '%s' not created" % filename)
-
# -- Reporting methods ---------------------------------------------
def get_outputs(self):
@@ -733,8 +757,7 @@ class install(Command):
outputs.append(filename)
if self.path_file and self.install_path_file:
- outputs.append(os.path.join(self.install_libbase,
- self.path_file + ".pth"))
+ outputs.append(os.path.join(self.install_libbase, self.path_file + ".pth"))
return outputs
@@ -753,8 +776,9 @@ class install(Command):
def has_lib(self):
"""Returns true if the current distribution has any Python
modules to install."""
- return (self.distribution.has_pure_modules() or
- self.distribution.has_ext_modules())
+ return (
+ self.distribution.has_pure_modules() or self.distribution.has_ext_modules()
+ )
def has_headers(self):
"""Returns true if the current distribution has any headers to
@@ -773,9 +797,10 @@ class install(Command):
# 'sub_commands': a list of commands this command might have to run to
# get its work done. See cmd.py for more info.
- sub_commands = [('install_lib', has_lib),
- ('install_headers', has_headers),
- ('install_scripts', has_scripts),
- ('install_data', has_data),
- ('install_egg_info', lambda self:True),
- ]
+ sub_commands = [
+ ('install_lib', has_lib),
+ ('install_headers', has_headers),
+ ('install_scripts', has_scripts),
+ ('install_data', has_data),
+ ('install_egg_info', lambda self: True),
+ ]
diff --git a/setuptools/_distutils/command/install_data.py b/setuptools/_distutils/command/install_data.py
index 947cd76a..23d91ade 100644
--- a/setuptools/_distutils/command/install_data.py
+++ b/setuptools/_distutils/command/install_data.py
@@ -9,18 +9,21 @@ import os
from distutils.core import Command
from distutils.util import change_root, convert_path
+
class install_data(Command):
description = "install data files"
user_options = [
- ('install-dir=', 'd',
- "base directory for installing data files "
- "(default: installation base dir)"),
- ('root=', None,
- "install everything relative to this alternate root directory"),
+ (
+ 'install-dir=',
+ 'd',
+ "base directory for installing data files "
+ "(default: installation base dir)",
+ ),
+ ('root=', None, "install everything relative to this alternate root directory"),
('force', 'f', "force installation (overwrite existing files)"),
- ]
+ ]
boolean_options = ['force']
@@ -33,11 +36,12 @@ class install_data(Command):
self.warn_dir = 1
def finalize_options(self):
- self.set_undefined_options('install',
- ('install_data', 'install_dir'),
- ('root', 'root'),
- ('force', 'force'),
- )
+ self.set_undefined_options(
+ 'install',
+ ('install_data', 'install_dir'),
+ ('root', 'root'),
+ ('force', 'force'),
+ )
def run(self):
self.mkpath(self.install_dir)
@@ -46,9 +50,10 @@ class install_data(Command):
# it's a simple file, so copy it
f = convert_path(f)
if self.warn_dir:
- self.warn("setup script did not provide a directory for "
- "'%s' -- installing right in '%s'" %
- (f, self.install_dir))
+ self.warn(
+ "setup script did not provide a directory for "
+ "'%s' -- installing right in '%s'" % (f, self.install_dir)
+ )
(out, _) = self.copy_file(f, self.install_dir)
self.outfiles.append(out)
else:
diff --git a/setuptools/_distutils/command/install_egg_info.py b/setuptools/_distutils/command/install_egg_info.py
index adc0323f..dc939633 100644
--- a/setuptools/_distutils/command/install_egg_info.py
+++ b/setuptools/_distutils/command/install_egg_info.py
@@ -8,6 +8,7 @@ from distutils.cmd import Command
from distutils import log, dir_util
import os, sys, re
+
class install_egg_info(Command):
"""Install an .egg-info file for the package"""
@@ -28,11 +29,11 @@ class install_egg_info(Command):
return "%s-%s-py%d.%d.egg-info" % (
to_filename(safe_name(self.distribution.get_name())),
to_filename(safe_version(self.distribution.get_version())),
- *sys.version_info[:2]
+ *sys.version_info[:2],
)
def finalize_options(self):
- self.set_undefined_options('install_lib',('install_dir','install_dir'))
+ self.set_undefined_options('install_lib', ('install_dir', 'install_dir'))
self.target = os.path.join(self.install_dir, self.basename)
self.outputs = [self.target]
@@ -41,10 +42,11 @@ class install_egg_info(Command):
if os.path.isdir(target) and not os.path.islink(target):
dir_util.remove_tree(target, dry_run=self.dry_run)
elif os.path.exists(target):
- self.execute(os.unlink,(self.target,),"Removing "+target)
+ self.execute(os.unlink, (self.target,), "Removing " + target)
elif not os.path.isdir(self.install_dir):
- self.execute(os.makedirs, (self.install_dir,),
- "Creating "+self.install_dir)
+ self.execute(
+ 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:
@@ -58,6 +60,7 @@ class install_egg_info(Command):
# can be replaced by importing them from pkg_resources once it is included
# in the stdlib.
+
def safe_name(name):
"""Convert an arbitrary string to a standard distribution name
@@ -72,7 +75,7 @@ def safe_version(version):
Spaces become dots, and all other non-alphanumeric characters become
dashes, with runs of multiple dashes condensed to a single dash.
"""
- version = version.replace(' ','.')
+ version = version.replace(' ', '.')
return re.sub('[^A-Za-z0-9.]+', '-', version)
@@ -81,4 +84,4 @@ def to_filename(name):
Any '-' characters are currently replaced with '_'.
"""
- return name.replace('-','_')
+ return name.replace('-', '_')
diff --git a/setuptools/_distutils/command/install_headers.py b/setuptools/_distutils/command/install_headers.py
index 9bb0b18d..87046ab3 100644
--- a/setuptools/_distutils/command/install_headers.py
+++ b/setuptools/_distutils/command/install_headers.py
@@ -11,11 +11,10 @@ class install_headers(Command):
description = "install C/C++ header files"
- user_options = [('install-dir=', 'd',
- "directory to install header files to"),
- ('force', 'f',
- "force installation (overwrite existing files)"),
- ]
+ user_options = [
+ ('install-dir=', 'd', "directory to install header files to"),
+ ('force', 'f', "force installation (overwrite existing files)"),
+ ]
boolean_options = ['force']
@@ -25,10 +24,9 @@ class install_headers(Command):
self.outfiles = []
def finalize_options(self):
- self.set_undefined_options('install',
- ('install_headers', 'install_dir'),
- ('force', 'force'))
-
+ self.set_undefined_options(
+ 'install', ('install_headers', 'install_dir'), ('force', 'force')
+ )
def run(self):
headers = self.distribution.headers
diff --git a/setuptools/_distutils/command/install_lib.py b/setuptools/_distutils/command/install_lib.py
index 6154cf09..ad3089c8 100644
--- a/setuptools/_distutils/command/install_lib.py
+++ b/setuptools/_distutils/command/install_lib.py
@@ -14,6 +14,7 @@ from distutils.errors import DistutilsOptionError
# Extension for Python source files.
PYTHON_SOURCE_EXTENSION = ".py"
+
class install_lib(Command):
description = "install all Python modules (extensions and pure Python)"
@@ -35,18 +36,21 @@ class install_lib(Command):
user_options = [
('install-dir=', 'd', "directory to install to"),
- ('build-dir=','b', "build directory (where to install from)"),
+ ('build-dir=', 'b', "build directory (where to install from)"),
('force', 'f', "force installation (overwrite existing files)"),
('compile', 'c', "compile .py to .pyc [default]"),
('no-compile', None, "don't compile .py files"),
- ('optimize=', 'O',
- "also compile with optimization: -O1 for \"python -O\", "
- "-O2 for \"python -OO\", and -O0 to disable [default: -O0]"),
+ (
+ 'optimize=',
+ 'O',
+ "also compile with optimization: -O1 for \"python -O\", "
+ "-O2 for \"python -OO\", and -O0 to disable [default: -O0]",
+ ),
('skip-build', None, "skip the build steps"),
- ]
+ ]
boolean_options = ['force', 'compile', 'skip-build']
- negative_opt = {'no-compile' : 'compile'}
+ negative_opt = {'no-compile': 'compile'}
def initialize_options(self):
# let the 'install' command dictate our installation directory
@@ -61,14 +65,15 @@ class install_lib(Command):
# Get all the information we need to install pure Python modules
# from the umbrella 'install' command -- build (source) directory,
# install (target) directory, and whether to compile .py files.
- self.set_undefined_options('install',
- ('build_lib', 'build_dir'),
- ('install_lib', 'install_dir'),
- ('force', 'force'),
- ('compile', 'compile'),
- ('optimize', 'optimize'),
- ('skip_build', 'skip_build'),
- )
+ self.set_undefined_options(
+ 'install',
+ ('build_lib', 'build_dir'),
+ ('install_lib', 'install_dir'),
+ ('force', 'force'),
+ ('compile', 'compile'),
+ ('optimize', 'optimize'),
+ ('skip_build', 'skip_build'),
+ )
if self.compile is None:
self.compile = True
@@ -110,8 +115,9 @@ class install_lib(Command):
if os.path.isdir(self.build_dir):
outfiles = self.copy_tree(self.build_dir, self.install_dir)
else:
- self.warn("'%s' does not exist -- no Python modules to install" %
- self.build_dir)
+ self.warn(
+ "'%s' does not exist -- no Python modules to install" % self.build_dir
+ )
return
return outfiles
@@ -129,14 +135,22 @@ class install_lib(Command):
install_root = self.get_finalized_command('install').root
if self.compile:
- byte_compile(files, optimize=0,
- force=self.force, prefix=install_root,
- dry_run=self.dry_run)
+ byte_compile(
+ files,
+ optimize=0,
+ force=self.force,
+ prefix=install_root,
+ dry_run=self.dry_run,
+ )
if self.optimize > 0:
- byte_compile(files, optimize=self.optimize,
- force=self.force, prefix=install_root,
- verbose=self.verbose, dry_run=self.dry_run)
-
+ byte_compile(
+ files,
+ optimize=self.optimize,
+ force=self.force,
+ prefix=install_root,
+ verbose=self.verbose,
+ dry_run=self.dry_run,
+ )
# -- Utility methods -----------------------------------------------
@@ -165,15 +179,18 @@ class install_lib(Command):
if ext != PYTHON_SOURCE_EXTENSION:
continue
if self.compile:
- bytecode_files.append(importlib.util.cache_from_source(
- py_file, optimization=''))
+ bytecode_files.append(
+ importlib.util.cache_from_source(py_file, optimization='')
+ )
if self.optimize > 0:
- bytecode_files.append(importlib.util.cache_from_source(
- py_file, optimization=self.optimize))
+ bytecode_files.append(
+ importlib.util.cache_from_source(
+ py_file, optimization=self.optimize
+ )
+ )
return bytecode_files
-
# -- External interface --------------------------------------------
# (called by outsiders)
@@ -182,19 +199,23 @@ class install_lib(Command):
were actually run. Not affected by the "dry-run" flag or whether
modules have actually been built yet.
"""
- pure_outputs = \
- self._mutate_outputs(self.distribution.has_pure_modules(),
- 'build_py', 'build_lib',
- self.install_dir)
+ pure_outputs = self._mutate_outputs(
+ self.distribution.has_pure_modules(),
+ 'build_py',
+ 'build_lib',
+ self.install_dir,
+ )
if self.compile:
bytecode_outputs = self._bytecode_filenames(pure_outputs)
else:
bytecode_outputs = []
- ext_outputs = \
- self._mutate_outputs(self.distribution.has_ext_modules(),
- 'build_ext', 'build_lib',
- self.install_dir)
+ ext_outputs = self._mutate_outputs(
+ self.distribution.has_ext_modules(),
+ 'build_ext',
+ 'build_lib',
+ self.install_dir,
+ )
return pure_outputs + bytecode_outputs + ext_outputs
diff --git a/setuptools/_distutils/command/install_scripts.py b/setuptools/_distutils/command/install_scripts.py
index 31a1130e..f09bd644 100644
--- a/setuptools/_distutils/command/install_scripts.py
+++ b/setuptools/_distutils/command/install_scripts.py
@@ -17,7 +17,7 @@ class install_scripts(Command):
user_options = [
('install-dir=', 'd', "directory to install scripts to"),
- ('build-dir=','b', "build directory (where to install from)"),
+ ('build-dir=', 'b', "build directory (where to install from)"),
('force', 'f', "force installation (overwrite existing files)"),
('skip-build', None, "skip the build steps"),
]
@@ -32,11 +32,12 @@ class install_scripts(Command):
def finalize_options(self):
self.set_undefined_options('build', ('build_scripts', 'build_dir'))
- self.set_undefined_options('install',
- ('install_scripts', 'install_dir'),
- ('force', 'force'),
- ('skip_build', 'skip_build'),
- )
+ self.set_undefined_options(
+ 'install',
+ ('install_scripts', 'install_dir'),
+ ('force', 'force'),
+ ('skip_build', 'skip_build'),
+ )
def run(self):
if not self.skip_build:
diff --git a/setuptools/_distutils/command/py37compat.py b/setuptools/_distutils/command/py37compat.py
index 754715a5..aa0c0a7f 100644
--- a/setuptools/_distutils/command/py37compat.py
+++ b/setuptools/_distutils/command/py37compat.py
@@ -7,12 +7,13 @@ def _pythonlib_compat():
library. See pypa/distutils#9.
"""
from distutils import sysconfig
+
if not sysconfig.get_config_var('Py_ENABLED_SHARED'):
return
yield 'python{}.{}{}'.format(
sys.hexversion >> 24,
- (sys.hexversion >> 16) & 0xff,
+ (sys.hexversion >> 16) & 0xFF,
sysconfig.get_config_var('ABIFLAGS'),
)
diff --git a/setuptools/_distutils/command/register.py b/setuptools/_distutils/command/register.py
index 0fac94e9..ca407eb7 100644
--- a/setuptools/_distutils/command/register.py
+++ b/setuptools/_distutils/command/register.py
@@ -14,17 +14,23 @@ from distutils.core import PyPIRCCommand
from distutils.errors import *
from distutils import log
+
class register(PyPIRCCommand):
- description = ("register the distribution with the Python package index")
+ description = "register the distribution with the Python package index"
user_options = PyPIRCCommand.user_options + [
- ('list-classifiers', None,
- 'list the valid Trove classifiers'),
- ('strict', None ,
- 'Will stop the registering if the meta-data are not fully compliant')
- ]
+ ('list-classifiers', None, 'list the valid Trove classifiers'),
+ (
+ 'strict',
+ None,
+ 'Will stop the registering if the meta-data are not fully compliant',
+ ),
+ ]
boolean_options = PyPIRCCommand.boolean_options + [
- 'verify', 'list-classifiers', 'strict']
+ 'verify',
+ 'list-classifiers',
+ 'strict',
+ ]
sub_commands = [('check', lambda self: True)]
@@ -36,8 +42,10 @@ class register(PyPIRCCommand):
def finalize_options(self):
PyPIRCCommand.finalize_options(self)
# setting options for the `check` subcommand
- check_options = {'strict': ('register', self.strict),
- 'restructuredtext': ('register', 1)}
+ check_options = {
+ 'strict': ('register', self.strict),
+ 'restructuredtext': ('register', 1),
+ }
self.distribution.command_options['check'] = check_options
def run(self):
@@ -57,8 +65,11 @@ class register(PyPIRCCommand):
def check_metadata(self):
"""Deprecated API."""
- warn("distutils.command.register.check_metadata is deprecated, \
- use the check command instead", PendingDeprecationWarning)
+ warn(
+ "distutils.command.register.check_metadata is deprecated, \
+ use the check command instead",
+ PendingDeprecationWarning,
+ )
check = self.distribution.get_command_obj('check')
check.ensure_finalized()
check.strict = self.strict
@@ -66,8 +77,7 @@ class register(PyPIRCCommand):
check.run()
def _set_config(self):
- ''' Reads the configuration file and set attributes.
- '''
+ '''Reads the configuration file and set attributes.'''
config = self._read_pypirc()
if config != {}:
self.username = config['username']
@@ -83,45 +93,43 @@ class register(PyPIRCCommand):
self.has_config = False
def classifiers(self):
- ''' Fetch the list of classifiers from the server.
- '''
- url = self.repository+'?:action=list_classifiers'
+ '''Fetch the list of classifiers from the server.'''
+ url = self.repository + '?:action=list_classifiers'
response = urllib.request.urlopen(url)
log.info(self._read_pypi_response(response))
def verify_metadata(self):
- ''' Send the metadata to the package index server to be checked.
- '''
+ '''Send the metadata to the package index server to be checked.'''
# send the info to the server and report the result
(code, result) = self.post_to_server(self.build_post_data('verify'))
log.info('Server response (%s): %s', code, result)
def send_metadata(self):
- ''' Send the metadata to the package index server.
+ '''Send the metadata to the package index server.
- Well, do the following:
- 1. figure who the user is, and then
- 2. send the data as a Basic auth'ed POST.
+ Well, do the following:
+ 1. figure who the user is, and then
+ 2. send the data as a Basic auth'ed POST.
- First we try to read the username/password from $HOME/.pypirc,
- which is a ConfigParser-formatted file with a section
- [distutils] containing username and password entries (both
- in clear text). Eg:
+ First we try to read the username/password from $HOME/.pypirc,
+ which is a ConfigParser-formatted file with a section
+ [distutils] containing username and password entries (both
+ in clear text). Eg:
- [distutils]
- index-servers =
- pypi
+ [distutils]
+ index-servers =
+ pypi
- [pypi]
- username: fred
- password: sekrit
+ [pypi]
+ username: fred
+ password: sekrit
- Otherwise, to figure who the user is, we offer the user three
- choices:
+ Otherwise, to figure who the user is, we offer the user three
+ choices:
- 1. use existing login,
- 2. register as a new user, or
- 3. set the password to a random string and email the user.
+ 1. use existing login,
+ 2. register as a new user, or
+ 3. set the password to a random string and email the user.
'''
# see if we can short-cut and get the username/password from the
@@ -137,13 +145,16 @@ class register(PyPIRCCommand):
# get the user's login info
choices = '1 2 3 4'.split()
while choice not in choices:
- self.announce('''\
+ self.announce(
+ '''\
We need to know who you are, so please choose either:
1. use your existing login,
2. register as a new user,
3. have the server generate a new password for you (and email it to you), or
4. quit
-Your selection [default 1]: ''', log.INFO)
+Your selection [default 1]: ''',
+ log.INFO,
+ )
choice = input()
if not choice:
choice = '1'
@@ -162,10 +173,8 @@ Your selection [default 1]: ''', log.INFO)
host = urllib.parse.urlparse(self.repository)[1]
auth.add_password(self.realm, host, username, password)
# send the info to the server and report the result
- code, result = self.post_to_server(self.build_post_data('submit'),
- auth)
- self.announce('Server response (%s): %s' % (code, result),
- log.INFO)
+ code, result = self.post_to_server(self.build_post_data('submit'), auth)
+ self.announce('Server response (%s): %s' % (code, result), log.INFO)
# possibly save the login
if code == 200:
@@ -174,10 +183,17 @@ Your selection [default 1]: ''', log.INFO)
# so the upload command can reuse it
self.distribution.password = password
else:
- self.announce(('I can store your PyPI login so future '
- 'submissions will be faster.'), log.INFO)
- self.announce('(the login will be stored in %s)' % \
- self._get_rc_file(), log.INFO)
+ self.announce(
+ (
+ 'I can store your PyPI login so future '
+ 'submissions will be faster.'
+ ),
+ log.INFO,
+ )
+ self.announce(
+ '(the login will be stored in %s)' % self._get_rc_file(),
+ log.INFO,
+ )
choice = 'X'
while choice.lower() not in 'yn':
choice = input('Save your login (y/N)?')
@@ -208,8 +224,7 @@ Your selection [default 1]: ''', log.INFO)
log.info('Server response (%s): %s', code, result)
else:
log.info('You will receive an email shortly.')
- log.info(('Follow the instructions in it to '
- 'complete registration.'))
+ log.info(('Follow the instructions in it to ' 'complete registration.'))
elif choice == '3':
data = {':action': 'password_reset'}
data['email'] = ''
@@ -224,7 +239,7 @@ Your selection [default 1]: ''', log.INFO)
meta = self.distribution.metadata
data = {
':action': action,
- 'metadata_version' : '1.0',
+ 'metadata_version': '1.0',
'name': meta.get_name(),
'version': meta.get_version(),
'summary': meta.get_description(),
@@ -247,12 +262,11 @@ Your selection [default 1]: ''', log.INFO)
return data
def post_to_server(self, data, auth=None):
- ''' Post a query to the server, and return a string response.
- '''
+ '''Post a query to the server, and return a string response.'''
if 'name' in data:
- self.announce('Registering %s to %s' % (data['name'],
- self.repository),
- log.INFO)
+ self.announce(
+ 'Registering %s to %s' % (data['name'], self.repository), log.INFO
+ )
# Build up the MIME payload for the urllib2 POST data
boundary = '--------------GHSKFJDLGDS7543FJKLFHRE75642756743254'
sep_boundary = '\n--' + boundary
@@ -260,12 +274,12 @@ Your selection [default 1]: ''', log.INFO)
body = io.StringIO()
for key, value in data.items():
# handle multiple entries for the same name
- if type(value) not in (type([]), type( () )):
+ if type(value) not in (type([]), type(())):
value = [value]
for value in value:
value = str(value)
body.write(sep_boundary)
- body.write('\nContent-Disposition: form-data; name="%s"'%key)
+ body.write('\nContent-Disposition: form-data; name="%s"' % key)
body.write("\n\n")
body.write(value)
if value and value[-1] == '\r':
@@ -276,8 +290,9 @@ Your selection [default 1]: ''', log.INFO)
# build the Request
headers = {
- 'Content-type': 'multipart/form-data; boundary=%s; charset=utf-8'%boundary,
- 'Content-length': str(len(body))
+ 'Content-type': 'multipart/form-data; boundary=%s; charset=utf-8'
+ % boundary,
+ 'Content-length': str(len(body)),
}
req = urllib.request.Request(self.repository, body, headers)
diff --git a/setuptools/_distutils/command/sdist.py b/setuptools/_distutils/command/sdist.py
index b4996fcb..aad3e713 100644
--- a/setuptools/_distutils/command/sdist.py
+++ b/setuptools/_distutils/command/sdist.py
@@ -24,13 +24,12 @@ def show_formats():
"""
from distutils.fancy_getopt import FancyGetopt
from distutils.archive_util import ARCHIVE_FORMATS
+
formats = []
for format in ARCHIVE_FORMATS.keys():
- formats.append(("formats=" + format, None,
- ARCHIVE_FORMATS[format][2]))
+ formats.append(("formats=" + format, None, ARCHIVE_FORMATS[format][2]))
formats.sort()
- FancyGetopt(formats).print_help(
- "List of available source distribution formats:")
+ FancyGetopt(formats).print_help("List of available source distribution formats:")
class sdist(Command):
@@ -44,55 +43,77 @@ class sdist(Command):
return self.metadata_check
user_options = [
- ('template=', 't',
- "name of manifest template file [default: MANIFEST.in]"),
- ('manifest=', 'm',
- "name of manifest file [default: MANIFEST]"),
- ('use-defaults', None,
- "include the default file set in the manifest "
- "[default; disable with --no-defaults]"),
- ('no-defaults', None,
- "don't include the default file set"),
- ('prune', None,
- "specifically exclude files/directories that should not be "
- "distributed (build tree, RCS/CVS dirs, etc.) "
- "[default; disable with --no-prune]"),
- ('no-prune', None,
- "don't automatically exclude anything"),
- ('manifest-only', 'o',
- "just regenerate the manifest and then stop "
- "(implies --force-manifest)"),
- ('force-manifest', 'f',
- "forcibly regenerate the manifest and carry on as usual. "
- "Deprecated: now the manifest is always regenerated."),
- ('formats=', None,
- "formats for source distribution (comma-separated list)"),
- ('keep-temp', 'k',
- "keep the distribution tree around after creating " +
- "archive file(s)"),
- ('dist-dir=', 'd',
- "directory to put the source distribution archive(s) in "
- "[default: dist]"),
- ('metadata-check', None,
- "Ensure that all required elements of meta-data "
- "are supplied. Warn if any missing. [default]"),
- ('owner=', 'u',
- "Owner name used when creating a tar file [default: current user]"),
- ('group=', 'g',
- "Group name used when creating a tar file [default: current group]"),
- ]
-
- boolean_options = ['use-defaults', 'prune',
- 'manifest-only', 'force-manifest',
- 'keep-temp', 'metadata-check']
+ ('template=', 't', "name of manifest template file [default: MANIFEST.in]"),
+ ('manifest=', 'm', "name of manifest file [default: MANIFEST]"),
+ (
+ 'use-defaults',
+ None,
+ "include the default file set in the manifest "
+ "[default; disable with --no-defaults]",
+ ),
+ ('no-defaults', None, "don't include the default file set"),
+ (
+ 'prune',
+ None,
+ "specifically exclude files/directories that should not be "
+ "distributed (build tree, RCS/CVS dirs, etc.) "
+ "[default; disable with --no-prune]",
+ ),
+ ('no-prune', None, "don't automatically exclude anything"),
+ (
+ 'manifest-only',
+ 'o',
+ "just regenerate the manifest and then stop " "(implies --force-manifest)",
+ ),
+ (
+ 'force-manifest',
+ 'f',
+ "forcibly regenerate the manifest and carry on as usual. "
+ "Deprecated: now the manifest is always regenerated.",
+ ),
+ ('formats=', None, "formats for source distribution (comma-separated list)"),
+ (
+ 'keep-temp',
+ 'k',
+ "keep the distribution tree around after creating " + "archive file(s)",
+ ),
+ (
+ 'dist-dir=',
+ 'd',
+ "directory to put the source distribution archive(s) in " "[default: dist]",
+ ),
+ (
+ 'metadata-check',
+ None,
+ "Ensure that all required elements of meta-data "
+ "are supplied. Warn if any missing. [default]",
+ ),
+ (
+ 'owner=',
+ 'u',
+ "Owner name used when creating a tar file [default: current user]",
+ ),
+ (
+ 'group=',
+ 'g',
+ "Group name used when creating a tar file [default: current group]",
+ ),
+ ]
+
+ boolean_options = [
+ 'use-defaults',
+ 'prune',
+ 'manifest-only',
+ 'force-manifest',
+ 'keep-temp',
+ 'metadata-check',
+ ]
help_options = [
- ('help-formats', None,
- "list available distribution formats", show_formats),
- ]
+ ('help-formats', None, "list available distribution formats", show_formats),
+ ]
- negative_opt = {'no-defaults': 'use-defaults',
- 'no-prune': 'prune' }
+ negative_opt = {'no-defaults': 'use-defaults', 'no-prune': 'prune'}
sub_commands = [('check', checking_metadata)]
@@ -131,8 +152,7 @@ class sdist(Command):
bad_format = archive_util.check_archive_formats(self.formats)
if bad_format:
- raise DistutilsOptionError(
- "unknown archive format '%s'" % bad_format)
+ raise DistutilsOptionError("unknown archive format '%s'" % bad_format)
if self.dist_dir is None:
self.dist_dir = "dist"
@@ -161,8 +181,11 @@ class sdist(Command):
def check_metadata(self):
"""Deprecated API."""
- warn("distutils.command.sdist.check_metadata is deprecated, \
- use the check command instead", PendingDeprecationWarning)
+ warn(
+ "distutils.command.sdist.check_metadata is deprecated, \
+ use the check command instead",
+ PendingDeprecationWarning,
+ )
check = self.distribution.get_command_obj('check')
check.ensure_finalized()
check.run()
@@ -189,9 +212,10 @@ class sdist(Command):
return
if not template_exists:
- self.warn(("manifest template '%s' does not exist " +
- "(using default file list)") %
- self.template)
+ self.warn(
+ ("manifest template '%s' does not exist " + "(using default file list)")
+ % self.template
+ )
self.filelist.findall()
if self.use_defaults:
@@ -259,8 +283,9 @@ class sdist(Command):
break
if not got_it:
- self.warn("standard file not found: should have one of " +
- ', '.join(alts))
+ self.warn(
+ "standard file not found: should have one of " + ', '.join(alts)
+ )
else:
if self._cs_path_exists(fn):
self.filelist.append(fn)
@@ -328,14 +353,20 @@ class sdist(Command):
'self.filelist', which updates itself accordingly.
"""
log.info("reading manifest template '%s'", self.template)
- template = TextFile(self.template, strip_comments=1, skip_blanks=1,
- join_lines=1, lstrip_ws=1, rstrip_ws=1,
- collapse_join=1)
+ template = TextFile(
+ self.template,
+ strip_comments=1,
+ skip_blanks=1,
+ join_lines=1,
+ lstrip_ws=1,
+ rstrip_ws=1,
+ collapse_join=1,
+ )
try:
while True:
line = template.readline()
- if line is None: # end of file
+ if line is None: # end of file
break
try:
@@ -344,9 +375,10 @@ class sdist(Command):
# malformed lines, or a ValueError from the lower-level
# convert_path function
except (DistutilsTemplateError, ValueError) as msg:
- self.warn("%s, line %d: %s" % (template.filename,
- template.current_line,
- msg))
+ self.warn(
+ "%s, line %d: %s"
+ % (template.filename, template.current_line, msg)
+ )
finally:
template.close()
@@ -369,8 +401,7 @@ class sdist(Command):
else:
seps = '/'
- vcs_dirs = ['RCS', 'CVS', r'\.svn', r'\.hg', r'\.git', r'\.bzr',
- '_darcs']
+ vcs_dirs = ['RCS', 'CVS', r'\.svn', r'\.hg', r'\.git', r'\.bzr', '_darcs']
vcs_ptrn = r'(^|%s)(%s)(%s).*' % (seps, '|'.join(vcs_dirs), seps)
self.filelist.exclude_pattern(vcs_ptrn, is_regex=1)
@@ -380,14 +411,19 @@ class sdist(Command):
named by 'self.manifest'.
"""
if self._manifest_is_not_generated():
- log.info("not writing to manually maintained "
- "manifest file '%s'" % self.manifest)
+ log.info(
+ "not writing to manually maintained "
+ "manifest file '%s'" % self.manifest
+ )
return
content = self.filelist.files[:]
content.insert(0, '# file GENERATED by distutils, do NOT edit')
- self.execute(file_util.write_file, (self.manifest, content),
- "writing manifest file '%s'" % self.manifest)
+ self.execute(
+ file_util.write_file,
+ (self.manifest, content),
+ "writing manifest file '%s'" % self.manifest,
+ )
def _manifest_is_not_generated(self):
# check for special comment used in 3.1.3 and higher
@@ -437,10 +473,10 @@ class sdist(Command):
# out-of-date, because by default we blow away 'base_dir' when
# we're done making the distribution archives.)
- if hasattr(os, 'link'): # can make hard links on this system
+ if hasattr(os, 'link'): # can make hard links on this system
link = 'hard'
msg = "making hard links in %s..." % base_dir
- else: # nope, have to copy
+ else: # nope, have to copy
link = None
msg = "copying files to %s..." % base_dir
@@ -471,14 +507,15 @@ class sdist(Command):
base_name = os.path.join(self.dist_dir, base_dir)
self.make_release_tree(base_dir, self.filelist.files)
- archive_files = [] # remember names of files we create
+ archive_files = [] # remember names of files we create
# tar archive must be created last to avoid overwrite and remove
if 'tar' in self.formats:
self.formats.append(self.formats.pop(self.formats.index('tar')))
for fmt in self.formats:
- file = self.make_archive(base_name, fmt, base_dir=base_dir,
- owner=self.owner, group=self.group)
+ file = self.make_archive(
+ base_name, fmt, base_dir=base_dir, owner=self.owner, group=self.group
+ )
archive_files.append(file)
self.distribution.dist_files.append(('sdist', '', file))
diff --git a/setuptools/_distutils/command/upload.py b/setuptools/_distutils/command/upload.py
index 95e9fda1..782e3dea 100644
--- a/setuptools/_distutils/command/upload.py
+++ b/setuptools/_distutils/command/upload.py
@@ -31,10 +31,9 @@ class upload(PyPIRCCommand):
description = "upload binary package to PyPI"
user_options = PyPIRCCommand.user_options + [
- ('sign', 's',
- 'sign files to upload using gpg'),
+ ('sign', 's', 'sign files to upload using gpg'),
('identity=', 'i', 'GPG identity used to sign files'),
- ]
+ ]
boolean_options = PyPIRCCommand.boolean_options + ['sign']
@@ -49,9 +48,7 @@ class upload(PyPIRCCommand):
def finalize_options(self):
PyPIRCCommand.finalize_options(self)
if self.identity and not self.sign:
- raise DistutilsOptionError(
- "Must use --sign for --identity to have meaning"
- )
+ raise DistutilsOptionError("Must use --sign for --identity to have meaning")
config = self._read_pypirc()
if config != {}:
self.username = config['username']
@@ -66,16 +63,17 @@ class upload(PyPIRCCommand):
def run(self):
if not self.distribution.dist_files:
- msg = ("Must create and upload files in one command "
- "(e.g. setup.py sdist upload)")
+ msg = (
+ "Must create and upload files in one command "
+ "(e.g. setup.py sdist upload)"
+ )
raise DistutilsOptionError(msg)
for command, pyversion, filename in self.distribution.dist_files:
self.upload_file(command, pyversion, filename)
def upload_file(self, command, pyversion, filename):
# Makes sure the repository URL is compliant
- schema, netloc, url, params, query, fragments = \
- urlparse(self.repository)
+ schema, netloc, url, params, query, fragments = urlparse(self.repository)
if params or query or fragments:
raise AssertionError("Incompatible url %s" % self.repository)
@@ -87,12 +85,11 @@ class upload(PyPIRCCommand):
gpg_args = ["gpg", "--detach-sign", "-a", filename]
if self.identity:
gpg_args[2:2] = ["--local-user", self.identity]
- spawn(gpg_args,
- dry_run=self.dry_run)
+ spawn(gpg_args, dry_run=self.dry_run)
# Fill in the data - send all the meta-data in case we need to
# register a new release
- f = open(filename,'rb')
+ f = open(filename, 'rb')
try:
content = f.read()
finally:
@@ -103,16 +100,13 @@ class upload(PyPIRCCommand):
# action
':action': 'file_upload',
'protocol_version': '1',
-
# identify release
'name': meta.get_name(),
'version': meta.get_version(),
-
# file content
- 'content': (os.path.basename(filename),content),
+ 'content': (os.path.basename(filename), content),
'filetype': command,
'pyversion': pyversion,
-
# additional meta-data
'metadata_version': '1.0',
'summary': meta.get_description(),
@@ -129,7 +123,7 @@ class upload(PyPIRCCommand):
'provides': meta.get_provides(),
'requires': meta.get_requires(),
'obsoletes': meta.get_obsoletes(),
- }
+ }
data['comment'] = ''
@@ -145,8 +139,7 @@ class upload(PyPIRCCommand):
if self.sign:
with open(filename + ".asc", "rb") as f:
- data['gpg_signature'] = (os.path.basename(filename) + ".asc",
- f.read())
+ data['gpg_signature'] = (os.path.basename(filename) + ".asc", f.read())
# set up the authentication
user_pass = (self.username + ":" + self.password).encode('ascii')
@@ -187,8 +180,7 @@ class upload(PyPIRCCommand):
'Authorization': auth,
}
- request = Request(self.repository, data=body,
- headers=headers)
+ request = Request(self.repository, data=body, headers=headers)
# send the data
try:
result = urlopen(request)
@@ -202,8 +194,7 @@ class upload(PyPIRCCommand):
raise
if status == 200:
- self.announce('Server response (%s): %s' % (status, reason),
- log.INFO)
+ self.announce('Server response (%s): %s' % (status, reason), log.INFO)
if self.show_response:
text = self._read_pypi_response(result)
msg = '\n'.join(('-' * 75, text, '-' * 75))