diff --git a/.travis.yml b/.travis.yml index 58a71c48768..ad712b2926d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,6 +9,7 @@ matrix: - env: TOXENV=docs - env: TOXENV=lint-py2 - env: TOXENV=lint-py3 + python: 3.6 - env: TOXENV=mypy - env: TOXENV=packaging # PyPy jobs start first -- they are the slowest diff --git a/docs/conf.py b/docs/conf.py index e615e6be874..fbae368fa42 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -142,7 +142,7 @@ 'collapsiblesidebar': True, 'externalrefs': True, 'navigation_depth': 3, - 'issues_url': 'https://github.com/pypa/pip/issues' + 'issues_url': 'https://github.com/pypa/pip/issues', } # Add any paths that contain custom themes here, relative to this directory. @@ -177,10 +177,7 @@ smart_quotes = False # Custom sidebar templates, maps document names to template names. -html_sidebars = { - '**': ['localtoc.html', 'relations.html'], - 'index': ['localtoc.html'] -} +html_sidebars = {'**': ['localtoc.html', 'relations.html'], 'index': ['localtoc.html']} # Additional templates that should be rendered to pages, maps page names to # template names. @@ -221,13 +218,7 @@ # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, documentclass [howto/manual]) latex_documents = [ - ( - 'index', - 'pip.tex', - u'pip Documentation', - u'pip developers', - 'manual', - ), + ('index', 'pip.tex', u'pip Documentation', u'pip developers', 'manual') ] # The name of an image file (relative to this directory) to place at the top of @@ -251,13 +242,7 @@ # List of manual pages generated man_pages = [ - ( - 'man/pip', - 'pip', - u'package manager for Python packages', - u'pip developers', - 1 - ) + ('man/pip', 'pip', u'package manager for Python packages', u'pip developers', 1) ] # Here, we crawl the entire man/commands/ directory and list every file with @@ -265,8 +250,6 @@ for fname in glob.glob('man/commands/*.rst'): fname_base = fname[:-4] outname = 'pip-' + fname_base[13:] - description = u'description of {} command'.format( - outname.replace('-', ' ') - ) + description = u'description of {} command'.format(outname.replace('-', ' ')) man_pages.append((fname_base, outname, description, u'pip developers', 1)) diff --git a/docs/pipext.py b/docs/pipext.py index c866e1d717d..fc38c6c786f 100644 --- a/docs/pipext.py +++ b/docs/pipext.py @@ -37,7 +37,6 @@ def run(self): class PipOptions(rst.Directive): - def _format_option(self, option, cmd_name=None): if cmd_name: bookmark_line = ".. _`%s_%s`:" % (cmd_name, option._long_opts[0]) @@ -77,16 +76,12 @@ def run(self): class PipGeneralOptions(PipOptions): def process_options(self): - self._format_options( - [o() for o in cmdoptions.general_group['options']] - ) + self._format_options([o() for o in cmdoptions.general_group['options']]) class PipIndexOptions(PipOptions): def process_options(self): - self._format_options( - [o() for o in cmdoptions.index_group['options']] - ) + self._format_options([o() for o in cmdoptions.index_group['options']]) class PipCommandOptions(PipOptions): @@ -94,10 +89,7 @@ class PipCommandOptions(PipOptions): def process_options(self): cmd = commands[self.arguments[0]]() - self._format_options( - cmd.parser.option_groups[0].option_list, - cmd_name=cmd.name, - ) + self._format_options(cmd.parser.option_groups[0].option_list, cmd_name=cmd.name) def setup(app): diff --git a/setup.cfg b/setup.cfg index 2a0bc6cc51c..6f4d37ca509 100644 --- a/setup.cfg +++ b/setup.cfg @@ -2,7 +2,7 @@ skip = _vendor __main__.py -multi_line_output = 5 +multi_line_output = 3 known_third_party = pip._vendor known_first_party = @@ -10,10 +10,13 @@ known_first_party = tests default_section = THIRDPARTY include_trailing_comma = true +force_grid_wrap = 0 +line_length = 88 [flake8] +max-line-length = 88 # Ignoring unused imports since mypy would warn of that. -ignore = F401 +ignore = F401,W503,E203 exclude = .tox,.idea,*.egg,build,_vendor,data select = E,W,F diff --git a/setup.py b/setup.py index f52160a8fae..edf6e9f91fa 100644 --- a/setup.py +++ b/setup.py @@ -18,11 +18,7 @@ def read(*parts): def find_version(*file_paths): version_file = read(*file_paths) - version_match = re.search( - r"^__version__ = ['\"]([^'\"]*)['\"]", - version_file, - re.M, - ) + version_match = re.search(r"^__version__ = ['\"]([^'\"]*)['\"]", version_file, re.M) if version_match: return version_match.group(1) @@ -36,7 +32,6 @@ def find_version(*file_paths): version=find_version("src", "pip", "__init__.py"), description="The PyPA recommended tool for installing Python packages.", long_description=long_description, - license='MIT', classifiers=[ "Development Status :: 5 - Production/Stable", @@ -55,15 +50,10 @@ def find_version(*file_paths): ], url='https://pip.pypa.io/', keywords='distutils easy_install egg setuptools wheel virtualenv', - author='The pip developers', author_email='pypa-dev@groups.google.com', - package_dir={"": "src"}, - packages=find_packages( - where="src", - exclude=["contrib", "docs", "tests*", "tasks"], - ), + packages=find_packages(where="src", exclude=["contrib", "docs", "tests*", "tasks"]), package_data={ "pip._vendor.certifi": ["*.pem"], "pip._vendor.requests": ["*.pem"], @@ -75,9 +65,8 @@ def find_version(*file_paths): "pip=pip._internal:main", "pip%s=pip._internal:main" % sys.version_info[:1], "pip%s.%s=pip._internal:main" % sys.version_info[:2], - ], + ] }, - zip_safe=False, python_requires='>=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*', ) diff --git a/src/pip/_internal/__init__.py b/src/pip/_internal/__init__.py index 865d9ec3cc3..9f50749c601 100755 --- a/src/pip/_internal/__init__.py +++ b/src/pip/_internal/__init__.py @@ -18,6 +18,7 @@ # in the DEP-8 tests, so just suppress the warning. pdb tells me this has to # be done before the import of pip.vcs. from pip._vendor.urllib3.exceptions import DependencyWarning + warnings.filterwarnings("ignore", category=DependencyWarning) # noqa # We want to inject the use of SecureTransport as early as possible so that any @@ -44,9 +45,7 @@ from pip._internal.utils.misc import get_installed_distributions, get_prog from pip._internal.utils import deprecation from pip._internal.vcs import git, mercurial, subversion, bazaar # noqa -from pip._internal.baseparser import ( - ConfigOptionParser, UpdatingDefaultsHelpFormatter, -) +from pip._internal.baseparser import ConfigOptionParser, UpdatingDefaultsHelpFormatter from pip._internal.commands import get_summaries, get_similar_commands from pip._internal.commands import commands_dict from pip._vendor.urllib3.exceptions import InsecureRequestWarning @@ -88,10 +87,10 @@ def autocomplete(): if subcommand_name == 'help': sys.exit(1) # special case: list locally installed dists for show and uninstall - should_list_installed = ( - subcommand_name in ['show', 'uninstall'] and - not current.startswith('-') - ) + should_list_installed = subcommand_name in [ + 'show', + 'uninstall', + ] and not current.startswith('-') if should_list_installed: installed = [] lc = current.lower() @@ -112,7 +111,7 @@ def autocomplete(): options.append((opt_str, opt.nargs)) # filter out previously specified options from available options - prev_opts = [x.split('=')[0] for x in cwords[1:cword - 1]] + prev_opts = [x.split('=')[0] for x in cwords[1 : cword - 1]] options = [(x, v) for (x, v) in options if x not in prev_opts] # filter options by current input options = [(k, v) for k, v in options if k.startswith(current)] @@ -151,7 +150,9 @@ def create_main_parser(): pip_pkg_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) parser.version = 'pip %s from %s (python %s)' % ( - __version__, pip_pkg_dir, sys.version[:3], + __version__, + pip_pkg_dir, + sys.version[:3], ) # add the general options diff --git a/src/pip/_internal/basecommand.py b/src/pip/_internal/basecommand.py index feeee1f3355..1f11016ad9d 100644 --- a/src/pip/_internal/basecommand.py +++ b/src/pip/_internal/basecommand.py @@ -8,12 +8,13 @@ import sys from pip._internal import cmdoptions -from pip._internal.baseparser import ( - ConfigOptionParser, UpdatingDefaultsHelpFormatter, -) +from pip._internal.baseparser import ConfigOptionParser, UpdatingDefaultsHelpFormatter from pip._internal.download import PipSession from pip._internal.exceptions import ( - BadCommand, CommandError, InstallationError, PreviousBuildDirError, + BadCommand, + CommandError, + InstallationError, + PreviousBuildDirError, UninstallationError, ) from pip._internal.index import PackageFinder @@ -21,7 +22,10 @@ from pip._internal.req.req_file import parse_requirements from pip._internal.req.req_install import InstallRequirement from pip._internal.status_codes import ( - ERROR, PREVIOUS_BUILD_DIR_ERROR, SUCCESS, UNKNOWN_ERROR, + ERROR, + PREVIOUS_BUILD_DIR_ERROR, + SUCCESS, + UNKNOWN_ERROR, VIRTUALENV_NOT_FOUND, ) from pip._internal.utils.logging import IndentingFormatter @@ -62,17 +66,15 @@ def __init__(self, isolated=False): self.cmd_opts = optparse.OptionGroup(self.parser, optgroup_name) # Add the general options - gen_opts = cmdoptions.make_option_group( - cmdoptions.general_group, - self.parser, - ) + gen_opts = cmdoptions.make_option_group(cmdoptions.general_group, self.parser) self.parser.add_option_group(gen_opts) def _build_session(self, options, retries=None, timeout=None): session = PipSession( cache=( normalize_path(os.path.join(options.cache_dir, "http")) - if options.cache_dir else None + if options.cache_dir + else None ), retries=retries if retries is not None else options.retries, insecure_hosts=options.trusted_hosts, @@ -88,16 +90,11 @@ def _build_session(self, options, retries=None, timeout=None): # Handle timeouts if options.timeout or timeout: - session.timeout = ( - timeout if timeout is not None else options.timeout - ) + session.timeout = timeout if timeout is not None else options.timeout # Handle configured proxies if options.proxy: - session.proxies = { - "http": options.proxy, - "https": options.proxy, - } + session.proxies = {"http": options.proxy, "https": options.proxy} # Determine if we can prompt the user for authentication or not session.auth.prompting = not options.no_input @@ -134,66 +131,67 @@ def main(self, args): logger_class = "pip._internal.utils.logging.ColorizedStreamHandler" handler_class = "pip._internal.utils.logging.BetterRotatingFileHandler" - logging.config.dictConfig({ - "version": 1, - "disable_existing_loggers": False, - "filters": { - "exclude_warnings": { - "()": "pip._internal.utils.logging.MaxLevelFilter", - "level": logging.WARNING, + logging.config.dictConfig( + { + "version": 1, + "disable_existing_loggers": False, + "filters": { + "exclude_warnings": { + "()": "pip._internal.utils.logging.MaxLevelFilter", + "level": logging.WARNING, + } }, - }, - "formatters": { - "indent": { - "()": IndentingFormatter, - "format": "%(message)s", + "formatters": { + "indent": {"()": IndentingFormatter, "format": "%(message)s"} }, - }, - "handlers": { - "console": { - "level": level, - "class": logger_class, - "no_color": options.no_color, - "stream": self.log_streams[0], - "filters": ["exclude_warnings"], - "formatter": "indent", + "handlers": { + "console": { + "level": level, + "class": logger_class, + "no_color": options.no_color, + "stream": self.log_streams[0], + "filters": ["exclude_warnings"], + "formatter": "indent", + }, + "console_errors": { + "level": "WARNING", + "class": logger_class, + "no_color": options.no_color, + "stream": self.log_streams[1], + "formatter": "indent", + }, + "user_log": { + "level": "DEBUG", + "class": handler_class, + "filename": options.log or "/dev/null", + "delay": True, + "formatter": "indent", + }, }, - "console_errors": { - "level": "WARNING", - "class": logger_class, - "no_color": options.no_color, - "stream": self.log_streams[1], - "formatter": "indent", + "root": { + "level": root_level, + "handlers": list( + filter( + None, + [ + "console", + "console_errors", + "user_log" if options.log else None, + ], + ) + ), }, - "user_log": { - "level": "DEBUG", - "class": handler_class, - "filename": options.log or "/dev/null", - "delay": True, - "formatter": "indent", + # Disable any logging besides WARNING unless we have DEBUG level + # logging enabled. These use both pip._vendor and the bare names + # for the case where someone unbundles our libraries. + "loggers": { + name: { + "level": ("WARNING" if level in ["INFO", "ERROR"] else "DEBUG") + } + for name in ["pip._vendor", "distlib", "requests", "urllib3"] }, - }, - "root": { - "level": root_level, - "handlers": list(filter(None, [ - "console", - "console_errors", - "user_log" if options.log else None, - ])), - }, - # Disable any logging besides WARNING unless we have DEBUG level - # logging enabled. These use both pip._vendor and the bare names - # for the case where someone unbundles our libraries. - "loggers": { - name: { - "level": ( - "WARNING" if level in ["INFO", "ERROR"] else "DEBUG" - ) - } for name in [ - "pip._vendor", "distlib", "requests", "urllib3" - ] - }, - }) + } + ) # TODO: try to get these passing down from the command? # without resorting to os.environ to hold these. @@ -207,9 +205,7 @@ def main(self, args): if options.require_venv and not self.ignore_require_venv: # If a venv is required check if it can really be found if not running_under_virtualenv(): - logger.critical( - 'Could not find an activated virtualenv (required).' - ) + logger.critical('Could not find an activated virtualenv (required).') sys.exit(VIRTUALENV_NOT_FOUND) original_root_handlers = set(logging.root.handlers) @@ -246,12 +242,12 @@ def main(self, args): return UNKNOWN_ERROR finally: # Check if we're using the latest version of pip available - if (not options.disable_pip_version_check and not - getattr(options, "no_index", False)): + if not options.disable_pip_version_check and not getattr( + options, "no_index", False + ): with self._build_session( - options, - retries=0, - timeout=min(5, options.timeout)) as session: + options, retries=0, timeout=min(5, options.timeout) + ) as session: pip_version_check(session, options) # Avoid leaking loggers for handler in set(logging.root.handlers) - original_root_handlers: @@ -262,10 +258,10 @@ def main(self, args): class RequirementCommand(Command): - @staticmethod - def populate_requirement_set(requirement_set, args, options, finder, - session, name, wheel_cache): + def populate_requirement_set( + requirement_set, args, options, finder, session, name, wheel_cache + ): """ Marshal cmd line args into a requirement set. """ @@ -274,34 +270,38 @@ def populate_requirement_set(requirement_set, args, options, finder, for filename in options.constraints: for req_to_add in parse_requirements( - filename, - constraint=True, finder=finder, options=options, - session=session, wheel_cache=wheel_cache): + filename, + constraint=True, + finder=finder, + options=options, + session=session, + wheel_cache=wheel_cache, + ): req_to_add.is_direct = True requirement_set.add_requirement(req_to_add) for req in args: req_to_add = InstallRequirement.from_line( - req, None, isolated=options.isolated_mode, - wheel_cache=wheel_cache + req, None, isolated=options.isolated_mode, wheel_cache=wheel_cache ) req_to_add.is_direct = True requirement_set.add_requirement(req_to_add) for req in options.editables: req_to_add = InstallRequirement.from_editable( - req, - isolated=options.isolated_mode, - wheel_cache=wheel_cache + req, isolated=options.isolated_mode, wheel_cache=wheel_cache ) req_to_add.is_direct = True requirement_set.add_requirement(req_to_add) for filename in options.requirements: for req_to_add in parse_requirements( - filename, - finder=finder, options=options, session=session, - wheel_cache=wheel_cache): + filename, + finder=finder, + options=options, + session=session, + wheel_cache=wheel_cache, + ): req_to_add.is_direct = True requirement_set.add_requirement(req_to_add) # If --require-hashes was a line in a requirements file, tell @@ -313,16 +313,24 @@ def populate_requirement_set(requirement_set, args, options, finder, if options.find_links: raise CommandError( 'You must give at least one requirement to %(name)s ' - '(maybe you meant "pip %(name)s %(links)s"?)' % - dict(opts, links=' '.join(options.find_links))) + '(maybe you meant "pip %(name)s %(links)s"?)' + % dict(opts, links=' '.join(options.find_links)) + ) else: raise CommandError( 'You must give at least one requirement to %(name)s ' - '(see "pip help %(name)s")' % opts) + '(see "pip help %(name)s")' % opts + ) - def _build_package_finder(self, options, session, - platform=None, python_versions=None, - abi=None, implementation=None): + def _build_package_finder( + self, + options, + session, + platform=None, + python_versions=None, + abi=None, + implementation=None, + ): """ Create a package finder appropriate to this requirement command. """ diff --git a/src/pip/_internal/baseparser.py b/src/pip/_internal/baseparser.py index 9a8d129747e..36b99552ad1 100644 --- a/src/pip/_internal/baseparser.py +++ b/src/pip/_internal/baseparser.py @@ -108,7 +108,6 @@ def expand_default(self, option): class CustomOptionParser(optparse.OptionParser): - def insert_option_group(self, idx, *args, **kwargs): """Insert an OptionGroup at a given position.""" group = self.add_option_group(*args, **kwargs) @@ -159,7 +158,7 @@ def _get_ordered_configuration_items(self): if not val: logger.debug( "Ignoring configuration key '%s' as it's value is empty.", - section_key + section_key, ) continue diff --git a/src/pip/_internal/build_env.py b/src/pip/_internal/build_env.py index 612b46352c2..c1d0db3f37b 100644 --- a/src/pip/_internal/build_env.py +++ b/src/pip/_internal/build_env.py @@ -33,10 +33,9 @@ def __enter__(self): self.save_nousersite = os.environ.get('PYTHONNOUSERSITE', None) install_scheme = 'nt' if (os.name == 'nt') else 'posix_prefix' - install_dirs = get_paths(install_scheme, vars={ - 'base': self.path, - 'platbase': self.path, - }) + install_dirs = get_paths( + install_scheme, vars={'base': self.path, 'platbase': self.path} + ) scripts = install_dirs['scripts'] if self.save_path: @@ -53,8 +52,7 @@ def __enter__(self): else: lib_dirs = purelib + os.pathsep + platlib if self.save_pythonpath: - os.environ['PYTHONPATH'] = lib_dirs + os.pathsep + \ - self.save_pythonpath + os.environ['PYTHONPATH'] = lib_dirs + os.pathsep + self.save_pythonpath else: os.environ['PYTHONPATH'] = lib_dirs @@ -78,9 +76,17 @@ def cleanup(self): def install_requirements(self, finder, requirements, message): args = [ - sys.executable, '-m', 'pip', 'install', '--ignore-installed', - '--no-user', '--prefix', self.path, '--no-warn-script-location', - '--only-binary', ':all:', + sys.executable, + '-m', + 'pip', + 'install', + '--ignore-installed', + '--no-user', + '--prefix', + self.path, + '--no-warn-script-location', + '--only-binary', + ':all:', ] if logger.getEffectiveLevel() <= logging.DEBUG: args.append('-v') diff --git a/src/pip/_internal/cache.py b/src/pip/_internal/cache.py index 1aa17aa96c2..3ba8e48c5b0 100644 --- a/src/pip/_internal/cache.py +++ b/src/pip/_internal/cache.py @@ -63,18 +63,12 @@ def _get_cache_path_parts(self, link): return parts def _get_candidates(self, link, package_name): - can_not_cache = ( - not self.cache_dir or - not package_name or - not link - ) + can_not_cache = not self.cache_dir or not package_name or not link if can_not_cache: return [] canonical_name = canonicalize_name(package_name) - formats = index.fmt_ctl_formats( - self.format_control, canonical_name - ) + formats = index.fmt_ctl_formats(self.format_control, canonical_name) if not self.allowed_formats.intersection(formats): return [] @@ -112,9 +106,7 @@ class SimpleWheelCache(Cache): """ def __init__(self, cache_dir, format_control): - super(SimpleWheelCache, self).__init__( - cache_dir, format_control, {"binary"} - ) + super(SimpleWheelCache, self).__init__(cache_dir, format_control, {"binary"}) def get_path_for_link(self, link): """Return a directory to store cached wheels for link @@ -163,9 +155,7 @@ def __init__(self, format_control): self._temp_dir = TempDirectory(kind="ephem-wheel-cache") self._temp_dir.create() - super(EphemWheelCache, self).__init__( - self._temp_dir.path, format_control - ) + super(EphemWheelCache, self).__init__(self._temp_dir.path, format_control) def cleanup(self): self._temp_dir.cleanup() @@ -179,9 +169,7 @@ class WheelCache(Cache): """ def __init__(self, cache_dir, format_control): - super(WheelCache, self).__init__( - cache_dir, format_control, {'binary'} - ) + super(WheelCache, self).__init__(cache_dir, format_control, {'binary'}) self._wheel_cache = SimpleWheelCache(cache_dir, format_control) self._ephem_cache = EphemWheelCache(format_control) diff --git a/src/pip/_internal/cmdoptions.py b/src/pip/_internal/cmdoptions.py index 17759d7c396..948fc4c5a9a 100644 --- a/src/pip/_internal/cmdoptions.py +++ b/src/pip/_internal/cmdoptions.py @@ -14,7 +14,9 @@ from optparse import SUPPRESS_HELP, Option, OptionGroup from pip._internal.index import ( - FormatControl, fmt_ctl_handle_mutual_exclude, fmt_ctl_no_binary, + FormatControl, + fmt_ctl_handle_mutual_exclude, + fmt_ctl_no_binary, ) from pip._internal.locations import USER_CACHE_DIR, src_prefix from pip._internal.models.index import PyPI @@ -50,13 +52,15 @@ def check_install_build_global(options, check_options=None): def getname(n): return getattr(check_options, n, None) + names = ["build_options", "global_options", "install_options"] if any(map(getname, names)): control = options.format_control fmt_ctl_no_binary(control) warnings.warn( 'Disabling all use of wheels due to the use of --build-options ' - '/ --global-options / --install-options.', stacklevel=2, + '/ --global-options / --install-options.', + stacklevel=2, ) @@ -65,11 +69,7 @@ def getname(n): ########### help_ = partial( - Option, - '-h', '--help', - dest='help', - action='help', - help='Show help.', + Option, '-h', '--help', dest='help', action='help', help='Show help.' ) # type: Any isolated_mode = partial( @@ -87,20 +87,22 @@ def getname(n): require_virtualenv = partial( Option, # Run only if inside a virtualenv, bail if not. - '--require-virtualenv', '--require-venv', + '--require-virtualenv', + '--require-venv', dest='require_venv', action='store_true', default=False, - help=SUPPRESS_HELP + help=SUPPRESS_HELP, ) # type: Any verbose = partial( Option, - '-v', '--verbose', + '-v', + '--verbose', dest='verbose', action='count', default=0, - help='Give more output. Option is additive, and can be used up to 3 times.' + help='Give more output. Option is additive, and can be used up to 3 times.', ) no_color = partial( @@ -114,7 +116,8 @@ def getname(n): version = partial( Option, - '-V', '--version', + '-V', + '--version', dest='version', action='store_true', help='Show version and exit.', @@ -122,7 +125,8 @@ def getname(n): quiet = partial( Option, - '-q', '--quiet', + '-q', + '--quiet', dest='quiet', action='count', default=0, @@ -141,17 +145,20 @@ def getname(n): choices=list(BAR_TYPES.keys()), default='on', help=( - 'Specify type of progress to be displayed [' + - '|'.join(BAR_TYPES.keys()) + '] (default: %default)' + 'Specify type of progress to be displayed [' + + '|'.join(BAR_TYPES.keys()) + + '] (default: %default)' ), ) # type: Any log = partial( Option, - "--log", "--log-file", "--local-log", + "--log", + "--log-file", + "--local-log", dest="log", metavar="path", - help="Path to a verbose appending log." + help="Path to a verbose appending log.", ) # type: Any no_input = partial( @@ -161,7 +168,7 @@ def getname(n): dest='no_input', action='store_true', default=False, - help=SUPPRESS_HELP + help=SUPPRESS_HELP, ) # type: Any proxy = partial( @@ -170,7 +177,7 @@ def getname(n): dest='proxy', type='str', default='', - help="Specify a proxy in the form [user:passwd@]proxy.server:port." + help="Specify a proxy in the form [user:passwd@]proxy.server:port.", ) # type: Any retries = partial( @@ -180,12 +187,13 @@ def getname(n): type='int', default=5, help="Maximum number of retries each connection should attempt " - "(default %default times).", + "(default %default times).", ) # type: Any timeout = partial( Option, - '--timeout', '--default-timeout', + '--timeout', + '--default-timeout', metavar='sec', dest='timeout', type='float', @@ -215,7 +223,7 @@ def exists_action(): action='append', metavar='action', help="Default action when a path already exists: " - "(s)witch, (i)gnore, (w)ipe, (b)ackup, (a)bort).", + "(s)witch, (i)gnore, (w)ipe, (b)ackup, (a)bort).", ) @@ -236,19 +244,21 @@ def exists_action(): default=None, metavar='path', help="Path to SSL client certificate, a single file containing the " - "private key and the certificate in PEM format.", + "private key and the certificate in PEM format.", ) # type: Any index_url = partial( Option, - '-i', '--index-url', '--pypi-url', + '-i', + '--index-url', + '--pypi-url', dest='index_url', metavar='URL', default=PyPI.simple_url, help="Base URL of Python Package Index (default %default). " - "This should point to a repository compliant with PEP 503 " - "(the simple repository API) or a local directory laid out " - "in the same format.", + "This should point to a repository compliant with PEP 503 " + "(the simple repository API) or a local directory laid out " + "in the same format.", ) # type: Any @@ -260,8 +270,8 @@ def extra_index_url(): action='append', default=[], help="Extra URLs of package indexes to use in addition to " - "--index-url. Should follow the same rules as " - "--index-url.", + "--index-url. Should follow the same rules as " + "--index-url.", ) @@ -277,14 +287,15 @@ def extra_index_url(): def find_links(): return Option( - '-f', '--find-links', + '-f', + '--find-links', dest='find_links', action='append', default=[], metavar='url', help="If a url or path to an html file, then parse for links to " - "archives. If a local path or file:// url that's a directory, " - "then look for archives in the directory listing.", + "archives. If a local path or file:// url that's a directory, " + "then look for archives in the directory listing.", ) @@ -296,7 +307,7 @@ def trusted_host(): metavar="HOSTNAME", default=[], help="Mark this host as trusted, even though it does not have valid " - "or any HTTPS.", + "or any HTTPS.", ) @@ -313,49 +324,57 @@ def trusted_host(): def constraints(): return Option( - '-c', '--constraint', + '-c', + '--constraint', dest='constraints', action='append', default=[], metavar='file', help='Constrain versions using the given constraints file. ' - 'This option can be used multiple times.' + 'This option can be used multiple times.', ) def requirements(): return Option( - '-r', '--requirement', + '-r', + '--requirement', dest='requirements', action='append', default=[], metavar='file', help='Install from the given requirements file. ' - 'This option can be used multiple times.' + 'This option can be used multiple times.', ) def editable(): return Option( - '-e', '--editable', + '-e', + '--editable', dest='editables', action='append', default=[], metavar='path/url', - help=('Install a project in editable mode (i.e. setuptools ' - '"develop mode") from a local project path or a VCS url.'), + help=( + 'Install a project in editable mode (i.e. setuptools ' + '"develop mode") from a local project path or a VCS url.' + ), ) src = partial( Option, - '--src', '--source', '--source-dir', '--source-directory', + '--src', + '--source', + '--source-dir', + '--source-directory', dest='src_dir', metavar='dir', default=src_prefix, help='Directory to check out editable projects into. ' 'The default in a virtualenv is "/src". ' - 'The default for global installs is "/src".' + 'The default for global installs is "/src".', ) # type: Any @@ -366,43 +385,45 @@ def _get_format_control(values, option): def _handle_no_binary(option, opt_str, value, parser): existing = getattr(parser.values, option.dest) - fmt_ctl_handle_mutual_exclude( - value, existing.no_binary, existing.only_binary, - ) + fmt_ctl_handle_mutual_exclude(value, existing.no_binary, existing.only_binary) def _handle_only_binary(option, opt_str, value, parser): existing = getattr(parser.values, option.dest) - fmt_ctl_handle_mutual_exclude( - value, existing.only_binary, existing.no_binary, - ) + fmt_ctl_handle_mutual_exclude(value, existing.only_binary, existing.no_binary) def no_binary(): return Option( - "--no-binary", dest="format_control", action="callback", - callback=_handle_no_binary, type="str", + "--no-binary", + dest="format_control", + action="callback", + callback=_handle_no_binary, + type="str", default=FormatControl(set(), set()), help="Do not use binary packages. Can be supplied multiple times, and " - "each time adds to the existing value. Accepts either :all: to " - "disable all binary packages, :none: to empty the set, or one or " - "more package names with commas between them. Note that some " - "packages are tricky to compile and may fail to install when " - "this option is used on them.", + "each time adds to the existing value. Accepts either :all: to " + "disable all binary packages, :none: to empty the set, or one or " + "more package names with commas between them. Note that some " + "packages are tricky to compile and may fail to install when " + "this option is used on them.", ) def only_binary(): return Option( - "--only-binary", dest="format_control", action="callback", - callback=_handle_only_binary, type="str", + "--only-binary", + dest="format_control", + action="callback", + callback=_handle_only_binary, + type="str", default=FormatControl(set(), set()), help="Do not use source packages. Can be supplied multiple times, and " - "each time adds to the existing value. Accepts either :all: to " - "disable all source packages, :none: to empty the set, or one or " - "more package names with commas between them. Packages without " - "binary distributions will fail to install when this option is " - "used on them.", + "each time adds to the existing value. Accepts either :all: to " + "disable all source packages, :none: to empty the set, or one or " + "more package names with commas between them. Packages without " + "binary distributions will fail to install when this option is " + "used on them.", ) @@ -412,7 +433,7 @@ def prefer_binary(): dest="prefer_binary", action="store_true", default=False, - help="Prefer older binary packages over newer source packages." + help="Prefer older binary packages over newer source packages.", ) @@ -422,7 +443,7 @@ def prefer_binary(): dest="cache_dir", default=USER_CACHE_DIR, metavar="dir", - help="Store the cache data in ." + help="Store the cache data in .", ) no_cache = partial( @@ -435,7 +456,8 @@ def prefer_binary(): no_deps = partial( Option, - '--no-deps', '--no-dependencies', + '--no-deps', + '--no-dependencies', dest='ignore_dependencies', action='store_true', default=False, @@ -444,14 +466,17 @@ def prefer_binary(): build_dir = partial( Option, - '-b', '--build', '--build-dir', '--build-directory', + '-b', + '--build', + '--build-dir', + '--build-directory', dest='build_dir', metavar='dir', help='Directory to unpack packages into and build in. Note that ' - 'an initial build still takes place in a temporary directory. ' - 'The location of temporary directories can be controlled by setting ' - 'the TMPDIR environment variable (TEMP on Windows) appropriately. ' - 'When passed, build directories are not cleaned in case of failures.' + 'an initial build still takes place in a temporary directory. ' + 'The location of temporary directories can be controlled by setting ' + 'the TMPDIR environment variable (TEMP on Windows) appropriately. ' + 'When passed, build directories are not cleaned in case of failures.', ) # type: Any ignore_requires_python = partial( @@ -459,7 +484,7 @@ def prefer_binary(): '--ignore-requires-python', dest='ignore_requires_python', action='store_true', - help='Ignore the Requires-Python information.' + help='Ignore the Requires-Python information.', ) # type: Any no_build_isolation = partial( @@ -469,8 +494,8 @@ def prefer_binary(): action='store_false', default=True, help='Disable isolation when building a modern source distribution. ' - 'Build dependencies specified by PEP 518 must be already installed ' - 'if this option is used.' + 'Build dependencies specified by PEP 518 must be already installed ' + 'if this option is used.', ) # type: Any install_options = partial( @@ -480,10 +505,10 @@ def prefer_binary(): action='append', metavar='options', help="Extra arguments to be supplied to the setup.py install " - "command (use like --install-option=\"--install-scripts=/usr/local/" - "bin\"). Use multiple --install-option options to pass multiple " - "options to setup.py install. If you are using an option with a " - "directory path, be sure to use absolute path.", + "command (use like --install-option=\"--install-scripts=/usr/local/" + "bin\"). Use multiple --install-option options to pass multiple " + "options to setup.py install. If you are using an option with a " + "directory path, be sure to use absolute path.", ) # type: Any global_options = partial( @@ -493,7 +518,7 @@ def prefer_binary(): action='append', metavar='options', help="Extra global options to be supplied to the setup.py " - "call before the install command.", + "call before the install command.", ) # type: Any no_clean = partial( @@ -501,7 +526,7 @@ def prefer_binary(): '--no-clean', action='store_true', default=False, - help="Don't clean up build directories)." + help="Don't clean up build directories).", ) # type: Any pre = partial( @@ -510,7 +535,7 @@ def prefer_binary(): action='store_true', default=False, help="Include pre-release and development versions. By default, " - "pip only finds stable versions.", + "pip only finds stable versions.", ) # type: Any disable_pip_version_check = partial( @@ -520,14 +545,15 @@ def prefer_binary(): action="store_true", default=False, help="Don't periodically check PyPI to determine whether a new version " - "of pip is available for download. Implied with --no-index.", + "of pip is available for download. Implied with --no-index.", ) # type: Any # Deprecated, Remove later always_unzip = partial( Option, - '-Z', '--always-unzip', + '-Z', + '--always-unzip', dest='always_unzip', action='store_true', help=SUPPRESS_HELP, @@ -542,12 +568,15 @@ def _merge_hash(option, opt_str, value, parser): try: algo, digest = value.split(':', 1) except ValueError: - parser.error('Arguments to %s must be a hash name ' - 'followed by a value, like --hash=sha256:abcde...' % - opt_str) + parser.error( + 'Arguments to %s must be a hash name ' + 'followed by a value, like --hash=sha256:abcde...' % opt_str + ) if algo not in STRONG_HASHES: - parser.error('Allowed hash algorithms for %s are %s.' % - (opt_str, ', '.join(STRONG_HASHES))) + parser.error( + 'Allowed hash algorithms for %s are %s.' + % (opt_str, ', '.join(STRONG_HASHES)) + ) parser.values.hashes.setdefault(algo, []).append(digest) @@ -561,7 +590,7 @@ def _merge_hash(option, opt_str, value, parser): callback=_merge_hash, type='string', help="Verify that the package's archive matches this " - 'hash before installing. Example: --hash=sha256:abcdef...', + 'hash before installing. Example: --hash=sha256:abcdef...', ) # type: Any @@ -572,8 +601,8 @@ def _merge_hash(option, opt_str, value, parser): action='store_true', default=False, help='Require a hash to check each requirement against, for ' - 'repeatable installs. This option is implied when any package in a ' - 'requirements file has a --hash option.', + 'repeatable installs. This option is implied when any package in a ' + 'requirements file has a --hash option.', ) # type: Any @@ -604,7 +633,7 @@ def _merge_hash(option, opt_str, value, parser): no_cache, disable_pip_version_check, no_color, - ] + ], } index_group = { @@ -615,5 +644,5 @@ def _merge_hash(option, opt_str, value, parser): no_index, find_links, process_dependency_links, - ] + ], } diff --git a/src/pip/_internal/commands/check.py b/src/pip/_internal/commands/check.py index 88db5101e7a..521ee9c82e5 100644 --- a/src/pip/_internal/commands/check.py +++ b/src/pip/_internal/commands/check.py @@ -2,7 +2,8 @@ from pip._internal.basecommand import Command from pip._internal.operations.check import ( - check_package_set, create_package_set_from_installed, + check_package_set, + create_package_set_from_installed, ) from pip._internal.utils.misc import get_installed_distributions @@ -11,6 +12,7 @@ class CheckCommand(Command): """Verify installed packages have compatible dependencies.""" + name = 'check' usage = """ %prog [options]""" @@ -25,7 +27,9 @@ def run(self, options, args): for dependency in missing[project_name]: logger.info( "%s %s requires %s, which is not installed.", - project_name, version, dependency[0], + project_name, + version, + dependency[0], ) for project_name in conflicting: @@ -33,7 +37,11 @@ def run(self, options, args): for dep_name, dep_version, req in conflicting[project_name]: logger.info( "%s %s has requirement %s, but you have %s %s.", - project_name, version, req, dep_name, dep_version, + project_name, + version, + req, + dep_name, + dep_version, ) if missing or conflicting: diff --git a/src/pip/_internal/commands/completion.py b/src/pip/_internal/commands/completion.py index c4b387364a5..fbbd53011ed 100644 --- a/src/pip/_internal/commands/completion.py +++ b/src/pip/_internal/commands/completion.py @@ -47,6 +47,7 @@ class CompletionCommand(Command): """A helper command to be used for command completion.""" + name = 'completion' summary = 'A helper command used for command completion.' ignore_require_venv = True @@ -57,23 +58,29 @@ def __init__(self, *args, **kw): cmd_opts = self.cmd_opts cmd_opts.add_option( - '--bash', '-b', + '--bash', + '-b', action='store_const', const='bash', dest='shell', - help='Emit completion code for bash') + help='Emit completion code for bash', + ) cmd_opts.add_option( - '--zsh', '-z', + '--zsh', + '-z', action='store_const', const='zsh', dest='shell', - help='Emit completion code for zsh') + help='Emit completion code for zsh', + ) cmd_opts.add_option( - '--fish', '-f', + '--fish', + '-f', action='store_const', const='fish', dest='shell', - help='Emit completion code for fish') + help='Emit completion code for fish', + ) self.parser.insert_option_group(0, cmd_opts) @@ -83,12 +90,8 @@ def run(self, options, args): shell_options = ['--' + shell for shell in sorted(shells)] if options.shell in shells: script = textwrap.dedent( - COMPLETION_SCRIPTS.get(options.shell, '') % { - 'prog': get_prog(), - } + COMPLETION_SCRIPTS.get(options.shell, '') % {'prog': get_prog()} ) print(BASE_COMPLETION % {'script': script, 'shell': options.shell}) else: - sys.stderr.write( - 'ERROR: You must pass %s\n' % ' or '.join(shell_options) - ) + sys.stderr.write('ERROR: You must pass %s\n' % ' or '.join(shell_options)) diff --git a/src/pip/_internal/commands/configuration.py b/src/pip/_internal/commands/configuration.py index 57448cb90d5..8fbe0505667 100644 --- a/src/pip/_internal/commands/configuration.py +++ b/src/pip/_internal/commands/configuration.py @@ -54,7 +54,7 @@ def __init__(self, *args, **kwargs): help=( 'Editor to use to edit the file. Uses VISUAL or EDITOR ' 'environment variables if not provided.' - ) + ), ) self.cmd_opts.add_option( @@ -62,7 +62,7 @@ def __init__(self, *args, **kwargs): dest='global_file', action='store_true', default=False, - help='Use the system-wide configuration file only' + help='Use the system-wide configuration file only', ) self.cmd_opts.add_option( @@ -70,7 +70,7 @@ def __init__(self, *args, **kwargs): dest='user_file', action='store_true', default=False, - help='Use the user configuration file only' + help='Use the user configuration file only', ) self.cmd_opts.add_option( @@ -78,7 +78,7 @@ def __init__(self, *args, **kwargs): dest='venv_file', action='store_true', default=False, - help='Use the virtualenv configuration file only' + help='Use the virtualenv configuration file only', ) self.parser.insert_option_group(0, self.cmd_opts) @@ -89,13 +89,13 @@ def run(self, options, args): "edit": self.open_in_editor, "get": self.get_name, "set": self.set_name_value, - "unset": self.unset_name + "unset": self.unset_name, } # Determine action if not args or args[0] not in handlers: - logger.error("Need an action ({}) to perform.".format( - ", ".join(sorted(handlers))) + logger.error( + "Need an action ({}) to perform.".format(", ".join(sorted(handlers))) ) return ERROR @@ -130,7 +130,7 @@ def _determine_file(self, options, need_value): file_options = { kinds.USER: options.user_file, kinds.GLOBAL: options.global_file, - kinds.VENV: options.venv_file + kinds.VENV: options.venv_file, } if sum(file_options.values()) == 0: @@ -185,8 +185,7 @@ def open_in_editor(self, options, args): subprocess.check_call([editor, fname]) except subprocess.CalledProcessError as e: raise PipError( - "Editor Subprocess exited with exit code {}" - .format(e.returncode) + "Editor Subprocess exited with exit code {}".format(e.returncode) ) def _get_n_args(self, args, example, n): @@ -211,8 +210,7 @@ def _save_configuration(self): self.configuration.save() except Exception: logger.error( - "Unable to save configuration. Please report this as a bug.", - exc_info=1 + "Unable to save configuration. Please report this as a bug.", exc_info=1 ) raise PipError("Internal Error.") diff --git a/src/pip/_internal/commands/download.py b/src/pip/_internal/commands/download.py index 66bcbd5c822..ac35638d092 100644 --- a/src/pip/_internal/commands/download.py +++ b/src/pip/_internal/commands/download.py @@ -29,6 +29,7 @@ class DownloadCommand(RequirementCommand): pip also supports downloading from "requirements files", which provide an easy way to specify a whole environment to be downloaded. """ + name = 'download' usage = """ @@ -61,7 +62,10 @@ def __init__(self, *args, **kw): cmd_opts.add_option(cmdoptions.no_build_isolation()) cmd_opts.add_option( - '-d', '--dest', '--destination-dir', '--destination-directory', + '-d', + '--dest', + '--destination-dir', + '--destination-directory', dest='download_dir', metavar='dir', default=os.curdir, @@ -73,8 +77,10 @@ def __init__(self, *args, **kw): dest='platform', metavar='platform', default=None, - help=("Only download wheels compatible with . " - "Defaults to the platform of the running system."), + help=( + "Only download wheels compatible with . " + "Defaults to the platform of the running system." + ), ) cmd_opts.add_option( @@ -82,12 +88,14 @@ def __init__(self, *args, **kw): dest='python_version', metavar='python_version', default=None, - help=("Only download wheels compatible with Python " - "interpreter version . If not specified, then the " - "current system interpreter minor version is used. A major " - "version (e.g. '2') can be specified to match all " - "minor revs of that major version. A minor version " - "(e.g. '34') can also be specified."), + help=( + "Only download wheels compatible with Python " + "interpreter version . If not specified, then the " + "current system interpreter minor version is used. A major " + "version (e.g. '2') can be specified to match all " + "minor revs of that major version. A minor version " + "(e.g. '34') can also be specified." + ), ) cmd_opts.add_option( @@ -95,11 +103,13 @@ def __init__(self, *args, **kw): dest='implementation', metavar='implementation', default=None, - help=("Only download wheels compatible with Python " - "implementation , e.g. 'pp', 'jy', 'cp', " - " or 'ip'. If not specified, then the current " - "interpreter implementation is used. Use 'py' to force " - "implementation-agnostic wheels."), + help=( + "Only download wheels compatible with Python " + "implementation , e.g. 'pp', 'jy', 'cp', " + " or 'ip'. If not specified, then the current " + "interpreter implementation is used. Use 'py' to force " + "implementation-agnostic wheels." + ), ) cmd_opts.add_option( @@ -107,18 +117,17 @@ def __init__(self, *args, **kw): dest='abi', metavar='abi', default=None, - help=("Only download wheels compatible with Python " - "abi , e.g. 'pypy_41'. If not specified, then the " - "current interpreter abi tag is used. Generally " - "you will need to specify --implementation, " - "--platform, and --python-version when using " - "this option."), + help=( + "Only download wheels compatible with Python " + "abi , e.g. 'pypy_41'. If not specified, then the " + "current interpreter abi tag is used. Generally " + "you will need to specify --implementation, " + "--platform, and --python-version when using " + "this option." + ), ) - index_opts = cmdoptions.make_option_group( - cmdoptions.index_group, - self.parser, - ) + index_opts = cmdoptions.make_option_group(cmdoptions.index_group, self.parser) self.parser.insert_option_group(0, index_opts) self.parser.insert_option_group(0, cmd_opts) @@ -134,16 +143,17 @@ def run(self, options, args): else: python_versions = None - dist_restriction_set = any([ - options.python_version, - options.platform, - options.abi, - options.implementation, - ]) + dist_restriction_set = any( + [ + options.python_version, + options.platform, + options.abi, + options.implementation, + ] + ) binary_only = FormatControl(set(), {':all:'}) no_sdist_dependencies = ( - options.format_control != binary_only and - not options.ignore_dependencies + options.format_control != binary_only and not options.ignore_dependencies ) if dist_restriction_set and no_sdist_dependencies: raise CommandError( @@ -168,7 +178,7 @@ def run(self, options, args): abi=options.abi, implementation=options.implementation, ) - build_delete = (not (options.no_clean or options.build_dir)) + build_delete = not (options.no_clean or options.build_dir) if options.cache_dir and not check_path_owner(options.cache_dir): logger.warning( "The directory '%s' or its parent directory is not owned " @@ -184,17 +194,9 @@ def run(self, options, args): options.build_dir, delete=build_delete, kind="download" ) as directory: - requirement_set = RequirementSet( - require_hashes=options.require_hashes, - ) + requirement_set = RequirementSet(require_hashes=options.require_hashes) self.populate_requirement_set( - requirement_set, - args, - options, - finder, - session, - self.name, - None + requirement_set, args, options, finder, session, self.name, None ) preparer = RequirementPreparer( @@ -221,9 +223,9 @@ def run(self, options, args): ) resolver.resolve(requirement_set) - downloaded = ' '.join([ - req.name for req in requirement_set.successfully_downloaded - ]) + downloaded = ' '.join( + [req.name for req in requirement_set.successfully_downloaded] + ) if downloaded: logger.info('Successfully downloaded %s', downloaded) diff --git a/src/pip/_internal/commands/freeze.py b/src/pip/_internal/commands/freeze.py index 0d3d4ae2404..c79d9c27a4d 100644 --- a/src/pip/_internal/commands/freeze.py +++ b/src/pip/_internal/commands/freeze.py @@ -17,6 +17,7 @@ class FreezeCommand(Command): packages are listed in a case-insensitive sorted order. """ + name = 'freeze' usage = """ %prog [options]""" @@ -27,46 +28,54 @@ def __init__(self, *args, **kw): super(FreezeCommand, self).__init__(*args, **kw) self.cmd_opts.add_option( - '-r', '--requirement', + '-r', + '--requirement', dest='requirements', action='append', default=[], metavar='file', help="Use the order in the given requirements file and its " - "comments when generating output. This option can be " - "used multiple times.") + "comments when generating output. This option can be " + "used multiple times.", + ) self.cmd_opts.add_option( - '-f', '--find-links', + '-f', + '--find-links', dest='find_links', action='append', default=[], metavar='URL', - help='URL for finding packages, which will be added to the ' - 'output.') + help='URL for finding packages, which will be added to the ' 'output.', + ) self.cmd_opts.add_option( - '-l', '--local', + '-l', + '--local', dest='local', action='store_true', default=False, help='If in a virtualenv that has global access, do not output ' - 'globally-installed packages.') + 'globally-installed packages.', + ) self.cmd_opts.add_option( '--user', dest='user', action='store_true', default=False, - help='Only output packages installed in user-site.') + help='Only output packages installed in user-site.', + ) self.cmd_opts.add_option( '--all', dest='freeze_all', action='store_true', help='Do not skip these packages in the output:' - ' %s' % ', '.join(DEV_PKGS)) + ' %s' % ', '.join(DEV_PKGS), + ) self.cmd_opts.add_option( '--exclude-editable', dest='exclude_editable', action='store_true', - help='Exclude editable package from output.') + help='Exclude editable package from output.', + ) self.parser.insert_option_group(0, self.cmd_opts) diff --git a/src/pip/_internal/commands/hash.py b/src/pip/_internal/commands/hash.py index 95353b0409b..6d5fcb08233 100644 --- a/src/pip/_internal/commands/hash.py +++ b/src/pip/_internal/commands/hash.py @@ -20,6 +20,7 @@ class HashCommand(Command): installs. """ + name = 'hash' usage = '%prog [options] ...' summary = 'Compute hashes of package archives.' @@ -28,13 +29,14 @@ class HashCommand(Command): def __init__(self, *args, **kw): super(HashCommand, self).__init__(*args, **kw) self.cmd_opts.add_option( - '-a', '--algorithm', + '-a', + '--algorithm', dest='algorithm', choices=STRONG_HASHES, action='store', default=FAVORITE_HASH, - help='The hash algorithm to use: one of %s' % - ', '.join(STRONG_HASHES)) + help='The hash algorithm to use: one of %s' % ', '.join(STRONG_HASHES), + ) self.parser.insert_option_group(0, self.cmd_opts) def run(self, options, args): @@ -44,8 +46,9 @@ def run(self, options, args): algorithm = options.algorithm for path in args: - logger.info('%s:\n--hash=%s:%s', - path, algorithm, _hash_of_file(path, algorithm)) + logger.info( + '%s:\n--hash=%s:%s', path, algorithm, _hash_of_file(path, algorithm) + ) def _hash_of_file(path, algorithm): diff --git a/src/pip/_internal/commands/help.py b/src/pip/_internal/commands/help.py index 06ca2c171ad..e74611dec32 100644 --- a/src/pip/_internal/commands/help.py +++ b/src/pip/_internal/commands/help.py @@ -6,6 +6,7 @@ class HelpCommand(Command): """Show help for commands""" + name = 'help' usage = """ %prog """ diff --git a/src/pip/_internal/commands/install.py b/src/pip/_internal/commands/install.py index 7492d09ee5f..e96e06ea228 100644 --- a/src/pip/_internal/commands/install.py +++ b/src/pip/_internal/commands/install.py @@ -11,7 +11,9 @@ from pip._internal.basecommand import RequirementCommand from pip._internal.cache import WheelCache from pip._internal.exceptions import ( - CommandError, InstallationError, PreviousBuildDirError, + CommandError, + InstallationError, + PreviousBuildDirError, ) from pip._internal.locations import distutils_scheme, virtualenv_no_global from pip._internal.operations.check import check_install_conflicts @@ -21,7 +23,8 @@ from pip._internal.status_codes import ERROR from pip._internal.utils.filesystem import check_path_owner from pip._internal.utils.misc import ( - ensure_dir, get_installed_version, + ensure_dir, + get_installed_version, protect_pip_from_modification_on_windows, ) from pip._internal.utils.temp_dir import TempDirectory @@ -48,6 +51,7 @@ class InstallCommand(RequirementCommand): pip also supports installing from "requirements files", which provide an easy way to specify a whole environment to be installed. """ + name = 'install' usage = """ @@ -71,54 +75,56 @@ def __init__(self, *args, **kw): cmd_opts.add_option(cmdoptions.editable()) cmd_opts.add_option( - '-t', '--target', + '-t', + '--target', dest='target_dir', metavar='dir', default=None, help='Install packages into . ' - 'By default this will not replace existing files/folders in ' - '. Use --upgrade to replace existing packages in ' - 'with new versions.' + 'By default this will not replace existing files/folders in ' + '. Use --upgrade to replace existing packages in ' + 'with new versions.', ) cmd_opts.add_option( '--user', dest='use_user_site', action='store_true', help="Install to the Python user install directory for your " - "platform. Typically ~/.local/, or %APPDATA%\\Python on " - "Windows. (See the Python documentation for site.USER_BASE " - "for full details.)") + "platform. Typically ~/.local/, or %APPDATA%\\Python on " + "Windows. (See the Python documentation for site.USER_BASE " + "for full details.)", + ) cmd_opts.add_option( - '--no-user', - dest='use_user_site', - action='store_false', - help=SUPPRESS_HELP) + '--no-user', dest='use_user_site', action='store_false', help=SUPPRESS_HELP + ) cmd_opts.add_option( '--root', dest='root_path', metavar='dir', default=None, - help="Install everything relative to this alternate root " - "directory.") + help="Install everything relative to this alternate root " "directory.", + ) cmd_opts.add_option( '--prefix', dest='prefix_path', metavar='dir', default=None, help="Installation prefix where lib, bin and other top-level " - "folders are placed") + "folders are placed", + ) cmd_opts.add_option(cmdoptions.build_dir()) cmd_opts.add_option(cmdoptions.src()) cmd_opts.add_option( - '-U', '--upgrade', + '-U', + '--upgrade', dest='upgrade', action='store_true', help='Upgrade all specified packages to the newest available ' - 'version. The handling of dependencies depends on the ' - 'upgrade-strategy used.' + 'version. The handling of dependencies depends on the ' + 'upgrade-strategy used.', ) cmd_opts.add_option( @@ -127,26 +133,28 @@ def __init__(self, *args, **kw): default='only-if-needed', choices=['only-if-needed', 'eager'], help='Determines how dependency upgrading should be handled ' - '[default: %default]. ' - '"eager" - dependencies are upgraded regardless of ' - 'whether the currently installed version satisfies the ' - 'requirements of the upgraded package(s). ' - '"only-if-needed" - are upgraded only when they do not ' - 'satisfy the requirements of the upgraded package(s).' + '[default: %default]. ' + '"eager" - dependencies are upgraded regardless of ' + 'whether the currently installed version satisfies the ' + 'requirements of the upgraded package(s). ' + '"only-if-needed" - are upgraded only when they do not ' + 'satisfy the requirements of the upgraded package(s).', ) cmd_opts.add_option( '--force-reinstall', dest='force_reinstall', action='store_true', - help='Reinstall all packages even if they are already ' - 'up-to-date.') + help='Reinstall all packages even if they are already ' 'up-to-date.', + ) cmd_opts.add_option( - '-I', '--ignore-installed', + '-I', + '--ignore-installed', dest='ignore_installed', action='store_true', - help='Ignore the installed packages (reinstalling instead).') + help='Ignore the installed packages (reinstalling instead).', + ) cmd_opts.add_option(cmdoptions.ignore_requires_python()) cmd_opts.add_option(cmdoptions.no_build_isolation()) @@ -191,10 +199,7 @@ def __init__(self, *args, **kw): cmd_opts.add_option(cmdoptions.require_hashes()) cmd_opts.add_option(cmdoptions.progress_bar()) - index_opts = cmdoptions.make_option_group( - cmdoptions.index_group, - self.parser, - ) + index_opts = cmdoptions.make_option_group(cmdoptions.index_group, self.parser) self.parser.insert_option_group(0, index_opts) self.parser.insert_option_group(0, cmd_opts) @@ -229,11 +234,11 @@ def run(self, options, args): if options.target_dir: options.ignore_installed = True options.target_dir = os.path.abspath(options.target_dir) - if (os.path.exists(options.target_dir) and not - os.path.isdir(options.target_dir)): + if os.path.exists(options.target_dir) and not os.path.isdir( + options.target_dir + ): raise CommandError( - "Target path exists but is not a directory, will not " - "continue." + "Target path exists but is not a directory, will not " "continue." ) # Create a target directory for using with the target option @@ -244,7 +249,7 @@ def run(self, options, args): with self._build_session(options) as session: finder = self._build_package_finder(options, session) - build_delete = (not (options.no_clean or options.build_dir)) + build_delete = not (options.no_clean or options.build_dir) wheel_cache = WheelCache(options.cache_dir, options.format_control) if options.cache_dir and not check_path_owner(options.cache_dir): @@ -261,14 +266,17 @@ def run(self, options, args): with TempDirectory( options.build_dir, delete=build_delete, kind="install" ) as directory: - requirement_set = RequirementSet( - require_hashes=options.require_hashes, - ) + requirement_set = RequirementSet(require_hashes=options.require_hashes) try: self.populate_requirement_set( - requirement_set, args, options, finder, session, - self.name, wheel_cache + requirement_set, + args, + options, + finder, + session, + self.name, + wheel_cache, ) preparer = RequirementPreparer( build_dir=directory.path, @@ -303,24 +311,25 @@ def run(self, options, args): if wheel and options.cache_dir: # build wheels before install. wb = WheelBuilder( - finder, preparer, wheel_cache, - build_options=[], global_options=[], + finder, + preparer, + wheel_cache, + build_options=[], + global_options=[], ) # Ignore the result: a failed wheel will be # installed from the sdist/vcs whatever. wb.build( requirement_set.requirements.values(), - session=session, autobuilding=True + session=session, + autobuilding=True, ) - to_install = resolver.get_installation_order( - requirement_set - ) + to_install = resolver.get_installation_order(requirement_set) # Consistency Checking of the package set we're installing. should_warn_about_conflicts = ( - not options.ignore_dependencies and - options.warn_about_conflicts + not options.ignore_dependencies and options.warn_about_conflicts ) if should_warn_about_conflicts: self._warn_about_conflicts(to_install) @@ -367,10 +376,10 @@ def run(self, options, args): if installed: logger.info('Successfully installed %s', installed) except EnvironmentError as error: - show_traceback = (self.verbosity >= 1) + show_traceback = self.verbosity >= 1 message = create_env_error_message( - error, show_traceback, options.use_user_site, + error, show_traceback, options.use_user_site ) logger.error(message, exc_info=show_traceback) @@ -424,7 +433,7 @@ def _handle_target_dir(self, target_dir, target_temp_dir, upgrade): logger.warning( 'Target directory %s already exists. Specify ' '--upgrade to force replacement.', - target_item_dir + target_item_dir, ) continue if os.path.islink(target_item_dir): @@ -433,7 +442,7 @@ def _handle_target_dir(self, target_dir, target_temp_dir, upgrade): 'a link. Pip will not automatically replace ' 'links, please remove if replacement is ' 'desired.', - target_item_dir + target_item_dir, ) continue if os.path.isdir(target_item_dir): @@ -441,10 +450,7 @@ def _handle_target_dir(self, target_dir, target_temp_dir, upgrade): else: os.remove(target_item_dir) - shutil.move( - os.path.join(lib_dir, item), - target_item_dir - ) + shutil.move(os.path.join(lib_dir, item), target_item_dir) def _warn_about_conflicts(self, to_install): package_set, _dep_info = check_install_conflicts(to_install) @@ -456,7 +462,9 @@ def _warn_about_conflicts(self, to_install): for dependency in missing[project_name]: logger.critical( "%s %s requires %s, which is not installed.", - project_name, version, dependency[1], + project_name, + version, + dependency[1], ) for project_name in conflicting: @@ -465,7 +473,11 @@ def _warn_about_conflicts(self, to_install): logger.critical( "%s %s has requirement %s, but you'll have %s %s which is " "incompatible.", - project_name, version, req, dep_name, dep_version, + project_name, + version, + req, + dep_name, + dep_version, ) @@ -499,10 +511,7 @@ def create_env_error_message(error, show_traceback, using_user_site): permissions_part = "Check the permissions" if not using_user_site: - parts.extend([ - user_option_part, " or ", - permissions_part.lower(), - ]) + parts.extend([user_option_part, " or ", permissions_part.lower()]) else: parts.append(permissions_part) parts.append(".\n") diff --git a/src/pip/_internal/commands/list.py b/src/pip/_internal/commands/list.py index 09f633f392d..51989666767 100644 --- a/src/pip/_internal/commands/list.py +++ b/src/pip/_internal/commands/list.py @@ -12,9 +12,7 @@ from pip._internal.exceptions import CommandError from pip._internal.index import PackageFinder from pip._internal.utils.deprecation import RemovedInPip11Warning -from pip._internal.utils.misc import ( - dist_is_editable, get_installed_distributions, -) +from pip._internal.utils.misc import dist_is_editable, get_installed_distributions from pip._internal.utils.packaging import get_installer logger = logging.getLogger(__name__) @@ -26,6 +24,7 @@ class ListCommand(Command): Packages are listed in a case-insensitive sorted order. """ + name = 'list' usage = """ %prog [options]""" @@ -37,40 +36,52 @@ def __init__(self, *args, **kw): cmd_opts = self.cmd_opts cmd_opts.add_option( - '-o', '--outdated', + '-o', + '--outdated', action='store_true', default=False, - help='List outdated packages') + help='List outdated packages', + ) cmd_opts.add_option( - '-u', '--uptodate', + '-u', + '--uptodate', action='store_true', default=False, - help='List uptodate packages') + help='List uptodate packages', + ) cmd_opts.add_option( - '-e', '--editable', + '-e', + '--editable', action='store_true', default=False, - help='List editable projects.') + help='List editable projects.', + ) cmd_opts.add_option( - '-l', '--local', + '-l', + '--local', action='store_true', default=False, - help=('If in a virtualenv that has global access, do not list ' - 'globally-installed packages.'), + help=( + 'If in a virtualenv that has global access, do not list ' + 'globally-installed packages.' + ), ) self.cmd_opts.add_option( '--user', dest='user', action='store_true', default=False, - help='Only output packages installed in user-site.') + help='Only output packages installed in user-site.', + ) cmd_opts.add_option( '--pre', action='store_true', default=False, - help=("Include pre-release and development versions. By default, " - "pip only finds stable versions."), + help=( + "Include pre-release and development versions. By default, " + "pip only finds stable versions." + ), ) cmd_opts.add_option( @@ -80,15 +91,14 @@ def __init__(self, *args, **kw): default="columns", choices=('legacy', 'columns', 'freeze', 'json'), help="Select the output format among: columns (default), freeze, " - "json, or legacy.", + "json, or legacy.", ) cmd_opts.add_option( '--not-required', action='store_true', dest='not_required', - help="List packages that are not dependencies of " - "installed packages.", + help="List packages that are not dependencies of " "installed packages.", ) cmd_opts.add_option( @@ -131,8 +141,7 @@ def run(self, options, args): ) if options.outdated and options.uptodate: - raise CommandError( - "Options --outdated and --uptodate cannot be combined.") + raise CommandError("Options --outdated and --uptodate cannot be combined.") packages = get_installed_distributions( local_only=options.local, @@ -153,13 +162,15 @@ def run(self, options, args): def get_outdated(self, packages, options): return [ - dist for dist in self.iter_packages_latest_infos(packages, options) + dist + for dist in self.iter_packages_latest_infos(packages, options) if dist.latest_version > dist.parsed_version ] def get_uptodate(self, packages, options): return [ - dist for dist in self.iter_packages_latest_infos(packages, options) + dist + for dist in self.iter_packages_latest_infos(packages, options) if dist.latest_version == dist.parsed_version ] @@ -178,9 +189,7 @@ def iter_packages_latest_infos(self, packages, options): dependency_links = [] for dist in packages: if dist.has_metadata('dependency_links.txt'): - dependency_links.extend( - dist.get_metadata_lines('dependency_links.txt'), - ) + dependency_links.extend(dist.get_metadata_lines('dependency_links.txt')) with self._build_session(options) as session: finder = self._build_package_finder(options, index_urls, session) @@ -191,13 +200,15 @@ def iter_packages_latest_infos(self, packages, options): all_candidates = finder.find_all_candidates(dist.key) if not options.pre: # Remove prereleases - all_candidates = [candidate for candidate in all_candidates - if not candidate.version.is_prerelease] + all_candidates = [ + candidate + for candidate in all_candidates + if not candidate.version.is_prerelease + ] if not all_candidates: continue - best_candidate = max(all_candidates, - key=finder._candidate_sort_key) + best_candidate = max(all_candidates, key=finder._candidate_sort_key) remote_version = best_candidate.version if best_candidate.location.is_wheel: typ = 'wheel' @@ -217,11 +228,7 @@ def output_legacy(self, dist, options): get_installer(dist), ) elif dist_is_editable(dist): - return '%s (%s, %s)' % ( - dist.project_name, - dist.version, - dist.location, - ) + return '%s (%s, %s)' % (dist.project_name, dist.version, dist.location) else: return '%s (%s)' % (dist.project_name, dist.version) @@ -233,18 +240,16 @@ def output_legacy_latest(self, dist, options): ) def output_package_listing(self, packages, options): - packages = sorted( - packages, - key=lambda dist: dist.project_name.lower(), - ) + packages = sorted(packages, key=lambda dist: dist.project_name.lower()) if options.list_format == 'columns' and packages: data, header = format_for_columns(packages, options) self.output_package_listing_columns(data, header) elif options.list_format == 'freeze': for dist in packages: if options.verbose >= 1: - logger.info("%s==%s (%s)", dist.project_name, - dist.version, dist.location) + logger.info( + "%s==%s (%s)", dist.project_name, dist.version, dist.location + ) else: logger.info("%s==%s", dist.project_name, dist.version) elif options.list_format == 'json': @@ -282,8 +287,12 @@ def tabulate(vals): result = [] for row in vals: - display = " ".join([str(c).ljust(s) if c is not None else '' - for s, c in zip_longest(sizes, row)]) + display = " ".join( + [ + str(c).ljust(s) if c is not None else '' + for s, c in zip_longest(sizes, row) + ] + ) result.append(display) return result, sizes @@ -329,10 +338,7 @@ def format_for_columns(pkgs, options): def format_for_json(packages, options): data = [] for dist in packages: - info = { - 'name': dist.project_name, - 'version': six.text_type(dist.version), - } + info = {'name': dist.project_name, 'version': six.text_type(dist.version)} if options.verbose >= 1: info['location'] = dist.location info['installer'] = get_installer(dist) diff --git a/src/pip/_internal/commands/search.py b/src/pip/_internal/commands/search.py index a47a9a7de26..5ce4f848c2e 100644 --- a/src/pip/_internal/commands/search.py +++ b/src/pip/_internal/commands/search.py @@ -7,6 +7,7 @@ from pip._vendor import pkg_resources from pip._vendor.packaging.version import parse as parse_version + # NOTE: XMLRPC Client is not annotated in typeshed as on 2017-07-17, which is # why we ignore the type on this import from pip._vendor.six.moves import xmlrpc_client # type: ignore @@ -24,6 +25,7 @@ class SearchCommand(Command): """Search for PyPI packages whose name or summary contains .""" + name = 'search' usage = """ %prog [options] """ @@ -33,11 +35,13 @@ class SearchCommand(Command): def __init__(self, *args, **kw): super(SearchCommand, self).__init__(*args, **kw) self.cmd_opts.add_option( - '-i', '--index', + '-i', + '--index', dest='index', metavar='URL', default=PyPI.pypi_url, - help='Base URL of Python Package Index (default %default)') + help='Base URL of Python Package Index (default %default)', + ) self.parser.insert_option_group(0, self.cmd_opts) @@ -79,11 +83,7 @@ def transform_hits(hits): version = hit['version'] if name not in packages.keys(): - packages[name] = { - 'name': name, - 'summary': summary, - 'versions': [version], - } + packages[name] = {'name': name, 'summary': summary, 'versions': [version]} else: packages[name]['versions'].append(version) @@ -98,10 +98,15 @@ def print_results(hits, name_column_width=None, terminal_width=None): if not hits: return if name_column_width is None: - name_column_width = max([ - len(hit['name']) + len(highest_version(hit.get('versions', ['-']))) - for hit in hits - ]) + 4 + name_column_width = ( + max( + [ + len(hit['name']) + len(highest_version(hit.get('versions', ['-']))) + for hit in hits + ] + ) + + 4 + ) installed_packages = [p.project_name for p in pkg_resources.working_set] for hit in hits: @@ -115,8 +120,7 @@ def print_results(hits, name_column_width=None, terminal_width=None): summary = textwrap.wrap(summary, target_width) summary = ('\n' + ' ' * (name_column_width + 3)).join(summary) - line = '%-*s - %s' % (name_column_width, - '%s (%s)' % (name, latest), summary) + line = '%-*s - %s' % (name_column_width, '%s (%s)' % (name, latest), summary) try: logger.info(line) if name in installed_packages: diff --git a/src/pip/_internal/commands/show.py b/src/pip/_internal/commands/show.py index 1a8d9681eee..4312d165969 100644 --- a/src/pip/_internal/commands/show.py +++ b/src/pip/_internal/commands/show.py @@ -15,6 +15,7 @@ class ShowCommand(Command): """Show information about one or more installed packages.""" + name = 'show' usage = """ %prog [options] ...""" @@ -24,11 +25,13 @@ class ShowCommand(Command): def __init__(self, *args, **kw): super(ShowCommand, self).__init__(*args, **kw) self.cmd_opts.add_option( - '-f', '--files', + '-f', + '--files', dest='files', action='store_true', default=False, - help='Show the full list of installed files for each package.') + help='Show the full list of installed files for each package.', + ) self.parser.insert_option_group(0, self.cmd_opts) @@ -40,7 +43,8 @@ def run(self, options, args): results = search_packages_info(query) if not print_results( - results, list_files=options.files, verbose=options.verbose): + results, list_files=options.files, verbose=options.verbose + ): return ERROR return SUCCESS @@ -102,15 +106,21 @@ def search_packages_info(query): feed_parser = FeedParser() feed_parser.feed(metadata) pkg_info_dict = feed_parser.close() - for key in ('metadata-version', 'summary', - 'home-page', 'author', 'author-email', 'license'): + for key in ( + 'metadata-version', + 'summary', + 'home-page', + 'author', + 'author-email', + 'license', + ): package[key] = pkg_info_dict.get(key) # It looks like FeedParser cannot deal with repeated headers classifiers = [] for line in metadata.splitlines(): if line.startswith('Classifier: '): - classifiers.append(line[len('Classifier: '):]) + classifiers.append(line[len('Classifier: ') :]) package['classifiers'] = classifiers if file_list: @@ -130,7 +140,8 @@ def print_results(distributions, list_files=False, verbose=False): name = dist.get('name', '') required_by = [ - pkg.project_name for pkg in pkg_resources.working_set + pkg.project_name + for pkg in pkg_resources.working_set if name in [required.name for required in pkg.requires()] ] @@ -146,8 +157,7 @@ def print_results(distributions, list_files=False, verbose=False): logger.info("Required-by: %s", ', '.join(required_by)) if verbose: - logger.info("Metadata-Version: %s", - dist.get('metadata-version', '')) + logger.info("Metadata-Version: %s", dist.get('metadata-version', '')) logger.info("Installer: %s", dist.get('installer', '')) logger.info("Classifiers:") for classifier in dist.get('classifiers', []): diff --git a/src/pip/_internal/commands/uninstall.py b/src/pip/_internal/commands/uninstall.py index ba5a2f55267..99170a53daf 100644 --- a/src/pip/_internal/commands/uninstall.py +++ b/src/pip/_internal/commands/uninstall.py @@ -18,6 +18,7 @@ class UninstallCommand(Command): leave behind no metadata to determine what files were installed. - Script wrappers installed by ``python setup.py develop``. """ + name = 'uninstall' usage = """ %prog [options] ... @@ -27,19 +28,22 @@ class UninstallCommand(Command): def __init__(self, *args, **kw): super(UninstallCommand, self).__init__(*args, **kw) self.cmd_opts.add_option( - '-r', '--requirement', + '-r', + '--requirement', dest='requirements', action='append', default=[], metavar='file', help='Uninstall all the packages listed in the given requirements ' - 'file. This option can be used multiple times.', + 'file. This option can be used multiple times.', ) self.cmd_opts.add_option( - '-y', '--yes', + '-y', + '--yes', dest='yes', action='store_true', - help="Don't ask for confirmation of uninstall deletions.") + help="Don't ask for confirmation of uninstall deletions.", + ) self.parser.insert_option_group(0, self.cmd_opts) @@ -47,16 +51,13 @@ def run(self, options, args): with self._build_session(options) as session: reqs_to_uninstall = {} for name in args: - req = InstallRequirement.from_line( - name, isolated=options.isolated_mode, - ) + req = InstallRequirement.from_line(name, isolated=options.isolated_mode) if req.name: reqs_to_uninstall[canonicalize_name(req.name)] = req for filename in options.requirements: for req in parse_requirements( - filename, - options=options, - session=session): + filename, options=options, session=session + ): if req.name: reqs_to_uninstall[canonicalize_name(req.name)] = req if not reqs_to_uninstall: @@ -71,7 +72,7 @@ def run(self, options, args): for req in reqs_to_uninstall.values(): uninstall_pathset = req.uninstall( - auto_confirm=options.yes, verbose=self.verbosity > 0, + auto_confirm=options.yes, verbose=self.verbosity > 0 ) if uninstall_pathset: uninstall_pathset.commit() diff --git a/src/pip/_internal/commands/wheel.py b/src/pip/_internal/commands/wheel.py index 0fb72c1a92b..814951c8807 100644 --- a/src/pip/_internal/commands/wheel.py +++ b/src/pip/_internal/commands/wheel.py @@ -48,12 +48,15 @@ def __init__(self, *args, **kw): cmd_opts = self.cmd_opts cmd_opts.add_option( - '-w', '--wheel-dir', + '-w', + '--wheel-dir', dest='wheel_dir', metavar='dir', default=os.curdir, - help=("Build wheels into , where the default is the " - "current working directory."), + help=( + "Build wheels into , where the default is the " + "current working directory." + ), ) cmd_opts.add_option(cmdoptions.no_binary()) cmd_opts.add_option(cmdoptions.only_binary()) @@ -81,23 +84,23 @@ def __init__(self, *args, **kw): action='append', metavar='options', help="Extra global options to be supplied to the setup.py " - "call before the 'bdist_wheel' command.") + "call before the 'bdist_wheel' command.", + ) cmd_opts.add_option( '--pre', action='store_true', default=False, - help=("Include pre-release and development versions. By default, " - "pip only finds stable versions."), + help=( + "Include pre-release and development versions. By default, " + "pip only finds stable versions." + ), ) cmd_opts.add_option(cmdoptions.no_clean()) cmd_opts.add_option(cmdoptions.require_hashes()) - index_opts = cmdoptions.make_option_group( - cmdoptions.index_group, - self.parser, - ) + index_opts = cmdoptions.make_option_group(cmdoptions.index_group, self.parser) self.parser.insert_option_group(0, index_opts) self.parser.insert_option_group(0, cmd_opts) @@ -117,20 +120,23 @@ def run(self, options, args): with self._build_session(options) as session: finder = self._build_package_finder(options, session) - build_delete = (not (options.no_clean or options.build_dir)) + build_delete = not (options.no_clean or options.build_dir) wheel_cache = WheelCache(options.cache_dir, options.format_control) with TempDirectory( options.build_dir, delete=build_delete, kind="wheel" ) as directory: - requirement_set = RequirementSet( - require_hashes=options.require_hashes, - ) + requirement_set = RequirementSet(require_hashes=options.require_hashes) try: self.populate_requirement_set( - requirement_set, args, options, finder, session, - self.name, wheel_cache + requirement_set, + args, + options, + finder, + session, + self.name, + wheel_cache, ) preparer = RequirementPreparer( @@ -159,18 +165,18 @@ def run(self, options, args): # build wheels wb = WheelBuilder( - finder, preparer, wheel_cache, + finder, + preparer, + wheel_cache, build_options=options.build_options or [], global_options=options.global_options or [], no_clean=options.no_clean, ) wheels_built_successfully = wb.build( - requirement_set.requirements.values(), session=session, + requirement_set.requirements.values(), session=session ) if not wheels_built_successfully: - raise CommandError( - "Failed to build one or more wheels" - ) + raise CommandError("Failed to build one or more wheels") except PreviousBuildDirError: options.no_clean = True raise diff --git a/src/pip/_internal/compat.py b/src/pip/_internal/compat.py index 4aefd58cd45..59ff5e6a010 100644 --- a/src/pip/_internal/compat.py +++ b/src/pip/_internal/compat.py @@ -18,13 +18,21 @@ from pip._vendor import ipaddress # type: ignore except ImportError: import ipaddr as ipaddress # type: ignore + ipaddress.ip_address = ipaddress.IPAddress ipaddress.ip_network = ipaddress.IPNetwork __all__ = [ - "ipaddress", "uses_pycache", "console_to_str", "native_str", - "get_path_uid", "stdlib_pkgs", "WINDOWS", "samefile", "get_terminal_size", + "ipaddress", + "uses_pycache", + "console_to_str", + "native_str", + "get_path_uid", + "stdlib_pkgs", + "WINDOWS", + "samefile", + "get_terminal_size", ] @@ -59,10 +67,8 @@ def backslashreplace_decode_fn(err): # Python 2 gave us characters - convert to numeric bytes raw_bytes = (ord(b) for b in raw_bytes) return u"".join(u"\\x%x" % c for c in raw_bytes), err.end - codecs.register_error( - "backslashreplace_decode", - backslashreplace_decode_fn, - ) + + codecs.register_error("backslashreplace_decode", backslashreplace_decode_fn) backslashreplace_decode = "backslashreplace_decode" @@ -90,8 +96,7 @@ def console_to_str(data): s = data.decode(encoding) except UnicodeDecodeError: logger.warning( - "Subprocess output does not appear to be encoded as %s", - encoding, + "Subprocess output does not appear to be encoded as %s", encoding ) s = data.decode(encoding, errors=backslashreplace_decode) @@ -107,8 +112,7 @@ def console_to_str(data): # or doesn't have an encoding attribute. Neither of these cases # should occur in normal pip use, but there's no harm in checking # in case people use pip in (unsupported) unusual situations. - output_encoding = getattr(getattr(sys, "__stderr__", None), - "encoding", None) + output_encoding = getattr(getattr(sys, "__stderr__", None), "encoding", None) if output_encoding: s = s.encode(output_encoding, errors="backslashreplace") @@ -118,12 +122,15 @@ def console_to_str(data): if sys.version_info >= (3,): + def native_str(s, replace=False): if isinstance(s, bytes): return s.decode('utf-8', 'replace' if replace else 'strict') return s + else: + def native_str(s, replace=False): # Replace is ignored -- unicode to UTF-8 can't fail if isinstance(s, text_type): @@ -154,9 +161,7 @@ def get_path_uid(path): file_uid = os.stat(path).st_uid else: # raise OSError for parity with os.O_NOFOLLOW above - raise OSError( - "%s is a symlink; Will not return uid for symlinks" % path - ) + raise OSError("%s is a symlink; Will not return uid for symlinks" % path) return file_uid @@ -181,8 +186,7 @@ def expanduser(path): # windows detection, covers cpython and ironpython -WINDOWS = (sys.platform.startswith("win") or - (sys.platform == 'cli' and os.name == 'nt')) +WINDOWS = sys.platform.startswith("win") or (sys.platform == 'cli' and os.name == 'nt') def samefile(file1, file2): @@ -196,32 +200,38 @@ def samefile(file1, file2): if hasattr(shutil, 'get_terminal_size'): + def get_terminal_size(): """ Returns a tuple (x, y) representing the width(x) and the height(y) in characters of the terminal window. """ return tuple(shutil.get_terminal_size()) + + else: + def get_terminal_size(): """ Returns a tuple (x, y) representing the width(x) and the height(y) in characters of the terminal window. """ + def ioctl_GWINSZ(fd): try: import fcntl import termios import struct + cr = struct.unpack_from( - 'hh', - fcntl.ioctl(fd, termios.TIOCGWINSZ, '12345678') + 'hh', fcntl.ioctl(fd, termios.TIOCGWINSZ, '12345678') ) except: return None if cr == (0, 0): return None return cr + cr = ioctl_GWINSZ(0) or ioctl_GWINSZ(1) or ioctl_GWINSZ(2) if not cr: try: diff --git a/src/pip/_internal/configuration.py b/src/pip/_internal/configuration.py index b15e3d5bac4..567fe508956 100644 --- a/src/pip/_internal/configuration.py +++ b/src/pip/_internal/configuration.py @@ -20,8 +20,11 @@ from pip._internal.exceptions import ConfigurationError from pip._internal.locations import ( - legacy_config_file, new_config_file, running_under_virtualenv, - site_config_files, venv_config_file, + legacy_config_file, + new_config_file, + running_under_virtualenv, + site_config_files, + venv_config_file, ) from pip._internal.utils.misc import ensure_dir, enum from pip._internal.utils.typing import MYPY_CHECK_RUNNING @@ -53,10 +56,10 @@ def _disassemble_key(name): # The kinds of configurations there are. kinds = enum( - USER="user", # User Specific - GLOBAL="global", # System Wide - VENV="venv", # Virtual Environment Specific - ENV="env", # from PIP_CONFIG_FILE + USER="user", # User Specific + GLOBAL="global", # System Wide + VENV="venv", # Virtual Environment Specific + ENV="env", # from PIP_CONFIG_FILE ENV_VAR="env-var", # from Environment Variables ) @@ -91,7 +94,11 @@ def __init__(self, isolated, load_only=None): # The order here determines the override order. self._override_order = [ - kinds.GLOBAL, kinds.USER, kinds.VENV, kinds.ENV, kinds.ENV_VAR + kinds.GLOBAL, + kinds.USER, + kinds.VENV, + kinds.ENV, + kinds.ENV_VAR, ] self._ignore_env_names = ["version", "help"] @@ -117,8 +124,7 @@ def get_file_to_edit(self): # type: () -> Optional[str] """Returns the file with highest priority in configuration """ - assert self.load_only is not None, \ - "Need to be specified a file to be editing" + assert self.load_only is not None, "Need to be specified a file to be editing" try: return self._get_parser_to_modify()[0] @@ -255,9 +261,7 @@ def _load_config_files(self): # If there's specific variant set in `load_only`, load only # that variant, not the others. if self.load_only is not None and variant != self.load_only: - logger.debug( - "Skipping file '%s' (variant: %s)", fname, variant - ) + logger.debug("Skipping file '%s' (variant: %s)", fname, variant) continue parser = self._load_file(variant, fname) @@ -287,11 +291,14 @@ def _construct_parser(self, fname): try: parser.read(fname) except UnicodeDecodeError: - raise ConfigurationError(( - "ERROR: " - "Configuration file contains invalid %s characters.\n" - "Please fix your configuration, located at %s\n" - ) % (locale.getpreferredencoding(False), fname)) + raise ConfigurationError( + ( + "ERROR: " + "Configuration file contains invalid %s characters.\n" + "Please fix your configuration, located at %s\n" + ) + % (locale.getpreferredencoding(False), fname) + ) return parser def _load_environment_vars(self): @@ -320,8 +327,7 @@ def _get_environ_vars(self): """Returns a generator with all environmental vars with prefix PIP_""" for key, val in os.environ.items(): should_be_yielded = ( - key.startswith("PIP_") and - key[4:].lower() not in self._ignore_env_names + key.startswith("PIP_") and key[4:].lower() not in self._ignore_env_names ) if should_be_yielded: yield key[4:].lower(), val diff --git a/src/pip/_internal/download.py b/src/pip/_internal/download.py index 8cf757d86ed..40b54fb2fad 100644 --- a/src/pip/_internal/download.py +++ b/src/pip/_internal/download.py @@ -21,6 +21,7 @@ from pip._vendor.requests.models import CONTENT_CHUNK_SIZE, Response from pip._vendor.requests.structures import CaseInsensitiveDict from pip._vendor.requests.utils import get_netrc_auth + # NOTE: XMLRPC Client is not annotated in typeshed as on 2017-07-17, which is # why we ignore the type on this import from pip._vendor.six.moves import xmlrpc_client # type: ignore @@ -39,8 +40,16 @@ from pip._internal.utils.glibc import libc_ver from pip._internal.utils.logging import indent_log from pip._internal.utils.misc import ( - ARCHIVE_EXTENSIONS, ask_path_exists, backup_dir, call_subprocess, consume, - display_path, format_size, get_installed_version, rmtree, splitext, + ARCHIVE_EXTENSIONS, + ask_path_exists, + backup_dir, + call_subprocess, + consume, + display_path, + format_size, + get_installed_version, + rmtree, + splitext, unpack_file, ) from pip._internal.utils.setuptools_build import SETUPTOOLS_SHIM @@ -55,11 +64,19 @@ HAS_TLS = (ssl is not None) or IS_PYOPENSSL -__all__ = ['get_file_content', - 'is_url', 'url_to_path', 'path_to_url', - 'is_archive_file', 'unpack_vcs_link', - 'unpack_file_url', 'is_vcs_url', 'is_file_url', - 'unpack_http_url', 'unpack_url'] +__all__ = [ + 'get_file_content', + 'is_url', + 'url_to_path', + 'path_to_url', + 'is_archive_file', + 'unpack_vcs_link', + 'unpack_file_url', + 'is_vcs_url', + 'is_file_url', + 'unpack_http_url', + 'unpack_url', +] logger = logging.getLogger(__name__) @@ -72,9 +89,7 @@ def user_agent(): data = { "installer": {"name": "pip", "version": pip.__version__}, "python": platform.python_version(), - "implementation": { - "name": platform.python_implementation(), - }, + "implementation": {"name": platform.python_implementation()}, } if data["implementation"]["name"] == 'CPython': @@ -96,14 +111,14 @@ def user_agent(): if sys.platform.startswith("linux"): from pip._vendor import distro - distro_infos = dict(filter( - lambda x: x[1], - zip(["name", "version", "id"], distro.linux_distribution()), - )) - libc = dict(filter( - lambda x: x[1], - zip(["lib", "version"], libc_ver()), - )) + + distro_infos = dict( + filter( + lambda x: x[1], + zip(["name", "version", "id"], distro.linux_distribution()), + ) + ) + libc = dict(filter(lambda x: x[1], zip(["lib", "version"], libc_ver()))) if libc: distro_infos["libc"] = libc if distro_infos: @@ -129,13 +144,11 @@ def user_agent(): data["setuptools_version"] = setuptools_version return "{data[installer][name]}/{data[installer][version]} {json}".format( - data=data, - json=json.dumps(data, separators=(",", ":"), sort_keys=True), + data=data, json=json.dumps(data, separators=(",", ":"), sort_keys=True) ) class MultiDomainBasicAuth(AuthBase): - def __init__(self, prompting=True): self.prompting = prompting self.passwords = {} @@ -218,9 +231,9 @@ def parse_credentials(self, netloc): class LocalFSAdapter(BaseAdapter): - - def send(self, request, stream=None, timeout=None, verify=None, cert=None, - proxies=None): + def send( + self, request, stream=None, timeout=None, verify=None, cert=None, proxies=None + ): pathname = url_to_path(request.url) resp = Response() @@ -235,11 +248,13 @@ def send(self, request, stream=None, timeout=None, verify=None, cert=None, else: modified = email.utils.formatdate(stats.st_mtime, usegmt=True) content_type = mimetypes.guess_type(pathname)[0] or "text/plain" - resp.headers = CaseInsensitiveDict({ - "Content-Type": content_type, - "Content-Length": stats.st_size, - "Last-Modified": modified, - }) + resp.headers = CaseInsensitiveDict( + { + "Content-Type": content_type, + "Content-Length": stats.st_size, + "Last-Modified": modified, + } + ) resp.raw = open(pathname, "rb") resp.close = resp.raw.close @@ -317,7 +332,6 @@ def delete(self, *args, **kwargs): class InsecureHTTPAdapter(HTTPAdapter): - def cert_verify(self, conn, url, verify, cert): conn.cert_reqs = 'CERT_NONE' conn.ca_certs = None @@ -346,7 +360,6 @@ def __init__(self, *args, **kwargs): # Set the total number of retries that a particular request can # have. total=retries, - # A 503 error from PyPI typically means that the Fastly -> Origin # connection got interrupted in some way. A 503 error in general # is typically considered a transient error so we'll go ahead and @@ -354,7 +367,6 @@ def __init__(self, *args, **kwargs): # A 500 may indicate transient error in Amazon S3 # A 520 or 527 - may indicate transient error in CloudFlare status_forcelist=[500, 503, 520, 527], - # Add a small amount of back off between failed requests in # order to prevent hammering the service. backoff_factor=0.25, @@ -366,8 +378,7 @@ def __init__(self, *args, **kwargs): # require manual eviction from the cache to fix it. if cache: secure_adapter = CacheControlAdapter( - cache=SafeFileCache(cache, use_dir_lock=True), - max_retries=retries, + cache=SafeFileCache(cache, use_dir_lock=True), max_retries=retries ) else: secure_adapter = HTTPAdapter(max_retries=retries) @@ -413,11 +424,11 @@ def get_file_content(url, comes_from=None, session=None): match = _scheme_re.search(url) if match: scheme = match.group(1).lower() - if (scheme == 'file' and comes_from and - comes_from.startswith('http')): + if scheme == 'file' and comes_from and comes_from.startswith('http'): raise InstallationError( 'Requirements file %s references URL %s, which is local' - % (comes_from, url)) + % (comes_from, url) + ) if scheme == 'file': path = url.split(':', 1)[1] path = path.replace('\\', '/') @@ -437,9 +448,7 @@ def get_file_content(url, comes_from=None, session=None): with open(url, 'rb') as f: content = auto_decode(f.read()) except IOError as exc: - raise InstallationError( - 'Could not open requirements file: %s' % str(exc) - ) + raise InstallationError('Could not open requirements file: %s' % str(exc)) return url, content @@ -460,7 +469,8 @@ def url_to_path(url): Convert a file: URL to a path. """ assert url.startswith('file:'), ( - "You can only turn file: urls into filenames (not %r)" % url) + "You can only turn file: urls into filenames (not %r)" % url + ) _, netloc, path, _, _ = urllib_parse.urlsplit(url) @@ -549,30 +559,31 @@ def resp_read(chunk_size): try: # Special case for urllib3. for chunk in resp.raw.stream( - chunk_size, - # We use decode_content=False here because we don't - # want urllib3 to mess with the raw bytes we get - # from the server. If we decompress inside of - # urllib3 then we cannot verify the checksum - # because the checksum will be of the compressed - # file. This breakage will only occur if the - # server adds a Content-Encoding header, which - # depends on how the server was configured: - # - Some servers will notice that the file isn't a - # compressible file and will leave the file alone - # and with an empty Content-Encoding - # - Some servers will notice that the file is - # already compressed and will leave the file - # alone and will add a Content-Encoding: gzip - # header - # - Some servers won't notice anything at all and - # will take a file that's already been compressed - # and compress it again and set the - # Content-Encoding: gzip header - # - # By setting this not to decode automatically we - # hope to eliminate problems with the second case. - decode_content=False): + chunk_size, + # We use decode_content=False here because we don't + # want urllib3 to mess with the raw bytes we get + # from the server. If we decompress inside of + # urllib3 then we cannot verify the checksum + # because the checksum will be of the compressed + # file. This breakage will only occur if the + # server adds a Content-Encoding header, which + # depends on how the server was configured: + # - Some servers will notice that the file isn't a + # compressible file and will leave the file alone + # and with an empty Content-Encoding + # - Some servers will notice that the file is + # already compressed and will leave the file + # alone and will add a Content-Encoding: gzip + # header + # - Some servers won't notice anything at all and + # will take a file that's already been compressed + # and compress it again and set the + # Content-Encoding: gzip header + # + # By setting this not to decode automatically we + # hope to eliminate problems with the second case. + decode_content=False, + ): yield chunk except AttributeError: # Standard file-like object. @@ -595,8 +606,7 @@ def written_chunks(chunks): url = link.url_without_fragment if show_progress: # We don't show progress on cached responses - progress_indicator = DownloadProgressProvider(progress_bar, - max=total_length) + progress_indicator = DownloadProgressProvider(progress_bar, max=total_length) if total_length: logger.info("Downloading %s (%s)", url, format_size(total_length)) else: @@ -609,10 +619,7 @@ def written_chunks(chunks): logger.debug('Downloading from URL %s', link) downloaded_chunks = written_chunks( - progress_indicator( - resp_read(CONTENT_CHUNK_SIZE), - CONTENT_CHUNK_SIZE - ) + progress_indicator(resp_read(CONTENT_CHUNK_SIZE), CONTENT_CHUNK_SIZE) ) if hashes: hashes.check_against_chunks(downloaded_chunks) @@ -625,8 +632,10 @@ def _copy_file(filename, location, link): download_location = os.path.join(location, link.filename) if os.path.exists(download_location): response = ask_path_exists( - 'The file %s exists. (i)gnore, (w)ipe, (b)ackup, (a)abort' % - display_path(download_location), ('i', 'w', 'b', 'a')) + 'The file %s exists. (i)gnore, (w)ipe, (b)ackup, (a)abort' + % display_path(download_location), + ('i', 'w', 'b', 'a'), + ) if response == 'i': copy = False elif response == 'w': @@ -647,8 +656,9 @@ def _copy_file(filename, location, link): logger.info('Saved %s', display_path(download_location)) -def unpack_http_url(link, location, download_dir=None, - session=None, hashes=None, progress_bar="on"): +def unpack_http_url( + link, location, download_dir=None, session=None, hashes=None, progress_bar="on" +): if session is None: raise TypeError( "unpack_http_url() missing 1 required keyword argument: 'session'" @@ -658,20 +668,16 @@ def unpack_http_url(link, location, download_dir=None, # If a download dir is specified, is the file already downloaded there? already_downloaded_path = None if download_dir: - already_downloaded_path = _check_download_dir(link, - download_dir, - hashes) + already_downloaded_path = _check_download_dir(link, download_dir, hashes) if already_downloaded_path: from_path = already_downloaded_path content_type = mimetypes.guess_type(from_path)[0] else: # let's download to a tmp dir - from_path, content_type = _download_http_url(link, - session, - temp_dir.path, - hashes, - progress_bar) + from_path, content_type = _download_http_url( + link, session, temp_dir.path, hashes, progress_bar + ) # unpack the archive to the build dir location. even when only # downloading archives, they have to be unpacked to parse dependencies @@ -713,9 +719,7 @@ def unpack_file_url(link, location, download_dir=None, hashes=None): # If a download dir is specified, is the file already there and valid? already_downloaded_path = None if download_dir: - already_downloaded_path = _check_download_dir(link, - download_dir, - hashes) + already_downloaded_path = _check_download_dir(link, download_dir, hashes) if already_downloaded_path: from_path = already_downloaded_path @@ -785,22 +789,28 @@ def request(self, host, handler, request_body, verbose=False): url = urllib_parse.urlunparse(parts) try: headers = {'Content-Type': 'text/xml'} - response = self._session.post(url, data=request_body, - headers=headers, stream=True) + response = self._session.post( + url, data=request_body, headers=headers, stream=True + ) response.raise_for_status() self.verbose = verbose return self.parse_response(response.raw) except requests.HTTPError as exc: logger.critical( - "HTTP error %s while getting %s", - exc.response.status_code, url, + "HTTP error %s while getting %s", exc.response.status_code, url ) raise -def unpack_url(link, location, download_dir=None, - only_download=False, session=None, hashes=None, - progress_bar="on"): +def unpack_url( + link, + location, + download_dir=None, + only_download=False, + session=None, + hashes=None, + progress_bar="on", +): """Unpack link. If link is a VCS link: if only_download, export into download_dir and ignore location @@ -834,7 +844,7 @@ def unpack_url(link, location, download_dir=None, download_dir, session, hashes=hashes, - progress_bar=progress_bar + progress_bar=progress_bar, ) if only_download: write_delete_marker_file(location) @@ -871,7 +881,7 @@ def _download_http_url(link, session, temp_dir, hashes, progress_bar): resp.raise_for_status() except requests.HTTPError as exc: logger.critical( - "HTTP error %s while getting %s", exc.response.status_code, link, + "HTTP error %s while getting %s", exc.response.status_code, link ) raise @@ -912,9 +922,8 @@ def _check_download_dir(link, download_dir, hashes): hashes.check_against_path(download_path) except HashMismatch: logger.warning( - 'Previously-downloaded file %s has bad hash. ' - 'Re-downloading.', - download_path + 'Previously-downloaded file %s has bad hash. ' 'Re-downloading.', + download_path, ) os.unlink(download_path) return None diff --git a/src/pip/_internal/exceptions.py b/src/pip/_internal/exceptions.py index ad6f4125356..49a0ea3f91c 100644 --- a/src/pip/_internal/exceptions.py +++ b/src/pip/_internal/exceptions.py @@ -96,6 +96,7 @@ class HashError(InstallationError): typically available earlier. """ + req = None head = '' @@ -129,8 +130,10 @@ class VcsHashUnsupported(HashError): we don't have a method for hashing those.""" order = 0 - head = ("Can't verify hashes for these requirements because we don't " - "have a way to hash version control repositories:") + head = ( + "Can't verify hashes for these requirements because we don't " + "have a way to hash version control repositories:" + ) class DirectoryUrlHashUnsupported(HashError): @@ -138,21 +141,25 @@ class DirectoryUrlHashUnsupported(HashError): we don't have a method for hashing those.""" order = 1 - head = ("Can't verify hashes for these file:// requirements because they " - "point to directories:") + head = ( + "Can't verify hashes for these file:// requirements because they " + "point to directories:" + ) class HashMissing(HashError): """A hash was needed for a requirement but is absent.""" order = 2 - head = ('Hashes are required in --require-hashes mode, but they are ' - 'missing from some requirements. Here is a list of those ' - 'requirements along with the hashes their downloaded archives ' - 'actually had. Add lines like these to your requirements files to ' - 'prevent tampering. (If you did not enable --require-hashes ' - 'manually, note that it turns on automatically when any package ' - 'has a hash.)') + head = ( + 'Hashes are required in --require-hashes mode, but they are ' + 'missing from some requirements. Here is a list of those ' + 'requirements along with the hashes their downloaded archives ' + 'actually had. Add lines like these to your requirements files to ' + 'prevent tampering. (If you did not enable --require-hashes ' + 'manually, note that it turns on automatically when any package ' + 'has a hash.)' + ) def __init__(self, gotten_hash): """ @@ -170,13 +177,18 @@ def body(self): # In the case of URL-based requirements, display the original URL # seen in the requirements file rather than the package name, # so the output can be directly copied into the requirements file. - package = (self.req.original_link if self.req.original_link - # In case someone feeds something downright stupid - # to InstallRequirement's constructor. - else getattr(self.req, 'req', None)) - return ' %s --hash=%s:%s' % (package or 'unknown package', - FAVORITE_HASH, - self.gotten_hash) + package = ( + self.req.original_link + if self.req.original_link + # In case someone feeds something downright stupid + # to InstallRequirement's constructor. + else getattr(self.req, 'req', None) + ) + return ' %s --hash=%s:%s' % ( + package or 'unknown package', + FAVORITE_HASH, + self.gotten_hash, + ) class HashUnpinned(HashError): @@ -184,8 +196,10 @@ class HashUnpinned(HashError): version.""" order = 3 - head = ('In --require-hashes mode, all requirements must have their ' - 'versions pinned with ==. These do not:') + head = ( + 'In --require-hashes mode, all requirements must have their ' + 'versions pinned with ==. These do not:' + ) class HashMismatch(HashError): @@ -197,11 +211,14 @@ class HashMismatch(HashError): improve its error message. """ + order = 4 - head = ('THESE PACKAGES DO NOT MATCH THE HASHES FROM THE REQUIREMENTS ' - 'FILE. If you have updated the package versions, please update ' - 'the hashes. Otherwise, examine the package contents carefully; ' - 'someone may have tampered with them.') + head = ( + 'THESE PACKAGES DO NOT MATCH THE HASHES FROM THE REQUIREMENTS ' + 'FILE. If you have updated the package versions, please update ' + 'the hashes. Otherwise, examine the package contents carefully; ' + 'someone may have tampered with them.' + ) def __init__(self, allowed, gots): """ @@ -214,8 +231,7 @@ def __init__(self, allowed, gots): self.gots = gots def body(self): - return ' %s:\n%s' % (self._requirement_name(), - self._hash_comparison()) + return ' %s:\n%s' % (self._requirement_name(), self._hash_comparison()) def _hash_comparison(self): """ @@ -228,6 +244,7 @@ def _hash_comparison(self): Got bcdefbcdefbcdefbcdefbcdefbcdefbcdefbcdefbcdef """ + def hash_then_or(hash_name): # For now, all the decent hashes have 6-char names, so we can get # away with hard-coding space literals. @@ -236,10 +253,12 @@ def hash_then_or(hash_name): lines = [] for hash_name, expecteds in iteritems(self.allowed): prefix = hash_then_or(hash_name) - lines.extend((' Expected %s %s' % (next(prefix), e)) - for e in expecteds) - lines.append(' Got %s\n' % - self.gots[hash_name].hexdigest()) + lines.extend( + (' Expected %s %s' % (next(prefix), e)) for e in expecteds + ) + lines.append( + ' Got %s\n' % self.gots[hash_name].hexdigest() + ) prefix = ' or' return '\n'.join(lines) diff --git a/src/pip/_internal/index.py b/src/pip/_internal/index.py index fe318a24f0d..fe05805c552 100644 --- a/src/pip/_internal/index.py +++ b/src/pip/_internal/index.py @@ -24,7 +24,9 @@ from pip._internal.compat import ipaddress from pip._internal.download import HAS_TLS, is_url, path_to_url, url_to_path from pip._internal.exceptions import ( - BestVersionAlreadyInstalled, DistributionNotFound, InvalidWheelFilename, + BestVersionAlreadyInstalled, + DistributionNotFound, + InvalidWheelFilename, UnsupportedWheel, ) from pip._internal.models.index import PyPI @@ -32,8 +34,12 @@ from pip._internal.utils.deprecation import RemovedInPip11Warning from pip._internal.utils.logging import indent_log from pip._internal.utils.misc import ( - ARCHIVE_EXTENSIONS, SUPPORTED_EXTENSIONS, cached_property, normalize_path, - remove_auth_from_url, splitext, + ARCHIVE_EXTENSIONS, + SUPPORTED_EXTENSIONS, + cached_property, + normalize_path, + remove_auth_from_url, + splitext, ) from pip._internal.utils.packaging import check_requires_python from pip._internal.wheel import Wheel, wheel_ext @@ -58,7 +64,6 @@ class InstallationCandidate(object): - def __init__(self, project, version, location): self.project = project self.version = parse_version(version) @@ -67,7 +72,7 @@ def __init__(self, project, version, location): def __repr__(self): return "".format( - self.project, self.version, self.location, + self.project, self.version, self.location ) def __hash__(self): @@ -105,11 +110,21 @@ class PackageFinder(object): packages, by reading pages and looking for appropriate links. """ - def __init__(self, find_links, index_urls, allow_all_prereleases=False, - trusted_hosts=None, process_dependency_links=False, - session=None, format_control=None, platform=None, - versions=None, abi=None, implementation=None, - prefer_binary=False): + def __init__( + self, + find_links, + index_urls, + allow_all_prereleases=False, + trusted_hosts=None, + process_dependency_links=False, + session=None, + format_control=None, + platform=None, + versions=None, + abi=None, + implementation=None, + prefer_binary=False, + ): """Create a PackageFinder. :param format_control: A FormatControl object or None. Used to control @@ -129,8 +144,7 @@ def __init__(self, find_links, index_urls, allow_all_prereleases=False, """ if session is None: raise TypeError( - "PackageFinder() missing 1 required keyword argument: " - "'session'" + "PackageFinder() missing 1 required keyword argument: " "'session'" ) # Build find_links. If an argument starts with ~, it may be @@ -156,8 +170,7 @@ def __init__(self, find_links, index_urls, allow_all_prereleases=False, # Domains that we won't emit warnings for when not using HTTPS self.secure_origins = [ - ("*", host, "*") - for host in (trusted_hosts if trusted_hosts else []) + ("*", host, "*") for host in (trusted_hosts if trusted_hosts else []) ] # Do we want to allow _all_ pre-releases? @@ -171,10 +184,7 @@ def __init__(self, find_links, index_urls, allow_all_prereleases=False, # The valid tags to check potential found wheel candidates against self.valid_tags = get_supported( - versions=versions, - platform=platform, - abi=abi, - impl=implementation, + versions=versions, platform=platform, abi=abi, impl=implementation ) # Do we prefer old, but valid, binary dist over new source dist @@ -197,13 +207,12 @@ def get_formatted_locations(self): lines = [] if self.index_urls and self.index_urls != [PyPI.simple_url]: lines.append( - "Looking in indexes: {}".format(", ".join( - remove_auth_from_url(url) for url in self.index_urls)) + "Looking in indexes: {}".format( + ", ".join(remove_auth_from_url(url) for url in self.index_urls) + ) ) if self.find_links: - lines.append( - "Looking in links: {}".format(", ".join(self.find_links)) - ) + lines.append("Looking in links: {}".format(", ".join(self.find_links))) return "\n".join(lines) def add_dependency_links(self, links): @@ -257,8 +266,8 @@ def sort_path(path): sort_path(path) else: logger.warning( - "Url '%s' is ignored: it is neither a file " - "nor a directory.", url, + "Url '%s' is ignored: it is neither a file " "nor a directory.", + url, ) elif is_url(url): # Only add url with clear scheme @@ -266,7 +275,8 @@ def sort_path(path): else: logger.warning( "Url '%s' is ignored. It is either a non-existing " - "path or lacks a specific scheme.", url, + "path or lacks a specific scheme.", + url, ) return files, urls @@ -321,7 +331,7 @@ def _validate_secure_origin(self, logger, location): # Determine if our origin is a secure origin by looking through our # hardcoded list of secure origins, as well as any additional ones # configured on this PackageFinder instance. - for secure_origin in (SECURE_ORIGINS + self.secure_origins): + for secure_origin in SECURE_ORIGINS + self.secure_origins: if protocol != secure_origin[0] and secure_origin[0] != "*": continue @@ -330,10 +340,7 @@ def _validate_secure_origin(self, logger, location): # unicode object, even on Python 2.x. addr = ipaddress.ip_address( origin[1] - if ( - isinstance(origin[1], six.text_type) or - origin[1] is None - ) + if (isinstance(origin[1], six.text_type) or origin[1] is None) else origin[1].decode("utf8") ) network = ipaddress.ip_network( @@ -344,9 +351,11 @@ def _validate_secure_origin(self, logger, location): except ValueError: # We don't have both a valid address or a valid network, so # we'll check this origin against hostnames. - if (origin[1] and - origin[1].lower() != secure_origin[1].lower() and - secure_origin[1] != "*"): + if ( + origin[1] + and origin[1].lower() != secure_origin[1].lower() + and secure_origin[1] != "*" + ): continue else: # We have a valid address and network, so see if the address @@ -355,9 +364,11 @@ def _validate_secure_origin(self, logger, location): continue # Check to see if the port patches - if (origin[2] != secure_origin[2] and - secure_origin[2] != "*" and - secure_origin[2] is not None): + if ( + origin[2] != secure_origin[2] + and secure_origin[2] != "*" + and secure_origin[2] is not None + ): continue # If we've gotten here, then this origin matches the current @@ -387,8 +398,8 @@ def _get_index_urls_locations(self, project_name): def mkurl_pypi_url(url): loc = posixpath.join( - url, - urllib_parse.quote(canonicalize_name(project_name))) + url, urllib_parse.quote(canonicalize_name(project_name)) + ) # For maximum compatibility with easy_install, ensure the path # ends in a trailing slash. Although this isn't in the spec # (and PyPI can handle it without the slash) some other index @@ -410,21 +421,21 @@ def find_all_candidates(self, project_name): """ index_locations = self._get_index_urls_locations(project_name) index_file_loc, index_url_loc = self._sort_locations(index_locations) - fl_file_loc, fl_url_loc = self._sort_locations( - self.find_links, expand_dir=True, - ) + fl_file_loc, fl_url_loc = self._sort_locations(self.find_links, expand_dir=True) dep_file_loc, dep_url_loc = self._sort_locations(self.dependency_links) - file_locations = (Link(url) for url in itertools.chain( - index_file_loc, fl_file_loc, dep_file_loc, - )) + file_locations = ( + Link(url) + for url in itertools.chain(index_file_loc, fl_file_loc, dep_file_loc) + ) # We trust every url that the user has given us whether it was given # via --index-url or --find-links # We explicitly do not trust links that came from dependency_links # We want to filter out any thing which does not have a secure origin. url_locations = [ - link for link in itertools.chain( + link + for link in itertools.chain( (Link(url) for url in index_url_loc), (Link(url) for url in fl_url_loc), (Link(url) for url in dep_url_loc), @@ -432,8 +443,11 @@ def find_all_candidates(self, project_name): if self._validate_secure_origin(logger, link) ] - logger.debug('%d location(s) to search for versions of %s:', - len(url_locations), project_name) + logger.debug( + '%d location(s) to search for versions of %s:', + len(url_locations), + project_name, + ) for location in url_locations: logger.debug('* %s', location) @@ -444,16 +458,14 @@ def find_all_candidates(self, project_name): find_links_versions = self._package_versions( # We trust every directly linked archive in find_links (Link(url, '-f') for url in self.find_links), - search + search, ) page_versions = [] for page in self._get_pages(url_locations, project_name): logger.debug('Analyzing links from page %s', page.url) with indent_log(): - page_versions.extend( - self._package_versions(page.links, search) - ) + page_versions.extend(self._package_versions(page.links, search)) dependency_versions = self._package_versions( (Link(url) for url in self.dependency_links), search @@ -461,9 +473,7 @@ def find_all_candidates(self, project_name): if dependency_versions: logger.debug( 'dependency_links found: %s', - ', '.join([ - version.location.url for version in dependency_versions - ]) + ', '.join([version.location.url for version in dependency_versions]), ) file_versions = self._package_versions(file_locations, search) @@ -471,17 +481,13 @@ def find_all_candidates(self, project_name): file_versions.sort(reverse=True) logger.debug( 'Local files found: %s', - ', '.join([ - url_to_path(candidate.location.url) - for candidate in file_versions - ]) + ', '.join( + [url_to_path(candidate.location.url) for candidate in file_versions] + ), ) # This is an intentional priority ordering - return ( - file_versions + find_links_versions + page_versions + - dependency_versions - ) + return file_versions + find_links_versions + page_versions + dependency_versions def find_requirement(self, req, upgrade): """Try to find a Link matching req @@ -504,19 +510,19 @@ def find_requirement(self, req, upgrade): # and start using our own, we can drop the cast to str(). [str(c.version) for c in all_candidates], prereleases=( - self.allow_all_prereleases - if self.allow_all_prereleases else None + self.allow_all_prereleases if self.allow_all_prereleases else None ), ) ) applicable_candidates = [ # Again, converting to str to deal with debundling. - c for c in all_candidates if str(c.version) in compatible_versions + c + for c in all_candidates + if str(c.version) in compatible_versions ] if applicable_candidates: - best_candidate = max(applicable_candidates, - key=self._candidate_sort_key) + best_candidate = max(applicable_candidates, key=self._candidate_sort_key) else: best_candidate = None @@ -531,21 +537,16 @@ def find_requirement(self, req, upgrade): '(from versions: %s)', req, ', '.join( - sorted( - {str(c.version) for c in all_candidates}, - key=parse_version, - ) - ) + sorted({str(c.version) for c in all_candidates}, key=parse_version) + ), ) - raise DistributionNotFound( - 'No matching distribution found for %s' % req - ) + raise DistributionNotFound('No matching distribution found for %s' % req) best_installed = False if installed_version and ( - best_candidate is None or - best_candidate.version <= installed_version): + best_candidate is None or best_candidate.version <= installed_version + ): best_installed = True if not upgrade and installed_version is not None: @@ -567,18 +568,16 @@ def find_requirement(self, req, upgrade): if best_installed: # We have an existing version, and its the best version logger.debug( - 'Installed version (%s) is most up-to-date (past versions: ' - '%s)', + 'Installed version (%s) is most up-to-date (past versions: ' '%s)', installed_version, - ', '.join(sorted(compatible_versions, key=parse_version)) or - "none", + ', '.join(sorted(compatible_versions, key=parse_version)) or "none", ) raise BestVersionAlreadyInstalled logger.debug( 'Using version %s (newest of versions: %s)', best_candidate.version, - ', '.join(sorted(compatible_versions, key=parse_version)) + ', '.join(sorted(compatible_versions, key=parse_version)), ) return best_candidate.location @@ -642,13 +641,11 @@ def _link_package_versions(self, link, search): self._log_skipped_link(link, 'not a file') return if ext not in SUPPORTED_EXTENSIONS: - self._log_skipped_link( - link, 'unsupported archive format: %s' % ext, - ) + self._log_skipped_link(link, 'unsupported archive format: %s' % ext) return if "binary" not in search.formats and ext == wheel_ext: self._log_skipped_link( - link, 'No binaries permitted for %s' % search.supplied, + link, 'No binaries permitted for %s' % search.supplied ) return if "macosx10" in link.path and ext == '.zip': @@ -662,12 +659,14 @@ def _link_package_versions(self, link, search): return if canonicalize_name(wheel.name) != search.canonical: self._log_skipped_link( - link, 'wrong project name (not %s)' % search.supplied) + link, 'wrong project name (not %s)' % search.supplied + ) return if not wheel.supported(self.valid_tags): self._log_skipped_link( - link, 'it is not compatible with this Python') + link, 'it is not compatible with this Python' + ) return version = wheel.version @@ -675,7 +674,7 @@ def _link_package_versions(self, link, search): # This should be up by the search.ok_binary check, but see issue 2700. if "source" not in search.formats and ext != wheel_ext: self._log_skipped_link( - link, 'No sources permitted for %s' % search.supplied, + link, 'No sources permitted for %s' % search.supplied ) return @@ -683,28 +682,34 @@ def _link_package_versions(self, link, search): version = egg_info_matches(egg_info, search.supplied, link) if version is None: self._log_skipped_link( - link, 'Missing project version for %s' % search.supplied) + link, 'Missing project version for %s' % search.supplied + ) return match = self._py_version_re.search(version) if match: - version = version[:match.start()] + version = version[: match.start()] py_version = match.group(1) if py_version != sys.version[:3]: - self._log_skipped_link( - link, 'Python version is incorrect') + self._log_skipped_link(link, 'Python version is incorrect') return try: support_this_python = check_requires_python(link.requires_python) except specifiers.InvalidSpecifier: - logger.debug("Package %s has an invalid Requires-Python entry: %s", - link.filename, link.requires_python) + logger.debug( + "Package %s has an invalid Requires-Python entry: %s", + link.filename, + link.requires_python, + ) support_this_python = True if not support_this_python: - logger.debug("The package %s is incompatible with the python" - "version in use. Acceptable python versions are:%s", - link, link.requires_python) + logger.debug( + "The package %s is incompatible with the python" + "version in use. Acceptable python versions are:%s", + link, + link.requires_python, + ) return logger.debug('Found link %s, version: %s', link, version) @@ -715,8 +720,11 @@ def _get_page(self, link): def egg_info_matches( - egg_info, search_name, link, - _egg_info_re=re.compile(r'([a-z0-9_.]+)-([a-z0-9_.!+-]+)', re.I)): + egg_info, + search_name, + link, + _egg_info_re=re.compile(r'([a-z0-9_.]+)-([a-z0-9_.!+-]+)', re.I), +): """Pull the version part out of a string. :param egg_info: The string to parse. E.g. foo-2.1 @@ -731,14 +739,14 @@ def egg_info_matches( return None if search_name is None: full_match = match.group(0) - return full_match[full_match.index('-'):] + return full_match[full_match.index('-') :] name = match.group(0).lower() # To match the "safe" name that pkg_resources creates: name = name.replace('_', '-') # project name and version must be separated by a dash look_for = search_name.lower() + "-" if name.startswith(look_for): - return match.group(0)[len(look_for):] + return match.group(0)[len(look_for) :] else: return None @@ -757,9 +765,7 @@ def __init__(self, content, url, headers=None): self.content = content self.parsed = html5lib.parse( - self.content, - transport_encoding=encoding, - namespaceHTMLElements=False, + self.content, transport_encoding=encoding, namespaceHTMLElements=False ) self.url = url self.headers = headers @@ -770,15 +776,14 @@ def __str__(self): @classmethod def get_page(cls, link, skip_archives=True, session=None): if session is None: - raise TypeError( - "get_page() missing 1 required keyword argument: 'session'" - ) + raise TypeError("get_page() missing 1 required keyword argument: 'session'") url = link.url url = url.split('#', 1)[0] # Check for VCS schemes that do not support lookup as web pages. from pip._internal.vcs import VcsSupport + for scheme in VcsSupport.schemes: if url.lower().startswith(scheme) and url[len(scheme)] in '+:': logger.debug('Cannot look at %s URL %s', scheme, link) @@ -789,9 +794,7 @@ def get_page(cls, link, skip_archives=True, session=None): filename = link.filename for bad_ext in ARCHIVE_EXTENSIONS: if filename.endswith(bad_ext): - content_type = cls._get_content_type( - url, session=session, - ) + content_type = cls._get_content_type(url, session=session) if content_type.lower().startswith('text/html'): break else: @@ -805,10 +808,8 @@ def get_page(cls, link, skip_archives=True, session=None): logger.debug('Getting page %s', url) # Tack index.html onto file:// URLs that point to directories - (scheme, netloc, path, params, query, fragment) = \ - urllib_parse.urlparse(url) - if (scheme == 'file' and - os.path.isdir(urllib_request.url2pathname(path))): + (scheme, netloc, path, params, query, fragment) = urllib_parse.urlparse(url) + if scheme == 'file' and os.path.isdir(urllib_request.url2pathname(path)): # add trailing slash if not present so urljoin doesn't trim # final segment if not url.endswith('/'): @@ -817,11 +818,7 @@ def get_page(cls, link, skip_archives=True, session=None): logger.debug(' file: URL is directory, getting %s', url) resp = session.get( - url, - headers={ - "Accept": "text/html", - "Cache-Control": "max-age=600", - }, + url, headers={"Accept": "text/html", "Cache-Control": "max-age=600"} ) resp.raise_for_status() @@ -833,9 +830,7 @@ def get_page(cls, link, skip_archives=True, session=None): content_type = resp.headers.get('Content-Type', 'unknown') if not content_type.lower().startswith("text/html"): logger.debug( - 'Skipping page %s because of Content-Type: %s', - link, - content_type, + 'Skipping page %s because of Content-Type: %s', link, content_type ) return @@ -876,10 +871,7 @@ def _get_content_type(url, session): @cached_property def base_url(self): - bases = [ - x for x in self.parsed.findall(".//base") - if x.get("href") is not None - ] + bases = [x for x in self.parsed.findall(".//base") if x.get("href") is not None] if bases and bases[0].get("href"): return bases[0].get("href") else: @@ -891,9 +883,7 @@ def links(self): for anchor in self.parsed.findall(".//a"): if anchor.get("href"): href = anchor.get("href") - url = self.clean_link( - urllib_parse.urljoin(self.base_url, href) - ) + url = self.clean_link(urllib_parse.urljoin(self.base_url, href)) pyrequire = anchor.get('data-requires-python') pyrequire = unescape(pyrequire) if pyrequire else None yield Link(url, self, requires_python=pyrequire) @@ -904,12 +894,10 @@ def clean_link(self, url): """Makes sure a link is fully encoded. That is, if a ' ' shows up in the link, it will be rewritten to %20 (while not over-quoting % or other characters).""" - return self._clean_re.sub( - lambda match: '%%%2x' % ord(match.group(0)), url) + return self._clean_re.sub(lambda match: '%%%2x' % ord(match.group(0)), url) class Link(object): - def __init__(self, url, comes_from=None, requires_python=None): """ Object representing a parsed link from https://pypi.org/simple/* @@ -983,7 +971,7 @@ def filename(self): _, netloc, path, _, _ = urllib_parse.urlsplit(self.url) name = posixpath.basename(path.rstrip('/')) or netloc name = urllib_parse.unquote(name) - assert name, ('URL %r produced no filename' % self.url) + assert name, 'URL %r produced no filename' % self.url return name @property @@ -1028,9 +1016,7 @@ def subdirectory_fragment(self): return None return match.group(1) - _hash_re = re.compile( - r'(sha1|sha224|sha384|sha256|sha512|md5)=([a-f0-9]+)' - ) + _hash_re = re.compile(r'(sha1|sha224|sha384|sha256|sha512|md5)=([a-f0-9]+)') @property def hash(self): @@ -1084,7 +1070,7 @@ def fmt_ctl_handle_mutual_exclude(value, target, other): other.clear() target.clear() target.add(':all:') - del new[:new.index(':all:') + 1] + del new[: new.index(':all:') + 1] if ':none:' not in new: # Without a none, we want to discard everything as :all: covers it return @@ -1111,9 +1097,7 @@ def fmt_ctl_formats(fmt_ctl, canonical_name): def fmt_ctl_no_binary(fmt_ctl): - fmt_ctl_handle_mutual_exclude( - ':all:', fmt_ctl.no_binary, fmt_ctl.only_binary, - ) + fmt_ctl_handle_mutual_exclude(':all:', fmt_ctl.no_binary, fmt_ctl.only_binary) Search = namedtuple('Search', 'supplied canonical formats') diff --git a/src/pip/_internal/locations.py b/src/pip/_internal/locations.py index 5a20c92a8ee..93936a26c12 100644 --- a/src/pip/_internal/locations.py +++ b/src/pip/_internal/locations.py @@ -69,9 +69,7 @@ def virtualenv_no_global(): src_prefix = os.path.join(os.getcwd(), 'src') except OSError: # In case the current working directory has been renamed or deleted - sys.exit( - "The folder you are executing pip from can no longer be found." - ) + sys.exit("The folder you are executing pip from can no longer be found.") # under macOS + virtualenv sys.prefix is not properly resolved # it is something like /path/to/python/bin/.. @@ -104,10 +102,7 @@ def virtualenv_no_global(): config_basename = 'pip.ini' legacy_storage_dir = os.path.join(user_dir, 'pip') - legacy_config_file = os.path.join( - legacy_storage_dir, - config_basename, - ) + legacy_config_file = os.path.join(legacy_storage_dir, config_basename) else: bin_py = os.path.join(sys.prefix, 'bin') bin_user = os.path.join(user_site, 'bin') @@ -115,26 +110,23 @@ def virtualenv_no_global(): config_basename = 'pip.conf' legacy_storage_dir = os.path.join(user_dir, '.pip') - legacy_config_file = os.path.join( - legacy_storage_dir, - config_basename, - ) + legacy_config_file = os.path.join(legacy_storage_dir, config_basename) # Forcing to use /usr/local/bin for standard macOS framework installs # Also log to ~/Library/Logs/ for use with the Console.app log viewer if sys.platform[:6] == 'darwin' and sys.prefix[:16] == '/System/Library/': bin_py = '/usr/local/bin' site_config_files = [ - os.path.join(path, config_basename) - for path in appdirs.site_config_dirs('pip') + os.path.join(path, config_basename) for path in appdirs.site_config_dirs('pip') ] venv_config_file = os.path.join(sys.prefix, config_basename) new_config_file = os.path.join(appdirs.user_config_dir("pip"), config_basename) -def distutils_scheme(dist_name, user=False, home=None, root=None, - isolated=False, prefix=None): +def distutils_scheme( + dist_name, user=False, home=None, root=None, isolated=False, prefix=None +): """ Return a distutils install scheme """ @@ -176,19 +168,11 @@ def distutils_scheme(dist_name, user=False, home=None, root=None, if running_under_virtualenv(): scheme['headers'] = os.path.join( - sys.prefix, - 'include', - 'site', - 'python' + sys.version[:3], - dist_name, + sys.prefix, 'include', 'site', 'python' + sys.version[:3], dist_name ) if root is not None: - path_no_drive = os.path.splitdrive( - os.path.abspath(scheme["headers"]))[1] - scheme["headers"] = os.path.join( - root, - path_no_drive[1:], - ) + path_no_drive = os.path.splitdrive(os.path.abspath(scheme["headers"]))[1] + scheme["headers"] = os.path.join(root, path_no_drive[1:]) return scheme diff --git a/src/pip/_internal/operations/freeze.py b/src/pip/_internal/operations/freeze.py index b6821c0e7ef..948e2f0cbb5 100644 --- a/src/pip/_internal/operations/freeze.py +++ b/src/pip/_internal/operations/freeze.py @@ -14,20 +14,22 @@ from pip._internal.req import InstallRequirement from pip._internal.req.req_file import COMMENT_RE from pip._internal.utils.deprecation import RemovedInPip11Warning -from pip._internal.utils.misc import ( - dist_is_editable, get_installed_distributions, -) +from pip._internal.utils.misc import dist_is_editable, get_installed_distributions logger = logging.getLogger(__name__) def freeze( - requirement=None, - find_links=None, local_only=None, user_only=None, skip_regex=None, - isolated=False, - wheel_cache=None, - exclude_editable=False, - skip=()): + requirement=None, + find_links=None, + local_only=None, + user_only=None, + skip_regex=None, + isolated=False, + wheel_cache=None, + exclude_editable=False, + skip=(), +): find_links = find_links or [] skip_match = None @@ -38,28 +40,20 @@ def freeze( for dist in pkg_resources.working_set: if dist.has_metadata('dependency_links.txt'): - dependency_links.extend( - dist.get_metadata_lines('dependency_links.txt') - ) + dependency_links.extend(dist.get_metadata_lines('dependency_links.txt')) for link in find_links: if '#egg=' in link: dependency_links.append(link) for link in find_links: yield '-f %s' % link installations = {} - for dist in get_installed_distributions(local_only=local_only, - skip=(), - user_only=user_only): + for dist in get_installed_distributions( + local_only=local_only, skip=(), user_only=user_only + ): try: - req = FrozenRequirement.from_dist( - dist, - dependency_links - ) + req = FrozenRequirement.from_dist(dist, dependency_links) except RequirementParseError: - logger.warning( - "Could not parse requirement: %s", - dist.project_name - ) + logger.warning("Could not parse requirement: %s", dist.project_name) continue if exclude_editable and req.editable: continue @@ -77,18 +71,27 @@ def freeze( for req_file_path in requirement: with open(req_file_path) as req_file: for line in req_file: - if (not line.strip() or - line.strip().startswith('#') or - (skip_match and skip_match(line)) or - line.startswith(( - '-r', '--requirement', - '-Z', '--always-unzip', - '-f', '--find-links', - '-i', '--index-url', + if ( + not line.strip() + or line.strip().startswith('#') + or (skip_match and skip_match(line)) + or line.startswith( + ( + '-r', + '--requirement', + '-Z', + '--always-unzip', + '-f', + '--find-links', + '-i', + '--index-url', '--pre', '--trusted-host', '--process-dependency-links', - '--extra-index-url'))): + '--extra-index-url', + ) + ) + ): line = line.rstrip() if line not in emitted_options: emitted_options.add(line) @@ -99,11 +102,9 @@ def freeze( if line.startswith('-e'): line = line[2:].strip() else: - line = line[len('--editable'):].strip().lstrip('=') + line = line[len('--editable') :].strip().lstrip('=') line_req = InstallRequirement.from_editable( - line, - isolated=isolated, - wheel_cache=wheel_cache, + line, isolated=isolated, wheel_cache=wheel_cache ) else: line_req = InstallRequirement.from_line( @@ -116,7 +117,8 @@ def freeze( logger.info( "Skipping line in requirement file [%s] because " "it's not clear what it would install: %s", - req_file_path, line.strip(), + req_file_path, + line.strip(), ) logger.info( " (add #egg=PackageName to the URL to avoid" @@ -143,15 +145,14 @@ def freeze( # single requirements file or in different requirements files). for name, files in six.iteritems(req_files): if len(files) > 1: - logger.warning("Requirement %s included multiple times [%s]", - name, ', '.join(sorted(set(files)))) - - yield( - '## The following requirements were added by ' - 'pip freeze:' - ) - for installation in sorted( - installations.values(), key=lambda x: x.name.lower()): + logger.warning( + "Requirement %s included multiple times [%s]", + name, + ', '.join(sorted(set(files))), + ) + + yield ('## The following requirements were added by ' 'pip freeze:') + for installation in sorted(installations.values(), key=lambda x: x.name.lower()): if canonicalize_name(installation.name) not in skip: yield str(installation).rstrip() @@ -171,6 +172,7 @@ def from_dist(cls, dist, dependency_links): location = os.path.normcase(os.path.abspath(dist.location)) comments = [] from pip._internal.vcs import vcs, get_src_requirement + if dist_is_editable(dist) and vcs.get_backend_name(location): editable = True try: @@ -178,39 +180,34 @@ def from_dist(cls, dist, dependency_links): except InstallationError as exc: logger.warning( "Error when trying to get requirement for VCS system %s, " - "falling back to uneditable format", exc + "falling back to uneditable format", + exc, ) req = None if req is None: logger.warning( 'Could not determine repository location of %s', location ) - comments.append( - '## !! Could not determine repository location' - ) + comments.append('## !! Could not determine repository location') req = dist.as_requirement() editable = False else: editable = False req = dist.as_requirement() specs = req.specs - assert len(specs) == 1 and specs[0][0] in ["==", "==="], \ - 'Expected 1 spec with == or ===; specs = %r; dist = %r' % \ - (specs, dist) + assert len(specs) == 1 and specs[0][0] in [ + "==", + "===", + ], 'Expected 1 spec with == or ===; specs = %r; dist = %r' % (specs, dist) version = specs[0][1] ver_match = cls._rev_re.search(version) date_match = cls._date_re.search(version) if ver_match or date_match: svn_backend = vcs.get_backend('svn') if svn_backend: - svn_location = svn_backend().get_location( - dist, - dependency_links, - ) + svn_location = svn_backend().get_location(dist, dependency_links) if not svn_location: - logger.warning( - 'Warning: cannot find svn location for %s', req, - ) + logger.warning('Warning: cannot find svn location for %s', req) comments.append( '## FIXME: could not find svn URL in dependency_links ' 'for this package:' @@ -222,19 +219,14 @@ def from_dist(cls, dist, dependency_links): RemovedInPip11Warning, ) comments.append( - '# Installing as editable to satisfy requirement %s:' % - req + '# Installing as editable to satisfy requirement %s:' % req ) if ver_match: rev = ver_match.group(1) else: rev = '{%s}' % date_match.group(1) editable = True - req = '%s@%s#egg=%s' % ( - svn_location, - rev, - cls.egg_name(dist) - ) + req = '%s@%s#egg=%s' % (svn_location, rev, cls.egg_name(dist)) return cls(dist.project_name, req, editable, comments) @staticmethod @@ -242,7 +234,7 @@ def egg_name(dist): name = dist.egg_name() match = re.search(r'-py\d\.\d$', name) if match: - name = name[:match.start()] + name = name[: match.start()] return name def __str__(self): diff --git a/src/pip/_internal/operations/prepare.py b/src/pip/_internal/operations/prepare.py index ff9b1e6a1df..62ca2fec753 100644 --- a/src/pip/_internal/operations/prepare.py +++ b/src/pip/_internal/operations/prepare.py @@ -9,11 +9,18 @@ from pip._internal.build_env import BuildEnvironment from pip._internal.compat import expanduser from pip._internal.download import ( - is_dir_url, is_file_url, is_vcs_url, unpack_url, url_to_path, + is_dir_url, + is_file_url, + is_vcs_url, + unpack_url, + url_to_path, ) from pip._internal.exceptions import ( - DirectoryUrlHashUnsupported, HashUnpinned, InstallationError, - PreviousBuildDirError, VcsHashUnsupported, + DirectoryUrlHashUnsupported, + HashUnpinned, + InstallationError, + PreviousBuildDirError, + VcsHashUnsupported, ) from pip._internal.utils.hashes import MissingHashes from pip._internal.utils.logging import indent_log @@ -71,10 +78,8 @@ def prep_for_dist(self, finder): class IsWheel(DistAbstraction): - def dist(self, finder): - return list(pkg_resources.find_distributions( - self.req.source_dir))[0] + return list(pkg_resources.find_distributions(self.req.source_dir))[0] def prep_for_dist(self, finder, build_isolation): # FIXME:https://github.com/pypa/pip/issues/1112 @@ -82,14 +87,11 @@ def prep_for_dist(self, finder, build_isolation): class IsSDist(DistAbstraction): - def dist(self, finder): dist = self.req.get_dist() # FIXME: shouldn't be globally added. if finder and dist.has_metadata('dependency_links.txt'): - finder.add_dependency_links( - dist.get_metadata_lines('dependency_links.txt') - ) + finder.add_dependency_links(dist.get_metadata_lines('dependency_links.txt')) return dist def prep_for_dist(self, finder, build_isolation): @@ -100,33 +102,35 @@ def prep_for_dist(self, finder, build_isolation): minimum_requirements = ('setuptools', 'wheel') missing_requirements = set(minimum_requirements) - set( - pkg_resources.Requirement(r).key - for r in build_requirements + pkg_resources.Requirement(r).key for r in build_requirements ) if missing_requirements: + def format_reqs(rs): return ' and '.join(map(repr, sorted(rs))) + logger.warning( - "Missing build time requirements in pyproject.toml for %s: " - "%s.", self.req, format_reqs(missing_requirements) + "Missing build time requirements in pyproject.toml for %s: " "%s.", + self.req, + format_reqs(missing_requirements), ) logger.warning( "This version of pip does not implement PEP 517 so it cannot " - "build a wheel without %s.", format_reqs(minimum_requirements) + "build a wheel without %s.", + format_reqs(minimum_requirements), ) if should_isolate: self.req.build_env = BuildEnvironment() self.req.build_env.install_requirements( - finder, build_requirements, - "Installing build dependencies") + finder, build_requirements, "Installing build dependencies" + ) self.req.run_egg_info() self.req.assert_source_matches_version() class Installed(DistAbstraction): - def dist(self, finder): return self.req.satisfied_by @@ -138,8 +142,15 @@ class RequirementPreparer(object): """Prepares a Requirement """ - def __init__(self, build_dir, download_dir, src_dir, wheel_download_dir, - progress_bar, build_isolation): + def __init__( + self, + build_dir, + download_dir, + src_dir, + wheel_download_dir, + progress_bar, + build_isolation, + ): super(RequirementPreparer, self).__init__() self.src_dir = src_dir @@ -177,11 +188,13 @@ def _download_should_save(self): logger.critical('Could not find download directory') raise InstallationError( "Could not find or access download directory '%s'" - % display_path(self.download_dir)) + % display_path(self.download_dir) + ) return False - def prepare_linked_requirement(self, req, session, finder, - upgrade_allowed, require_hashes): + def prepare_linked_requirement( + self, req, session, finder, upgrade_allowed, require_hashes + ): """Prepare a requirement that would be obtained from req.link """ # TODO: Breakup into smaller functions @@ -274,21 +287,21 @@ def prepare_linked_requirement(self, req, session, finder, # wheel. autodelete_unpacked = False unpack_url( - req.link, req.source_dir, - download_dir, autodelete_unpacked, - session=session, hashes=hashes, - progress_bar=self.progress_bar + req.link, + req.source_dir, + download_dir, + autodelete_unpacked, + session=session, + hashes=hashes, + progress_bar=self.progress_bar, ) except requests.HTTPError as exc: logger.critical( - 'Could not install requirement %s because of error %s', - req, - exc, + 'Could not install requirement %s because of error %s', req, exc ) raise InstallationError( 'Could not install requirement %s because of HTTP ' - 'error %s for URL %s' % - (req, exc, req.link) + 'error %s for URL %s' % (req, exc, req.link) ) abstract_dist = make_abstract_dist(req) abstract_dist.prep_for_dist(finder, self.build_isolation) @@ -298,8 +311,7 @@ def prepare_linked_requirement(self, req, session, finder, req.archive(self.download_dir) return abstract_dist - def prepare_editable_requirement(self, req, require_hashes, use_user_site, - finder): + def prepare_editable_requirement(self, req, require_hashes, use_user_site, finder): """Prepare an editable requirement """ assert req.editable, "cannot prepare a non-editable req as editable" @@ -334,8 +346,7 @@ def prepare_installed_requirement(self, req, require_hashes, skip_reason): "is set to %r" % (req.satisfied_by,) ) logger.info( - 'Requirement %s: %s (%s)', - skip_reason, req, req.satisfied_by.version + 'Requirement %s: %s (%s)', skip_reason, req, req.satisfied_by.version ) with indent_log(): if require_hashes: diff --git a/src/pip/_internal/pep425tags.py b/src/pip/_internal/pep425tags.py index 0b5c7832d4f..03f15dd3e63 100644 --- a/src/pip/_internal/pep425tags.py +++ b/src/pip/_internal/pep425tags.py @@ -51,8 +51,11 @@ def get_impl_version_info(): version.""" if get_abbr_impl() == 'pp': # as per https://github.com/pypa/pip/issues/2882 - return (sys.version_info[0], sys.pypy_version_info.major, - sys.pypy_version_info.minor) + return ( + sys.version_info[0], + sys.pypy_version_info.major, + sys.pypy_version_info.minor, + ) else: return sys.version_info[0], sys.version_info[1] @@ -70,8 +73,9 @@ def get_flag(var, fallback, expected=True, warn=True): val = get_config_var(var) if val is None: if warn: - logger.debug("Config variable '%s' is unset, Python ABI tag may " - "be incorrect", var) + logger.debug( + "Config variable '%s' is unset, Python ABI tag may " "be incorrect", var + ) return fallback() return val == expected @@ -85,20 +89,18 @@ def get_abi_tag(): d = '' m = '' u = '' - if get_flag('Py_DEBUG', - lambda: hasattr(sys, 'gettotalrefcount'), - warn=(impl == 'cp')): + if get_flag( + 'Py_DEBUG', lambda: hasattr(sys, 'gettotalrefcount'), warn=(impl == 'cp') + ): d = 'd' - if get_flag('WITH_PYMALLOC', - lambda: impl == 'cp', - warn=(impl == 'cp')): + if get_flag('WITH_PYMALLOC', lambda: impl == 'cp', warn=(impl == 'cp')): m = 'm' - if get_flag('Py_UNICODE_SIZE', - lambda: sys.maxunicode == 0x10ffff, - expected=4, - warn=(impl == 'cp' and - sys.version_info < (3, 3))) \ - and sys.version_info < (3, 3): + if get_flag( + 'Py_UNICODE_SIZE', + lambda: sys.maxunicode == 0x10ffff, + expected=4, + warn=(impl == 'cp' and sys.version_info < (3, 3)), + ) and sys.version_info < (3, 3): u = 'u' abi = '%s%s%s%s%s' % (impl, get_impl_ver(), d, m, u) elif soabi and soabi.startswith('cpython-'): @@ -148,6 +150,7 @@ def is_manylinux1_compatible(): # Check for presence of _manylinux module try: import _manylinux + return bool(_manylinux.manylinux1_compatible) except (ImportError, AttributeError): # Fall through to heuristic check below @@ -199,12 +202,14 @@ def _supports_arch(major, minor, arch): return True return False - groups = OrderedDict([ - ("fat", ("i386", "ppc")), - ("intel", ("x86_64", "i386")), - ("fat64", ("x86_64", "ppc64")), - ("fat32", ("x86_64", "i386", "ppc")), - ]) + groups = OrderedDict( + [ + ("fat", ("i386", "ppc")), + ("intel", ("x86_64", "i386")), + ("fat64", ("x86_64", "ppc64")), + ("fat32", ("x86_64", "i386", "ppc")), + ] + ) if _supports_arch(major, minor, machine): arches.append(machine) @@ -218,8 +223,7 @@ def _supports_arch(major, minor, arch): return arches -def get_supported(versions=None, noarch=False, platform=None, - impl=None, abi=None): +def get_supported(versions=None, noarch=False, platform=None, impl=None, abi=None): """Return a list of supported tags for each version specified in `versions`. @@ -253,6 +257,7 @@ def get_supported(versions=None, noarch=False, platform=None, abi3s = set() import imp + for suffix in imp.get_suffixes(): if suffix[0].startswith('.abi'): abi3s.add(suffix[0].split('.', 2)[1]) @@ -291,7 +296,7 @@ def get_supported(versions=None, noarch=False, platform=None, # abi3 was introduced in Python 3.2 if version in {'31', '30'}: break - for abi in abi3s: # empty set if not Python 3 + for abi in abi3s: # empty set if not Python 3 for arch in arches: supported.append(("%s%s" % (impl, version), abi, arch)) diff --git a/src/pip/_internal/req/__init__.py b/src/pip/_internal/req/__init__.py index c9b4c3ce39f..f5b9ff5dc1a 100644 --- a/src/pip/_internal/req/__init__.py +++ b/src/pip/_internal/req/__init__.py @@ -9,15 +9,16 @@ __all__ = [ - "RequirementSet", "InstallRequirement", - "parse_requirements", "install_given_reqs", + "RequirementSet", + "InstallRequirement", + "parse_requirements", + "install_given_reqs", ] logger = logging.getLogger(__name__) -def install_given_reqs(to_install, install_options, global_options=(), - *args, **kwargs): +def install_given_reqs(to_install, install_options, global_options=(), *args, **kwargs): """ Install everything in the given list. @@ -34,24 +35,15 @@ def install_given_reqs(to_install, install_options, global_options=(), for requirement in to_install: if requirement.conflicts_with: logger.info( - 'Found existing installation: %s', - requirement.conflicts_with, + 'Found existing installation: %s', requirement.conflicts_with ) with indent_log(): - uninstalled_pathset = requirement.uninstall( - auto_confirm=True - ) + uninstalled_pathset = requirement.uninstall(auto_confirm=True) try: - requirement.install( - install_options, - global_options, - *args, - **kwargs - ) + requirement.install(install_options, global_options, *args, **kwargs) except: should_rollback = ( - requirement.conflicts_with and - not requirement.install_succeeded + requirement.conflicts_with and not requirement.install_succeeded ) # if install did not succeed, rollback previous uninstall if should_rollback: @@ -59,8 +51,7 @@ def install_given_reqs(to_install, install_options, global_options=(), raise else: should_commit = ( - requirement.conflicts_with and - requirement.install_succeeded + requirement.conflicts_with and requirement.install_succeeded ) if should_commit: uninstalled_pathset.commit() diff --git a/src/pip/_internal/req/req_file.py b/src/pip/_internal/req/req_file.py index f8684979602..591f6b6fc45 100644 --- a/src/pip/_internal/req/req_file.py +++ b/src/pip/_internal/req/req_file.py @@ -57,8 +57,15 @@ SUPPORTED_OPTIONS_REQ_DEST = [o().dest for o in SUPPORTED_OPTIONS_REQ] -def parse_requirements(filename, finder=None, comes_from=None, options=None, - session=None, constraint=False, wheel_cache=None): +def parse_requirements( + filename, + finder=None, + comes_from=None, + options=None, + session=None, + constraint=False, + wheel_cache=None, +): """Parse a requirements file and yield InstallRequirement instances. :param filename: Path or url of requirements file. @@ -72,20 +79,25 @@ def parse_requirements(filename, finder=None, comes_from=None, options=None, """ if session is None: raise TypeError( - "parse_requirements() missing 1 required keyword argument: " - "'session'" + "parse_requirements() missing 1 required keyword argument: " "'session'" ) - _, content = get_file_content( - filename, comes_from=comes_from, session=session - ) + _, content = get_file_content(filename, comes_from=comes_from, session=session) lines_enum = preprocess(content, options) for line_number, line in lines_enum: - req_iter = process_line(line, filename, line_number, finder, - comes_from, options, session, wheel_cache, - constraint=constraint) + req_iter = process_line( + line, + filename, + line_number, + finder, + comes_from, + options, + session, + wheel_cache, + constraint=constraint, + ) for req in req_iter: yield req @@ -104,9 +116,17 @@ def preprocess(content, options): return lines_enum -def process_line(line, filename, line_number, finder=None, comes_from=None, - options=None, session=None, wheel_cache=None, - constraint=False): +def process_line( + line, + filename, + line_number, + finder=None, + comes_from=None, + options=None, + session=None, + wheel_cache=None, + constraint=False, +): """Process a single requirements line; This can result in creating/yielding requirements, or updating the finder. @@ -138,7 +158,9 @@ def process_line(line, filename, line_number, finder=None, comes_from=None, # preserve for the nested code path line_comes_from = '%s %s (line %s)' % ( - '-c' if constraint else '-r', filename, line_number, + '-c' if constraint else '-r', + filename, + line_number, ) # yield a line requirement @@ -152,16 +174,23 @@ def process_line(line, filename, line_number, finder=None, comes_from=None, if dest in opts.__dict__ and opts.__dict__[dest]: req_options[dest] = opts.__dict__[dest] yield InstallRequirement.from_line( - args_str, line_comes_from, constraint=constraint, - isolated=isolated, options=req_options, wheel_cache=wheel_cache + args_str, + line_comes_from, + constraint=constraint, + isolated=isolated, + options=req_options, + wheel_cache=wheel_cache, ) # yield an editable requirement elif opts.editables: isolated = options.isolated_mode if options else False yield InstallRequirement.from_editable( - opts.editables[0], comes_from=line_comes_from, - constraint=constraint, isolated=isolated, wheel_cache=wheel_cache + opts.editables[0], + comes_from=line_comes_from, + constraint=constraint, + isolated=isolated, + wheel_cache=wheel_cache, ) # parse a nested requirements file @@ -182,8 +211,13 @@ def process_line(line, filename, line_number, finder=None, comes_from=None, req_path = os.path.join(os.path.dirname(filename), req_path) # TODO: Why not use `comes_from='-r {} (line {})'` here as well? parser = parse_requirements( - req_path, finder, comes_from, options, session, - constraint=nested_constraint, wheel_cache=wheel_cache + req_path, + finder, + comes_from, + options, + session, + constraint=nested_constraint, + wheel_cache=wheel_cache, ) for req in parser: yield req @@ -216,7 +250,8 @@ def process_line(line, filename, line_number, finder=None, comes_from=None, finder.process_dependency_links = True if opts.trusted_hosts: finder.secure_origins.extend( - ("*", host, "*") for host in opts.trusted_hosts) + ("*", host, "*") for host in opts.trusted_hosts + ) def break_args_options(line): @@ -253,6 +288,7 @@ def parser_exit(self, msg): # add offending line msg = 'Invalid requirement: %s\n%s' % (line, msg) raise RequirementsFileParseError(msg) + parser.exit = parser_exit return parser diff --git a/src/pip/_internal/req/req_install.py b/src/pip/_internal/req/req_install.py index f3515e40ce2..2a94413ac96 100644 --- a/src/pip/_internal/req/req_install.py +++ b/src/pip/_internal/req/req_install.py @@ -24,21 +24,26 @@ from pip._internal import wheel from pip._internal.build_env import NoOpBuildEnvironment from pip._internal.compat import native_str -from pip._internal.download import ( - is_archive_file, is_url, path_to_url, url_to_path, -) +from pip._internal.download import is_archive_file, is_url, path_to_url, url_to_path from pip._internal.exceptions import InstallationError, UninstallationError -from pip._internal.locations import ( - PIP_DELETE_MARKER_FILENAME, running_under_virtualenv, -) +from pip._internal.locations import PIP_DELETE_MARKER_FILENAME, running_under_virtualenv from pip._internal.req.req_uninstall import UninstallPathSet from pip._internal.utils.deprecation import RemovedInPip11Warning from pip._internal.utils.hashes import Hashes from pip._internal.utils.logging import indent_log from pip._internal.utils.misc import ( - _make_build_dir, ask_path_exists, backup_dir, call_subprocess, - display_path, dist_in_site_packages, dist_in_usersite, ensure_dir, - get_installed_version, is_installable_dir, read_text_file, rmtree, + _make_build_dir, + ask_path_exists, + backup_dir, + call_subprocess, + display_path, + dist_in_site_packages, + dist_in_usersite, + ensure_dir, + get_installed_version, + is_installable_dir, + read_text_file, + rmtree, ) from pip._internal.utils.setuptools_build import SETUPTOOLS_SHIM from pip._internal.utils.temp_dir import TempDirectory @@ -70,10 +75,21 @@ class InstallRequirement(object): installing the said requirement. """ - def __init__(self, req, comes_from, source_dir=None, editable=False, - link=None, update=True, markers=None, - isolated=False, options=None, wheel_cache=None, - constraint=False, extras=()): + def __init__( + self, + req, + comes_from, + source_dir=None, + editable=False, + link=None, + update=True, + markers=None, + isolated=False, + options=None, + wheel_cache=None, + constraint=False, + extras=(), + ): assert req is None or isinstance(req, Requirement), req self.req = req self.comes_from = comes_from @@ -89,14 +105,13 @@ def __init__(self, req, comes_from, source_dir=None, editable=False, self.link = self.original_link = link else: from pip._internal.index import Link + self.link = self.original_link = req and req.url and Link(req.url) if extras: self.extras = extras elif req: - self.extras = { - pkg_resources.safe_extra(extra) for extra in req.extras - } + self.extras = {pkg_resources.safe_extra(extra) for extra in req.extras} else: self.extras = set() if markers is not None: @@ -130,8 +145,15 @@ def __init__(self, req, comes_from, source_dir=None, editable=False, self.build_env = NoOpBuildEnvironment() @classmethod - def from_editable(cls, editable_req, comes_from=None, isolated=False, - options=None, wheel_cache=None, constraint=False): + def from_editable( + cls, + editable_req, + comes_from=None, + isolated=False, + options=None, + wheel_cache=None, + constraint=False, + ): from pip._internal.index import Link name, url, extras_override = parse_editable(editable_req) @@ -148,7 +170,9 @@ def from_editable(cls, editable_req, comes_from=None, isolated=False, else: req = None return cls( - req, comes_from, source_dir=source_dir, + req, + comes_from, + source_dir=source_dir, editable=True, link=Link(url), constraint=constraint, @@ -173,8 +197,14 @@ def from_req(cls, req, comes_from=None, isolated=False, wheel_cache=None): @classmethod def from_line( - cls, name, comes_from=None, isolated=False, options=None, - wheel_cache=None, constraint=False): + cls, + name, + comes_from=None, + isolated=False, + options=None, + wheel_cache=None, + constraint=False, + ): """Creates an InstallRequirement from a name, which might be a requirement, directory containing 'setup.py', filename, or URL. """ @@ -204,9 +234,9 @@ def from_line( else: p, extras = _strip_extras(path) looks_like_dir = os.path.isdir(p) and ( - os.path.sep in name or - (os.path.altsep is not None and os.path.altsep in name) or - name.startswith('.') + os.path.sep in name + or (os.path.altsep is not None and os.path.altsep in name) + or name.startswith('.') ) if looks_like_dir: if not is_installable_dir(p): @@ -220,7 +250,7 @@ def from_line( logger.warning( 'Requirement %r looks like a filename, but the ' 'file does not exist', - name + name, ) link = Link(path_to_url(p)) @@ -228,8 +258,7 @@ def from_line( if link: # Handle relative file URLs if link.scheme == 'file' and re.search(r'\.\./', link.url): - link = Link( - path_to_url(os.path.normpath(os.path.abspath(link.path)))) + link = Link(path_to_url(os.path.normpath(os.path.abspath(link.path)))) # wheel file if link.is_wheel: wheel = Wheel(link.filename) # can raise InvalidWheelFilename @@ -259,9 +288,13 @@ def from_line( else: add_msg = traceback.format_exc() raise InstallationError( - "Invalid requirement: '%s'\n%s" % (req, add_msg)) + "Invalid requirement: '%s'\n%s" % (req, add_msg) + ) return cls( - req, comes_from, link=link, markers=markers, + req, + comes_from, + link=link, + markers=markers, isolated=isolated, options=options if options else {}, wheel_cache=wheel_cache, @@ -289,7 +322,10 @@ def __str__(self): def __repr__(self): return '<%s object: %s editable=%r>' % ( - self.__class__.__name__, str(self), self.editable) + self.__class__.__name__, + str(self), + self.editable, + ) def populate_link(self, finder, upgrade, require_hashes): """Ensure that if a link can be found for this, that it is found. @@ -322,8 +358,7 @@ def is_pinned(self): For example, some-package==1.2 is pinned; some-package>1.2 is not. """ specifiers = self.specifier - return (len(specifiers) == 1 and - next(iter(specifiers)).operator in {'==', '==='}) + return len(specifiers) == 1 and next(iter(specifiers)).operator in {'==', '==='} def from_path(self): if self.req is None: @@ -387,10 +422,13 @@ def _correct_build_location(self): if os.path.exists(new_location): raise InstallationError( 'A package already exists in %s; please remove it to continue' - % display_path(new_location)) + % display_path(new_location) + ) logger.debug( 'Moving package %s from %s to new location %s', - self, display_path(old_location), display_path(new_location), + self, + display_path(old_location), + display_path(new_location), ) shutil.move(old_location, new_location) self._temp_build_dir.path = new_location @@ -407,8 +445,8 @@ def name(self): @property def setup_py_dir(self): return os.path.join( - self.source_dir, - self.link and self.link.subdirectory_fragment or '') + self.source_dir, self.link and self.link.subdirectory_fragment or '' + ) @property def setup_py(self): @@ -455,12 +493,14 @@ def run_egg_info(self): if self.name: logger.debug( 'Running setup.py (path:%s) egg_info for package %s', - self.setup_py, self.name, + self.setup_py, + self.name, ) else: logger.debug( 'Running setup.py (path:%s) egg_info for package from %s', - self.setup_py, self.link, + self.setup_py, + self.link, ) with indent_log(): @@ -483,7 +523,8 @@ def run_egg_info(self): egg_info_cmd + egg_base_option, cwd=self.setup_py_dir, show_stdout=False, - command_desc='python setup.py egg_info') + command_desc='python setup.py egg_info', + ) if not self.req: if isinstance(parse_version(self.pkg_info()["Version"]), Version): @@ -491,11 +532,7 @@ def run_egg_info(self): else: op = "===" self.req = Requirement( - "".join([ - self.pkg_info()["Name"], - op, - self.pkg_info()["Version"], - ]) + "".join([self.pkg_info()["Name"], op, self.pkg_info()["Version"]]) ) self._correct_build_location() else: @@ -505,7 +542,10 @@ def run_egg_info(self): 'Running setup.py (path:%s) egg_info for package %s ' 'produced metadata for project name %s. Fix your ' '#egg=%s fragments.', - self.setup_py, self.name, metadata_name, self.name + self.setup_py, + self.name, + metadata_name, + self.name, ) self.req = Requirement(metadata_name) @@ -540,37 +580,31 @@ def egg_info_path(self, filename): for dir in list(dirs): # Don't search in anything that looks like a virtualenv # environment - if ( - os.path.lexists( - os.path.join(root, dir, 'bin', 'python') - ) or - os.path.exists( - os.path.join( - root, dir, 'Scripts', 'Python.exe' - ) - )): + if os.path.lexists( + os.path.join(root, dir, 'bin', 'python') + ) or os.path.exists( + os.path.join(root, dir, 'Scripts', 'Python.exe') + ): dirs.remove(dir) # Also don't search through tests elif dir == 'test' or dir == 'tests': dirs.remove(dir) - filenames.extend([os.path.join(root, dir) - for dir in dirs]) + filenames.extend([os.path.join(root, dir) for dir in dirs]) filenames = [f for f in filenames if f.endswith('.egg-info')] if not filenames: raise InstallationError( 'No files/directories in %s (from %s)' % (base, filename) ) - assert filenames, \ - "No files/directories in %s (from %s)" % (base, filename) + assert filenames, "No files/directories in %s (from %s)" % (base, filename) # if we have more than one match, we pick the toplevel one. This # can easily be the case if there is a dist folder which contains # an extracted tarball for testing purposes. if len(filenames) > 1: filenames.sort( - key=lambda x: x.count(os.path.sep) + - (os.path.altsep and x.count(os.path.altsep) or 0) + key=lambda x: x.count(os.path.sep) + + (os.path.altsep and x.count(os.path.altsep) or 0) ) self._egg_info_path = os.path.join(base, filenames[0]) return os.path.join(self._egg_info_path, filename) @@ -596,11 +630,7 @@ def assert_source_matches_version(self): assert self.source_dir version = self.pkg_info()['version'] if self.req.specifier and version not in self.req.specifier: - logger.warning( - 'Requested %s, but installing version %s', - self, - version, - ) + logger.warning('Requested %s, but installing version %s', self, version) else: logger.debug( 'Source in %s has version %s, which satisfies requirement %s', @@ -612,8 +642,7 @@ def assert_source_matches_version(self): def update_editable(self, obtain=True): if not self.link: logger.debug( - "Cannot update repository at %s; repository location is " - "unknown", + "Cannot update repository at %s; repository location is " "unknown", self.source_dir, ) return @@ -634,12 +663,12 @@ def update_editable(self, obtain=True): else: vcs_backend.export(self.source_dir) else: - assert 0, ( - 'Unexpected version control type (in %s): %s' - % (self.link, vc_type)) + assert 0, 'Unexpected version control type (in %s): %s' % ( + self.link, + vc_type, + ) - def uninstall(self, auto_confirm=False, verbose=False, - use_user_site=False): + def uninstall(self, auto_confirm=False, verbose=False, use_user_site=False): """ Uninstall the distribution currently satisfying this requirement. @@ -668,8 +697,10 @@ def archive(self, build_dir): archive_path = os.path.join(build_dir, archive_name) if os.path.exists(archive_path): response = ask_path_exists( - 'The file %s exists. (i)gnore, (w)ipe, (b)ackup, (a)bort ' % - display_path(archive_path), ('i', 'w', 'b', 'a')) + 'The file %s exists. (i)gnore, (w)ipe, (b)ackup, (a)bort ' + % display_path(archive_path), + ('i', 'w', 'b', 'a'), + ) if response == 'i': create_archive = False elif response == 'w': @@ -687,8 +718,7 @@ def archive(self, build_dir): sys.exit(-1) if create_archive: zip = zipfile.ZipFile( - archive_path, 'w', zipfile.ZIP_DEFLATED, - allowZip64=True + archive_path, 'w', zipfile.ZIP_DEFLATED, allowZip64=True ) dir = os.path.normcase(os.path.abspath(self.setup_py_dir)) for dirpath, dirnames, filenames in os.walk(dir): @@ -710,10 +740,10 @@ def archive(self, build_dir): logger.info('Saved %s', display_path(archive_path)) def _clean_zip_name(self, name, prefix): - assert name.startswith(prefix + os.path.sep), ( - "name %r doesn't start with prefix %r" % (name, prefix) - ) - name = name[len(prefix) + 1:] + assert name.startswith( + prefix + os.path.sep + ), "name %r doesn't start with prefix %r" % (name, prefix) + name = name[len(prefix) + 1 :] name = name.replace(os.path.sep, '/') return name @@ -724,28 +754,38 @@ def match_markers(self, extras_requested=None): extras_requested = ('',) if self.markers is not None: return any( - self.markers.evaluate({'extra': extra}) - for extra in extras_requested) + self.markers.evaluate({'extra': extra}) for extra in extras_requested + ) else: return True - def install(self, install_options, global_options=None, root=None, - home=None, prefix=None, warn_script_location=True, - use_user_site=False, pycompile=True): + def install( + self, + install_options, + global_options=None, + root=None, + home=None, + prefix=None, + warn_script_location=True, + use_user_site=False, + pycompile=True, + ): global_options = global_options if global_options is not None else [] if self.editable: - self.install_editable( - install_options, global_options, prefix=prefix, - ) + self.install_editable(install_options, global_options, prefix=prefix) return if self.is_wheel: version = wheel.wheel_version(self.source_dir) wheel.check_compatibility(version, self.name) self.move_wheel_files( - self.source_dir, root=root, prefix=prefix, home=home, + self.source_dir, + root=root, + prefix=prefix, + home=home, warn_script_location=warn_script_location, - use_user_site=use_user_site, pycompile=pycompile, + use_user_site=use_user_site, + pycompile=pycompile, ) self.install_succeeded = True return @@ -755,10 +795,10 @@ def install(self, install_options, global_options=None, root=None, # Options specified in requirements file override those # specified on the command line, since the last option given # to setup.py is the one that is used. - global_options = list(global_options) + \ - self.options.get('global_options', []) - install_options = list(install_options) + \ - self.options.get('install_options', []) + global_options = list(global_options) + self.options.get('global_options', []) + install_options = list(install_options) + self.options.get( + 'install_options', [] + ) if self.isolated: global_options = global_options + ["--no-user-cfg"] @@ -766,7 +806,7 @@ def install(self, install_options, global_options=None, root=None, with TempDirectory(kind="record") as temp_dir: record_filename = os.path.join(temp_dir.path, 'install-record.txt') install_args = self.get_install_args( - global_options, record_filename, root, prefix, pycompile, + global_options, record_filename, root, prefix, pycompile ) msg = 'Running setup.py install for %s' % (self.name,) with open_spinner(msg) as spinner: @@ -834,13 +874,13 @@ def ensure_has_source_dir(self, parent_dir): self.source_dir = self.build_location(parent_dir) return self.source_dir - def get_install_args(self, global_options, record_filename, root, prefix, - pycompile): + def get_install_args( + self, global_options, record_filename, root, prefix, pycompile + ): install_args = [sys.executable, "-u"] install_args.append('-c') install_args.append(SETUPTOOLS_SHIM % self.setup_py) - install_args += list(global_options) + \ - ['install', '--record', record_filename] + install_args += list(global_options) + ['install', '--record', record_filename] install_args += ['--single-version-externally-managed'] if root is not None: @@ -855,9 +895,10 @@ def get_install_args(self, global_options, record_filename, root, prefix, if running_under_virtualenv(): py_ver_str = 'python' + sysconfig.get_python_version() - install_args += ['--install-headers', - os.path.join(sys.prefix, 'include', 'site', - py_ver_str, self.name)] + install_args += [ + '--install-headers', + os.path.join(sys.prefix, 'include', 'site', py_ver_str, self.name), + ] return install_args @@ -865,15 +906,15 @@ def remove_temporary_source(self): """Remove the source files from this requirement, if they are marked for deletion""" if self.source_dir and os.path.exists( - os.path.join(self.source_dir, PIP_DELETE_MARKER_FILENAME)): + os.path.join(self.source_dir, PIP_DELETE_MARKER_FILENAME) + ): logger.debug('Removing source in %s', self.source_dir) rmtree(self.source_dir) self.source_dir = None self._temp_build_dir.cleanup() self.build_env.cleanup() - def install_editable(self, install_options, - global_options=(), prefix=None): + def install_editable(self, install_options, global_options=(), prefix=None): logger.info('Running setup.py develop for %s', self.name) if self.isolated: @@ -887,15 +928,10 @@ def install_editable(self, install_options, # FIXME: should we do --install-headers here too? with self.build_env: call_subprocess( - [ - sys.executable, - '-c', - SETUPTOOLS_SHIM % self.setup_py - ] + - list(global_options) + - ['develop', '--no-deps'] + - list(install_options), - + [sys.executable, '-c', SETUPTOOLS_SHIM % self.setup_py] + + list(global_options) + + ['develop', '--no-deps'] + + list(install_options), cwd=self.setup_py_dir, show_stdout=False, ) @@ -926,18 +962,17 @@ def check_if_exists(self, use_user_site): except pkg_resources.DistributionNotFound: return False except pkg_resources.VersionConflict: - existing_dist = pkg_resources.get_distribution( - self.req.name - ) + existing_dist = pkg_resources.get_distribution(self.req.name) if use_user_site: if dist_in_usersite(existing_dist): self.conflicts_with = existing_dist - elif (running_under_virtualenv() and - dist_in_site_packages(existing_dist)): + elif running_under_virtualenv() and dist_in_site_packages( + existing_dist + ): raise InstallationError( "Will not install to the user site because it will " - "lack sys.path precedence to %s in %s" % - (existing_dist.project_name, existing_dist.location) + "lack sys.path precedence to %s in %s" + % (existing_dist.project_name, existing_dist.location) ) else: self.conflicts_with = existing_dist @@ -947,11 +982,20 @@ def check_if_exists(self, use_user_site): def is_wheel(self): return self.link and self.link.is_wheel - def move_wheel_files(self, wheeldir, root=None, home=None, prefix=None, - warn_script_location=True, use_user_site=False, - pycompile=True): + def move_wheel_files( + self, + wheeldir, + root=None, + home=None, + prefix=None, + warn_script_location=True, + use_user_site=False, + pycompile=True, + ): move_wheel_files( - self.name, self.req, wheeldir, + self.name, + self.req, + wheeldir, user=use_user_site, home=home, root=root, @@ -968,9 +1012,7 @@ def get_dist(self): metadata = pkg_resources.PathMetadata(base_dir, egg_info) dist_name = os.path.splitext(os.path.basename(egg_info))[0] return pkg_resources.Distribution( - os.path.dirname(egg_info), - project_name=dist_name, - metadata=metadata, + os.path.dirname(egg_info), project_name=dist_name, metadata=metadata ) @property @@ -1042,8 +1084,8 @@ def parse_editable(editable_req): if os.path.isdir(url_no_extras): if not os.path.exists(os.path.join(url_no_extras, 'setup.py')): raise InstallationError( - "Directory %r is not installable. File 'setup.py' not found." % - url_no_extras + "Directory %r is not installable. File 'setup.py' not found." + % url_no_extras ) # Treating it as code that has already been checked out url_no_extras = path_to_url(url_no_extras) @@ -1067,16 +1109,17 @@ def parse_editable(editable_req): if '+' not in url: raise InstallationError( '%s should either be a path to a local project or a VCS url ' - 'beginning with svn+, git+, hg+, or bzr+' % - editable_req + 'beginning with svn+, git+, hg+, or bzr+' % editable_req ) vc_type = url.split('+', 1)[0].lower() if not vcs.get_backend(vc_type): - error_message = 'For --editable=%s only ' % editable_req + \ - ', '.join([backend.name + '+URL' for backend in vcs.backends]) + \ - ' is currently supported' + error_message = ( + 'For --editable=%s only ' % editable_req + + ', '.join([backend.name + '+URL' for backend in vcs.backends]) + + ' is currently supported' + ) raise InstallationError(error_message) package_name = Link(url).egg_fragment @@ -1102,14 +1145,20 @@ def deduce_helpful_msg(req): with open(req, 'r') as fp: # parse first line only next(parse_requirements(fp.read())) - msg += " The argument you provided " + \ - "(%s) appears to be a" % (req) + \ - " requirements file. If that is the" + \ - " case, use the '-r' flag to install" + \ - " the packages specified within it." + msg += ( + " The argument you provided " + + "(%s) appears to be a" % (req) + + " requirements file. If that is the" + + " case, use the '-r' flag to install" + + " the packages specified within it." + ) except RequirementParseError: - logger.debug("Cannot parse '%s' as requirements \ - file" % (req), exc_info=1) + logger.debug( + "Cannot parse '%s' as requirements \ + file" + % (req), + exc_info=1, + ) else: msg += " File '%s' does not exist." % (req) return msg diff --git a/src/pip/_internal/req/req_set.py b/src/pip/_internal/req/req_set.py index 2bc6b745138..57678b212e7 100644 --- a/src/pip/_internal/req/req_set.py +++ b/src/pip/_internal/req/req_set.py @@ -11,7 +11,6 @@ class RequirementSet(object): - def __init__(self, require_hashes=False): """Create a RequirementSet. """ @@ -26,8 +25,7 @@ def __init__(self, require_hashes=False): self.reqs_to_cleanup = [] def __str__(self): - reqs = [req for req in self.requirements.values() - if not req.comes_from] + reqs = [req for req in self.requirements.values() if not req.comes_from] reqs.sort(key=lambda req: req.name.lower()) return ' '.join([str(req.req) for req in reqs]) @@ -35,11 +33,13 @@ def __repr__(self): reqs = [req for req in self.requirements.values()] reqs.sort(key=lambda req: req.name.lower()) reqs_str = ', '.join([str(req.req) for req in reqs]) - return ('<%s object; %d requirement(s): %s>' - % (self.__class__.__name__, len(reqs), reqs_str)) + return '<%s object; %d requirement(s): %s>' % ( + self.__class__.__name__, + len(reqs), + reqs_str, + ) - def add_requirement(self, install_req, parent_req_name=None, - extras_requested=None): + def add_requirement(self, install_req, parent_req_name=None, extras_requested=None): """Add install_req as a requirement to install. :param parent_req_name: The name of the requirement that needed this @@ -56,9 +56,11 @@ def add_requirement(self, install_req, parent_req_name=None, """ name = install_req.name if not install_req.match_markers(extras_requested): - logger.info("Ignoring %s: markers '%s' don't match your " - "environment", install_req.name, - install_req.markers) + logger.info( + "Ignoring %s: markers '%s' don't match your " "environment", + install_req.name, + install_req.markers, + ) return [], None # This check has to come after we filter requirements with the @@ -67,8 +69,7 @@ def add_requirement(self, install_req, parent_req_name=None, wheel = Wheel(install_req.link.filename) if not wheel.supported(): raise InstallationError( - "%s is not a supported wheel on this platform." % - wheel.filename + "%s is not a supported wheel on this platform." % wheel.filename ) # This next bit is really a sanity check. @@ -86,13 +87,17 @@ def add_requirement(self, install_req, parent_req_name=None, existing_req = self.get_requirement(name) except KeyError: existing_req = None - if (parent_req_name is None and existing_req and not - existing_req.constraint and - existing_req.extras == install_req.extras and not - existing_req.req.specifier == install_req.req.specifier): + if ( + parent_req_name is None + and existing_req + and not existing_req.constraint + and existing_req.extras == install_req.extras + and not existing_req.req.specifier == install_req.req.specifier + ): raise InstallationError( 'Double requirement given: %s (already in %s, name=%r)' - % (install_req, existing_req, name)) + % (install_req, existing_req, name) + ) if not existing_req: # Add requirement self.requirements[name] = install_req @@ -105,22 +110,25 @@ def add_requirement(self, install_req, parent_req_name=None, # encountered this for scanning. result = [] if not install_req.constraint and existing_req.constraint: - if (install_req.link and not (existing_req.link and - install_req.link.path == existing_req.link.path)): + if install_req.link and not ( + existing_req.link + and install_req.link.path == existing_req.link.path + ): self.reqs_to_cleanup.append(install_req) raise InstallationError( "Could not satisfy constraints for '%s': " "installation from path or url cannot be " - "constrained to a version" % name, + "constrained to a version" % name ) # If we're now installing a constraint, mark the existing # object for real installation. existing_req.constraint = False existing_req.extras = tuple( - sorted(set(existing_req.extras).union( - set(install_req.extras)))) - logger.debug("Setting %s extras to: %s", - existing_req, existing_req.extras) + sorted(set(existing_req.extras).union(set(install_req.extras))) + ) + logger.debug( + "Setting %s extras to: %s", existing_req, existing_req.extras + ) # And now we need to scan this. result = [existing_req] # Canonicalise to the already-added object for the backref @@ -133,17 +141,21 @@ def add_requirement(self, install_req, parent_req_name=None, def has_requirement(self, project_name): name = project_name.lower() - if (name in self.requirements and - not self.requirements[name].constraint or - name in self.requirement_aliases and - not self.requirements[self.requirement_aliases[name]].constraint): + if ( + name in self.requirements + and not self.requirements[name].constraint + or name in self.requirement_aliases + and not self.requirements[self.requirement_aliases[name]].constraint + ): return True return False @property def has_requirements(self): - return list(req for req in self.requirements.values() if not - req.constraint) or self.unnamed_requirements + return ( + list(req for req in self.requirements.values() if not req.constraint) + or self.unnamed_requirements + ) def get_requirement(self, project_name): for name in project_name, project_name.lower(): diff --git a/src/pip/_internal/req/req_uninstall.py b/src/pip/_internal/req/req_uninstall.py index a3cc7bf66b5..cf39fe429e6 100644 --- a/src/pip/_internal/req/req_uninstall.py +++ b/src/pip/_internal/req/req_uninstall.py @@ -14,8 +14,14 @@ from pip._internal.locations import bin_py, bin_user from pip._internal.utils.logging import indent_log from pip._internal.utils.misc import ( - FakeFile, ask, dist_in_usersite, dist_is_local, egg_link_path, is_local, - normalize_path, renames, + FakeFile, + ask, + dist_in_usersite, + dist_is_local, + egg_link_path, + is_local, + normalize_path, + renames, ) from pip._internal.utils.temp_dir import TempDirectory @@ -51,6 +57,7 @@ def unique(*args, **kw): if item not in seen: seen.add(item) yield item + return unique @@ -85,8 +92,8 @@ def compact(paths): short_paths = set() for path in sorted(paths, key=len): should_add = any( - path.startswith(shortpath.rstrip("*")) and - path[len(shortpath.rstrip("*").rstrip(sep))] == sep + path.startswith(shortpath.rstrip("*")) + and path[len(shortpath.rstrip("*").rstrip(sep))] == sep for shortpath in short_paths ) if not should_add: @@ -133,9 +140,7 @@ def compress_for_output_listing(paths): # We are skipping this file. Add it to the set. will_skip.add(file_) - will_remove = files | { - os.path.join(folder, "*") for folder in folders - } + will_remove = files | {os.path.join(folder, "*") for folder in folders} return will_remove, will_skip @@ -143,6 +148,7 @@ def compress_for_output_listing(paths): class UninstallPathSet(object): """A set of file paths to be removed in the uninstallation of a requirement.""" + def __init__(self, dist): self.paths = set() self._refuse = set() @@ -203,9 +209,7 @@ def remove(self, auto_confirm=False, verbose=False): ) return - dist_name_version = ( - self.dist.project_name + "-" + self.dist.version - ) + dist_name_version = self.dist.project_name + "-" + self.dist.version logger.info('Uninstalling %s:', dist_name_version) with indent_log(): @@ -253,8 +257,7 @@ def rollback(self): """Rollback the changes previously made by remove().""" if self.save_dir.path is None: logger.error( - "Can't roll back %s; was not uninstalled", - self.dist.project_name, + "Can't roll back %s; was not uninstalled", self.dist.project_name ) return False logger.info('Rolling back uninstall of %s', self.dist.project_name) @@ -282,9 +285,11 @@ def from_dist(cls, dist): ) return cls(dist) - if dist_path in {p for p in {sysconfig.get_path("stdlib"), - sysconfig.get_path("platstdlib")} - if p}: + if dist_path in { + p + for p in {sysconfig.get_path("stdlib"), sysconfig.get_path("platstdlib")} + if p + }: logger.info( "Not uninstalling %s at %s, as it is in the standard library.", dist.key, @@ -295,24 +300,27 @@ def from_dist(cls, dist): paths_to_remove = cls(dist) develop_egg_link = egg_link_path(dist) develop_egg_link_egg_info = '{}.egg-info'.format( - pkg_resources.to_filename(dist.project_name)) + pkg_resources.to_filename(dist.project_name) + ) egg_info_exists = dist.egg_info and os.path.exists(dist.egg_info) # Special case for distutils installed package distutils_egg_info = getattr(dist._provider, 'path', None) # Uninstall cases order do matter as in the case of 2 installs of the # same package, pip needs to uninstall the currently detected version - if (egg_info_exists and dist.egg_info.endswith('.egg-info') and - not dist.egg_info.endswith(develop_egg_link_egg_info)): + if ( + egg_info_exists + and dist.egg_info.endswith('.egg-info') + and not dist.egg_info.endswith(develop_egg_link_egg_info) + ): # if dist.egg_info.endswith(develop_egg_link_egg_info), we # are in fact in the develop_egg_link case paths_to_remove.add(dist.egg_info) if dist.has_metadata('installed-files.txt'): for installed_file in dist.get_metadata( - 'installed-files.txt').splitlines(): - path = os.path.normpath( - os.path.join(dist.egg_info, installed_file) - ) + 'installed-files.txt' + ).splitlines(): + path = os.path.normpath(os.path.join(dist.egg_info, installed_file)) paths_to_remove.add(path) # FIXME: need a test for this elif block # occurs with --single-version-externally-managed/--record outside @@ -323,9 +331,10 @@ def from_dist(cls, dist): else: namespaces = [] for top_level_pkg in [ - p for p - in dist.get_metadata('top_level.txt').splitlines() - if p and p not in namespaces]: + p + for p in dist.get_metadata('top_level.txt').splitlines() + if p and p not in namespaces + ]: path = os.path.join(dist.location, top_level_pkg) paths_to_remove.add(path) paths_to_remove.add(path + '.py') @@ -337,7 +346,7 @@ def from_dist(cls, dist): "Cannot uninstall {!r}. It is a distutils installed project " "and thus we cannot accurately determine which files belong " "to it which would lead to only a partial uninstall.".format( - dist.project_name, + dist.project_name ) ) @@ -347,8 +356,9 @@ def from_dist(cls, dist): # i.e. setuptools-0.6c11-py2.6.egg vs setuptools-0.6rc11-py2.6.egg paths_to_remove.add(dist.location) easy_install_egg = os.path.split(dist.location)[1] - easy_install_pth = os.path.join(os.path.dirname(dist.location), - 'easy-install.pth') + easy_install_pth = os.path.join( + os.path.dirname(dist.location), 'easy-install.pth' + ) paths_to_remove.add_pth(easy_install_pth, './' + easy_install_egg) elif egg_info_exists and dist.egg_info.endswith('.dist-info'): @@ -359,19 +369,19 @@ def from_dist(cls, dist): # develop egg with open(develop_egg_link, 'r') as fh: link_pointer = os.path.normcase(fh.readline().strip()) - assert (link_pointer == dist.location), ( + assert link_pointer == dist.location, ( 'Egg-link %s does not match installed location of %s ' '(at %s)' % (link_pointer, dist.project_name, dist.location) ) paths_to_remove.add(develop_egg_link) - easy_install_pth = os.path.join(os.path.dirname(develop_egg_link), - 'easy-install.pth') + easy_install_pth = os.path.join( + os.path.dirname(develop_egg_link), 'easy-install.pth' + ) paths_to_remove.add_pth(easy_install_pth, dist.location) else: logger.debug( - 'Not sure how to uninstall: %s - Check: %s', - dist, dist.location, + 'Not sure how to uninstall: %s - Check: %s', dist, dist.location ) # find distutils scripts= scripts @@ -445,9 +455,7 @@ def remove(self): def rollback(self): if self._saved_lines is None: - logger.error( - 'Cannot roll back changes to %s, none were made', self.file - ) + logger.error('Cannot roll back changes to %s, none were made', self.file) return False logger.debug('Rolling %s back to previous state', self.file) with open(self.file, 'wb') as fh: diff --git a/src/pip/_internal/resolve.py b/src/pip/_internal/resolve.py index 3200fca8ad7..f1954b3d1f9 100644 --- a/src/pip/_internal/resolve.py +++ b/src/pip/_internal/resolve.py @@ -15,7 +15,10 @@ from itertools import chain from pip._internal.exceptions import ( - BestVersionAlreadyInstalled, DistributionNotFound, HashError, HashErrors, + BestVersionAlreadyInstalled, + DistributionNotFound, + HashError, + HashErrors, UnsupportedPythonVersion, ) @@ -34,9 +37,20 @@ class Resolver(object): _allowed_strategies = {"eager", "only-if-needed", "to-satisfy-only"} - def __init__(self, preparer, session, finder, wheel_cache, use_user_site, - ignore_dependencies, ignore_installed, ignore_requires_python, - force_reinstall, isolated, upgrade_strategy): + def __init__( + self, + preparer, + session, + finder, + wheel_cache, + use_user_site, + ignore_dependencies, + ignore_installed, + ignore_requires_python, + force_reinstall, + isolated, + upgrade_strategy, + ): super(Resolver, self).__init__() assert upgrade_strategy in self._allowed_strategies @@ -77,13 +91,11 @@ def resolve(self, requirement_set): # If any top-level requirement has a hash specified, enter # hash-checking mode, which requires hashes from all. - root_reqs = ( - requirement_set.unnamed_requirements + - list(requirement_set.requirements.values()) + root_reqs = requirement_set.unnamed_requirements + list( + requirement_set.requirements.values() ) - self.require_hashes = ( - requirement_set.require_hashes or - any(req.has_hash_options for req in root_reqs) + self.require_hashes = requirement_set.require_hashes or any( + req.has_hash_options for req in root_reqs ) # Display where finder is looking for packages @@ -99,9 +111,7 @@ def resolve(self, requirement_set): hash_errors = HashErrors() for req in chain(root_reqs, discovered_reqs): try: - discovered_reqs.extend( - self._resolve_one(requirement_set, req) - ) + discovered_reqs.extend(self._resolve_one(requirement_set, req)) except HashError as exc: exc.req = req hash_errors.append(exc) @@ -185,13 +195,13 @@ def _get_abstract_dist_for(self, req): """Takes a InstallRequirement and returns a single AbstractDist \ representing a prepared variant of the same. """ - assert self.require_hashes is not None, ( - "require_hashes should have been set in Resolver.resolve()" - ) + assert ( + self.require_hashes is not None + ), "require_hashes should have been set in Resolver.resolve()" if req.editable: return self.preparer.prepare_editable_requirement( - req, self.require_hashes, self.use_user_site, self.finder, + req, self.require_hashes, self.use_user_site, self.finder ) # satisfied_by is only evaluated by calling _check_skip_installed, @@ -206,8 +216,7 @@ def _get_abstract_dist_for(self, req): upgrade_allowed = self._is_upgrade_allowed(req) abstract_dist = self.preparer.prepare_linked_requirement( - req, self.session, self.finder, upgrade_allowed, - self.require_hashes + req, self.session, self.finder, upgrade_allowed, self.require_hashes ) # NOTE @@ -223,17 +232,17 @@ def _get_abstract_dist_for(self, req): if req.satisfied_by: should_modify = ( - self.upgrade_strategy != "to-satisfy-only" or - self.force_reinstall or - self.ignore_installed or - req.link.scheme == 'file' + self.upgrade_strategy != "to-satisfy-only" + or self.force_reinstall + or self.ignore_installed + or req.link.scheme == 'file' ) if should_modify: self._set_req_to_reinstall(req) else: logger.info( - 'Requirement already satisfied (use --upgrade to upgrade):' - ' %s', req, + 'Requirement already satisfied (use --upgrade to upgrade):' ' %s', + req, ) return abstract_dist @@ -282,9 +291,7 @@ def add_req(subreq, extras_requested): extras_requested=extras_requested, ) if parent_req_name and add_to_parent: - self._discovered_dependencies[parent_req_name].append( - add_to_parent - ) + self._discovered_dependencies[parent_req_name].append(add_to_parent) more_reqs.extend(to_scan_again) with indent_log(): @@ -293,9 +300,7 @@ def add_req(subreq, extras_requested): if not requirement_set.has_requirement(req_to_install.name): # 'unnamed' requirements will get added here req_to_install.is_direct = True - requirement_set.add_requirement( - req_to_install, parent_req_name=None, - ) + requirement_set.add_requirement(req_to_install, parent_req_name=None) if not self.ignore_dependencies: if req_to_install.extras: @@ -308,8 +313,7 @@ def add_req(subreq, extras_requested): ) for missing in missing_requested: logger.warning( - '%s does not provide the extra \'%s\'', - dist, missing + '%s does not provide the extra \'%s\'', dist, missing ) available_requested = sorted( diff --git a/src/pip/_internal/utils/appdirs.py b/src/pip/_internal/utils/appdirs.py index 28c5d4b3c75..637d0c75c56 100644 --- a/src/pip/_internal/utils/appdirs.py +++ b/src/pip/_internal/utils/appdirs.py @@ -92,21 +92,16 @@ def user_data_dir(appname, roaming=False): const = roaming and "CSIDL_APPDATA" or "CSIDL_LOCAL_APPDATA" path = os.path.join(os.path.normpath(_get_win_folder(const)), appname) elif sys.platform == "darwin": - path = os.path.join( - expanduser('~/Library/Application Support/'), - appname, - ) if os.path.isdir(os.path.join( - expanduser('~/Library/Application Support/'), - appname, - ) - ) else os.path.join( - expanduser('~/.config/'), - appname, + path = ( + os.path.join(expanduser('~/Library/Application Support/'), appname) + if os.path.isdir( + os.path.join(expanduser('~/Library/Application Support/'), appname) + ) + else os.path.join(expanduser('~/.config/'), appname) ) else: path = os.path.join( - os.getenv('XDG_DATA_HOME', expanduser("~/.local/share")), - appname, + os.getenv('XDG_DATA_HOME', expanduser("~/.local/share")), appname ) return path @@ -185,6 +180,7 @@ def site_config_dirs(appname): # -- Windows support functions -- + def _get_win_folder_from_registry(csidl_name): """ This is a fallback technique at best. I'm not sure if using the @@ -201,7 +197,7 @@ def _get_win_folder_from_registry(csidl_name): key = _winreg.OpenKey( _winreg.HKEY_CURRENT_USER, - r"Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders" + r"Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders", ) directory, _type = _winreg.QueryValueEx(key, shell_folder_name) return directory @@ -235,6 +231,7 @@ def _get_win_folder_with_ctypes(csidl_name): if WINDOWS: try: import ctypes + _get_win_folder = _get_win_folder_with_ctypes except ImportError: _get_win_folder = _get_win_folder_from_registry diff --git a/src/pip/_internal/utils/deprecation.py b/src/pip/_internal/utils/deprecation.py index a9071729be5..c1a7b5cfeeb 100644 --- a/src/pip/_internal/utils/deprecation.py +++ b/src/pip/_internal/utils/deprecation.py @@ -37,9 +37,7 @@ class RemovedInPip12Warning(PipDeprecationWarning, Pending): def _showwarning(message, category, filename, lineno, file=None, line=None): if file is not None: if _warnings_showwarning is not None: - _warnings_showwarning( - message, category, filename, lineno, file, line, - ) + _warnings_showwarning(message, category, filename, lineno, file, line) else: if issubclass(category, PipDeprecationWarning): # We use a specially named logger which will handle all of the @@ -61,9 +59,7 @@ def _showwarning(message, category, filename, lineno, file=None, line=None): else: logger.error(log_message) else: - _warnings_showwarning( - message, category, filename, lineno, file, line, - ) + _warnings_showwarning(message, category, filename, lineno, file, line) def install_warning_logger(): diff --git a/src/pip/_internal/utils/encoding.py b/src/pip/_internal/utils/encoding.py index 56f60361138..5dd13b95e92 100644 --- a/src/pip/_internal/utils/encoding.py +++ b/src/pip/_internal/utils/encoding.py @@ -22,12 +22,10 @@ def auto_decode(data): Fallback to locale.getpreferredencoding(False) like open() on Python3""" for bom, encoding in BOMS: if data.startswith(bom): - return data[len(bom):].decode(encoding) + return data[len(bom) :].decode(encoding) # Lets check the first two lines as in PEP263 for line in data.split(b'\n')[:2]: if line[0:1] == b'#' and ENCODING_RE.search(line): encoding = ENCODING_RE.search(line).groups()[0].decode('ascii') return data.decode(encoding) - return data.decode( - locale.getpreferredencoding(False) or sys.getdefaultencoding(), - ) + return data.decode(locale.getpreferredencoding(False) or sys.getdefaultencoding()) diff --git a/src/pip/_internal/utils/glibc.py b/src/pip/_internal/utils/glibc.py index ebcfc5be20e..6c859262a16 100644 --- a/src/pip/_internal/utils/glibc.py +++ b/src/pip/_internal/utils/glibc.py @@ -40,11 +40,16 @@ def check_glibc_version(version_str, required_major, minimum_minor): # uses version strings like "2.20-2014.11"). See gh-3588. m = re.match(r"(?P[0-9]+)\.(?P[0-9]+)", version_str) if not m: - warnings.warn("Expected glibc version with 2 components major.minor," - " got: %s" % version_str, RuntimeWarning) + warnings.warn( + "Expected glibc version with 2 components major.minor," + " got: %s" % version_str, + RuntimeWarning, + ) return False - return (int(m.group("major")) == required_major and - int(m.group("minor")) >= minimum_minor) + return ( + int(m.group("major")) == required_major + and int(m.group("minor")) >= minimum_minor + ) def have_compatible_glibc(required_major, minimum_minor): diff --git a/src/pip/_internal/utils/hashes.py b/src/pip/_internal/utils/hashes.py index 8b909ba155c..f351f1396d5 100644 --- a/src/pip/_internal/utils/hashes.py +++ b/src/pip/_internal/utils/hashes.py @@ -4,9 +4,7 @@ from pip._vendor.six import iteritems, iterkeys, itervalues -from pip._internal.exceptions import ( - HashMismatch, HashMissing, InstallationError, -) +from pip._internal.exceptions import HashMismatch, HashMissing, InstallationError from pip._internal.utils.misc import read_chunks # The recommended hash algo of the moment. Change this whenever the state of @@ -24,6 +22,7 @@ class Hashes(object): known-good values """ + def __init__(self, hashes=None): """ :param hashes: A dict of algorithm names pointing to lists of allowed @@ -84,6 +83,7 @@ class MissingHashes(Hashes): exception showing it to the user. """ + def __init__(self): """Don't offer the ``hashes`` kwarg.""" # Pass our favorite hash in to generate a "gotten hash". With the diff --git a/src/pip/_internal/utils/logging.py b/src/pip/_internal/utils/logging.py index 0c1495dac66..67c47bf35ce 100644 --- a/src/pip/_internal/utils/logging.py +++ b/src/pip/_internal/utils/logging.py @@ -44,23 +44,22 @@ def get_indentation(): class IndentingFormatter(logging.Formatter): - def format(self, record): """ Calls the standard formatter, but will indent all of the log messages by our current indentation level. """ formatted = logging.Formatter.format(self, record) - formatted = "".join([ - (" " * get_indentation()) + line - for line in formatted.splitlines(True) - ]) + formatted = "".join( + [(" " * get_indentation()) + line for line in formatted.splitlines(True)] + ) return formatted def _color_wrap(*colors): def wrapped(inp): return "".join(list(colors) + [inp, colorama.Style.RESET_ALL]) + return wrapped @@ -89,7 +88,8 @@ def should_color(self): return False real_stream = ( - self.stream if not isinstance(self.stream, colorama.AnsiToWin32) + self.stream + if not isinstance(self.stream, colorama.AnsiToWin32) else self.stream.wrapped ) @@ -117,14 +117,12 @@ def format(self, record): class BetterRotatingFileHandler(logging.handlers.RotatingFileHandler): - def _open(self): ensure_dir(os.path.dirname(self.baseFilename)) return logging.handlers.RotatingFileHandler._open(self) class MaxLevelFilter(logging.Filter): - def __init__(self, level): self.level = level diff --git a/src/pip/_internal/utils/misc.py b/src/pip/_internal/utils/misc.py index f69381b8c68..fcc62797517 100644 --- a/src/pip/_internal/utils/misc.py +++ b/src/pip/_internal/utils/misc.py @@ -4,6 +4,7 @@ import errno import io import locale + # we have a submodule named 'logging' which would shadow this if we used the # regular name: import logging as std_logging @@ -19,6 +20,7 @@ from collections import deque from pip._vendor import pkg_resources + # NOTE: retrying is not annotated in typeshed as on 2017-07-17, which is # why we ignore the type on this import. from pip._vendor.retrying import retry # type: ignore @@ -26,12 +28,13 @@ from pip._vendor.six.moves import input from pip._vendor.six.moves.urllib import parse as urllib_parse -from pip._internal.compat import ( - WINDOWS, console_to_str, expanduser, stdlib_pkgs, -) +from pip._internal.compat import WINDOWS, console_to_str, expanduser, stdlib_pkgs from pip._internal.exceptions import CommandError, InstallationError from pip._internal.locations import ( - running_under_virtualenv, site_packages, user_site, virtualenv_no_global, + running_under_virtualenv, + site_packages, + user_site, + virtualenv_no_global, write_delete_marker_file, ) @@ -40,17 +43,32 @@ else: from io import StringIO -__all__ = ['rmtree', 'display_path', 'backup_dir', - 'ask', 'splitext', - 'format_size', 'is_installable_dir', - 'is_svn_page', 'file_contents', - 'split_leading_dir', 'has_leading_dir', - 'normalize_path', - 'renames', 'get_prog', - 'unzip_file', 'untar_file', 'unpack_file', 'call_subprocess', - 'captured_stdout', 'ensure_dir', - 'ARCHIVE_EXTENSIONS', 'SUPPORTED_EXTENSIONS', - 'get_installed_version', 'remove_auth_from_url'] +__all__ = [ + 'rmtree', + 'display_path', + 'backup_dir', + 'ask', + 'splitext', + 'format_size', + 'is_installable_dir', + 'is_svn_page', + 'file_contents', + 'split_leading_dir', + 'has_leading_dir', + 'normalize_path', + 'renames', + 'get_prog', + 'unzip_file', + 'untar_file', + 'unpack_file', + 'call_subprocess', + 'captured_stdout', + 'ensure_dir', + 'ARCHIVE_EXTENSIONS', + 'SUPPORTED_EXTENSIONS', + 'get_installed_version', + 'remove_auth_from_url', +] logger = std_logging.getLogger(__name__) @@ -59,11 +77,11 @@ XZ_EXTENSIONS = ('.tar.xz', '.txz', '.tlz', '.tar.lz', '.tar.lzma') ZIP_EXTENSIONS = ('.zip', '.whl') TAR_EXTENSIONS = ('.tar.gz', '.tgz', '.tar') -ARCHIVE_EXTENSIONS = ( - ZIP_EXTENSIONS + BZ2_EXTENSIONS + TAR_EXTENSIONS + XZ_EXTENSIONS) +ARCHIVE_EXTENSIONS = ZIP_EXTENSIONS + BZ2_EXTENSIONS + TAR_EXTENSIONS + XZ_EXTENSIONS SUPPORTED_EXTENSIONS = ZIP_EXTENSIONS + TAR_EXTENSIONS try: import bz2 # noqa + SUPPORTED_EXTENSIONS += BZ2_EXTENSIONS except ImportError: logger.debug('bz2 module is not available') @@ -71,6 +89,7 @@ try: # Only for Python 3.3+ import lzma # noqa + SUPPORTED_EXTENSIONS += XZ_EXTENSIONS except ImportError: logger.debug('lzma module is not available') @@ -107,8 +126,7 @@ def get_prog(): # Retry every half second for up to 3 seconds @retry(stop_max_delay=3000, wait_fixed=500) def rmtree(dir, ignore_errors=False): - shutil.rmtree(dir, ignore_errors=ignore_errors, - onerror=rmtree_errorhandler) + shutil.rmtree(dir, ignore_errors=ignore_errors, onerror=rmtree_errorhandler) def rmtree_errorhandler(func, path, exc_info): @@ -134,7 +152,7 @@ def display_path(path): path = path.decode(sys.getfilesystemencoding(), 'replace') path = path.encode(sys.getdefaultencoding(), 'replace') if path.startswith(os.getcwd() + os.path.sep): - path = '.' + path[len(os.getcwd()):] + path = '.' + path[len(os.getcwd()) :] return path @@ -161,8 +179,7 @@ def ask(message, options): while 1: if os.environ.get('PIP_NO_INPUT'): raise Exception( - 'No input was expected ($PIP_NO_INPUT set); question: %s' % - message + 'No input was expected ($PIP_NO_INPUT set); question: %s' % message ) response = input(message) response = response.strip().lower() @@ -200,8 +217,9 @@ def is_svn_page(html): """ Returns true if the page appears to be the index page of an svn repository """ - return (re.search(r'[^<]*Revision \d+:', html) and - re.search(r'Powered by (?:<a[^>]*?>)?Subversion', html, re.I)) + return re.search(r'<title>[^<]*Revision \d+:', html) and re.search( + r'Powered by (?:<a[^>]*?>)?Subversion', html, re.I + ) def file_contents(filename): @@ -220,8 +238,9 @@ def read_chunks(file, size=io.DEFAULT_BUFFER_SIZE): def split_leading_dir(path): path = path.lstrip('/').lstrip('\\') - if '/' in path and (('\\' in path and path.find('/') < path.find('\\')) or - '\\' not in path): + if '/' in path and ( + ('\\' in path and path.find('/') < path.find('\\')) or '\\' not in path + ): return path.split('/', 1) elif '\\' in path: return path.split('\\', 1) @@ -319,9 +338,7 @@ def dist_in_site_packages(dist): Return True if given Distribution is installed in sysconfig.get_python_lib(). """ - return normalize_path( - dist_location(dist) - ).startswith(normalize_path(site_packages)) + return normalize_path(dist_location(dist)).startswith(normalize_path(site_packages)) def dist_is_editable(dist): @@ -333,11 +350,13 @@ def dist_is_editable(dist): return False -def get_installed_distributions(local_only=True, - skip=stdlib_pkgs, - include_editables=True, - editables_only=False, - user_only=False): +def get_installed_distributions( + local_only=True, + skip=stdlib_pkgs, + include_editables=True, + editables_only=False, + user_only=False, +): """ Return a list of installed Distribution objects. @@ -358,36 +377,46 @@ def get_installed_distributions(local_only=True, if local_only: local_test = dist_is_local else: + def local_test(d): return True if include_editables: + def editable_test(d): return True + else: + def editable_test(d): return not dist_is_editable(d) if editables_only: + def editables_only_test(d): return dist_is_editable(d) + else: + def editables_only_test(d): return True if user_only: user_test = dist_in_usersite else: + def user_test(d): return True - return [d for d in pkg_resources.working_set - if local_test(d) and - d.key not in skip and - editable_test(d) and - editables_only_test(d) and - user_test(d) - ] + return [ + d + for d in pkg_resources.working_set + if local_test(d) + and d.key not in skip + and editable_test(d) + and editables_only_test(d) + and user_test(d) + ] def egg_link_path(dist): @@ -510,17 +539,18 @@ def untar_file(filename, location): elif filename.lower().endswith('.tar'): mode = 'r' else: - logger.warning( - 'Cannot determine compression type for file %s', filename, - ) + logger.warning('Cannot determine compression type for file %s', filename) mode = 'r:*' tar = tarfile.open(filename, mode) try: # note: python<=2.5 doesn't seem to know about pax headers, filter them - leading = has_leading_dir([ - member.name for member in tar.getmembers() - if member.name != 'pax_global_header' - ]) + leading = has_leading_dir( + [ + member.name + for member in tar.getmembers() + if member.name != 'pax_global_header' + ] + ) for member in tar.getmembers(): fn = member.name if fn == 'pax_global_header': @@ -538,7 +568,9 @@ def untar_file(filename, location): # (specifically bad symlinks) logger.warning( 'In the tar file %s the member %s is invalid: %s', - filename, member.name, exc, + filename, + member.name, + exc, ) continue else: @@ -549,7 +581,9 @@ def untar_file(filename, location): # (specifically bad symlinks) logger.warning( 'In the tar file %s the member %s is invalid: %s', - filename, member.name, exc, + filename, + member.name, + exc, ) continue ensure_dir(os.path.dirname(path)) @@ -569,23 +603,26 @@ def untar_file(filename, location): def unpack_file(filename, location, content_type, link): filename = os.path.realpath(filename) - if (content_type == 'application/zip' or - filename.lower().endswith(ZIP_EXTENSIONS) or - zipfile.is_zipfile(filename)): - unzip_file( - filename, - location, - flatten=not filename.endswith('.whl') - ) - elif (content_type == 'application/x-gzip' or - tarfile.is_tarfile(filename) or - filename.lower().endswith( - TAR_EXTENSIONS + BZ2_EXTENSIONS + XZ_EXTENSIONS)): + if ( + content_type == 'application/zip' + or filename.lower().endswith(ZIP_EXTENSIONS) + or zipfile.is_zipfile(filename) + ): + unzip_file(filename, location, flatten=not filename.endswith('.whl')) + elif ( + content_type == 'application/x-gzip' + or tarfile.is_tarfile(filename) + or filename.lower().endswith(TAR_EXTENSIONS + BZ2_EXTENSIONS + XZ_EXTENSIONS) + ): untar_file(filename, location) - elif (content_type and content_type.startswith('text/html') and - is_svn_page(file_contents(filename))): + elif ( + content_type + and content_type.startswith('text/html') + and is_svn_page(file_contents(filename)) + ): # We don't really care about this from pip._internal.vcs.subversion import Subversion + Subversion('svn+' + link.url).unpack(location) else: # FIXME: handle? @@ -593,17 +630,23 @@ def unpack_file(filename, location, content_type, link): logger.critical( 'Cannot unpack file %s (downloaded from %s, content-type: %s); ' 'cannot detect archive format', - filename, location, content_type, - ) - raise InstallationError( - 'Cannot determine archive format of %s' % location + filename, + location, + content_type, ) - - -def call_subprocess(cmd, show_stdout=True, cwd=None, - on_returncode='raise', - command_desc=None, - extra_environ=None, unset_environ=None, spinner=None): + raise InstallationError('Cannot determine archive format of %s' % location) + + +def call_subprocess( + cmd, + show_stdout=True, + cwd=None, + on_returncode='raise', + command_desc=None, + extra_environ=None, + unset_environ=None, + spinner=None, +): """ Args: unset_environ: an iterable of environment variable names to unset @@ -651,14 +694,16 @@ def call_subprocess(cmd, show_stdout=True, cwd=None, env.pop(name, None) try: proc = subprocess.Popen( - cmd, stderr=subprocess.STDOUT, stdin=subprocess.PIPE, - stdout=stdout, cwd=cwd, env=env, + cmd, + stderr=subprocess.STDOUT, + stdin=subprocess.PIPE, + stdout=stdout, + cwd=cwd, + env=env, ) proc.stdin.close() except Exception as exc: - logger.critical( - "Error %s while executing command %s", exc, command_desc, - ) + logger.critical("Error %s while executing command %s", exc, command_desc) raise all_output = [] if stdout is not None: @@ -687,28 +732,26 @@ def call_subprocess(cmd, show_stdout=True, cwd=None, spinner.finish("done") if proc.returncode: if on_returncode == 'raise': - if (logger.getEffectiveLevel() > std_logging.DEBUG and - not show_stdout): + if logger.getEffectiveLevel() > std_logging.DEBUG and not show_stdout: + logger.info('Complete output from command %s:', command_desc) logger.info( - 'Complete output from command %s:', command_desc, - ) - logger.info( - ''.join(all_output) + - '\n----------------------------------------' + ''.join(all_output) + '\n----------------------------------------' ) raise InstallationError( 'Command "%s" failed with error code %s in %s' - % (command_desc, proc.returncode, cwd)) + % (command_desc, proc.returncode, cwd) + ) elif on_returncode == 'warn': logger.warning( 'Command "%s" had error code %s in %s', - command_desc, proc.returncode, cwd, + command_desc, + proc.returncode, + cwd, ) elif on_returncode == 'ignore': pass else: - raise ValueError('Invalid value: on_returncode=%s' % - repr(on_returncode)) + raise ValueError('Invalid value: on_returncode=%s' % repr(on_returncode)) if not show_stdout: return ''.join(all_output) @@ -745,6 +788,7 @@ def _make_build_dir(build_dir): class FakeFile(object): """Wrap a list of lines in an object with readline() to make ConfigParser happy.""" + def __init__(self, lines): self._gen = (l for l in lines) @@ -762,7 +806,6 @@ def __iter__(self): class StreamWrapper(StringIO): - @classmethod def from_stream(cls, orig_stream): cls.orig_stream = orig_stream @@ -861,13 +904,10 @@ def remove_auth_from_url(url): # parsed url purl = urllib_parse.urlsplit(url) - stripped_netloc = \ - purl.netloc.split('@')[-1] + stripped_netloc = purl.netloc.split('@')[-1] # stripped url - url_pieces = ( - purl.scheme, stripped_netloc, purl.path, purl.query, purl.fragment - ) + url_pieces = (purl.scheme, stripped_netloc, purl.path, purl.query, purl.fragment) surl = urllib_parse.urlunsplit(url_pieces) return surl @@ -881,21 +921,18 @@ def protect_pip_from_modification_on_windows(modifying_pip): pip_names = [ "pip.exe", "pip{}.exe".format(sys.version_info[0]), - "pip{}.{}.exe".format(*sys.version_info[:2]) + "pip{}.{}.exe".format(*sys.version_info[:2]), ] # See https://github.com/pypa/pip/issues/1299 for more discussion should_show_use_python_msg = ( - modifying_pip and - WINDOWS and - os.path.basename(sys.argv[0]) in pip_names + modifying_pip and WINDOWS and os.path.basename(sys.argv[0]) in pip_names ) if should_show_use_python_msg: - new_command = [ - sys.executable, "-m", "pip" - ] + sys.argv[1:] + new_command = [sys.executable, "-m", "pip"] + sys.argv[1:] raise CommandError( - 'To modify pip, please run the following command:\n{}' - .format(" ".join(new_command)) + 'To modify pip, please run the following command:\n{}'.format( + " ".join(new_command) + ) ) diff --git a/src/pip/_internal/utils/outdated.py b/src/pip/_internal/utils/outdated.py index 8c3b50b9828..a2ceed14710 100644 --- a/src/pip/_internal/utils/outdated.py +++ b/src/pip/_internal/utils/outdated.py @@ -54,8 +54,7 @@ def save(self, pypi_version, current_time): } with open(self.statefile_path, "w") as statefile: - json.dump(state, statefile, sort_keys=True, - separators=(",", ":")) + json.dump(state, statefile, sort_keys=True, separators=(",", ":")) def pip_installed_by_pip(): @@ -66,8 +65,9 @@ def pip_installed_by_pip(): """ try: dist = pkg_resources.get_distribution('pip') - return (dist.has_metadata('INSTALLER') and - 'pip' in dist.get_metadata_lines('INSTALLER')) + return dist.has_metadata('INSTALLER') and 'pip' in dist.get_metadata_lines( + 'INSTALLER' + ) except pkg_resources.DistributionNotFound: return False @@ -93,8 +93,7 @@ def pip_version_check(session, options): # Determine if we need to refresh the state if "last_check" in state.state and "pypi_version" in state.state: last_check = datetime.datetime.strptime( - state.state["last_check"], - SELFCHECK_DATE_FMT + state.state["last_check"], SELFCHECK_DATE_FMT ) if (current_time - last_check).total_seconds() < 7 * 24 * 60 * 60: pypi_version = state.state["pypi_version"] @@ -113,9 +112,7 @@ def pip_version_check(session, options): all_candidates = finder.find_all_candidates("pip") if not all_candidates: return - pypi_version = str( - max(all_candidates, key=lambda c: c.version).version - ) + pypi_version = str(max(all_candidates, key=lambda c: c.version).version) # save that we've performed a check state.save(pypi_version, current_time) @@ -123,9 +120,11 @@ def pip_version_check(session, options): remote_version = packaging_version.parse(pypi_version) # Determine if our pypi_version is older - if (pip_version < remote_version and - pip_version.base_version != remote_version.base_version and - pip_installed_by_pip()): + if ( + pip_version < remote_version + and pip_version.base_version != remote_version.base_version + and pip_installed_by_pip() + ): # Advise "python -m pip" on Windows to avoid issues # with overwriting pip.exe. if WINDOWS: @@ -136,10 +135,11 @@ def pip_version_check(session, options): "You are using pip version %s, however version %s is " "available.\nYou should consider upgrading via the " "'%s install --upgrade pip' command.", - pip_version, pypi_version, pip_cmd + pip_version, + pypi_version, + pip_cmd, ) except Exception: logger.debug( - "There was an error checking the latest version of pip", - exc_info=True, + "There was an error checking the latest version of pip", exc_info=True ) diff --git a/src/pip/_internal/utils/packaging.py b/src/pip/_internal/utils/packaging.py index 5f9bb93d2e5..1d6dbbff1ef 100644 --- a/src/pip/_internal/utils/packaging.py +++ b/src/pip/_internal/utils/packaging.py @@ -33,8 +33,9 @@ def check_requires_python(requires_python): def get_metadata(dist): - if (isinstance(dist, pkg_resources.DistInfoDistribution) and - dist.has_metadata('METADATA')): + if isinstance(dist, pkg_resources.DistInfoDistribution) and dist.has_metadata( + 'METADATA' + ): return dist.get_metadata('METADATA') elif dist.has_metadata('PKG-INFO'): return dist.get_metadata('PKG-INFO') @@ -49,15 +50,19 @@ def check_dist_requires_python(dist): try: if not check_requires_python(requires_python): raise exceptions.UnsupportedPythonVersion( - "%s requires Python '%s' but the running Python is %s" % ( + "%s requires Python '%s' but the running Python is %s" + % ( dist.project_name, requires_python, - '.'.join(map(str, sys.version_info[:3])),) + '.'.join(map(str, sys.version_info[:3])), + ) ) except specifiers.InvalidSpecifier as e: logger.warning( "Package %s has an invalid Requires-Python entry %s - %s", - dist.project_name, requires_python, e, + dist.project_name, + requires_python, + e, ) return diff --git a/src/pip/_internal/utils/ui.py b/src/pip/_internal/utils/ui.py index 8ade1e210a3..827d402d564 100644 --- a/src/pip/_internal/utils/ui.py +++ b/src/pip/_internal/utils/ui.py @@ -9,7 +9,11 @@ from pip._vendor import six from pip._vendor.progress.bar import ( - Bar, ChargingBar, FillingCirclesBar, FillingSquaresBar, IncrementalBar, + Bar, + ChargingBar, + FillingCirclesBar, + FillingSquaresBar, + IncrementalBar, ShadyBar, ) from pip._vendor.progress.helpers import HIDE_CURSOR, SHOW_CURSOR, WritelnMixin @@ -119,7 +123,6 @@ def handle_sigint(self, signum, frame): class SilentBar(Bar): - def update(self): pass @@ -133,7 +136,6 @@ class BlueEmojiBar(IncrementalBar): class DownloadProgressMixin(object): - def __init__(self, *args, **kwargs): super(DownloadProgressMixin, self).__init__(*args, **kwargs) self.message = (" " * (get_indentation() + 2)) + self.message @@ -163,7 +165,6 @@ def iter(self, it, n=1): class WindowsMixin(object): - def __init__(self, *args, **kwargs): # The Windows terminal does not support the hide/show cursor ANSI codes # even with colorama. So we'll ensure that hide_cursor is False on @@ -191,19 +192,18 @@ def __init__(self, *args, **kwargs): self.file.flush = lambda: self.file.wrapped.flush() -class BaseDownloadProgressBar(WindowsMixin, InterruptibleMixin, - DownloadProgressMixin): +class BaseDownloadProgressBar(WindowsMixin, InterruptibleMixin, DownloadProgressMixin): file = sys.stdout message = "%(percent)d%%" suffix = "%(downloaded)s %(download_speed)s %(pretty_eta)s" + # NOTE: The "type: ignore" comments on the following classes are there to # work around https://github.com/python/typing/issues/241 -class DefaultDownloadProgressBar(BaseDownloadProgressBar, - _BaseBar): # type: ignore +class DefaultDownloadProgressBar(BaseDownloadProgressBar, _BaseBar): # type: ignore pass @@ -211,13 +211,11 @@ class DownloadSilentBar(BaseDownloadProgressBar, SilentBar): # type: ignore pass -class DownloadIncrementalBar(BaseDownloadProgressBar, # type: ignore - IncrementalBar): +class DownloadIncrementalBar(BaseDownloadProgressBar, IncrementalBar): # type: ignore pass -class DownloadChargingBar(BaseDownloadProgressBar, # type: ignore - ChargingBar): +class DownloadChargingBar(BaseDownloadProgressBar, ChargingBar): # type: ignore pass @@ -225,23 +223,27 @@ class DownloadShadyBar(BaseDownloadProgressBar, ShadyBar): # type: ignore pass -class DownloadFillingSquaresBar(BaseDownloadProgressBar, # type: ignore - FillingSquaresBar): +class DownloadFillingSquaresBar( + BaseDownloadProgressBar, FillingSquaresBar # type: ignore +): pass -class DownloadFillingCirclesBar(BaseDownloadProgressBar, # type: ignore - FillingCirclesBar): +class DownloadFillingCirclesBar( + BaseDownloadProgressBar, FillingCirclesBar # type: ignore +): pass -class DownloadBlueEmojiProgressBar(BaseDownloadProgressBar, # type: ignore - BlueEmojiBar): +class DownloadBlueEmojiProgressBar( + BaseDownloadProgressBar, BlueEmojiBar # type: ignore +): pass -class DownloadProgressSpinner(WindowsMixin, InterruptibleMixin, - DownloadProgressMixin, WritelnMixin, Spinner): +class DownloadProgressSpinner( + WindowsMixin, InterruptibleMixin, DownloadProgressMixin, WritelnMixin, Spinner +): file = sys.stdout suffix = "%(downloaded)s %(download_speed)s" @@ -255,13 +257,9 @@ def update(self): message = self.message % self phase = self.next_phase() suffix = self.suffix % self - line = ''.join([ - message, - " " if message else "", - phase, - " " if suffix else "", - suffix, - ]) + line = ''.join( + [message, " " if message else "", phase, " " if suffix else "", suffix] + ) self.writeln(line) @@ -271,7 +269,7 @@ def update(self): "on": (DefaultDownloadProgressBar, DownloadProgressSpinner), "ascii": (DownloadIncrementalBar, DownloadProgressSpinner), "pretty": (DownloadFillingCirclesBar, DownloadProgressSpinner), - "emoji": (DownloadBlueEmojiProgressBar, DownloadProgressSpinner) + "emoji": (DownloadBlueEmojiProgressBar, DownloadProgressSpinner), } @@ -290,6 +288,7 @@ def DownloadProgressProvider(progress_bar, max=None): # what we need. ################################################################ + @contextlib.contextmanager def hidden_cursor(file): # The Windows terminal does not support the hide/show cursor ANSI codes, @@ -324,9 +323,14 @@ def reset(self): class InteractiveSpinner(object): - def __init__(self, message, file=None, spin_chars="-\\|/", - # Empirically, 8 updates/second looks nice - min_update_interval_seconds=0.125): + def __init__( + self, + message, + file=None, + spin_chars="-\\|/", + # Empirically, 8 updates/second looks nice + min_update_interval_seconds=0.125, + ): self._message = message if file is None: file = sys.stdout diff --git a/src/pip/_internal/vcs/__init__.py b/src/pip/_internal/vcs/__init__.py index 8b159cb9195..7424a39d4f5 100644 --- a/src/pip/_internal/vcs/__init__.py +++ b/src/pip/_internal/vcs/__init__.py @@ -12,7 +12,11 @@ from pip._internal.exceptions import BadCommand from pip._internal.utils.misc import ( - display_path, backup_dir, call_subprocess, rmtree, ask_path_exists, + display_path, + backup_dir, + call_subprocess, + rmtree, + ask_path_exists, ) from pip._internal.utils.typing import MYPY_CHECK_RUNNING @@ -141,8 +145,7 @@ def get_backend_name(self, location): """ for vc_type in self._registry.values(): if vc_type.controls_location(location): - logger.debug('Determine that %s uses VCS: %s', - location, vc_type.name) + logger.debug('Determine that %s uses VCS: %s', location, vc_type.name) return vc_type.name return None @@ -237,8 +240,9 @@ def get_info(self, location): """ Returns (url, revision), where both are strings """ - assert not location.rstrip('/').endswith(self.dirname), \ + assert not location.rstrip('/').endswith(self.dirname), ( 'Bad directory: %s' % location + ) return self.get_url(location), self.get_revision(location) def normalize_url(self, url): @@ -252,7 +256,7 @@ def compare_urls(self, url1, url2): """ Compare two repo URLs for identity, ignoring incidental differences. """ - return (self.normalize_url(url1) == self.normalize_url(url2)) + return self.normalize_url(url1) == self.normalize_url(url2) def obtain(self, dest): """ @@ -322,8 +326,7 @@ def check_destination(self, dest, url, rev_options): ) self.update(dest, rev_options) else: - logger.info( - 'Skipping because already up-to-date.') + logger.info('Skipping because already up-to-date.') else: logger.warning( '%s %s in %s exists with URL %s', @@ -332,8 +335,10 @@ def check_destination(self, dest, url, rev_options): display_path(dest), existing_url, ) - prompt = ('(s)witch, (i)gnore, (w)ipe, (b)ackup ', - ('s', 'i', 'w', 'b')) + prompt = ( + '(s)witch, (i)gnore, (w)ipe, (b)ackup ', + ('s', 'i', 'w', 'b'), + ) else: logger.warning( 'Directory %s already exists, and is not a %s %s.', @@ -344,12 +349,9 @@ def check_destination(self, dest, url, rev_options): prompt = ('(i)gnore, (w)ipe, (b)ackup ', ('i', 'w', 'b')) if prompt: logger.warning( - 'The plan is to install the %s repository %s', - self.name, - url, + 'The plan is to install the %s repository %s', self.name, url ) - response = ask_path_exists('What to do? %s' % prompt[0], - prompt[1]) + response = ask_path_exists('What to do? %s' % prompt[0], prompt[1]) if response == 's': logger.info( @@ -369,9 +371,7 @@ def check_destination(self, dest, url, rev_options): checkout = True elif response == 'b': dest_dir = backup_dir(dest) - logger.warning( - 'Backing up %s to %s', display_path(dest), dest_dir, - ) + logger.warning('Backing up %s to %s', display_path(dest), dest_dir) shutil.move(dest, dest_dir) checkout = True elif response == 'a': @@ -409,10 +409,16 @@ def get_revision(self, location): """ raise NotImplementedError - def run_command(self, cmd, show_stdout=True, cwd=None, - on_returncode='raise', - command_desc=None, - extra_environ=None, spinner=None): + def run_command( + self, + cmd, + show_stdout=True, + cwd=None, + on_returncode='raise', + command_desc=None, + extra_environ=None, + spinner=None, + ): """ Run a VCS subcommand This is simply a wrapper around call_subprocess that adds the VCS @@ -420,11 +426,16 @@ def run_command(self, cmd, show_stdout=True, cwd=None, """ cmd = [self.name] + cmd try: - return call_subprocess(cmd, show_stdout, cwd, - on_returncode, - command_desc, extra_environ, - unset_environ=self.unset_environ, - spinner=spinner) + return call_subprocess( + cmd, + show_stdout, + cwd, + on_returncode, + command_desc, + extra_environ, + unset_environ=self.unset_environ, + spinner=spinner, + ) except OSError as e: # errno.ENOENT = no such file or directory # In other words, the VCS executable isn't available @@ -432,7 +443,8 @@ def run_command(self, cmd, show_stdout=True, cwd=None, raise BadCommand( 'Cannot find command %r - do you have ' '%r installed and in your ' - 'PATH?' % (self.name, self.name)) + 'PATH?' % (self.name, self.name) + ) else: raise # re-raise exception if a different error occurred @@ -443,8 +455,7 @@ def controls_location(cls, location): It is meant to be overridden to implement smarter detection mechanisms for specific vcs. """ - logger.debug('Checking in %s for %s (%s)...', - location, cls.dirname, cls.name) + logger.debug('Checking in %s for %s (%s)...', location, cls.dirname, cls.name) path = os.path.join(location, cls.dirname) return os.path.exists(path) @@ -453,8 +464,7 @@ def get_src_requirement(dist, location): version_control = vcs.get_backend_from_location(location) if version_control: try: - return version_control().get_src_requirement(dist, - location) + return version_control().get_src_requirement(dist, location) except BadCommand: logger.warning( 'cannot determine version of editable source in %s ' diff --git a/src/pip/_internal/vcs/bazaar.py b/src/pip/_internal/vcs/bazaar.py index b4e46e0e1cd..a56040ea0b9 100644 --- a/src/pip/_internal/vcs/bazaar.py +++ b/src/pip/_internal/vcs/bazaar.py @@ -18,7 +18,12 @@ class Bazaar(VersionControl): dirname = '.bzr' repo_name = 'branch' schemes = ( - 'bzr', 'bzr+http', 'bzr+https', 'bzr+ssh', 'bzr+sftp', 'bzr+ftp', + 'bzr', + 'bzr+http', + 'bzr+https', + 'bzr+ssh', + 'bzr+sftp', + 'bzr+ftp', 'bzr+lp', ) @@ -43,10 +48,7 @@ def export(self, location): with TempDirectory(kind="export") as temp_dir: self.unpack(temp_dir.path) - self.run_command( - ['export', location], - cwd=temp_dir.path, show_stdout=False, - ) + self.run_command(['export', location], cwd=temp_dir.path, show_stdout=False) def switch(self, dest, url, rev_options): self.run_command(['switch', url], cwd=dest) @@ -60,12 +62,7 @@ def obtain(self, dest): rev_options = self.make_rev_options(rev) if self.check_destination(dest, url, rev_options): rev_display = rev_options.to_display() - logger.info( - 'Checking out %s%s to %s', - url, - rev_display, - display_path(dest), - ) + logger.info('Checking out %s%s to %s', url, rev_display, display_path(dest)) cmd_args = ['branch', '-q'] + rev_options.to_args() + [url, dest] self.run_command(cmd_args) @@ -80,8 +77,7 @@ def get_url(self, location): urls = self.run_command(['info'], show_stdout=False, cwd=location) for line in urls.splitlines(): line = line.strip() - for x in ('checkout of branch: ', - 'parent branch: '): + for x in ('checkout of branch: ', 'parent branch: '): if line.startswith(x): repo = line.split(x)[1] if self._is_local_repository(repo): @@ -90,9 +86,7 @@ def get_url(self, location): return None def get_revision(self, location): - revision = self.run_command( - ['revno'], show_stdout=False, cwd=location, - ) + revision = self.run_command(['revno'], show_stdout=False, cwd=location) return revision.splitlines()[-1] def get_src_requirement(self, dist, location): diff --git a/src/pip/_internal/vcs/git.py b/src/pip/_internal/vcs/git.py index 99f9a1700a4..7b01abdccc7 100644 --- a/src/pip/_internal/vcs/git.py +++ b/src/pip/_internal/vcs/git.py @@ -32,9 +32,7 @@ class Git(VersionControl): name = 'git' dirname = '.git' repo_name = 'clone' - schemes = ( - 'git', 'git+http', 'git+https', 'git+ssh', 'git+git', 'git+file', - ) + schemes = ('git', 'git+http', 'git+https', 'git+ssh', 'git+git', 'git+file') # Prevent the user's environment variables from interfering with pip: # https://github.com/pypa/pip/issues/1130 unset_environ = ('GIT_DIR', 'GIT_WORK_TREE') @@ -47,16 +45,14 @@ def __init__(self, url=None, *args, **kwargs): if url: scheme, netloc, path, query, fragment = urlsplit(url) if scheme.endswith('file'): - initial_slashes = path[:-len(path.lstrip('/'))] - newpath = ( - initial_slashes + - urllib_request.url2pathname(path) - .replace('\\', '/').lstrip('/') - ) + initial_slashes = path[: -len(path.lstrip('/'))] + newpath = initial_slashes + urllib_request.url2pathname(path).replace( + '\\', '/' + ).lstrip('/') url = urlunsplit((scheme, netloc, newpath, query, fragment)) after_plus = scheme.find('+') + 1 url = scheme[:after_plus] + urlunsplit( - (scheme[after_plus:], netloc, newpath, query, fragment), + (scheme[after_plus:], netloc, newpath, query, fragment) ) super(Git, self).__init__(url, *args, **kwargs) @@ -68,7 +64,7 @@ def get_git_version(self): VERSION_PFX = 'git version ' version = self.run_command(['version'], show_stdout=False) if version.startswith(VERSION_PFX): - version = version[len(VERSION_PFX):].split()[0] + version = version[len(VERSION_PFX) :].split()[0] else: version = '' # get first 3 positions of the git version becasue @@ -86,7 +82,8 @@ def export(self, location): self.unpack(temp_dir.path) self.run_command( ['checkout-index', '-a', '-f', '--prefix', location], - show_stdout=False, cwd=temp_dir.path + show_stdout=False, + cwd=temp_dir.path, ) def get_revision_sha(self, dest, rev): @@ -99,8 +96,9 @@ def get_revision_sha(self, dest, rev): rev: the revision name. """ # Pass rev to pre-filter the list. - output = self.run_command(['show-ref', rev], cwd=dest, - show_stdout=False, on_returncode='ignore') + output = self.run_command( + ['show-ref', rev], cwd=dest, show_stdout=False, on_returncode='ignore' + ) refs = {} for line in output.strip().splitlines(): try: @@ -136,8 +134,7 @@ def check_rev_options(self, dest, rev_options): # the form of a Git commit hash. if not looks_like_hash(rev): logger.warning( - "Did not find branch or tag '%s', assuming revision or ref.", - rev, + "Did not find branch or tag '%s', assuming revision or ref.", rev ) return rev_options @@ -181,9 +178,7 @@ def obtain(self, dest): rev_options = self.make_rev_options(rev) if self.check_destination(dest, url, rev_options): rev_display = rev_options.to_display() - logger.info( - 'Cloning %s%s to %s', url, rev_display, display_path(dest), - ) + logger.info('Cloning %s%s to %s', url, rev_display, display_path(dest)) self.run_command(['clone', '-q', url, dest]) if rev: @@ -195,8 +190,7 @@ def obtain(self, dest): # Only fetch the revision if it's a ref if rev.startswith('refs/'): self.run_command( - ['fetch', '-q', url] + rev_options.to_args(), - cwd=dest, + ['fetch', '-q', url] + rev_options.to_args(), cwd=dest ) # Change the revision to the SHA of the ref we fetched rev = 'FETCH_HEAD' @@ -209,7 +203,8 @@ def get_url(self, location): """Return URL of the first remote encountered.""" remotes = self.run_command( ['config', '--get-regexp', r'remote\..*\.url'], - show_stdout=False, cwd=location, + show_stdout=False, + cwd=location, ) remotes = remotes.splitlines() found_remote = remotes[0] @@ -222,15 +217,16 @@ def get_url(self, location): def get_revision(self, location): current_rev = self.run_command( - ['rev-parse', 'HEAD'], show_stdout=False, cwd=location, + ['rev-parse', 'HEAD'], show_stdout=False, cwd=location ) return current_rev.strip() def _get_subdirectory(self, location): """Return the relative path of setup.py to the git repo root.""" # find the repo root - git_dir = self.run_command(['rev-parse', '--git-dir'], - show_stdout=False, cwd=location).strip() + git_dir = self.run_command( + ['rev-parse', '--git-dir'], show_stdout=False, cwd=location + ).strip() if not os.path.isabs(git_dir): git_dir = os.path.join(location, git_dir) root_dir = os.path.join(git_dir, '..') @@ -288,8 +284,7 @@ def update_submodules(self, location): if not os.path.exists(os.path.join(location, '.gitmodules')): return self.run_command( - ['submodule', 'update', '--init', '--recursive', '-q'], - cwd=location, + ['submodule', 'update', '--init', '--recursive', '-q'], cwd=location ) @classmethod @@ -297,14 +292,16 @@ def controls_location(cls, location): if super(Git, cls).controls_location(location): return True try: - r = cls().run_command(['rev-parse'], - cwd=location, - show_stdout=False, - on_returncode='ignore') + r = cls().run_command( + ['rev-parse'], cwd=location, show_stdout=False, on_returncode='ignore' + ) return not r except BadCommand: - logger.debug("could not determine if %s is under git control " - "because git is not available", location) + logger.debug( + "could not determine if %s is under git control " + "because git is not available", + location, + ) return False diff --git a/src/pip/_internal/vcs/mercurial.py b/src/pip/_internal/vcs/mercurial.py index 52a1cce5471..a779101957d 100644 --- a/src/pip/_internal/vcs/mercurial.py +++ b/src/pip/_internal/vcs/mercurial.py @@ -40,9 +40,7 @@ def switch(self, dest, url, rev_options): with open(repo_config, 'w') as config_file: config.write(config_file) except (OSError, configparser.NoSectionError) as exc: - logger.warning( - 'Could not switch Mercurial repository to %s: %s', url, exc, - ) + logger.warning('Could not switch Mercurial repository to %s: %s', url, exc) else: cmd_args = ['update', '-q'] + rev_options.to_args() self.run_command(cmd_args, cwd=dest) @@ -57,34 +55,29 @@ def obtain(self, dest): rev_options = self.make_rev_options(rev) if self.check_destination(dest, url, rev_options): rev_display = rev_options.to_display() - logger.info( - 'Cloning hg %s%s to %s', - url, - rev_display, - display_path(dest), - ) + logger.info('Cloning hg %s%s to %s', url, rev_display, display_path(dest)) self.run_command(['clone', '--noupdate', '-q', url, dest]) cmd_args = ['update', '-q'] + rev_options.to_args() self.run_command(cmd_args, cwd=dest) def get_url(self, location): url = self.run_command( - ['showconfig', 'paths.default'], - show_stdout=False, cwd=location).strip() + ['showconfig', 'paths.default'], show_stdout=False, cwd=location + ).strip() if self._is_local_repository(url): url = path_to_url(url) return url.strip() def get_revision(self, location): current_revision = self.run_command( - ['parents', '--template={rev}'], - show_stdout=False, cwd=location).strip() + ['parents', '--template={rev}'], show_stdout=False, cwd=location + ).strip() return current_revision def get_revision_hash(self, location): current_rev_hash = self.run_command( - ['parents', '--template={node}'], - show_stdout=False, cwd=location).strip() + ['parents', '--template={node}'], show_stdout=False, cwd=location + ).strip() return current_rev_hash def get_src_requirement(self, dist, location): diff --git a/src/pip/_internal/vcs/subversion.py b/src/pip/_internal/vcs/subversion.py index de448c7c685..84c9e653d4e 100644 --- a/src/pip/_internal/vcs/subversion.py +++ b/src/pip/_internal/vcs/subversion.py @@ -33,18 +33,16 @@ def get_base_rev_args(self, rev): def get_info(self, location): """Returns (url, revision), where both are strings""" - assert not location.rstrip('/').endswith(self.dirname), \ + assert not location.rstrip('/').endswith(self.dirname), ( 'Bad directory: %s' % location + ) output = self.run_command( - ['info', location], - show_stdout=False, - extra_environ={'LANG': 'C'}, + ['info', location], show_stdout=False, extra_environ={'LANG': 'C'} ) match = _svn_url_re.search(output) if not match: logger.warning( - 'Cannot determine URL of svn checkout %s', - display_path(location), + 'Cannot determine URL of svn checkout %s', display_path(location) ) logger.debug('Output that cannot be parsed: \n%s', output) return None, None @@ -52,8 +50,7 @@ def get_info(self, location): match = _svn_revision_re.search(output) if not match: logger.warning( - 'Cannot determine revision of svn checkout %s', - display_path(location), + 'Cannot determine revision of svn checkout %s', display_path(location) ) logger.debug('Output that cannot be parsed: \n%s', output) return url, None @@ -87,12 +84,7 @@ def obtain(self, dest): url = remove_auth_from_url(url) if self.check_destination(dest, url, rev_options): rev_display = rev_options.to_display() - logger.info( - 'Checking out %s%s to %s', - url, - rev_display, - display_path(dest), - ) + logger.info('Checking out %s%s to %s', url, rev_display, display_path(dest)) cmd_args = ['checkout', '-q'] + rev_options.to_args() + [url, dest] self.run_command(cmd_args) @@ -120,7 +112,7 @@ def get_revision(self, location): for base, dirs, files in os.walk(location): if self.dirname not in dirs: dirs[:] = [] - continue # no sense walking uncontrolled subdirs + continue # no sense walking uncontrolled subdirs dirs.remove(self.dirname) entries_fn = os.path.join(base, self.dirname, 'entries') if not os.path.exists(entries_fn): @@ -130,10 +122,10 @@ def get_revision(self, location): dirurl, localrev = self._get_svn_url_rev(base) if base == location: - base = dirurl + '/' # save the root url + base = dirurl + '/' # save the root url elif not dirurl or not dirurl.startswith(base): dirs[:] = [] - continue # not part of the same svn tree, skip it + continue # not part of the same svn tree, skip it revision = max(revision, localrev) return revision @@ -174,9 +166,7 @@ def _get_svn_url_rev(self, location): else: # subversion >= 1.7 does not have the 'entries' file data = '' - if (data.startswith('8') or - data.startswith('9') or - data.startswith('10')): + if data.startswith('8') or data.startswith('9') or data.startswith('10'): data = list(map(str.splitlines, data.split('\n\x0c\n'))) del data[0][0] # get rid of the '8' url = data[0][3] @@ -185,19 +175,14 @@ def _get_svn_url_rev(self, location): match = _svn_xml_url_re.search(data) if not match: raise ValueError('Badly formatted data: %r' % data) - url = match.group(1) # get repository URL + url = match.group(1) # get repository URL revs = [int(m.group(1)) for m in _svn_rev_re.finditer(data)] + [0] else: try: # subversion >= 1.7 - xml = self.run_command( - ['info', '--xml', location], - show_stdout=False, - ) + xml = self.run_command(['info', '--xml', location], show_stdout=False) url = _svn_info_xml_url_re.search(xml).group(1) - revs = [ - int(m.group(1)) for m in _svn_info_xml_rev_re.finditer(xml) - ] + revs = [int(m.group(1)) for m in _svn_info_xml_rev_re.finditer(xml)] except InstallationError: url, revs = None, [] diff --git a/src/pip/_internal/wheel.py b/src/pip/_internal/wheel.py index 4723bf7b7c3..210cd30f9cc 100644 --- a/src/pip/_internal/wheel.py +++ b/src/pip/_internal/wheel.py @@ -26,14 +26,17 @@ from pip._internal import pep425tags from pip._internal.download import path_to_url, unpack_url from pip._internal.exceptions import ( - InstallationError, InvalidWheelFilename, UnsupportedWheel, -) -from pip._internal.locations import ( - PIP_DELETE_MARKER_FILENAME, distutils_scheme, + InstallationError, + InvalidWheelFilename, + UnsupportedWheel, ) +from pip._internal.locations import PIP_DELETE_MARKER_FILENAME, distutils_scheme from pip._internal.utils.logging import indent_log from pip._internal.utils.misc import ( - call_subprocess, captured_stdout, ensure_dir, read_chunks, + call_subprocess, + captured_stdout, + ensure_dir, + read_chunks, ) from pip._internal.utils.setuptools_build import SETUPTOOLS_SHIM from pip._internal.utils.temp_dir import TempDirectory @@ -59,9 +62,7 @@ def rehash(path, algo='sha256', blocksize=1 << 20): for block in read_chunks(f, size=blocksize): length += len(block) h.update(block) - digest = 'sha256=' + urlsafe_b64encode( - h.digest() - ).decode('latin1').rstrip('=') + digest = 'sha256=' + urlsafe_b64encode(h.digest()).decode('latin1').rstrip('=') return (digest, length) @@ -93,8 +94,11 @@ def fix_script(path): return True -dist_info_re = re.compile(r"""^(?P<namever>(?P<name>.+?)(-(?P<ver>.+?))?) - \.dist-info$""", re.VERBOSE) +dist_info_re = re.compile( + r"""^(?P<namever>(?P<name>.+?)(-(?P<ver>.+?))?) + \.dist-info$""", + re.VERBOSE, +) def root_is_purelib(name, wheeldir): @@ -163,14 +167,14 @@ def message_about_scripts_not_on_PATH(scripts): # We don't want to warn for directories that are on PATH. not_warn_dirs = [ - os.path.normcase(i).rstrip(os.sep) for i in - os.environ["PATH"].split(os.pathsep) + os.path.normcase(i).rstrip(os.sep) for i in os.environ["PATH"].split(os.pathsep) ] # If an executable sits with sys.executable, we don't warn for it. # This covers the case of venv invocations without activating the venv. not_warn_dirs.append(os.path.normcase(os.path.dirname(sys.executable))) warn_for = { - parent_dir: scripts for parent_dir, scripts in grouped_by_dir.items() + parent_dir: scripts + for parent_dir, scripts in grouped_by_dir.items() if os.path.normcase(parent_dir) not in not_warn_dirs } if not warn_for: @@ -188,8 +192,9 @@ def message_about_scripts_not_on_PATH(scripts): ) msg_lines.append( - "The {} installed in '{}' which is not on PATH." - .format(start_text, parent_dir) + "The {} installed in '{}' which is not on PATH.".format( + start_text, parent_dir + ) ) last_line_fmt = ( @@ -205,15 +210,24 @@ def message_about_scripts_not_on_PATH(scripts): return "\n".join(msg_lines) -def move_wheel_files(name, req, wheeldir, user=False, home=None, root=None, - pycompile=True, scheme=None, isolated=False, prefix=None, - warn_script_location=True): +def move_wheel_files( + name, + req, + wheeldir, + user=False, + home=None, + root=None, + pycompile=True, + scheme=None, + isolated=False, + prefix=None, + warn_script_location=True, +): """Install a wheel""" if not scheme: scheme = distutils_scheme( - name, user=user, home=home, root=root, isolated=isolated, - prefix=prefix, + name, user=user, home=home, root=root, isolated=isolated, prefix=prefix ) if root_is_purelib(name, wheeldir): @@ -256,7 +270,7 @@ def clobber(source, dest, is_base, fixer=None, filter=None): ensure_dir(dest) # common for the 'include' path for dir, subdirs, files in os.walk(source): - basedir = dir[len(source):].lstrip(os.path.sep) + basedir = dir[len(source) :].lstrip(os.path.sep) destdir = os.path.join(dest, basedir) if is_base and basedir.split(os.path.sep, 1)[0].endswith('.data'): continue @@ -265,13 +279,17 @@ def clobber(source, dest, is_base, fixer=None, filter=None): if is_base and basedir == '' and destsubdir.endswith('.data'): data_dirs.append(s) continue - elif (is_base and - s.endswith('.dist-info') and - canonicalize_name(s).startswith( - canonicalize_name(req.name))): - assert not info_dir, ('Multiple .dist-info directories: ' + - destsubdir + ', ' + - ', '.join(info_dir)) + elif ( + is_base + and s.endswith('.dist-info') + and canonicalize_name(s).startswith(canonicalize_name(req.name)) + ): + assert not info_dir, ( + 'Multiple .dist-info directories: ' + + destsubdir + + ', ' + + ', '.join(info_dir) + ) info_dir.append(destsubdir) for f in files: # Skip unwanted files @@ -342,7 +360,7 @@ def is_entrypoint_wrapper(name): else: matchname = name # Ignore setuptools-generated scripts - return (matchname in console or matchname in gui) + return matchname in console or matchname in gui for datadir in data_dirs: fixer = None @@ -480,10 +498,7 @@ def _get_script_text(entry): if len(gui) > 0: generated.extend( - maker.make_multiple( - ['%s = %s' % kv for kv in gui.items()], - {'gui': True} - ) + maker.make_multiple(['%s = %s' % kv for kv in gui.items()], {'gui': True}) ) # Record pip as the installer @@ -547,9 +562,7 @@ def check_compatibility(version, name): :raises UnsupportedWheel: when an incompatible Wheel-Version is given """ if not version: - raise UnsupportedWheel( - "%s is in an unsupported or invalid wheel" % name - ) + raise UnsupportedWheel("%s is in an unsupported or invalid wheel" % name) if version[0] > VERSION_COMPATIBLE[0]: raise UnsupportedWheel( "%s's Wheel-Version (%s) is not compatible with this version " @@ -557,8 +570,7 @@ def check_compatibility(version, name): ) elif version > VERSION_COMPATIBLE: logger.warning( - 'Installing from a newer Wheel-Version (%s)', - '.'.join(map(str, version)), + 'Installing from a newer Wheel-Version (%s)', '.'.join(map(str, version)) ) @@ -571,7 +583,7 @@ class Wheel(object): r"""^(?P<namever>(?P<name>.+?)-(?P<ver>.*?)) ((-(?P<build>\d[^-]*?))?-(?P<pyver>.+?)-(?P<abi>.+?)-(?P<plat>.+?) \.whl|\.dist-info)$""", - re.VERBOSE + re.VERBOSE, ) def __init__(self, filename): @@ -580,9 +592,7 @@ def __init__(self, filename): """ wheel_info = self.wheel_file_re.match(filename) if not wheel_info: - raise InvalidWheelFilename( - "%s is not a valid wheel filename." % filename - ) + raise InvalidWheelFilename("%s is not a valid wheel filename." % filename) self.filename = filename self.name = wheel_info.group('name').replace('_', '-') # we'll assume "_" means "-" due to wheel naming scheme @@ -595,8 +605,7 @@ def __init__(self, filename): # All the tag combinations from this file self.file_tags = { - (x, y, z) for x in self.pyversions - for y in self.abis for z in self.plats + (x, y, z) for x in self.pyversions for y in self.abis for z in self.plats } def support_index_min(self, tags=None): @@ -621,8 +630,15 @@ def supported(self, tags=None): class WheelBuilder(object): """Build wheels from a RequirementSet.""" - def __init__(self, finder, preparer, wheel_cache, - build_options=None, global_options=None, no_clean=False): + def __init__( + self, + finder, + preparer, + wheel_cache, + build_options=None, + global_options=None, + no_clean=False, + ): self.finder = finder self.preparer = preparer self.wheel_cache = wheel_cache @@ -640,8 +656,7 @@ def _build_one(self, req, output_dir, python_tag=None): """ # Install build deps into temporary directory (PEP 518) with req.build_env: - return self._build_one_inside_env(req, output_dir, - python_tag=python_tag) + return self._build_one_inside_env(req, output_dir, python_tag=python_tag) def _build_one_inside_env(self, req, output_dir, python_tag=None): with TempDirectory(kind="wheel") as temp_dir: @@ -649,9 +664,7 @@ def _build_one_inside_env(self, req, output_dir, python_tag=None): try: wheel_name = os.listdir(temp_dir.path)[0] wheel_path = os.path.join(output_dir, wheel_name) - shutil.move( - os.path.join(temp_dir.path, wheel_name), wheel_path - ) + shutil.move(os.path.join(temp_dir.path, wheel_name), wheel_path) logger.info('Stored in directory: %s', output_dir) return wheel_path except: @@ -665,10 +678,9 @@ def _base_setup_args(self, req): # isolating. Currently, it breaks Python in virtualenvs, because it # relies on site.py to find parts of the standard library outside the # virtualenv. - return [ - sys.executable, '-u', '-c', - SETUPTOOLS_SHIM % req.setup_py - ] + list(self.global_options) + return [sys.executable, '-u', '-c', SETUPTOOLS_SHIM % req.setup_py] + list( + self.global_options + ) def __build_one(self, req, tempd, python_tag=None): base_args = self._base_setup_args(req) @@ -676,15 +688,15 @@ def __build_one(self, req, tempd, python_tag=None): spin_message = 'Running setup.py bdist_wheel for %s' % (req.name,) with open_spinner(spin_message) as spinner: logger.debug('Destination directory: %s', tempd) - wheel_args = base_args + ['bdist_wheel', '-d', tempd] \ - + self.build_options + wheel_args = base_args + ['bdist_wheel', '-d', tempd] + self.build_options if python_tag is not None: wheel_args += ["--python-tag", python_tag] try: - call_subprocess(wheel_args, cwd=req.setup_py_dir, - show_stdout=False, spinner=spinner) + call_subprocess( + wheel_args, cwd=req.setup_py_dir, show_stdout=False, spinner=spinner + ) return True except: spinner.finish("error") @@ -723,9 +735,7 @@ def build(self, requirements, session, autobuilding=False): continue if req.is_wheel: if not autobuilding: - logger.info( - 'Skipping %s, due to already being wheel.', req.name, - ) + logger.info('Skipping %s, due to already being wheel.', req.name) elif autobuilding and req.editable: pass elif autobuilding and not req.source_dir: @@ -742,11 +752,12 @@ def build(self, requirements, session, autobuilding=False): # E.g. local directory. Build wheel just for this run. ephem_cache = True if "binary" not in index.fmt_ctl_formats( - self.finder.format_control, - canonicalize_name(req.name)): + self.finder.format_control, canonicalize_name(req.name) + ): logger.info( "Skipping bdist_wheel for %s, due to binaries " - "being disabled for it.", req.name, + "being disabled for it.", + req.name, ) continue buildset.append((req, ephem_cache)) @@ -773,16 +784,12 @@ def build(self, requirements, session, autobuilding=False): try: ensure_dir(output_dir) except OSError as e: - logger.warning("Building wheel for %s failed: %s", - req.name, e) + logger.warning("Building wheel for %s failed: %s", req.name, e) build_failure.append(req) continue else: output_dir = self._wheel_dir - wheel_file = self._build_one( - req, output_dir, - python_tag=python_tag, - ) + wheel_file = self._build_one(req, output_dir, python_tag=python_tag) if wheel_file: build_success.append(req) if autobuilding: @@ -791,24 +798,21 @@ def build(self, requirements, session, autobuilding=False): # method. # The code below assumes temporary source dirs - # prevent it doing bad things. - if req.source_dir and not os.path.exists(os.path.join( - req.source_dir, PIP_DELETE_MARKER_FILENAME)): - raise AssertionError( - "bad source dir - missing marker") + if req.source_dir and not os.path.exists( + os.path.join(req.source_dir, PIP_DELETE_MARKER_FILENAME) + ): + raise AssertionError("bad source dir - missing marker") # Delete the source we built the wheel from req.remove_temporary_source() # set the build directory again - name is known from # the work prepare_files did. - req.source_dir = req.build_location( - self.preparer.build_dir - ) + req.source_dir = req.build_location(self.preparer.build_dir) # Update the link for this. req.link = index.Link(path_to_url(wheel_file)) assert req.link.is_wheel # extract the wheel into the dir unpack_url( - req.link, req.source_dir, None, False, - session=session, + req.link, req.source_dir, None, False, session=session ) else: build_failure.append(req) @@ -816,13 +820,11 @@ def build(self, requirements, session, autobuilding=False): # notify success/failure if build_success: logger.info( - 'Successfully built %s', - ' '.join([req.name for req in build_success]), + 'Successfully built %s', ' '.join([req.name for req in build_success]) ) if build_failure: logger.info( - 'Failed to build %s', - ' '.join([req.name for req in build_failure]), + 'Failed to build %s', ' '.join([req.name for req in build_failure]) ) # Return True if all builds were successful return len(build_failure) == 0 diff --git a/tasks/generate.py b/tasks/generate.py index 69960231c3b..149162a782d 100644 --- a/tasks/generate.py +++ b/tasks/generate.py @@ -13,8 +13,9 @@ def authors(ctx): # Note that it's necessary to use double quotes in the # --format"=%aN <%aE>" part of the command, as the Windows # shell doesn't recognise single quotes here. - r = ctx.run('git log --use-mailmap --format"=%aN <%aE>"', - encoding="utf-8", hide=True) + r = ctx.run( + 'git log --use-mailmap --format"=%aN <%aE>"', encoding="utf-8", hide=True + ) authors = [] seen_authors = set() diff --git a/tasks/vendoring/__init__.py b/tasks/vendoring/__init__.py index 17627bf70a0..f5e6dea56f1 100644 --- a/tasks/vendoring/__init__.py +++ b/tasks/vendoring/__init__.py @@ -9,12 +9,7 @@ TASK_NAME = 'update' -FILE_WHITE_LIST = ( - 'Makefile', - 'vendor.txt', - '__init__.py', - 'README.rst', -) +FILE_WHITE_LIST = ('Makefile', 'vendor.txt', '__init__.py', 'README.rst') def drop_dir(path, **kwargs): @@ -83,9 +78,7 @@ def rewrite_file_imports(item, vendored_libs): text, ) text = re.sub( - r'(\n\s*)from %s(\.|\s+)' % lib, - r'\1from pip._vendor.%s\2' % lib, - text, + r'(\n\s*)from %s(\.|\s+)' % lib, r'\1from pip._vendor.%s\2' % lib, text ) item.write_text(text, encoding='utf-8') @@ -102,7 +95,7 @@ def vendor(ctx, vendor_dir): # the chain. ctx.run( 'pip install -t {0} -r {0}/vendor.txt --no-compile --no-deps'.format( - str(vendor_dir), + str(vendor_dir) ) ) remove_all(vendor_dir.glob('*.dist-info')) diff --git a/tests/conftest.py b/tests/conftest.py index 1e927fc1389..7fb2d8b1d0d 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -24,14 +24,15 @@ def pytest_collection_modifyitems(items): item.add_marker(pytest.mark.flaky(reruns=3)) module_path = os.path.relpath( - item.module.__file__, - os.path.commonprefix([__file__, item.module.__file__]), + item.module.__file__, os.path.commonprefix([__file__, item.module.__file__]) ) module_root_dir = module_path.split(os.pathsep)[0] - if (module_root_dir.startswith("functional") or - module_root_dir.startswith("integration") or - module_root_dir.startswith("lib")): + if ( + module_root_dir.startswith("functional") + or module_root_dir.startswith("integration") + or module_root_dir.startswith("lib") + ): item.add_marker(pytest.mark.integration) elif module_root_dir.startswith("unit"): item.add_marker(pytest.mark.unit) @@ -44,9 +45,7 @@ def pytest_collection_modifyitems(items): "(filename = {}, item = {})".format(module_path, item) ) else: - raise RuntimeError( - "Unknown test type (filename = {})".format(module_path) - ) + raise RuntimeError("Unknown test type (filename = {})".format(module_path)) @pytest.yield_fixture @@ -92,11 +91,9 @@ def isolate(tmpdir): if sys.platform == 'win32': # Note: this will only take effect in subprocesses... home_drive, home_path = os.path.splitdrive(home_dir) - os.environ.update({ - 'USERPROFILE': home_dir, - 'HOMEDRIVE': home_drive, - 'HOMEPATH': home_path, - }) + os.environ.update( + {'USERPROFILE': home_dir, 'HOMEDRIVE': home_drive, 'HOMEPATH': home_path} + ) for env_var, sub_path in ( ('APPDATA', 'AppData/Roaming'), ('LOCALAPPDATA', 'AppData/Local'), @@ -114,10 +111,12 @@ def isolate(tmpdir): os.environ["XDG_CONFIG_HOME"] = os.path.join(home_dir, ".config") os.environ["XDG_CACHE_HOME"] = os.path.join(home_dir, ".cache") os.environ["XDG_RUNTIME_DIR"] = os.path.join(home_dir, ".runtime") - os.environ["XDG_DATA_DIRS"] = ":".join([ - os.path.join(fake_root, "usr", "local", "share"), - os.path.join(fake_root, "usr", "share"), - ]) + os.environ["XDG_DATA_DIRS"] = ":".join( + [ + os.path.join(fake_root, "usr", "local", "share"), + os.path.join(fake_root, "usr", "share"), + ] + ) os.environ["XDG_CONFIG_DIRS"] = os.path.join(fake_root, "etc", "xdg") # Configure git, because without an author name/email git will complain @@ -132,9 +131,7 @@ def isolate(tmpdir): # FIXME: Windows... os.makedirs(os.path.join(home_dir, ".config", "git")) with open(os.path.join(home_dir, ".config", "git", "config"), "wb") as fp: - fp.write( - b"[user]\n\tname = pip\n\temail = pypa-dev@googlegroups.com\n" - ) + fp.write(b"[user]\n\tname = pip\n\temail = pypa-dev@googlegroups.com\n") @pytest.fixture(scope='session') @@ -145,8 +142,18 @@ def pip_src(tmpdir_factory): SRC_DIR, pip_src.abspath, ignore=shutil.ignore_patterns( - "*.pyc", "__pycache__", "contrib", "docs", "tasks", "*.txt", - "tests", "pip.egg-info", "build", "dist", ".tox", ".git", + "*.pyc", + "__pycache__", + "contrib", + "docs", + "tasks", + "*.txt", + "tests", + "pip.egg-info", + "build", + "dist", + ".tox", + ".git", ), ) return pip_src @@ -157,9 +164,7 @@ def virtualenv_template(tmpdir_factory, pip_src): tmpdir = Path(str(tmpdir_factory.mktemp('virtualenv'))) # Create the virtual environment venv = VirtualEnvironment.create( - tmpdir.join("venv_orig"), - pip_source_dir=pip_src, - relocatable=True, + tmpdir.join("venv_orig"), pip_source_dir=pip_src, relocatable=True ) # Fix `site.py`. site_py = venv.lib / 'site.py' @@ -170,9 +175,7 @@ def virtualenv_template(tmpdir_factory, pip_src): # Ensure `virtualenv.system_site_packages = True` (needed # for testing `--user`) does not result in adding the real # site-packages' directory to `sys.path`. - ( - '\ndef virtual_addsitepackages(known_paths):\n' - ), + ('\ndef virtual_addsitepackages(known_paths):\n'), ( '\ndef virtual_addsitepackages(known_paths):\n' ' return known_paths\n' @@ -237,16 +240,12 @@ def script(tmpdir, virtualenv): return PipTestEnvironment( # The base location for our test environment tmpdir.join("workspace"), - # Tell the Test Environment where our virtualenv is located virtualenv=virtualenv.location, - # Do not ignore hidden files, they need to be checked as well ignore_hidden=False, - # We are starting with an already empty directory start_clear=False, - # We want to ensure no temporary files are left behind, so the # PipTestEnvironment needs to capture and assert against temp capture_temp=True, @@ -258,10 +257,9 @@ def script(tmpdir, virtualenv): def common_wheels(tmpdir_factory): """Provide a directory with latest setuptools and wheel wheels""" wheels_dir = tmpdir_factory.mktemp('common_wheels') - subprocess.check_call([ - 'pip', 'download', 'wheel', 'setuptools', - '-d', str(wheels_dir), - ]) + subprocess.check_call( + ['pip', 'download', 'wheel', 'setuptools', '-d', str(wheels_dir)] + ) yield wheels_dir wheels_dir.remove(ignore_errors=True) diff --git a/tests/data/packages/BrokenEmitsUTF8/setup.py b/tests/data/packages/BrokenEmitsUTF8/setup.py index 81c5baeadba..8db605dadf4 100644 --- a/tests/data/packages/BrokenEmitsUTF8/setup.py +++ b/tests/data/packages/BrokenEmitsUTF8/setup.py @@ -7,20 +7,28 @@ class FakeError(Exception): pass + if sys.argv[1] == 'install': if hasattr(sys.stdout, 'buffer'): - sys.stdout.buffer.write('\nThis package prints out UTF-8 stuff like:\n'.encode('utf-8')) - sys.stdout.buffer.write('* return type of ‘main’ is not ‘int’\n'.encode('utf-8')) - sys.stdout.buffer.write('* Björk Guðmundsdóttir [ˈpjÅ“rÌ¥k ˈkvÊðmÊntsËŒtoÊŠhtɪr]'.encode('utf-8')) + sys.stdout.buffer.write( + '\nThis package prints out UTF-8 stuff like:\n'.encode('utf-8') + ) + sys.stdout.buffer.write( + '* return type of ‘main’ is not ‘int’\n'.encode('utf-8') + ) + sys.stdout.buffer.write( + '* Björk Guðmundsdóttir [ˈpjÅ“rÌ¥k ˈkvÊðmÊntsËŒtoÊŠhtɪr]'.encode('utf-8') + ) else: pass sys.stdout.write('\nThis package prints out UTF-8 stuff like:\n') - sys.stdout.write('* return type of \xe2\x80\x98main\xe2\x80\x99 is not \xe2\x80\x98int\xe2\x80\x99\n') - sys.stdout.write('* Bj\xc3\xb6rk Gu\xc3\xb0mundsd\xc3\xb3ttir [\xcb\x88pj\xc5\x93r\xcc\xa5k \xcb\x88kv\xca\x8f\xc3\xb0m\xca\x8fnts\xcb\x8cto\xca\x8aht\xc9\xaar]\n') + sys.stdout.write( + '* return type of \xe2\x80\x98main\xe2\x80\x99 is not \xe2\x80\x98int\xe2\x80\x99\n' + ) + sys.stdout.write( + '* Bj\xc3\xb6rk Gu\xc3\xb0mundsd\xc3\xb3ttir [\xcb\x88pj\xc5\x93r\xcc\xa5k \xcb\x88kv\xca\x8f\xc3\xb0m\xca\x8fnts\xcb\x8cto\xca\x8aht\xc9\xaar]\n' + ) raise FakeError('this package designed to fail on install') -setup(name='broken', - version='0.2', - py_modules=['broken'], - ) +setup(name='broken', version='0.2', py_modules=['broken']) diff --git a/tests/data/packages/FSPkg/setup.py b/tests/data/packages/FSPkg/setup.py index d1b725e8cc4..dfec519f619 100644 --- a/tests/data/packages/FSPkg/setup.py +++ b/tests/data/packages/FSPkg/setup.py @@ -2,24 +2,25 @@ version = '0.1dev' -setup(name='FSPkg', - version=version, - description="File system test package", - long_description="""\ +setup( + name='FSPkg', + version=version, + description="File system test package", + long_description="""\ File system test package""", - classifiers=[], # Get strings from https://pypi.org/pypi?%3Aaction=list_classifiers - keywords='pip tests', - author='pip', - author_email='pip@openplans.org', - url='http://pip.openplans.org', - license='', - packages=find_packages(exclude=['ez_setup', 'examples', 'tests']), - include_package_data=True, - zip_safe=False, - install_requires=[ - # -*- Extra requirements: -*- - ], - entry_points=""" + classifiers=[], # Get strings from https://pypi.org/pypi?%3Aaction=list_classifiers + keywords='pip tests', + author='pip', + author_email='pip@openplans.org', + url='http://pip.openplans.org', + license='', + packages=find_packages(exclude=['ez_setup', 'examples', 'tests']), + include_package_data=True, + zip_safe=False, + install_requires=[ + # -*- Extra requirements: -*- + ], + entry_points=""" # -*- Entry points: -*- """, - ) +) diff --git a/tests/data/packages/HackedEggInfo/setup.py b/tests/data/packages/HackedEggInfo/setup.py index 171f5a2a34b..65f7953ead4 100644 --- a/tests/data/packages/HackedEggInfo/setup.py +++ b/tests/data/packages/HackedEggInfo/setup.py @@ -4,7 +4,7 @@ from setuptools.command import egg_info as orig_egg_info -class egg_info (orig_egg_info.egg_info): +class egg_info(orig_egg_info.egg_info): def run(self): orig_egg_info.egg_info.run(self) @@ -12,6 +12,6 @@ def run(self): setup( name="hackedegginfo", version='0.0.0', - cmdclass={'egg_info':egg_info}, + cmdclass={'egg_info': egg_info}, zip_safe=False, ) diff --git a/tests/data/packages/LocalEnvironMarker/setup.py b/tests/data/packages/LocalEnvironMarker/setup.py index 00f18d583db..86d19a75330 100644 --- a/tests/data/packages/LocalEnvironMarker/setup.py +++ b/tests/data/packages/LocalEnvironMarker/setup.py @@ -26,5 +26,5 @@ def path_to_url(path): version='0.0.1', packages=find_packages(), extras_require={":python_version == '2.7' or python_version == '3.4'": ['simple']}, - dependency_links=[DEP_URL] + dependency_links=[DEP_URL], ) diff --git a/tests/data/packages/LocalExtras-0.0.2/setup.py b/tests/data/packages/LocalExtras-0.0.2/setup.py index acc55f96777..55902be9e4a 100644 --- a/tests/data/packages/LocalExtras-0.0.2/setup.py +++ b/tests/data/packages/LocalExtras-0.0.2/setup.py @@ -27,5 +27,5 @@ def path_to_url(path): packages=find_packages(), install_requires=['simple==1.0'], extras_require={'bar': ['simple==2.0'], 'baz': ['singlemodule']}, - dependency_links=[DEP_URL] + dependency_links=[DEP_URL], ) diff --git a/tests/data/packages/LocalExtras/setup.py b/tests/data/packages/LocalExtras/setup.py index f25cc16c616..43bffe4379b 100644 --- a/tests/data/packages/LocalExtras/setup.py +++ b/tests/data/packages/LocalExtras/setup.py @@ -26,5 +26,5 @@ def path_to_url(path): version='0.0.1', packages=find_packages(), extras_require={'bar': ['simple'], 'baz': ['singlemodule']}, - dependency_links=[DEP_URL] + dependency_links=[DEP_URL], ) diff --git a/tests/data/packages/SetupPyLatin1/setup.py b/tests/data/packages/SetupPyLatin1/setup.py index 3ca77c00c96..40f6c4521c3 100644 --- a/tests/data/packages/SetupPyLatin1/setup.py +++ b/tests/data/packages/SetupPyLatin1/setup.py @@ -2,6 +2,4 @@ from distutils.core import setup -setup(name="SetupPyUTF8", - author=u"Saúl Ibarra Corretgé", - ) +setup(name="SetupPyUTF8", author=u"Saúl Ibarra Corretgé") diff --git a/tests/data/packages/SetupPyUTF8/setup.py b/tests/data/packages/SetupPyUTF8/setup.py index 9b65f5e79fc..dc888750375 100644 --- a/tests/data/packages/SetupPyUTF8/setup.py +++ b/tests/data/packages/SetupPyUTF8/setup.py @@ -2,6 +2,4 @@ from distutils.core import setup -setup(name="SetupPyUTF8", - author="Saúl Ibarra Corretgé", - ) +setup(name="SetupPyUTF8", author="Saúl Ibarra Corretgé") diff --git a/tests/data/packages/requires_wheelbroken_upper/setup.py b/tests/data/packages/requires_wheelbroken_upper/setup.py index 150f98dfbf7..a502288c69b 100644 --- a/tests/data/packages/requires_wheelbroken_upper/setup.py +++ b/tests/data/packages/requires_wheelbroken_upper/setup.py @@ -3,4 +3,5 @@ setuptools.setup( name="requires_wheelbroken_upper", version="0", - install_requires=['wheelbroken', 'upper']) + install_requires=['wheelbroken', 'upper'], +) diff --git a/tests/data/packages/symlinks/setup.py b/tests/data/packages/symlinks/setup.py index b71e35f1e1e..fe6a846f64b 100644 --- a/tests/data/packages/symlinks/setup.py +++ b/tests/data/packages/symlinks/setup.py @@ -2,7 +2,4 @@ version = '0.1' -setup(name='symlinks', - version=version, - packages=["symlinks"], - ) +setup(name='symlinks', version=version, packages=["symlinks"]) diff --git a/tests/data/src/TopoRequires/setup.py b/tests/data/src/TopoRequires/setup.py index 6cd29a7b656..0400138e3ea 100644 --- a/tests/data/src/TopoRequires/setup.py +++ b/tests/data/src/TopoRequires/setup.py @@ -1,7 +1,3 @@ from setuptools import setup -setup( - name='TopoRequires', - version='0.0.1', - packages=['toporequires'], -) +setup(name='TopoRequires', version='0.0.1', packages=['toporequires']) diff --git a/tests/data/src/compilewheel/setup.py b/tests/data/src/compilewheel/setup.py index 8319a2a5c20..55df35cf2bb 100644 --- a/tests/data/src/compilewheel/setup.py +++ b/tests/data/src/compilewheel/setup.py @@ -1,7 +1,4 @@ #!/usr/bin/env python from setuptools import find_packages, setup -setup(name='compilewheel', - version='1.0', - packages=find_packages() - ) +setup(name='compilewheel', version='1.0', packages=find_packages()) diff --git a/tests/data/src/pep518-3.0/pep518.py b/tests/data/src/pep518-3.0/pep518.py index 7986d11379a..9ce06a81ea4 100644 --- a/tests/data/src/pep518-3.0/pep518.py +++ b/tests/data/src/pep518-3.0/pep518.py @@ -1 +1 @@ -#dummy +# dummy diff --git a/tests/data/src/pep518-3.0/setup.py b/tests/data/src/pep518-3.0/setup.py index b63f59926f7..1424320d417 100644 --- a/tests/data/src/pep518-3.0/setup.py +++ b/tests/data/src/pep518-3.0/setup.py @@ -3,7 +3,4 @@ import simplewheel # ensure dependency is installed -setup(name='pep518', - version='3.0', - py_modules=['pep518'], - ) +setup(name='pep518', version='3.0', py_modules=['pep518']) diff --git a/tests/data/src/pep518_with_extra_and_markers-1.0/pep518_with_extra_and_markers.py b/tests/data/src/pep518_with_extra_and_markers-1.0/pep518_with_extra_and_markers.py index 7986d11379a..9ce06a81ea4 100644 --- a/tests/data/src/pep518_with_extra_and_markers-1.0/pep518_with_extra_and_markers.py +++ b/tests/data/src/pep518_with_extra_and_markers-1.0/pep518_with_extra_and_markers.py @@ -1 +1 @@ -#dummy +# dummy diff --git a/tests/data/src/pep518_with_extra_and_markers-1.0/setup.py b/tests/data/src/pep518_with_extra_and_markers-1.0/setup.py index 29a8175e4d1..5759c8a7d12 100644 --- a/tests/data/src/pep518_with_extra_and_markers-1.0/setup.py +++ b/tests/data/src/pep518_with_extra_and_markers-1.0/setup.py @@ -9,7 +9,8 @@ assert simplewheel.__version__ == '1.0' if sys.version_info < (3,) else '2.0' -setup(name='pep518_with_extra_and_markers', - version='1.0', - py_modules=['pep518_with_extra_and_markers'], - ) +setup( + name='pep518_with_extra_and_markers', + version='1.0', + py_modules=['pep518_with_extra_and_markers'], +) diff --git a/tests/data/src/prjwithdatafile/setup.py b/tests/data/src/prjwithdatafile/setup.py index 94863b57b01..3a280a75d7b 100755 --- a/tests/data/src/prjwithdatafile/setup.py +++ b/tests/data/src/prjwithdatafile/setup.py @@ -7,6 +7,6 @@ packages=['prjwithdatafile'], data_files=[ (r'packages1', ['prjwithdatafile/README.txt']), - (r'packages2', ['prjwithdatafile/README.txt']) - ] + (r'packages2', ['prjwithdatafile/README.txt']), + ], ) diff --git a/tests/data/src/requires_simple/setup.py b/tests/data/src/requires_simple/setup.py index 57122041aed..5b45b79d5f2 100644 --- a/tests/data/src/requires_simple/setup.py +++ b/tests/data/src/requires_simple/setup.py @@ -1,6 +1,3 @@ from setuptools import find_packages, setup -setup(name='requires_simple', - version='0.1', - install_requires=['simple==1.0'] - ) +setup(name='requires_simple', version='0.1', install_requires=['simple==1.0']) diff --git a/tests/data/src/requires_simple_extra/setup.py b/tests/data/src/requires_simple_extra/setup.py index 3378c2ce7d1..d09b248de5e 100644 --- a/tests/data/src/requires_simple_extra/setup.py +++ b/tests/data/src/requires_simple_extra/setup.py @@ -1,9 +1,8 @@ from setuptools import setup -setup(name='requires_simple_extra', - version='0.1', - py_modules=['requires_simple_extra'], - extras_require={ - 'extra': ['simple==1.0'] - } +setup( + name='requires_simple_extra', + version='0.1', + py_modules=['requires_simple_extra'], + extras_require={'extra': ['simple==1.0']}, ) diff --git a/tests/data/src/sample/sample/__init__.py b/tests/data/src/sample/sample/__init__.py index c1699a74701..949740b6386 100644 --- a/tests/data/src/sample/sample/__init__.py +++ b/tests/data/src/sample/sample/__init__.py @@ -1,5 +1,6 @@ __version__ = '1.2.0' + def main(): """Entry point for the application script""" print("Call your main application code here") diff --git a/tests/data/src/sample/setup.py b/tests/data/src/sample/setup.py index 73172bedc4e..dd53f592e7d 100644 --- a/tests/data/src/sample/setup.py +++ b/tests/data/src/sample/setup.py @@ -17,8 +17,7 @@ def find_version(*file_paths): # The version line must have the form # __version__ = 'ver' - version_match = re.search(r"^__version__ = ['\"]([^'\"]*)['\"]", - version_file, re.M) + version_match = re.search(r"^__version__ = ['\"]([^'\"]*)['\"]", version_file, re.M) if version_match: return version_match.group(1) raise RuntimeError("Unable to find version string.") @@ -33,31 +32,24 @@ def find_version(*file_paths): version=find_version('sample', '__init__.py'), description="A sample Python project", long_description=long_description, - # The project URL. url='https://github.com/pypa/sampleproject', - # Author details author='The Python Packaging Authority', author_email='pypa-dev@googlegroups.com', - # Choose your license license='MIT', - classifiers=[ # How mature is this project? Common values are # 3 - Alpha # 4 - Beta # 5 - Production/Stable 'Development Status :: 3 - Alpha', - # Indicate who your project is intended for 'Intended Audience :: Developers', 'Topic :: Software Development :: Build Tools', - # Pick your license as you wish (should match "license" above) 'License :: OSI Approved :: MIT License', - # Specify the Python versions you support here. In particular, ensure # that you indicate whether you support Python 2, Python 3 or both. 'Programming Language :: Python :: 2', @@ -67,37 +59,25 @@ def find_version(*file_paths): 'Programming Language :: Python :: 3.2', 'Programming Language :: Python :: 3.3', ], - # What does your project relate to? keywords='sample setuptools development', - # You can just specify the packages manually here if your project is # simple. Or you can use find_packages. packages=find_packages(exclude=["contrib", "docs", "tests*"]), - # List run-time dependencies here. These will be installed by pip when your # project is installed. install_requires=['peppercorn'], - # If there are data files included in your packages that need to be # installed, specify them here. If using Python 2.6 or less, then these # have to be included in MANIFEST.in as well. - package_data={ - 'sample': ['package_data.dat'], - }, - + package_data={'sample': ['package_data.dat']}, # Although 'package_data' is the preferred approach, in some case you may # need to place data files outside of your packages. # see http://docs.python.org/3.4/distutils/setupscript.html#installing-additional-files # In this case, 'data_file' will be installed into '<sys.prefix>/my_data' data_files=[('my_data', ['data/data_file'])], - # To provide executable scripts, use entry points in preference to the # "scripts" keyword. Entry points provide cross-platform support and allow # pip to create the appropriate form of executable for the target platform. - entry_points={ - 'console_scripts': [ - 'sample=sample:main', - ], - }, + entry_points={'console_scripts': ['sample=sample:main']}, ) diff --git a/tests/data/src/simplewheel-1.0/setup.py b/tests/data/src/simplewheel-1.0/setup.py index 461536dce68..30339eb48ff 100644 --- a/tests/data/src/simplewheel-1.0/setup.py +++ b/tests/data/src/simplewheel-1.0/setup.py @@ -3,7 +3,4 @@ import simplewheel -setup(name='simplewheel', - version=simplewheel.__version__, - packages=['simplewheel'], - ) +setup(name='simplewheel', version=simplewheel.__version__, packages=['simplewheel']) diff --git a/tests/data/src/simplewheel-2.0/setup.py b/tests/data/src/simplewheel-2.0/setup.py index 461536dce68..30339eb48ff 100644 --- a/tests/data/src/simplewheel-2.0/setup.py +++ b/tests/data/src/simplewheel-2.0/setup.py @@ -3,7 +3,4 @@ import simplewheel -setup(name='simplewheel', - version=simplewheel.__version__, - packages=['simplewheel'], - ) +setup(name='simplewheel', version=simplewheel.__version__, packages=['simplewheel']) diff --git a/tests/data/src/withpyproject/setup.py b/tests/data/src/withpyproject/setup.py index 326f7fd1e7b..1ea9e3e41c5 100644 --- a/tests/data/src/withpyproject/setup.py +++ b/tests/data/src/withpyproject/setup.py @@ -1,2 +1,3 @@ from setuptools import setup + setup(name='withpyproject', version='0.0.1') diff --git a/tests/functional/test_check.py b/tests/functional/test_check.py index e0c65d0e7a7..3f7ba705f4f 100644 --- a/tests/functional/test_check.py +++ b/tests/functional/test_check.py @@ -14,9 +14,7 @@ def test_basic_check_clean(script): """ result = script.pip('check') - expected_lines = ( - "No broken requirements found.", - ) + expected_lines = ("No broken requirements found.",) assert matches_expected_lines(result.stdout, expected_lines) assert result.returncode == 0 @@ -24,8 +22,7 @@ def test_basic_check_clean(script): def test_basic_check_missing_dependency(script): # Setup a small project pkga_path = create_test_package_with_setup( - script, - name='pkga', version='1.0', install_requires=['missing==0.1'], + script, name='pkga', version='1.0', install_requires=['missing==0.1'] ) # Let's install pkga without its dependency res = script.pip('install', '--no-index', pkga_path, '--no-deps') @@ -33,9 +30,7 @@ def test_basic_check_missing_dependency(script): result = script.pip('check', expect_error=True) - expected_lines = ( - "pkga 1.0 requires missing, which is not installed.", - ) + expected_lines = ("pkga 1.0 requires missing, which is not installed.",) assert matches_expected_lines(result.stdout, expected_lines) assert result.returncode == 1 @@ -43,37 +38,28 @@ def test_basic_check_missing_dependency(script): def test_basic_check_broken_dependency(script): # Setup pkga depending on pkgb>=1.0 pkga_path = create_test_package_with_setup( - script, - name='pkga', version='1.0', install_requires=['broken>=1.0'], + script, name='pkga', version='1.0', install_requires=['broken>=1.0'] ) # Let's install pkga without its dependency res = script.pip('install', '--no-index', pkga_path, '--no-deps') assert "Successfully installed pkga-1.0" in res.stdout, str(res) # Setup broken==0.1 - broken_path = create_test_package_with_setup( - script, - name='broken', version='0.1', - ) + broken_path = create_test_package_with_setup(script, name='broken', version='0.1') # Let's install broken==0.1 - res = script.pip( - 'install', '--no-index', broken_path, '--no-warn-conflicts', - ) + res = script.pip('install', '--no-index', broken_path, '--no-warn-conflicts') assert "Successfully installed broken-0.1" in res.stdout, str(res) result = script.pip('check', expect_error=True) - expected_lines = ( - "pkga 1.0 has requirement broken>=1.0, but you have broken 0.1.", - ) + expected_lines = ("pkga 1.0 has requirement broken>=1.0, but you have broken 0.1.",) assert matches_expected_lines(result.stdout, expected_lines) assert result.returncode == 1 def test_basic_check_broken_dependency_and_missing_dependency(script): pkga_path = create_test_package_with_setup( - script, - name='pkga', version='1.0', install_requires=['broken>=1.0'], + script, name='pkga', version='1.0', install_requires=['broken>=1.0'] ) # Let's install pkga without its dependency res = script.pip('install', '--no-index', pkga_path, '--no-deps') @@ -81,8 +67,7 @@ def test_basic_check_broken_dependency_and_missing_dependency(script): # Setup broken==0.1 broken_path = create_test_package_with_setup( - script, - name='broken', version='0.1', install_requires=['missing'], + script, name='broken', version='0.1', install_requires=['missing'] ) # Let's install broken==0.1 res = script.pip('install', '--no-index', broken_path, '--no-deps') @@ -92,7 +77,7 @@ def test_basic_check_broken_dependency_and_missing_dependency(script): expected_lines = ( "broken 0.1 requires missing, which is not installed.", - "pkga 1.0 has requirement broken>=1.0, but you have broken 0.1." + "pkga 1.0 has requirement broken>=1.0, but you have broken 0.1.", ) assert matches_expected_lines(result.stdout, expected_lines) @@ -101,9 +86,7 @@ def test_basic_check_broken_dependency_and_missing_dependency(script): def test_check_complicated_name_missing(script): package_a_path = create_test_package_with_setup( - script, - name='package_A', version='1.0', - install_requires=['Dependency-B>=1.0'], + script, name='package_A', version='1.0', install_requires=['Dependency-B>=1.0'] ) # Without dependency @@ -111,22 +94,17 @@ def test_check_complicated_name_missing(script): assert "Successfully installed package-A-1.0" in result.stdout, str(result) result = script.pip('check', expect_error=True) - expected_lines = ( - "package-a 1.0 requires dependency-b, which is not installed.", - ) + expected_lines = ("package-a 1.0 requires dependency-b, which is not installed.",) assert matches_expected_lines(result.stdout, expected_lines) assert result.returncode == 1 def test_check_complicated_name_broken(script): package_a_path = create_test_package_with_setup( - script, - name='package_A', version='1.0', - install_requires=['Dependency-B>=1.0'], + script, name='package_A', version='1.0', install_requires=['Dependency-B>=1.0'] ) dependency_b_path_incompatible = create_test_package_with_setup( - script, - name='dependency-b', version='0.1', + script, name='dependency-b', version='0.1' ) # With broken dependency @@ -134,7 +112,7 @@ def test_check_complicated_name_broken(script): assert "Successfully installed package-A-1.0" in result.stdout, str(result) result = script.pip( - 'install', '--no-index', dependency_b_path_incompatible, '--no-deps', + 'install', '--no-index', dependency_b_path_incompatible, '--no-deps' ) assert "Successfully installed dependency-b-0.1" in result.stdout @@ -149,27 +127,20 @@ def test_check_complicated_name_broken(script): def test_check_complicated_name_clean(script): package_a_path = create_test_package_with_setup( - script, - name='package_A', version='1.0', - install_requires=['Dependency-B>=1.0'], + script, name='package_A', version='1.0', install_requires=['Dependency-B>=1.0'] ) dependency_b_path = create_test_package_with_setup( - script, - name='dependency-b', version='1.0', + script, name='dependency-b', version='1.0' ) result = script.pip('install', '--no-index', package_a_path, '--no-deps') assert "Successfully installed package-A-1.0" in result.stdout, str(result) - result = script.pip( - 'install', '--no-index', dependency_b_path, '--no-deps', - ) + result = script.pip('install', '--no-index', dependency_b_path, '--no-deps') assert "Successfully installed dependency-b-1.0" in result.stdout result = script.pip('check', expect_error=True) - expected_lines = ( - "No broken requirements found.", - ) + expected_lines = ("No broken requirements found.",) assert matches_expected_lines(result.stdout, expected_lines) assert result.returncode == 0 @@ -177,7 +148,8 @@ def test_check_complicated_name_clean(script): def test_check_considers_conditional_reqs(script): package_a_path = create_test_package_with_setup( script, - name='package_A', version='1.0', + name='package_A', + version='1.0', install_requires=[ "Dependency-B>=1.0; python_version != '2.7'", "Dependency-B>=2.0; python_version == '2.7'", @@ -188,9 +160,7 @@ def test_check_considers_conditional_reqs(script): assert "Successfully installed package-A-1.0" in result.stdout, str(result) result = script.pip('check', expect_error=True) - expected_lines = ( - "package-a 1.0 requires dependency-b, which is not installed.", - ) + expected_lines = ("package-a 1.0 requires dependency-b, which is not installed.",) assert matches_expected_lines(result.stdout, expected_lines) assert result.returncode == 1 @@ -198,8 +168,7 @@ def test_check_considers_conditional_reqs(script): def test_check_development_versions_are_also_considered(script): # Setup pkga depending on pkgb>=1.0 pkga_path = create_test_package_with_setup( - script, - name='pkga', version='1.0', install_requires=['depend>=1.0'], + script, name='pkga', version='1.0', install_requires=['depend>=1.0'] ) # Let's install pkga without its dependency res = script.pip('install', '--no-index', pkga_path, '--no-deps') @@ -207,18 +176,13 @@ def test_check_development_versions_are_also_considered(script): # Setup depend==1.1.0.dev0 depend_path = create_test_package_with_setup( - script, - name='depend', version='1.1.0.dev0', + script, name='depend', version='1.1.0.dev0' ) # Let's install depend==1.1.0.dev0 - res = script.pip( - 'install', '--no-index', depend_path, '--no-warn-conflicts', - ) + res = script.pip('install', '--no-index', depend_path, '--no-warn-conflicts') assert "Successfully installed depend-1.1.0.dev0" in res.stdout, str(res) result = script.pip('check') - expected_lines = ( - "No broken requirements found.", - ) + expected_lines = ("No broken requirements found.",) assert matches_expected_lines(result.stdout, expected_lines) assert result.returncode == 0 diff --git a/tests/functional/test_completion.py b/tests/functional/test_completion.py index 996dcc63d0f..3261fa4fb62 100644 --- a/tests/functional/test_completion.py +++ b/tests/functional/test_completion.py @@ -73,8 +73,9 @@ def test_completion_alone(script): Test getting completion for none shell, just pip completion """ result = script.pip('completion', expect_error=True) - assert 'ERROR: You must pass --bash or --fish or --zsh' in result.stderr, \ - 'completion alone failed -- ' + result.stderr + assert 'ERROR: You must pass --bash or --fish or --zsh' in result.stderr, ( + 'completion alone failed -- ' + result.stderr + ) def setup_completion(script, words, cword): @@ -85,7 +86,9 @@ def setup_completion(script, words, cword): # expect_error is True because autocomplete exists with 1 status code result = script.run( - 'python', '-c', 'import pip._internal;pip._internal.autocomplete()', + 'python', + '-c', + 'import pip._internal;pip._internal.autocomplete()', expect_error=True, ) @@ -107,8 +110,7 @@ def test_completion_for_default_parameters(script): """ res, env = setup_completion(script, 'pip --', '1') - assert '--help' in res.stdout,\ - "autocomplete function could not complete ``--``" + assert '--help' in res.stdout, "autocomplete function could not complete ``--``" def test_completion_option_for_command(script): @@ -117,8 +119,7 @@ def test_completion_option_for_command(script): """ res, env = setup_completion(script, 'pip search --', '2') - assert '--help' in res.stdout,\ - "autocomplete function could not complete ``--``" + assert '--help' in res.stdout, "autocomplete function could not complete ``--``" def test_completion_short_option(script): @@ -128,8 +129,9 @@ def test_completion_short_option(script): res, env = setup_completion(script, 'pip -', '1') - assert '-h' in res.stdout.split(),\ - "autocomplete function could not complete short options after ``-``" + assert ( + '-h' in res.stdout.split() + ), "autocomplete function could not complete short options after ``-``" def test_completion_short_option_for_command(script): @@ -140,8 +142,9 @@ def test_completion_short_option_for_command(script): res, env = setup_completion(script, 'pip search -', '2') - assert '-h' in res.stdout.split(),\ - "autocomplete function could not complete short options after ``-``" + assert ( + '-h' in res.stdout.split() + ), "autocomplete function could not complete short options after ``-``" @pytest.mark.parametrize('flag', ['--bash', '--zsh', '--fish']) diff --git a/tests/functional/test_configuration.py b/tests/functional/test_configuration.py index 2ff02134051..8ca408fb2c4 100644 --- a/tests/functional/test_configuration.py +++ b/tests/functional/test_configuration.py @@ -15,7 +15,6 @@ def test_no_options_passed_should_error(script): class TestBasicLoading(ConfigurationMixin): - @pytest.mark.skip("Can't modify underlying file for any mode") def test_reads_file_appropriately(self, script): contents = """ @@ -45,10 +44,9 @@ def test_listing_is_correct(self, script): result = script.pip("config", "list") - lines = list(filter( - lambda x: x.startswith("test.listing-"), - result.stdout.splitlines() - )) + lines = list( + filter(lambda x: x.startswith("test.listing-"), result.stdout.splitlines()) + ) expected = """ test.listing-alpha='1' diff --git a/tests/functional/test_download.py b/tests/functional/test_download.py index 4cbfb5665a3..b6fd6756922 100644 --- a/tests/functional/test_download.py +++ b/tests/functional/test_download.py @@ -8,9 +8,9 @@ def fake_wheel(data, wheel_path): - data.packages.join( - 'simple.dist-0.1-py2.py3-none-any.whl' - ).copy(data.packages.join(wheel_path)) + data.packages.join('simple.dist-0.1-py2.py3-none-any.whl').copy( + data.packages.join(wheel_path) + ) @pytest.mark.network @@ -21,8 +21,10 @@ def test_download_if_requested(script): result = script.pip( 'download', '-d', 'pip_downloads', 'INITools==0.1', expect_error=True ) - assert Path('scratch') / 'pip_downloads' / 'INITools-0.1.tar.gz' \ + assert ( + Path('scratch') / 'pip_downloads' / 'INITools-0.1.tar.gz' in result.files_created + ) assert script.site_packages / 'initools' not in result.files_created @@ -33,9 +35,7 @@ def test_basic_download_setuptools(script): """ result = script.pip('download', 'setuptools') setuptools_prefix = str(Path('scratch') / 'setuptools') - assert any( - path.startswith(setuptools_prefix) for path in result.files_created - ) + assert any(path.startswith(setuptools_prefix) for path in result.files_created) def test_download_wheel(script, data): @@ -43,15 +43,9 @@ def test_download_wheel(script, data): Test using "pip download" to download a *.whl archive. """ result = script.pip( - 'download', - '--no-index', - '-f', data.packages, - '-d', '.', 'meta' - ) - assert ( - Path('scratch') / 'meta-1.0-py2.py3-none-any.whl' - in result.files_created + 'download', '--no-index', '-f', data.packages, '-d', '.', 'meta' ) + assert Path('scratch') / 'meta-1.0-py2.py3-none-any.whl' in result.files_created assert script.site_packages / 'piptestpackage' not in result.files_created @@ -61,11 +55,19 @@ def test_single_download_from_requirements_file(script): It should support download (in the scratch path) from PyPi from a requirements file """ - script.scratch_path.join("test-req.txt").write(textwrap.dedent(""" + script.scratch_path.join("test-req.txt").write( + textwrap.dedent( + """ INITools==0.1 - """)) + """ + ) + ) result = script.pip( - 'download', '-r', script.scratch_path / 'test-req.txt', '-d', '.', + 'download', + '-r', + script.scratch_path / 'test-req.txt', + '-d', + '.', expect_error=True, ) assert Path('scratch') / 'INITools-0.1.tar.gz' in result.files_created @@ -78,13 +80,11 @@ def test_basic_download_should_download_dependencies(script): It should download dependencies (in the scratch path) """ result = script.pip( - 'download', 'Paste[openid]==1.7.5.1', '-d', '.', expect_error=True, + 'download', 'Paste[openid]==1.7.5.1', '-d', '.', expect_error=True ) assert Path('scratch') / 'Paste-1.7.5.1.tar.gz' in result.files_created openid_tarball_prefix = str(Path('scratch') / 'python-openid-') - assert any( - path.startswith(openid_tarball_prefix) for path in result.files_created - ) + assert any(path.startswith(openid_tarball_prefix) for path in result.files_created) assert script.site_packages / 'openid' not in result.files_created @@ -94,10 +94,7 @@ def test_download_wheel_archive(script, data): """ wheel_filename = 'colander-0.9.9-py2.py3-none-any.whl' wheel_path = '/'.join((data.find_links, wheel_filename)) - result = script.pip( - 'download', wheel_path, - '-d', '.', '--no-deps' - ) + result = script.pip('download', wheel_path, '-d', '.', '--no-deps') assert Path('scratch') / wheel_filename in result.files_created @@ -109,8 +106,7 @@ def test_download_should_download_wheel_deps(script, data): dep_filename = 'translationstring-1.1.tar.gz' wheel_path = '/'.join((data.find_links, wheel_filename)) result = script.pip( - 'download', wheel_path, - '-d', '.', '--find-links', data.find_links, '--no-index' + 'download', wheel_path, '-d', '.', '--find-links', data.find_links, '--no-index' ) assert Path('scratch') / wheel_filename in result.files_created assert Path('scratch') / dep_filename in result.files_created @@ -121,32 +117,46 @@ def test_download_should_skip_existing_files(script): """ It should not download files already existing in the scratch dir """ - script.scratch_path.join("test-req.txt").write(textwrap.dedent(""" + script.scratch_path.join("test-req.txt").write( + textwrap.dedent( + """ INITools==0.1 - """)) + """ + ) + ) result = script.pip( - 'download', '-r', script.scratch_path / 'test-req.txt', '-d', '.', + 'download', + '-r', + script.scratch_path / 'test-req.txt', + '-d', + '.', expect_error=True, ) assert Path('scratch') / 'INITools-0.1.tar.gz' in result.files_created assert script.site_packages / 'initools' not in result.files_created # adding second package to test-req.txt - script.scratch_path.join("test-req.txt").write(textwrap.dedent(""" + script.scratch_path.join("test-req.txt").write( + textwrap.dedent( + """ INITools==0.1 python-openid==2.2.5 - """)) + """ + ) + ) # only the second package should be downloaded result = script.pip( - 'download', '-r', script.scratch_path / 'test-req.txt', '-d', '.', + 'download', + '-r', + script.scratch_path / 'test-req.txt', + '-d', + '.', expect_error=True, ) openid_tarball_prefix = str(Path('scratch') / 'python-openid-') - assert any( - path.startswith(openid_tarball_prefix) for path in result.files_created - ) + assert any(path.startswith(openid_tarball_prefix) for path in result.files_created) assert Path('scratch') / 'INITools-0.1.tar.gz' not in result.files_created assert script.site_packages / 'initools' not in result.files_created assert script.site_packages / 'openid' not in result.files_created @@ -160,10 +170,7 @@ def test_download_vcs_link(script): result = script.pip( 'download', '-d', '.', 'git+git://github.com/pypa/pip-test-package.git' ) - assert ( - Path('scratch') / 'pip-test-package-0.1.1.zip' - in result.files_created - ) + assert Path('scratch') / 'pip-test-package-0.1.1.zip' in result.files_created assert script.site_packages / 'piptestpackage' not in result.files_created @@ -175,16 +182,18 @@ def test_only_binary_set_then_download_specific_platform(script, data): fake_wheel(data, 'fake-1.0-py2.py3-none-any.whl') result = script.pip( - 'download', '--no-index', '--find-links', data.find_links, + 'download', + '--no-index', + '--find-links', + data.find_links, '--only-binary=:all:', - '--dest', '.', - '--platform', 'linux_x86_64', - 'fake' - ) - assert ( - Path('scratch') / 'fake-1.0-py2.py3-none-any.whl' - in result.files_created + '--dest', + '.', + '--platform', + 'linux_x86_64', + 'fake', ) + assert Path('scratch') / 'fake-1.0-py2.py3-none-any.whl' in result.files_created def test_no_deps_set_then_download_specific_platform(script, data): @@ -195,16 +204,18 @@ def test_no_deps_set_then_download_specific_platform(script, data): fake_wheel(data, 'fake-1.0-py2.py3-none-any.whl') result = script.pip( - 'download', '--no-index', '--find-links', data.find_links, + 'download', + '--no-index', + '--find-links', + data.find_links, '--no-deps', - '--dest', '.', - '--platform', 'linux_x86_64', - 'fake' - ) - assert ( - Path('scratch') / 'fake-1.0-py2.py3-none-any.whl' - in result.files_created + '--dest', + '.', + '--platform', + 'linux_x86_64', + 'fake', ) + assert Path('scratch') / 'fake-1.0-py2.py3-none-any.whl' in result.files_created def test_download_specific_platform_fails(script, data): @@ -215,9 +226,14 @@ def test_download_specific_platform_fails(script, data): fake_wheel(data, 'fake-1.0-py2.py3-none-any.whl') result = script.pip( - 'download', '--no-index', '--find-links', data.find_links, - '--dest', '.', - '--platform', 'linux_x86_64', + 'download', + '--no-index', + '--find-links', + data.find_links, + '--dest', + '.', + '--platform', + 'linux_x86_64', 'fake', expect_error=True, ) @@ -232,11 +248,16 @@ def test_no_binary_set_then_download_specific_platform_fails(script, data): fake_wheel(data, 'fake-1.0-py2.py3-none-any.whl') result = script.pip( - 'download', '--no-index', '--find-links', data.find_links, + 'download', + '--no-index', + '--find-links', + data.find_links, '--only-binary=:all:', '--no-binary=fake', - '--dest', '.', - '--platform', 'linux_x86_64', + '--dest', + '.', + '--platform', + 'linux_x86_64', 'fake', expect_error=True, ) @@ -253,23 +274,30 @@ def test_download_specify_platform(script, data): # Confirm that universal wheels are returned even for specific # platforms. result = script.pip( - 'download', '--no-index', '--find-links', data.find_links, + 'download', + '--no-index', + '--find-links', + data.find_links, '--only-binary=:all:', - '--dest', '.', - '--platform', 'linux_x86_64', - 'fake' - ) - assert ( - Path('scratch') / 'fake-1.0-py2.py3-none-any.whl' - in result.files_created + '--dest', + '.', + '--platform', + 'linux_x86_64', + 'fake', ) + assert Path('scratch') / 'fake-1.0-py2.py3-none-any.whl' in result.files_created result = script.pip( - 'download', '--no-index', '--find-links', data.find_links, + 'download', + '--no-index', + '--find-links', + data.find_links, '--only-binary=:all:', - '--dest', '.', - '--platform', 'macosx_10_9_x86_64', - 'fake' + '--dest', + '.', + '--platform', + 'macosx_10_9_x86_64', + 'fake', ) data.reset() @@ -277,44 +305,63 @@ def test_download_specify_platform(script, data): fake_wheel(data, 'fake-2.0-py2.py3-none-linux_x86_64.whl') result = script.pip( - 'download', '--no-index', '--find-links', data.find_links, + 'download', + '--no-index', + '--find-links', + data.find_links, '--only-binary=:all:', - '--dest', '.', - '--platform', 'macosx_10_10_x86_64', - 'fake' + '--dest', + '.', + '--platform', + 'macosx_10_10_x86_64', + 'fake', ) assert ( - Path('scratch') / - 'fake-1.0-py2.py3-none-macosx_10_9_x86_64.whl' + Path('scratch') / 'fake-1.0-py2.py3-none-macosx_10_9_x86_64.whl' in result.files_created ) # OSX platform wheels are not backward-compatible. result = script.pip( - 'download', '--no-index', '--find-links', data.find_links, + 'download', + '--no-index', + '--find-links', + data.find_links, '--only-binary=:all:', - '--dest', '.', - '--platform', 'macosx_10_8_x86_64', + '--dest', + '.', + '--platform', + 'macosx_10_8_x86_64', 'fake', expect_error=True, ) # No linux wheel provided for this version. result = script.pip( - 'download', '--no-index', '--find-links', data.find_links, + 'download', + '--no-index', + '--find-links', + data.find_links, '--only-binary=:all:', - '--dest', '.', - '--platform', 'linux_x86_64', + '--dest', + '.', + '--platform', + 'linux_x86_64', 'fake==1', expect_error=True, ) result = script.pip( - 'download', '--no-index', '--find-links', data.find_links, + 'download', + '--no-index', + '--find-links', + data.find_links, '--only-binary=:all:', - '--dest', '.', - '--platform', 'linux_x86_64', - 'fake==2' + '--dest', + '.', + '--platform', + 'linux_x86_64', + 'fake==2', ) assert ( Path('scratch') / 'fake-2.0-py2.py3-none-linux_x86_64.whl' @@ -331,29 +378,35 @@ def test_download_platform_manylinux(script, data): # Confirm that universal wheels are returned even for specific # platforms. result = script.pip( - 'download', '--no-index', '--find-links', data.find_links, + 'download', + '--no-index', + '--find-links', + data.find_links, '--only-binary=:all:', - '--dest', '.', - '--platform', 'linux_x86_64', + '--dest', + '.', + '--platform', + 'linux_x86_64', 'fake', ) - assert ( - Path('scratch') / 'fake-1.0-py2.py3-none-any.whl' - in result.files_created - ) + assert Path('scratch') / 'fake-1.0-py2.py3-none-any.whl' in result.files_created data.reset() fake_wheel(data, 'fake-1.0-py2.py3-none-manylinux1_x86_64.whl') result = script.pip( - 'download', '--no-index', '--find-links', data.find_links, + 'download', + '--no-index', + '--find-links', + data.find_links, '--only-binary=:all:', - '--dest', '.', - '--platform', 'manylinux1_x86_64', + '--dest', + '.', + '--platform', + 'manylinux1_x86_64', 'fake', ) assert ( - Path('scratch') / - 'fake-1.0-py2.py3-none-manylinux1_x86_64.whl' + Path('scratch') / 'fake-1.0-py2.py3-none-manylinux1_x86_64.whl' in result.files_created ) @@ -363,10 +416,15 @@ def test_download_platform_manylinux(script, data): data.reset() fake_wheel(data, 'fake-1.0-py2.py3-none-linux_x86_64.whl') result = script.pip( - 'download', '--no-index', '--find-links', data.find_links, + 'download', + '--no-index', + '--find-links', + data.find_links, '--only-binary=:all:', - '--dest', '.', - '--platform', 'linux_x86_64', + '--dest', + '.', + '--platform', + 'linux_x86_64', 'fake', expect_error=True, ) @@ -379,39 +437,56 @@ def test_download_specify_python_version(script, data): """ fake_wheel(data, 'fake-1.0-py2.py3-none-any.whl') result = script.pip( - 'download', '--no-index', '--find-links', data.find_links, + 'download', + '--no-index', + '--find-links', + data.find_links, '--only-binary=:all:', - '--dest', '.', - '--python-version', '2', - 'fake' - ) - assert ( - Path('scratch') / 'fake-1.0-py2.py3-none-any.whl' - in result.files_created + '--dest', + '.', + '--python-version', + '2', + 'fake', ) + assert Path('scratch') / 'fake-1.0-py2.py3-none-any.whl' in result.files_created result = script.pip( - 'download', '--no-index', '--find-links', data.find_links, + 'download', + '--no-index', + '--find-links', + data.find_links, '--only-binary=:all:', - '--dest', '.', - '--python-version', '3', - 'fake' + '--dest', + '.', + '--python-version', + '3', + 'fake', ) result = script.pip( - 'download', '--no-index', '--find-links', data.find_links, + 'download', + '--no-index', + '--find-links', + data.find_links, '--only-binary=:all:', - '--dest', '.', - '--python-version', '27', - 'fake' + '--dest', + '.', + '--python-version', + '27', + 'fake', ) result = script.pip( - 'download', '--no-index', '--find-links', data.find_links, + 'download', + '--no-index', + '--find-links', + data.find_links, '--only-binary=:all:', - '--dest', '.', - '--python-version', '33', - 'fake' + '--dest', + '.', + '--python-version', + '33', + 'fake', ) data.reset() @@ -420,45 +495,59 @@ def test_download_specify_python_version(script, data): # No py3 provided for version 1. result = script.pip( - 'download', '--no-index', '--find-links', data.find_links, + 'download', + '--no-index', + '--find-links', + data.find_links, '--only-binary=:all:', - '--dest', '.', - '--python-version', '3', + '--dest', + '.', + '--python-version', + '3', 'fake==1.0', expect_error=True, ) result = script.pip( - 'download', '--no-index', '--find-links', data.find_links, + 'download', + '--no-index', + '--find-links', + data.find_links, '--only-binary=:all:', - '--dest', '.', - '--python-version', '2', - 'fake' - ) - assert ( - Path('scratch') / 'fake-1.0-py2-none-any.whl' - in result.files_created + '--dest', + '.', + '--python-version', + '2', + 'fake', ) + assert Path('scratch') / 'fake-1.0-py2-none-any.whl' in result.files_created result = script.pip( - 'download', '--no-index', '--find-links', data.find_links, + 'download', + '--no-index', + '--find-links', + data.find_links, '--only-binary=:all:', - '--dest', '.', - '--python-version', '26', - 'fake' + '--dest', + '.', + '--python-version', + '26', + 'fake', ) result = script.pip( - 'download', '--no-index', '--find-links', data.find_links, + 'download', + '--no-index', + '--find-links', + data.find_links, '--only-binary=:all:', - '--dest', '.', - '--python-version', '3', - 'fake' - ) - assert ( - Path('scratch') / 'fake-2.0-py3-none-any.whl' - in result.files_created + '--dest', + '.', + '--python-version', + '3', + 'fake', ) + assert Path('scratch') / 'fake-2.0-py3-none-any.whl' in result.files_created def test_download_specify_abi(script, data): @@ -468,32 +557,46 @@ def test_download_specify_abi(script, data): """ fake_wheel(data, 'fake-1.0-py2.py3-none-any.whl') result = script.pip( - 'download', '--no-index', '--find-links', data.find_links, + 'download', + '--no-index', + '--find-links', + data.find_links, '--only-binary=:all:', - '--dest', '.', - '--implementation', 'fk', - '--abi', 'fake_abi', - 'fake' - ) - assert ( - Path('scratch') / 'fake-1.0-py2.py3-none-any.whl' - in result.files_created + '--dest', + '.', + '--implementation', + 'fk', + '--abi', + 'fake_abi', + 'fake', ) + assert Path('scratch') / 'fake-1.0-py2.py3-none-any.whl' in result.files_created result = script.pip( - 'download', '--no-index', '--find-links', data.find_links, + 'download', + '--no-index', + '--find-links', + data.find_links, '--only-binary=:all:', - '--dest', '.', - '--implementation', 'fk', - '--abi', 'none', - 'fake' + '--dest', + '.', + '--implementation', + 'fk', + '--abi', + 'none', + 'fake', ) result = script.pip( - 'download', '--no-index', '--find-links', data.find_links, + 'download', + '--no-index', + '--find-links', + data.find_links, '--only-binary=:all:', - '--dest', '.', - '--abi', 'cp27m', + '--dest', + '.', + '--abi', + 'cp27m', 'fake', expect_error=True, ) @@ -501,14 +604,22 @@ def test_download_specify_abi(script, data): data.reset() fake_wheel(data, 'fake-1.0-fk2-fakeabi-fake_platform.whl') result = script.pip( - 'download', '--no-index', '--find-links', data.find_links, + 'download', + '--no-index', + '--find-links', + data.find_links, '--only-binary=:all:', - '--dest', '.', - '--python-version', '2', - '--implementation', 'fk', - '--platform', 'fake_platform', - '--abi', 'fakeabi', - 'fake' + '--dest', + '.', + '--python-version', + '2', + '--implementation', + 'fk', + '--platform', + 'fake_platform', + '--abi', + 'fakeabi', + 'fake', ) assert ( Path('scratch') / 'fake-1.0-fk2-fakeabi-fake_platform.whl' @@ -516,12 +627,19 @@ def test_download_specify_abi(script, data): ) result = script.pip( - 'download', '--no-index', '--find-links', data.find_links, + 'download', + '--no-index', + '--find-links', + data.find_links, '--only-binary=:all:', - '--dest', '.', - '--implementation', 'fk', - '--platform', 'fake_platform', - '--abi', 'none', + '--dest', + '.', + '--implementation', + 'fk', + '--platform', + 'fake_platform', + '--abi', + 'none', 'fake', expect_error=True, ) @@ -534,52 +652,65 @@ def test_download_specify_implementation(script, data): """ fake_wheel(data, 'fake-1.0-py2.py3-none-any.whl') result = script.pip( - 'download', '--no-index', '--find-links', data.find_links, + 'download', + '--no-index', + '--find-links', + data.find_links, '--only-binary=:all:', - '--dest', '.', - '--implementation', 'fk', - 'fake' - ) - assert ( - Path('scratch') / 'fake-1.0-py2.py3-none-any.whl' - in result.files_created + '--dest', + '.', + '--implementation', + 'fk', + 'fake', ) + assert Path('scratch') / 'fake-1.0-py2.py3-none-any.whl' in result.files_created data.reset() fake_wheel(data, 'fake-1.0-fk2.fk3-none-any.whl') result = script.pip( - 'download', '--no-index', '--find-links', data.find_links, + 'download', + '--no-index', + '--find-links', + data.find_links, '--only-binary=:all:', - '--dest', '.', - '--implementation', 'fk', - 'fake' - ) - assert ( - Path('scratch') / 'fake-1.0-fk2.fk3-none-any.whl' - in result.files_created + '--dest', + '.', + '--implementation', + 'fk', + 'fake', ) + assert Path('scratch') / 'fake-1.0-fk2.fk3-none-any.whl' in result.files_created data.reset() fake_wheel(data, 'fake-1.0-fk3-none-any.whl') result = script.pip( - 'download', '--no-index', '--find-links', data.find_links, + 'download', + '--no-index', + '--find-links', + data.find_links, '--only-binary=:all:', - '--dest', '.', - '--implementation', 'fk', - '--python-version', '3', - 'fake' - ) - assert ( - Path('scratch') / 'fake-1.0-fk3-none-any.whl' - in result.files_created + '--dest', + '.', + '--implementation', + 'fk', + '--python-version', + '3', + 'fake', ) + assert Path('scratch') / 'fake-1.0-fk3-none-any.whl' in result.files_created result = script.pip( - 'download', '--no-index', '--find-links', data.find_links, + 'download', + '--no-index', + '--find-links', + data.find_links, '--only-binary=:all:', - '--dest', '.', - '--implementation', 'fk', - '--python-version', '2', + '--dest', + '.', + '--implementation', + 'fk', + '--python-version', + '2', 'fake', expect_error=True, ) @@ -590,9 +721,7 @@ def test_download_exit_status_code_when_no_requirements(script): Test download exit status code when no requirements specified """ result = script.pip('download', expect_error=True) - assert ( - "You must give at least one requirement to download" in result.stderr - ) + assert "You must give at least one requirement to download" in result.stderr assert result.returncode == ERROR @@ -610,40 +739,40 @@ def test_download_prefer_binary_when_tarball_higher_than_wheel(script, data): 'download', '--prefer-binary', '--no-index', - '-f', data.packages, - '-d', '.', 'source' - ) - assert ( - Path('scratch') / 'source-0.8-py2.py3-none-any.whl' - in result.files_created - ) - assert ( - Path('scratch') / 'source-1.0.tar.gz' - not in result.files_created + '-f', + data.packages, + '-d', + '.', + 'source', ) + assert Path('scratch') / 'source-0.8-py2.py3-none-any.whl' in result.files_created + assert Path('scratch') / 'source-1.0.tar.gz' not in result.files_created def test_download_prefer_binary_when_wheel_doesnt_satisfy_req(script, data): fake_wheel(data, 'source-0.8-py2.py3-none-any.whl') - script.scratch_path.join("test-req.txt").write(textwrap.dedent(""" + script.scratch_path.join("test-req.txt").write( + textwrap.dedent( + """ source>0.9 - """)) + """ + ) + ) result = script.pip( 'download', '--prefer-binary', '--no-index', - '-f', data.packages, - '-d', '.', - '-r', script.scratch_path / 'test-req.txt' - ) + '-f', + data.packages, + '-d', + '.', + '-r', + script.scratch_path / 'test-req.txt', + ) + assert Path('scratch') / 'source-1.0.tar.gz' in result.files_created assert ( - Path('scratch') / 'source-1.0.tar.gz' - in result.files_created - ) - assert ( - Path('scratch') / 'source-0.8-py2.py3-none-any.whl' - not in result.files_created + Path('scratch') / 'source-0.8-py2.py3-none-any.whl' not in result.files_created ) @@ -652,10 +781,10 @@ def test_download_prefer_binary_when_only_tarball_exists(script, data): 'download', '--prefer-binary', '--no-index', - '-f', data.packages, - '-d', '.', 'source' - ) - assert ( - Path('scratch') / 'source-1.0.tar.gz' - in result.files_created + '-f', + data.packages, + '-d', + '.', + 'source', ) + assert Path('scratch') / 'source-1.0.tar.gz' in result.files_created diff --git a/tests/functional/test_freeze.py b/tests/functional/test_freeze.py index d51029281f6..eb6baa5197e 100644 --- a/tests/functional/test_freeze.py +++ b/tests/functional/test_freeze.py @@ -7,7 +7,9 @@ import pytest from tests.lib import ( - _create_test_package, _create_test_package_with_srcdir, need_bzr, + _create_test_package, + _create_test_package_with_srcdir, + need_bzr, need_mercurial, ) @@ -37,8 +39,7 @@ def banner(msg): return '\n========== %s ==========\n' % msg assert checker.check_output(expected, actual, ELLIPSIS), ( - banner('EXPECTED') + expected + banner('ACTUAL') + actual + - banner(6 * '=') + banner('EXPECTED') + expected + banner('ACTUAL') + actual + banner(6 * '=') ) @@ -51,19 +52,23 @@ def test_basic_freeze(script): currently it is not). """ - script.scratch_path.join("initools-req.txt").write(textwrap.dedent("""\ + script.scratch_path.join("initools-req.txt").write( + textwrap.dedent( + """\ simple==2.0 # and something else to test out: simple2<=3.0 - """)) - script.pip_install_local( - '-r', script.scratch_path / 'initools-req.txt', + """ + ) ) + script.pip_install_local('-r', script.scratch_path / 'initools-req.txt') result = script.pip('freeze', expect_stderr=True) - expected = textwrap.dedent("""\ + expected = textwrap.dedent( + """\ ...simple==2.0 simple2==3.0... - <BLANKLINE>""") + <BLANKLINE>""" + ) _check_output(result.stdout, expected) @@ -80,39 +85,42 @@ def test_freeze_with_invalid_names(script): def fake_install(pkgname, dest): egg_info_path = os.path.join( - dest, '{}-1.0-py{}.{}.egg-info'.format( - pkgname.replace('-', '_'), - sys.version_info[0], - sys.version_info[1] - ) + dest, + '{}-1.0-py{}.{}.egg-info'.format( + pkgname.replace('-', '_'), sys.version_info[0], sys.version_info[1] + ), ) with open(egg_info_path, 'w') as egg_info_file: - egg_info_file.write(textwrap.dedent("""\ + egg_info_file.write( + textwrap.dedent( + """\ Metadata-Version: 1.0 Name: {} Version: 1.0 - """.format(pkgname) - )) + """.format( + pkgname + ) + ) + ) valid_pkgnames = ('middle-dash', 'middle_underscore', 'middle.dot') invalid_pkgnames = ( - '-leadingdash', '_leadingunderscore', '.leadingdot', - 'trailingdash-', 'trailingunderscore_', 'trailingdot.' + '-leadingdash', + '_leadingunderscore', + '.leadingdot', + 'trailingdash-', + 'trailingunderscore_', + 'trailingdot.', ) for pkgname in valid_pkgnames + invalid_pkgnames: fake_install(pkgname, script.site_packages_path) result = script.pip('freeze', expect_stderr=True) for pkgname in valid_pkgnames: - _check_output( - result.stdout, - '...{}==1.0...'.format(pkgname.replace('_', '-')) - ) + _check_output(result.stdout, '...{}==1.0...'.format(pkgname.replace('_', '-'))) for pkgname in invalid_pkgnames: _check_output( result.stderr, - '...Could not parse requirement: {}\n...'.format( - pkgname.replace('_', '-') - ) + '...Could not parse requirement: {}\n...'.format(pkgname.replace('_', '-')), ) @@ -123,14 +131,13 @@ def test_freeze_svn(script, tmpdir): checkout_path = _create_test_package(script, vcs='svn') # Install with develop - script.run( - 'python', 'setup.py', 'develop', - cwd=checkout_path, expect_stderr=True - ) + script.run('python', 'setup.py', 'develop', cwd=checkout_path, expect_stderr=True) result = script.pip('freeze', expect_stderr=True) - expected = textwrap.dedent("""\ + expected = textwrap.dedent( + """\ ...-e svn+...#egg=version_pkg - ...""") + ...""" + ) _check_output(result.stdout, expected) @@ -144,14 +151,11 @@ def test_freeze_exclude_editable(script, tmpdir): pkg_version = _create_test_package(script) result = script.run( - 'git', 'clone', pkg_version, 'pip-test-package', - expect_stderr=True, + 'git', 'clone', pkg_version, 'pip-test-package', expect_stderr=True ) repo_dir = script.scratch_path / 'pip-test-package' result = script.run( - 'python', 'setup.py', 'develop', - cwd=repo_dir, - expect_stderr=True, + 'python', 'setup.py', 'develop', cwd=repo_dir, expect_stderr=True ) result = script.pip('freeze', '--exclude-editable', expect_stderr=True) expected = textwrap.dedent( @@ -172,14 +176,11 @@ def test_freeze_git_clone(script, tmpdir): pkg_version = _create_test_package(script) result = script.run( - 'git', 'clone', pkg_version, 'pip-test-package', - expect_stderr=True, + 'git', 'clone', pkg_version, 'pip-test-package', expect_stderr=True ) repo_dir = script.scratch_path / 'pip-test-package' result = script.run( - 'python', 'setup.py', 'develop', - cwd=repo_dir, - expect_stderr=True, + 'python', 'setup.py', 'develop', cwd=repo_dir, expect_stderr=True ) result = script.pip('freeze', expect_stderr=True) expected = textwrap.dedent( @@ -191,22 +192,25 @@ def test_freeze_git_clone(script, tmpdir): _check_output(result.stdout, expected) result = script.pip( - 'freeze', '-f', '%s#egg=pip_test_package' % repo_dir, - expect_stderr=True, + 'freeze', '-f', '%s#egg=pip_test_package' % repo_dir, expect_stderr=True ) expected = textwrap.dedent( """ -f %(repo)s#egg=pip_test_package... -e git+...#egg=version_pkg ... - """ % {'repo': repo_dir}, + """ + % {'repo': repo_dir} ).strip() _check_output(result.stdout, expected) # Check that slashes in branch or tag names are translated. # See also issue #1083: https://github.com/pypa/pip/issues/1083 script.run( - 'git', 'checkout', '-b', 'branch/name/with/slash', + 'git', + 'checkout', + '-b', + 'branch/name/with/slash', cwd=repo_dir, expect_stderr=True, ) @@ -237,14 +241,11 @@ def test_freeze_git_clone_srcdir(script, tmpdir): pkg_version = _create_test_package_with_srcdir(script) result = script.run( - 'git', 'clone', pkg_version, 'pip-test-package', - expect_stderr=True, + 'git', 'clone', pkg_version, 'pip-test-package', expect_stderr=True ) repo_dir = script.scratch_path / 'pip-test-package' result = script.run( - 'python', 'setup.py', 'develop', - cwd=repo_dir / 'subdir', - expect_stderr=True, + 'python', 'setup.py', 'develop', cwd=repo_dir / 'subdir', expect_stderr=True ) result = script.pip('freeze', expect_stderr=True) expected = textwrap.dedent( @@ -256,15 +257,15 @@ def test_freeze_git_clone_srcdir(script, tmpdir): _check_output(result.stdout, expected) result = script.pip( - 'freeze', '-f', '%s#egg=pip_test_package' % repo_dir, - expect_stderr=True, + 'freeze', '-f', '%s#egg=pip_test_package' % repo_dir, expect_stderr=True ) expected = textwrap.dedent( """ -f %(repo)s#egg=pip_test_package... -e git+...#egg=version_pkg&subdirectory=subdir ... - """ % {'repo': repo_dir}, + """ + % {'repo': repo_dir} ).strip() _check_output(result.stdout, expected) @@ -278,47 +279,56 @@ def test_freeze_git_remote(script, tmpdir): pkg_version = _create_test_package(script) result = script.run( - 'git', 'clone', pkg_version, 'pip-test-package', - expect_stderr=True, + 'git', 'clone', pkg_version, 'pip-test-package', expect_stderr=True ) repo_dir = script.scratch_path / 'pip-test-package' result = script.run( - 'python', 'setup.py', 'develop', - cwd=repo_dir, - expect_stderr=True, + 'python', 'setup.py', 'develop', cwd=repo_dir, expect_stderr=True ) origin_remote = pkg_version other_remote = pkg_version + '-other' # check frozen remote after clone result = script.pip('freeze', expect_stderr=True) - expected = textwrap.dedent( - """ + expected = ( + textwrap.dedent( + """ ...-e git+{remote}@...#egg=version_pkg ... """ - ).format(remote=origin_remote).strip() + ) + .format(remote=origin_remote) + .strip() + ) _check_output(result.stdout, expected) # check frozen remote when there is no remote named origin script.run('git', 'remote', 'remove', 'origin', cwd=repo_dir) script.run('git', 'remote', 'add', 'other', other_remote, cwd=repo_dir) result = script.pip('freeze', expect_stderr=True) - expected = textwrap.dedent( - """ + expected = ( + textwrap.dedent( + """ ...-e git+{remote}@...#egg=version_pkg ... """ - ).format(remote=other_remote).strip() + ) + .format(remote=other_remote) + .strip() + ) _check_output(result.stdout, expected) # when there are more than one origin, priority is given to the # remote named origin script.run('git', 'remote', 'add', 'origin', origin_remote, cwd=repo_dir) result = script.pip('freeze', expect_stderr=True) - expected = textwrap.dedent( - """ + expected = ( + textwrap.dedent( + """ ...-e git+{remote}@...#egg=version_pkg ... """ - ).format(remote=origin_remote).strip() + ) + .format(remote=origin_remote) + .strip() + ) _check_output(result.stdout, expected) @@ -332,14 +342,11 @@ def test_freeze_mercurial_clone(script, tmpdir): pkg_version = _create_test_package(script, vcs='hg') result = script.run( - 'hg', 'clone', pkg_version, 'pip-test-package', - expect_stderr=True, + 'hg', 'clone', pkg_version, 'pip-test-package', expect_stderr=True ) repo_dir = script.scratch_path / 'pip-test-package' result = script.run( - 'python', 'setup.py', 'develop', - cwd=repo_dir, - expect_stderr=True, + 'python', 'setup.py', 'develop', cwd=repo_dir, expect_stderr=True ) result = script.pip('freeze', expect_stderr=True) expected = textwrap.dedent( @@ -351,15 +358,15 @@ def test_freeze_mercurial_clone(script, tmpdir): _check_output(result.stdout, expected) result = script.pip( - 'freeze', '-f', '%s#egg=pip_test_package' % repo_dir, - expect_stderr=True, + 'freeze', '-f', '%s#egg=pip_test_package' % repo_dir, expect_stderr=True ) expected = textwrap.dedent( """ -f %(repo)s#egg=pip_test_package... ...-e hg+...#egg=version_pkg ... - """ % {'repo': repo_dir}, + """ + % {'repo': repo_dir} ).strip() _check_output(result.stdout, expected) @@ -375,34 +382,38 @@ def test_freeze_bazaar_clone(script, tmpdir): except OSError as e: pytest.fail('Invoking `bzr` failed: %s' % e) + result = script.run('bzr', 'checkout', checkout_path, 'bzr-package') result = script.run( - 'bzr', 'checkout', checkout_path, 'bzr-package' - ) - result = script.run( - 'python', 'setup.py', 'develop', + 'python', + 'setup.py', + 'develop', cwd=script.scratch_path / 'bzr-package', expect_stderr=True, ) result = script.pip('freeze', expect_stderr=True) - expected = textwrap.dedent("""\ + expected = textwrap.dedent( + """\ ...-e bzr+file://...@1#egg=version_pkg - ...""") + ...""" + ) _check_output(result.stdout, expected) result = script.pip( - 'freeze', '-f', - '%s/#egg=django-wikiapp' % checkout_path, - expect_stderr=True, + 'freeze', '-f', '%s/#egg=django-wikiapp' % checkout_path, expect_stderr=True ) - expected = textwrap.dedent("""\ + expected = textwrap.dedent( + """\ -f %(repo)s/#egg=django-wikiapp ...-e bzr+file://...@...#egg=version_pkg - ...""" % {'repo': checkout_path}) + ...""" + % {'repo': checkout_path} + ) _check_output(result.stdout, expected) # used by the test_freeze_with_requirement_* tests below -_freeze_req_opts = textwrap.dedent("""\ +_freeze_req_opts = textwrap.dedent( + """\ # Unchanged requirements below this line -r ignore.txt --requirement ignore.txt @@ -416,7 +427,8 @@ def test_freeze_bazaar_clone(script, tmpdir): --extra-index-url http://ignore --find-links http://ignore --index-url http://ignore -""") +""" +) def test_freeze_with_requirement_option(script): @@ -425,21 +437,25 @@ def test_freeze_with_requirement_option(script): """ - script.scratch_path.join("hint.txt").write(textwrap.dedent("""\ + script.scratch_path.join("hint.txt").write( + textwrap.dedent( + """\ INITools==0.1 NoExist==4.2 # A comment that ensures end of line comments work. simple==3.0; python_version > '1.0' - """) + _freeze_req_opts) + """ + ) + + _freeze_req_opts + ) result = script.pip_install_local('initools==0.2') result = script.pip_install_local('simple') - result = script.pip( - 'freeze', '--requirement', 'hint.txt', - expect_stderr=True, - ) - expected = textwrap.dedent("""\ + result = script.pip('freeze', '--requirement', 'hint.txt', expect_stderr=True) + expected = textwrap.dedent( + """\ INITools==0.2 simple==3.0 - """) + """ + ) expected += _freeze_req_opts expected += "## The following requirements were added by pip freeze:..." _check_output(result.stdout, expected) @@ -455,35 +471,55 @@ def test_freeze_with_requirement_option_multiple(script): --requirement hints """ - script.scratch_path.join('hint1.txt').write(textwrap.dedent("""\ + script.scratch_path.join('hint1.txt').write( + textwrap.dedent( + """\ INITools==0.1 NoExist==4.2 simple==3.0; python_version > '1.0' - """) + _freeze_req_opts) - script.scratch_path.join('hint2.txt').write(textwrap.dedent("""\ + """ + ) + + _freeze_req_opts + ) + script.scratch_path.join('hint2.txt').write( + textwrap.dedent( + """\ NoExist2==2.0 simple2==1.0 - """) + _freeze_req_opts) + """ + ) + + _freeze_req_opts + ) result = script.pip_install_local('initools==0.2') result = script.pip_install_local('simple') result = script.pip_install_local('simple2==1.0') result = script.pip_install_local('meta') result = script.pip( - 'freeze', '--requirement', 'hint1.txt', '--requirement', 'hint2.txt', + 'freeze', + '--requirement', + 'hint1.txt', + '--requirement', + 'hint2.txt', expect_stderr=True, ) - expected = textwrap.dedent("""\ + expected = textwrap.dedent( + """\ INITools==0.2 simple==1.0 - """) + """ + ) expected += _freeze_req_opts - expected += textwrap.dedent("""\ + expected += textwrap.dedent( + """\ simple2==1.0 - """) + """ + ) expected += "## The following requirements were added by pip freeze:" - expected += '\n' + textwrap.dedent("""\ + expected += '\n' + textwrap.dedent( + """\ ...meta==1.0... - """) + """ + ) _check_output(result.stdout, expected) assert ( "Requirement file [hint1.txt] contains NoExist==4.2, but that " @@ -503,28 +539,36 @@ def test_freeze_with_requirement_option_package_repeated_one_file(script): Test freezing with single requirements file that contains a package multiple times """ - script.scratch_path.join('hint1.txt').write(textwrap.dedent("""\ + script.scratch_path.join('hint1.txt').write( + textwrap.dedent( + """\ simple2 simple2 NoExist - """) + _freeze_req_opts) + """ + ) + + _freeze_req_opts + ) result = script.pip_install_local('simple2==1.0') result = script.pip_install_local('meta') - result = script.pip( - 'freeze', '--requirement', 'hint1.txt', - expect_stderr=True, - ) - expected_out = textwrap.dedent("""\ + result = script.pip('freeze', '--requirement', 'hint1.txt', expect_stderr=True) + expected_out = textwrap.dedent( + """\ simple2==1.0 - """) + """ + ) expected_out += _freeze_req_opts expected_out += "## The following requirements were added by pip freeze:" - expected_out += '\n' + textwrap.dedent("""\ + expected_out += '\n' + textwrap.dedent( + """\ ...meta==1.0... - """) + """ + ) _check_output(result.stdout, expected_out) - err1 = ("Requirement file [hint1.txt] contains NoExist, " - "but that package is not installed\n") + err1 = ( + "Requirement file [hint1.txt] contains NoExist, " + "but that package is not installed\n" + ) err2 = "Requirement simple2 included multiple times [hint1.txt]\n" assert err1 in result.stderr assert err2 in result.stderr @@ -536,34 +580,52 @@ def test_freeze_with_requirement_option_package_repeated_multi_file(script): """ Test freezing with multiple requirements file that contain a package """ - script.scratch_path.join('hint1.txt').write(textwrap.dedent("""\ + script.scratch_path.join('hint1.txt').write( + textwrap.dedent( + """\ simple - """) + _freeze_req_opts) - script.scratch_path.join('hint2.txt').write(textwrap.dedent("""\ + """ + ) + + _freeze_req_opts + ) + script.scratch_path.join('hint2.txt').write( + textwrap.dedent( + """\ simple NoExist - """) + _freeze_req_opts) + """ + ) + + _freeze_req_opts + ) result = script.pip_install_local('simple==1.0') result = script.pip_install_local('meta') result = script.pip( - 'freeze', '--requirement', 'hint1.txt', - '--requirement', 'hint2.txt', + 'freeze', + '--requirement', + 'hint1.txt', + '--requirement', + 'hint2.txt', expect_stderr=True, ) - expected_out = textwrap.dedent("""\ + expected_out = textwrap.dedent( + """\ simple==1.0 - """) + """ + ) expected_out += _freeze_req_opts expected_out += "## The following requirements were added by pip freeze:" - expected_out += '\n' + textwrap.dedent("""\ + expected_out += '\n' + textwrap.dedent( + """\ ...meta==1.0... - """) + """ + ) _check_output(result.stdout, expected_out) - err1 = ("Requirement file [hint2.txt] contains NoExist, but that " - "package is not installed\n") - err2 = ("Requirement simple included multiple times " - "[hint1.txt, hint2.txt]\n") + err1 = ( + "Requirement file [hint2.txt] contains NoExist, but that " + "package is not installed\n" + ) + err2 = "Requirement simple included multiple times " "[hint1.txt, hint2.txt]\n" assert err1 in result.stderr assert err2 in result.stderr # there shouldn't be any other 'is not installed' warnings @@ -577,13 +639,13 @@ def test_freeze_user(script, virtualenv, data): """ script.pip('download', 'setuptools', 'wheel', '-d', data.packages) virtualenv.system_site_packages = True - script.pip_install_local('--find-links', data.find_links, - '--user', 'simple==2.0') - script.pip_install_local('--find-links', data.find_links, - 'simple2==3.0') + script.pip_install_local('--find-links', data.find_links, '--user', 'simple==2.0') + script.pip_install_local('--find-links', data.find_links, 'simple2==3.0') result = script.pip('freeze', '--user', expect_stderr=True) - expected = textwrap.dedent("""\ + expected = textwrap.dedent( + """\ simple==2.0 - <BLANKLINE>""") + <BLANKLINE>""" + ) _check_output(result.stdout, expected) assert 'simple2' not in result.stdout diff --git a/tests/functional/test_hash.py b/tests/functional/test_hash.py index 441f72e75d4..f3b5db434f6 100644 --- a/tests/functional/test_hash.py +++ b/tests/functional/test_hash.py @@ -3,25 +3,30 @@ def test_basic_hash(script, tmpdir): """Run 'pip hash' through its default behavior.""" - expected = ('--hash=sha256:2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425' - 'e73043362938b9824') + expected = ( + '--hash=sha256:2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425' + 'e73043362938b9824' + ) result = script.pip('hash', _hello_file(tmpdir)) assert expected in str(result) def test_good_algo_option(script, tmpdir): """Make sure the -a option works.""" - expected = ('--hash=sha512:9b71d224bd62f3785d96d46ad3ea3d73319bfbc2890caad' - 'ae2dff72519673ca72323c3d99ba5c11d7c7acc6e14b8c5da0c4663475c2e' - '5c3adef46f73bcdec043') + expected = ( + '--hash=sha512:9b71d224bd62f3785d96d46ad3ea3d73319bfbc2890caad' + 'ae2dff72519673ca72323c3d99ba5c11d7c7acc6e14b8c5da0c4663475c2e' + '5c3adef46f73bcdec043' + ) result = script.pip('hash', '-a', 'sha512', _hello_file(tmpdir)) assert expected in str(result) def test_bad_algo_option(script, tmpdir): """Make sure the -a option raises an error when given a bad operand.""" - result = script.pip('hash', '-a', 'invalidname', _hello_file(tmpdir), - expect_error=True) + result = script.pip( + 'hash', '-a', 'invalidname', _hello_file(tmpdir), expect_error=True + ) assert "invalid choice: 'invalidname'" in str(result) diff --git a/tests/functional/test_help.py b/tests/functional/test_help.py index 1c3bc0eb348..ea338450d47 100644 --- a/tests/functional/test_help.py +++ b/tests/functional/test_help.py @@ -85,6 +85,7 @@ def test_help_commands_equally_functional(in_memory_pip): continue assert ( - in_memory_pip.pip('help', name).stdout == - in_memory_pip.pip(name, '--help').stdout != "" + in_memory_pip.pip('help', name).stdout + == in_memory_pip.pip(name, '--help').stdout + != "" ) diff --git a/tests/functional/test_install.py b/tests/functional/test_install.py index 385db77ae34..32b7c4d879b 100644 --- a/tests/functional/test_install.py +++ b/tests/functional/test_install.py @@ -11,8 +11,14 @@ from pip._internal.status_codes import ERROR from pip._internal.utils.misc import rmtree from tests.lib import ( - _create_svn_repo, _create_test_package, create_test_package_with_setup, - need_bzr, need_mercurial, path_to_url, pyversion, pyversion_tuple, + _create_svn_repo, + _create_test_package, + create_test_package_with_setup, + need_bzr, + need_mercurial, + path_to_url, + pyversion, + pyversion_tuple, requirements_file, ) from tests.lib.local_repos import local_checkout @@ -26,41 +32,56 @@ def test_pep518_uses_build_env(script, data, common_wheels, command, variant): script.pip("uninstall", "-y", "setuptools") elif variant == 'bad_setuptools': setuptools_init_path = script.site_packages_path.join( - "setuptools", "__init__.py") + "setuptools", "__init__.py" + ) with open(setuptools_init_path, 'a') as f: f.write('\nraise ImportError("toto")') else: raise ValueError(variant) script.pip( - command, '--no-index', '-f', common_wheels, '-f', data.packages, - data.src.join("pep518-3.0"), use_module=True + command, + '--no-index', + '-f', + common_wheels, + '-f', + data.packages, + data.src.join("pep518-3.0"), + use_module=True, ) -def test_pep518_with_user_pip(script, virtualenv, pip_src, - data, common_wheels): +def test_pep518_with_user_pip(script, virtualenv, pip_src, data, common_wheels): virtualenv.system_site_packages = True - script.pip("install", "--ignore-installed", "--user", pip_src, - use_module=True) + script.pip("install", "--ignore-installed", "--user", pip_src, use_module=True) system_pip_dir = script.site_packages_path / 'pip' system_pip_dir.rmtree() system_pip_dir.mkdir() with open(system_pip_dir / '__init__.py', 'w') as fp: fp.write('raise ImportError\n') script.pip( - 'wheel', '--no-index', '-f', common_wheels, '-f', data.packages, - data.src.join("pep518-3.0"), use_module=True, + 'wheel', + '--no-index', + '-f', + common_wheels, + '-f', + data.packages, + data.src.join("pep518-3.0"), + use_module=True, ) def test_pep518_with_extra_and_markers(script, data, common_wheels): script.pip( - 'wheel', '--no-index', - '-f', common_wheels, - '-f', data.find_links, + 'wheel', + '--no-index', + '-f', + common_wheels, + '-f', + data.find_links, # Add tests/data/packages4, which contains a wheel for # simple==1.0 (needed by requires_simple_extra[extra]). - '-f', data.find_links4, + '-f', + data.find_links4, data.src.join("pep518_with_extra_and_markers-1.0"), use_module=True, ) @@ -81,9 +102,7 @@ def test_pip_second_command_line_interface_works(script, data): args.extend(['install', 'INITools==0.2']) args.extend(['-f', data.packages]) result = script.run(*args, **kwargs) - egg_info_folder = ( - script.site_packages / 'INITools-0.2-py%s.egg-info' % pyversion - ) + egg_info_folder = script.site_packages / 'INITools-0.2-py%s.egg-info' % pyversion initools_folder = script.site_packages / 'initools' assert egg_info_folder in result.files_created, str(result) assert initools_folder in result.files_created, str(result) @@ -112,9 +131,7 @@ def test_basic_install_from_pypi(script): Test installing a package from PyPI. """ result = script.pip('install', '-vvv', 'INITools==0.2') - egg_info_folder = ( - script.site_packages / 'INITools-0.2-py%s.egg-info' % pyversion - ) + egg_info_folder = script.site_packages / 'INITools-0.2-py%s.egg-info' % pyversion initools_folder = script.site_packages / 'initools' assert egg_info_folder in result.files_created, str(result) assert initools_folder in result.files_created, str(result) @@ -144,10 +161,7 @@ def test_basic_install_editable_from_svn(script): """ checkout_path = _create_test_package(script) repo_url = _create_svn_repo(script, checkout_path) - result = script.pip( - 'install', - '-e', 'svn+' + repo_url + '#egg=version-pkg' - ) + result = script.pip('install', '-e', 'svn+' + repo_url + '#egg=version-pkg') result.assert_installed('version-pkg', with_files=['.svn']) @@ -164,8 +178,7 @@ def test_basic_install_editable_from_git(script, tmpdir): @pytest.mark.network -def test_install_editable_from_git_autobuild_wheel( - script, tmpdir, common_wheels): +def test_install_editable_from_git_autobuild_wheel(script, tmpdir, common_wheels): script.pip('install', 'wheel', '--no-index', '-f', common_wheels) _test_install_editable_from_git(script, tmpdir) @@ -184,11 +197,11 @@ def test_install_editable_uninstalls_existing(data, script, tmpdir): result.assert_installed('piptestpackage', editable=False) result = script.pip( - 'install', '-e', - '%s#egg=pip-test-package' % - local_checkout( - 'git+https://github.com/pypa/pip-test-package.git', - tmpdir.join("cache"), + 'install', + '-e', + '%s#egg=pip-test-package' + % local_checkout( + 'git+https://github.com/pypa/pip-test-package.git', tmpdir.join("cache") ), ) result.assert_installed('pip-test-package', with_files=['.git']) @@ -209,10 +222,7 @@ def test_install_editable_uninstalls_existing_from_path(script, data): result.assert_installed('simplewheel', editable=False) assert simple_folder in result.files_created, str(result.stdout) - result = script.pip( - 'install', '-e', - to_install, - ) + result = script.pip('install', '-e', to_install) install_path = script.site_packages / 'simplewheel.egg-link' assert install_path in result.files_created, str(result) assert 'Found existing installation: simplewheel 1.0' in result.stdout @@ -257,9 +267,10 @@ def test_vcs_url_urlquote_normalization(script, tmpdir): Test that urlquoted characters are normalized for repo URL comparison. """ script.pip( - 'install', '-e', - '%s/#egg=django-wikiapp' % - local_checkout( + 'install', + '-e', + '%s/#egg=django-wikiapp' + % local_checkout( 'bzr+http://bazaar.launchpad.net/%7Edjango-wikiapp/django-wikiapp' '/release-0.1', tmpdir.join("cache"), @@ -274,9 +285,7 @@ def test_basic_install_from_local_directory(script, data): to_install = data.packages.join("FSPkg") result = script.pip('install', to_install, expect_error=False) fspkg_folder = script.site_packages / 'fspkg' - egg_info_folder = ( - script.site_packages / 'FSPkg-0.1.dev0-py%s.egg-info' % pyversion - ) + egg_info_folder = script.site_packages / 'FSPkg-0.1.dev0-py%s.egg-info' % pyversion assert fspkg_folder in result.files_created, str(result.stdout) assert egg_info_folder in result.files_created, str(result) @@ -285,34 +294,26 @@ def test_basic_install_relative_directory(script, data): """ Test installing a requirement using a relative path. """ - egg_info_file = ( - script.site_packages / 'FSPkg-0.1.dev0-py%s.egg-info' % pyversion - ) - egg_link_file = ( - script.site_packages / 'FSPkg.egg-link' - ) + egg_info_file = script.site_packages / 'FSPkg-0.1.dev0-py%s.egg-info' % pyversion + egg_link_file = script.site_packages / 'FSPkg.egg-link' package_folder = script.site_packages / 'fspkg' # Compute relative install path to FSPkg from scratch path. full_rel_path = data.packages.join('FSPkg') - script.scratch_path - full_rel_url = ( - 'file:' + full_rel_path.replace(os.path.sep, '/') + '#egg=FSPkg' - ) + full_rel_url = 'file:' + full_rel_path.replace(os.path.sep, '/') + '#egg=FSPkg' embedded_rel_path = script.scratch_path.join(full_rel_path) # For each relative path, install as either editable or not using either # URLs with egg links or not. for req_path in (full_rel_path, full_rel_url, embedded_rel_path): # Regular install. - result = script.pip('install', req_path, - cwd=script.scratch_path) + result = script.pip('install', req_path, cwd=script.scratch_path) assert egg_info_file in result.files_created, str(result) assert package_folder in result.files_created, str(result) script.pip('uninstall', '-y', 'fspkg') # Editable install. - result = script.pip('install', '-e' + req_path, - cwd=script.scratch_path) + result = script.pip('install', '-e' + req_path, cwd=script.scratch_path) assert egg_link_file in result.files_created, str(result) script.pip('uninstall', '-y', 'fspkg') @@ -340,14 +341,14 @@ def test_hashed_install_success(script, data, tmpdir): scenes). """ - file_url = path_to_url( - (data.packages / 'simple-1.0.tar.gz').abspath) + file_url = path_to_url((data.packages / 'simple-1.0.tar.gz').abspath) with requirements_file( - 'simple2==1.0 --hash=sha256:9336af72ca661e6336eb87bc7de3e8844d853e' - '3848c2b9bbd2e8bf01db88c2c7\n' - '{simple} --hash=sha256:393043e672415891885c9a2a0929b1af95fb866d6c' - 'a016b42d2e6ce53619b653'.format(simple=file_url), - tmpdir) as reqs_file: + 'simple2==1.0 --hash=sha256:9336af72ca661e6336eb87bc7de3e8844d853e' + '3848c2b9bbd2e8bf01db88c2c7\n' + '{simple} --hash=sha256:393043e672415891885c9a2a0929b1af95fb866d6c' + 'a016b42d2e6ce53619b653'.format(simple=file_url), + tmpdir, + ) as reqs_file: script.pip_install_local('-r', reqs_file.abspath, expect_error=False) @@ -359,17 +360,16 @@ def test_hashed_install_failure(script, tmpdir): kinds of hashes are in test_req.py. """ - with requirements_file('simple2==1.0 --hash=sha256:9336af72ca661e6336eb87b' - 'c7de3e8844d853e3848c2b9bbd2e8bf01db88c2c\n', - tmpdir) as reqs_file: - result = script.pip_install_local('-r', - reqs_file.abspath, - expect_error=True) + with requirements_file( + 'simple2==1.0 --hash=sha256:9336af72ca661e6336eb87b' + 'c7de3e8844d853e3848c2b9bbd2e8bf01db88c2c\n', + tmpdir, + ) as reqs_file: + result = script.pip_install_local('-r', reqs_file.abspath, expect_error=True) assert len(result.files_created) == 0 -def test_install_from_local_directory_with_symlinks_to_directories( - script, data): +def test_install_from_local_directory_with_symlinks_to_directories(script, data): """ Test installing from a local directory containing symlinks to directories. """ @@ -435,9 +435,7 @@ def test_install_curdir(script, data): rmtree(egg_info) result = script.pip('install', curdir, cwd=run_from, expect_error=False) fspkg_folder = script.site_packages / 'fspkg' - egg_info_folder = ( - script.site_packages / 'FSPkg-0.1.dev0-py%s.egg-info' % pyversion - ) + egg_info_folder = script.site_packages / 'FSPkg-0.1.dev0-py%s.egg-info' % pyversion assert fspkg_folder in result.files_created, str(result.stdout) assert egg_info_folder in result.files_created, str(result) @@ -449,9 +447,7 @@ def test_install_pardir(script, data): run_from = data.packages.join("FSPkg", "fspkg") result = script.pip('install', pardir, cwd=run_from, expect_error=False) fspkg_folder = script.site_packages / 'fspkg' - egg_info_folder = ( - script.site_packages / 'FSPkg-0.1.dev0-py%s.egg-info' % pyversion - ) + egg_info_folder = script.site_packages / 'FSPkg-0.1.dev0-py%s.egg-info' % pyversion assert fspkg_folder in result.files_created, str(result.stdout) assert egg_info_folder in result.files_created, str(result) @@ -463,8 +459,8 @@ def test_install_global_option(script): (In particular those that disable the actual install action) """ result = script.pip( - 'install', '--global-option=--version', "INITools==0.1", - expect_stderr=True) + 'install', '--global-option=--version', "INITools==0.1", expect_stderr=True + ) assert '0.1\n' in result.stdout @@ -493,13 +489,15 @@ def test_install_using_install_option_and_editable(script, tmpdir): script.scratch_path.join(folder).mkdir() url = 'git+git://github.com/pypa/pip-test-package' result = script.pip( - 'install', '-e', '%s#egg=pip-test-package' % - local_checkout(url, tmpdir.join("cache")), + 'install', + '-e', + '%s#egg=pip-test-package' % local_checkout(url, tmpdir.join("cache")), '--install-option=--script-dir=%s' % folder, - expect_stderr=True) + expect_stderr=True, + ) script_file = ( - script.venv / 'src' / 'pip-test-package' / - folder / 'pip-test-package' + script.exe + script.venv / 'src' / 'pip-test-package' / folder / 'pip-test-package' + + script.exe ) assert script_file in result.files_created @@ -512,9 +510,12 @@ def test_install_global_option_using_editable(script, tmpdir): """ url = 'hg+http://bitbucket.org/runeh/anyjson' result = script.pip( - 'install', '--global-option=--version', '-e', + 'install', + '--global-option=--version', + '-e', '%s@0.2.5#egg=anyjson' % local_checkout(url, tmpdir.join("cache")), - expect_stderr=True) + expect_stderr=True, + ) assert 'Successfully installed anyjson' in result.stdout @@ -529,10 +530,12 @@ def test_install_package_with_same_name_in_curdir(script): assert egg_folder in result.files_created, str(result) -mock100_setup_py = textwrap.dedent('''\ +mock100_setup_py = textwrap.dedent( + '''\ from setuptools import setup setup(name='mock', - version='100.1')''') + version='100.1')''' +) def test_install_folder_using_dot_slash(script): @@ -580,8 +583,7 @@ def test_install_package_which_contains_dev_in_name(script): result = script.pip('install', 'django-devserver==0.0.4') devserver_folder = script.site_packages / 'devserver' egg_info_folder = ( - script.site_packages / 'django_devserver-0.0.4-py%s.egg-info' % - pyversion + script.site_packages / 'django_devserver-0.0.4-py%s.egg-info' % pyversion ) assert devserver_folder in result.files_created, str(result.stdout) assert egg_info_folder in result.files_created, str(result) @@ -593,35 +595,28 @@ def test_install_package_with_target(script): """ target_dir = script.scratch_path / 'target' result = script.pip_install_local('-t', target_dir, "simple==1.0") - assert Path('scratch') / 'target' / 'simple' in result.files_created, ( - str(result) - ) + assert Path('scratch') / 'target' / 'simple' in result.files_created, str(result) # Test repeated call without --upgrade, no files should have changed result = script.pip_install_local( - '-t', target_dir, "simple==1.0", expect_stderr=True, + '-t', target_dir, "simple==1.0", expect_stderr=True ) assert not Path('scratch') / 'target' / 'simple' in result.files_updated # Test upgrade call, check that new version is installed - result = script.pip_install_local('--upgrade', '-t', - target_dir, "simple==2.0") - assert Path('scratch') / 'target' / 'simple' in result.files_updated, ( - str(result) - ) - egg_folder = ( - Path('scratch') / 'target' / 'simple-2.0-py%s.egg-info' % pyversion) - assert egg_folder in result.files_created, ( - str(result) - ) + result = script.pip_install_local('--upgrade', '-t', target_dir, "simple==2.0") + assert Path('scratch') / 'target' / 'simple' in result.files_updated, str(result) + egg_folder = Path('scratch') / 'target' / 'simple-2.0-py%s.egg-info' % pyversion + assert egg_folder in result.files_created, str(result) # Test install and upgrade of single-module package result = script.pip_install_local('-t', target_dir, 'singlemodule==0.0.0') singlemodule_py = Path('scratch') / 'target' / 'singlemodule.py' assert singlemodule_py in result.files_created, str(result) - result = script.pip_install_local('-t', target_dir, 'singlemodule==0.0.1', - '--upgrade') + result = script.pip_install_local( + '-t', target_dir, 'singlemodule==0.0.1', '--upgrade' + ) assert singlemodule_py in result.files_updated, str(result) @@ -636,7 +631,9 @@ def test_install_with_target_and_scripts_no_warning(script, common_wheels): target_dir = script.scratch_path / 'target' pkga_path = script.scratch_path / 'pkga' pkga_path.mkdir() - pkga_path.join("setup.py").write(textwrap.dedent(""" + pkga_path.join("setup.py").write( + textwrap.dedent( + """ from setuptools import setup setup(name='pkga', version='0.1', @@ -645,10 +642,16 @@ def test_install_with_target_and_scripts_no_warning(script, common_wheels): 'console_scripts': ['pkga=pkga:main'] } ) - """)) - pkga_path.join("pkga.py").write(textwrap.dedent(""" + """ + ) + ) + pkga_path.join("pkga.py").write( + textwrap.dedent( + """ def main(): pass - """)) + """ + ) + ) result = script.pip('install', '--target', target_dir, pkga_path) # This assertion isn't actually needed, if we get the script warning # the script.pip() call will fail with "stderr not expected". But we @@ -662,19 +665,21 @@ def test_install_package_with_root(script, data): """ root_dir = script.scratch_path / 'root' result = script.pip( - 'install', '--root', root_dir, '-f', data.find_links, '--no-index', + 'install', + '--root', + root_dir, + '-f', + data.find_links, + '--no-index', 'simple==1.0', ) normal_install_path = ( - script.base_path / script.site_packages / 'simple-1.0-py%s.egg-info' % - pyversion + script.base_path / script.site_packages / 'simple-1.0-py%s.egg-info' % pyversion ) # use distutils to change the root exactly how the --root option does it from distutils.util import change_root - root_path = change_root( - os.path.join(script.scratch, 'root'), - normal_install_path - ) + + root_path = change_root(os.path.join(script.scratch, 'root'), normal_install_path) assert root_path in result.files_created, str(result) # Should show find-links location in output @@ -688,15 +693,21 @@ def test_install_package_with_prefix(script, data): """ prefix_path = script.scratch_path / 'prefix' result = script.pip( - 'install', '--prefix', prefix_path, '-f', data.find_links, - '--no-binary', 'simple', '--no-index', 'simple==1.0', + 'install', + '--prefix', + prefix_path, + '-f', + data.find_links, + '--no-binary', + 'simple', + '--no-index', + 'simple==1.0', ) rel_prefix_path = script.scratch / 'prefix' - install_path = ( - distutils.sysconfig.get_python_lib(prefix=rel_prefix_path) / - 'simple-1.0-py{}.egg-info'.format(pyversion) - ) + install_path = distutils.sysconfig.get_python_lib( + prefix=rel_prefix_path + ) / 'simple-1.0-py{}.egg-info'.format(pyversion) assert install_path in result.files_created, str(result) @@ -704,15 +715,20 @@ def test_install_editable_with_prefix(script): # make a dummy project pkga_path = script.scratch_path / 'pkga' pkga_path.mkdir() - pkga_path.join("setup.py").write(textwrap.dedent(""" + pkga_path.join("setup.py").write( + textwrap.dedent( + """ from setuptools import setup setup(name='pkga', version='0.1') - """)) + """ + ) + ) if hasattr(sys, "pypy_version_info"): site_packages = os.path.join( - 'prefix', 'lib', 'python{}'.format(pyversion), 'site-packages') + 'prefix', 'lib', 'python{}'.format(pyversion), 'site-packages' + ) else: site_packages = distutils.sysconfig.get_python_lib(prefix='prefix') @@ -723,8 +739,7 @@ def test_install_editable_with_prefix(script): # install pkga package into the absolute prefix directory prefix_path = script.scratch_path / 'prefix' - result = script.pip( - 'install', '--editable', pkga_path, '--prefix', prefix_path) + result = script.pip('install', '--editable', pkga_path, '--prefix', prefix_path) # assert pkga is installed at correct location install_path = script.scratch / site_packages / 'pkga.egg-link' @@ -737,13 +752,18 @@ def test_install_package_conflict_prefix_and_user(script, data): """ prefix_path = script.scratch_path / 'prefix' result = script.pip( - 'install', '-f', data.find_links, '--no-index', '--user', - '--prefix', prefix_path, 'simple==1.0', - expect_error=True, quiet=True, - ) - assert ( - "Can not combine '--user' and '--prefix'" in result.stderr + 'install', + '-f', + data.find_links, + '--no-index', + '--user', + '--prefix', + prefix_path, + 'simple==1.0', + expect_error=True, + quiet=True, ) + assert "Can not combine '--user' and '--prefix'" in result.stderr # skip on win/py3 for now, see issue #782 @@ -756,11 +776,9 @@ def test_install_package_that_emits_unicode(script, data): """ to_install = data.packages.join("BrokenEmitsUTF8") result = script.pip( - 'install', to_install, expect_error=True, expect_temp=True, quiet=True, - ) - assert ( - 'FakeError: this package designed to fail on install' in result.stdout + 'install', to_install, expect_error=True, expect_temp=True, quiet=True ) + assert 'FakeError: this package designed to fail on install' in result.stdout assert 'UnicodeDecodeError' not in result.stdout @@ -830,9 +848,7 @@ def test_url_incorrect_case_no_index(script, data): where the incorrect case is given in the name of the package to install rather than in a requirements file. """ - result = script.pip( - 'install', '--no-index', '-f', data.find_links, "upper", - ) + result = script.pip('install', '--no-index', '-f', data.find_links, "upper") # only Upper-2.0.tar.gz should get installed. egg_folder = script.site_packages / 'Upper-1.0-py%s.egg-info' % pyversion @@ -848,8 +864,7 @@ def test_url_incorrect_case_file_index(script, data): rather than in a requirements file. """ result = script.pip( - 'install', '--index-url', data.find_links3, "dinner", - expect_stderr=True, + 'install', '--index-url', data.find_links3, "dinner", expect_stderr=True ) # only Upper-2.0.tar.gz should get installed. @@ -873,9 +888,7 @@ def test_compiles_pyc(script): # There are many locations for the __init__.pyc file so attempt to find # any of them - exists = [ - os.path.exists(script.site_packages_path / "initools/__init__.pyc"), - ] + exists = [os.path.exists(script.site_packages_path / "initools/__init__.pyc")] exists += glob.glob( script.site_packages_path / "initools/__pycache__/__init__*.pyc" @@ -894,9 +907,7 @@ def test_no_compiles_pyc(script): # There are many locations for the __init__.pyc file so attempt to find # any of them - exists = [ - os.path.exists(script.site_packages_path / "initools/__init__.pyc"), - ] + exists = [os.path.exists(script.site_packages_path / "initools/__init__.pyc")] exists += glob.glob( script.site_packages_path / "initools/__pycache__/__init__*.pyc" @@ -908,23 +919,31 @@ def test_no_compiles_pyc(script): def test_install_upgrade_editable_depending_on_other_editable(script): script.scratch_path.join("pkga").mkdir() pkga_path = script.scratch_path / 'pkga' - pkga_path.join("setup.py").write(textwrap.dedent(""" + pkga_path.join("setup.py").write( + textwrap.dedent( + """ from setuptools import setup setup(name='pkga', version='0.1') - """)) + """ + ) + ) script.pip('install', '--editable', pkga_path) result = script.pip('list', '--format=freeze') assert "pkga==0.1" in result.stdout script.scratch_path.join("pkgb").mkdir() pkgb_path = script.scratch_path / 'pkgb' - pkgb_path.join("setup.py").write(textwrap.dedent(""" + pkgb_path.join("setup.py").write( + textwrap.dedent( + """ from setuptools import setup setup(name='pkgb', version='0.1', install_requires=['pkga']) - """)) + """ + ) + ) script.pip('install', '--upgrade', '--editable', pkgb_path, '--no-index') result = script.pip('list', '--format=freeze') assert "pkgb==0.1" in result.stdout @@ -947,20 +966,19 @@ def test_install_subprocess_output_handling(script, data): # If the install fails, then we *should* show the output... but only once, # even if --verbose is given. - result = script.pip(*(args + ["--global-option=--fail"]), - expect_error=True) + result = script.pip(*(args + ["--global-option=--fail"]), expect_error=True) assert 1 == result.stdout.count("I DIE, I DIE") - result = script.pip(*(args + ["--global-option=--fail", "--verbose"]), - expect_error=True) + result = script.pip( + *(args + ["--global-option=--fail", "--verbose"]), expect_error=True + ) assert 1 == result.stdout.count("I DIE, I DIE") def test_install_log(script, data, tmpdir): # test that verbose logs go to "--log" file f = tmpdir.join("log.txt") - args = ['--log=%s' % f, - 'install', data.src.join('chattymodule')] + args = ['--log=%s' % f, 'install', data.src.join('chattymodule')] result = script.pip(*args) assert 0 == result.stdout.count("HELLO FROM CHATTYMODULE") with open(f, 'r') as fp: @@ -980,9 +998,15 @@ def test_install_topological_sort(script, data): def test_install_wheel_broken(script, data, common_wheels): script.pip('install', 'wheel', '--no-index', '-f', common_wheels) res = script.pip( - 'install', '--no-index', '-f', data.find_links, '-f', common_wheels, + 'install', + '--no-index', + '-f', + data.find_links, + '-f', + common_wheels, 'wheelbroken', - expect_stderr=True) + expect_stderr=True, + ) assert "Successfully installed wheelbroken-0.1" in str(res), str(res) @@ -990,9 +1014,15 @@ def test_install_wheel_broken(script, data, common_wheels): def test_cleanup_after_failed_wheel(script, data, common_wheels): script.pip('install', 'wheel', '--no-index', '-f', common_wheels) res = script.pip( - 'install', '--no-index', '-f', data.find_links, '-f', common_wheels, + 'install', + '--no-index', + '-f', + data.find_links, + '-f', + common_wheels, 'wheelbrokenafter', - expect_stderr=True) + expect_stderr=True, + ) # One of the effects of not cleaning up is broken scripts: script_py = script.bin_path / "script.py" assert script_py.exists, script_py @@ -1005,10 +1035,14 @@ def test_cleanup_after_failed_wheel(script, data, common_wheels): @pytest.mark.network def test_install_builds_wheels(script, data, common_wheels): # We need to use a subprocess to get the right value on Windows. - res = script.run('python', '-c', ( - 'from pip._internal.utils import appdirs; ' - 'print(appdirs.user_cache_dir("pip"))' - )) + res = script.run( + 'python', + '-c', + ( + 'from pip._internal.utils import appdirs; ' + 'print(appdirs.user_cache_dir("pip"))' + ), + ) wheels_cache = os.path.join(res.stdout.rstrip('\n'), 'wheels') # NB This incidentally tests a local tree + tarball inputs # see test_install_editable_from_git_autobuild_wheel for editable @@ -1016,10 +1050,19 @@ def test_install_builds_wheels(script, data, common_wheels): script.pip('install', 'wheel', '--no-index', '-f', common_wheels) to_install = data.packages.join('requires_wheelbroken_upper') res = script.pip( - 'install', '--no-index', '-f', data.find_links, '-f', common_wheels, - to_install, expect_stderr=True) - expected = ("Successfully installed requires-wheelbroken-upper-0" - " upper-2.0 wheelbroken-0.1") + 'install', + '--no-index', + '-f', + data.find_links, + '-f', + common_wheels, + to_install, + expect_stderr=True, + ) + expected = ( + "Successfully installed requires-wheelbroken-upper-0" + " upper-2.0 wheelbroken-0.1" + ) # Must have installed it all assert expected in str(res), str(res) wheels = [] @@ -1040,22 +1083,28 @@ def test_install_builds_wheels(script, data, common_wheels): # wheelbroken has to run install assert "Running setup.py install for wheelb" in str(res), str(res) # We want to make sure we used the correct implementation tag - assert wheels == [ - "Upper-2.0-{}-none-any.whl".format(pep425tags.implementation_tag), - ] + assert wheels == ["Upper-2.0-{}-none-any.whl".format(pep425tags.implementation_tag)] @pytest.mark.network -def test_install_no_binary_disables_building_wheels( - script, data, common_wheels): +def test_install_no_binary_disables_building_wheels(script, data, common_wheels): script.pip('install', 'wheel', '--no-index', '-f', common_wheels) to_install = data.packages.join('requires_wheelbroken_upper') res = script.pip( - 'install', '--no-index', '--no-binary=upper', '-f', data.find_links, - '-f', common_wheels, - to_install, expect_stderr=True) - expected = ("Successfully installed requires-wheelbroken-upper-0" - " upper-2.0 wheelbroken-0.1") + 'install', + '--no-index', + '--no-binary=upper', + '-f', + data.find_links, + '-f', + common_wheels, + to_install, + expect_stderr=True, + ) + expected = ( + "Successfully installed requires-wheelbroken-upper-0" + " upper-2.0 wheelbroken-0.1" + ) # Must have installed it all assert expected in str(res), str(res) # and built wheels for wheelbroken only @@ -1076,12 +1125,18 @@ def test_install_no_binary_disables_cached_wheels(script, data, common_wheels): script.pip('install', 'wheel', '--no-index', '-f', common_wheels) # Seed the cache script.pip( - 'install', '--no-index', '-f', data.find_links, '-f', common_wheels, - 'upper') + 'install', '--no-index', '-f', data.find_links, '-f', common_wheels, 'upper' + ) script.pip('uninstall', 'upper', '-y') res = script.pip( - 'install', '--no-index', '--no-binary=:all:', '-f', data.find_links, - 'upper', expect_stderr=True) + 'install', + '--no-index', + '--no-binary=:all:', + '-f', + data.find_links, + 'upper', + expect_stderr=True, + ) assert "Successfully installed upper-2.0" in str(res), str(res) # No wheel building for upper, which was blacklisted assert "Running setup.py bdist_wheel for upper" not in str(res), str(res) @@ -1092,17 +1147,23 @@ def test_install_no_binary_disables_cached_wheels(script, data, common_wheels): def test_install_editable_with_wrong_egg_name(script): script.scratch_path.join("pkga").mkdir() pkga_path = script.scratch_path / 'pkga' - pkga_path.join("setup.py").write(textwrap.dedent(""" + pkga_path.join("setup.py").write( + textwrap.dedent( + """ from setuptools import setup setup(name='pkga', version='0.1') - """)) + """ + ) + ) result = script.pip( - 'install', '--editable', 'file://%s#egg=pkgb' % pkga_path, - expect_error=True) - assert ("egg_info for package pkgb produced metadata " - "for project name pkga. Fix your #egg=pkgb " - "fragments.") in result.stderr + 'install', '--editable', 'file://%s#egg=pkgb' % pkga_path, expect_error=True + ) + assert ( + "egg_info for package pkgb produced metadata " + "for project name pkga. Fix your #egg=pkgb " + "fragments." + ) in result.stderr assert "Successfully installed pkga" in str(result), str(result) @@ -1128,9 +1189,7 @@ def test_double_install(script): """ Test double install passing with two same version requirements """ - result = script.pip('install', 'pip', 'pip', - use_module=True, - expect_error=False) + result = script.pip('install', 'pip', 'pip', use_module=True, expect_error=False) msg = "Double requirement given: pip (already in pip, name='pip')" assert msg not in result.stderr @@ -1140,83 +1199,112 @@ def test_double_install_fail(script): Test double install failing with two different version requirements """ result = script.pip('install', 'pip==*', 'pip==7.1.2', expect_error=True) - msg = ("Double requirement given: pip==7.1.2 (already in pip==*, " - "name='pip')") + msg = "Double requirement given: pip==7.1.2 (already in pip==*, " "name='pip')" assert msg in result.stderr def test_install_incompatible_python_requires(script, common_wheels): script.scratch_path.join("pkga").mkdir() pkga_path = script.scratch_path / 'pkga' - pkga_path.join("setup.py").write(textwrap.dedent(""" + pkga_path.join("setup.py").write( + textwrap.dedent( + """ from setuptools import setup setup(name='pkga', python_requires='<1.0', version='0.1') - """)) + """ + ) + ) script.pip( - 'install', 'setuptools>24.2', # This should not be needed - '--no-index', '-f', common_wheels, + 'install', + 'setuptools>24.2', # This should not be needed + '--no-index', + '-f', + common_wheels, ) result = script.pip('install', pkga_path, expect_error=True) - assert ("pkga requires Python '<1.0' " - "but the running Python is ") in result.stderr, str(result) + assert ( + "pkga requires Python '<1.0' " "but the running Python is " + ) in result.stderr, str(result) def test_install_incompatible_python_requires_editable(script, common_wheels): script.scratch_path.join("pkga").mkdir() pkga_path = script.scratch_path / 'pkga' - pkga_path.join("setup.py").write(textwrap.dedent(""" + pkga_path.join("setup.py").write( + textwrap.dedent( + """ from setuptools import setup setup(name='pkga', python_requires='<1.0', version='0.1') - """)) + """ + ) + ) script.pip( - 'install', 'setuptools>24.2', # This should not be needed - '--no-index', '-f', common_wheels, + 'install', + 'setuptools>24.2', # This should not be needed + '--no-index', + '-f', + common_wheels, ) - result = script.pip( - 'install', '--editable=%s' % pkga_path, expect_error=True) - assert ("pkga requires Python '<1.0' " - "but the running Python is ") in result.stderr, str(result) + result = script.pip('install', '--editable=%s' % pkga_path, expect_error=True) + assert ( + "pkga requires Python '<1.0' " "but the running Python is " + ) in result.stderr, str(result) @pytest.mark.network def test_install_incompatible_python_requires_wheel(script, common_wheels): script.scratch_path.join("pkga").mkdir() pkga_path = script.scratch_path / 'pkga' - pkga_path.join("setup.py").write(textwrap.dedent(""" + pkga_path.join("setup.py").write( + textwrap.dedent( + """ from setuptools import setup setup(name='pkga', python_requires='<1.0', version='0.1') - """)) + """ + ) + ) script.pip( - 'install', 'setuptools>24.2', # This should not be needed - '--no-index', '-f', common_wheels, + 'install', + 'setuptools>24.2', # This should not be needed + '--no-index', + '-f', + common_wheels, ) script.pip('install', 'wheel', '--no-index', '-f', common_wheels) - script.run( - 'python', 'setup.py', 'bdist_wheel', '--universal', cwd=pkga_path) - result = script.pip('install', './pkga/dist/pkga-0.1-py2.py3-none-any.whl', - expect_error=True) - assert ("pkga requires Python '<1.0' " - "but the running Python is ") in result.stderr + script.run('python', 'setup.py', 'bdist_wheel', '--universal', cwd=pkga_path) + result = script.pip( + 'install', './pkga/dist/pkga-0.1-py2.py3-none-any.whl', expect_error=True + ) + assert ( + "pkga requires Python '<1.0' " "but the running Python is " + ) in result.stderr def test_install_compatible_python_requires(script, common_wheels): script.scratch_path.join("pkga").mkdir() pkga_path = script.scratch_path / 'pkga' - pkga_path.join("setup.py").write(textwrap.dedent(""" + pkga_path.join("setup.py").write( + textwrap.dedent( + """ from setuptools import setup setup(name='pkga', python_requires='>1.0', version='0.1') - """)) + """ + ) + ) script.pip( - 'install', 'setuptools>24.2', # This should not be needed - '--no-index', '-f', common_wheels, + 'install', + 'setuptools>24.2', # This should not be needed + '--no-index', + '-f', + common_wheels, ) res = script.pip('install', pkga_path, expect_error=True) assert "Successfully installed pkga-0.1" in res.stdout, res @@ -1225,11 +1313,12 @@ def test_install_compatible_python_requires(script, common_wheels): @pytest.mark.network def test_install_pep508_with_url(script): res = script.pip( - 'install', '--no-index', + 'install', + '--no-index', 'packaging@https://files.pythonhosted.org/packages/2f/2b/' 'c681de3e1dbcd469537aefb15186b800209aa1f299d933d23b48d85c9d56/' 'packaging-15.3-py2.py3-none-any.whl#sha256=' - 'ce1a869fe039fbf7e217df36c4653d1dbe657778b2d41709593a0003584405f4' + 'ce1a869fe039fbf7e217df36c4653d1dbe657778b2d41709593a0003584405f4', ) assert "Successfully installed packaging-15.3" in str(res), str(res) @@ -1237,7 +1326,9 @@ def test_install_pep508_with_url(script): @pytest.mark.network def test_install_pep508_with_url_in_install_requires(script): pkga_path = create_test_package_with_setup( - script, name='pkga', version='1.0', + script, + name='pkga', + version='1.0', install_requires=[ 'packaging@https://files.pythonhosted.org/packages/2f/2b/' 'c681de3e1dbcd469537aefb15186b800209aa1f299d933d23b48d85c9d56/' @@ -1260,8 +1351,7 @@ def test_installing_scripts_outside_path_prints_warning(script): def test_installing_scripts_outside_path_can_suppress_warning(script): result = script.pip_install_local( - "--prefix", script.scratch_path, "--no-warn-script-location", - "script_wheel1" + "--prefix", script.scratch_path, "--no-warn-script-location", "script_wheel1" ) assert "Successfully installed script-wheel1" in result.stdout, str(result) assert "--no-warn-script-location" not in result.stderr @@ -1282,9 +1372,7 @@ def test_installed_files_recorded_in_deterministic_order(script, data): result = script.pip('install', to_install, expect_error=False) fspkg_folder = script.site_packages / 'fspkg' egg_info = 'FSPkg-0.1.dev0-py%s.egg-info' % pyversion - installed_files_path = ( - script.site_packages / egg_info / 'installed-files.txt' - ) + installed_files_path = script.site_packages / egg_info / 'installed-files.txt' assert fspkg_folder in result.files_created, str(result.stdout) assert installed_files_path in result.files_created, str(result) @@ -1297,43 +1385,30 @@ def test_installed_files_recorded_in_deterministic_order(script, data): def test_install_conflict_results_in_warning(script, data): pkgA_path = create_test_package_with_setup( - script, - name='pkgA', version='1.0', install_requires=['pkgb == 1.0'], - ) - pkgB_path = create_test_package_with_setup( - script, - name='pkgB', version='2.0', + script, name='pkgA', version='1.0', install_requires=['pkgb == 1.0'] ) + pkgB_path = create_test_package_with_setup(script, name='pkgB', version='2.0') # Install pkgA without its dependency result1 = script.pip('install', '--no-index', pkgA_path, '--no-deps') assert "Successfully installed pkgA-1.0" in result1.stdout, str(result1) # Then install an incorrect version of the dependency - result2 = script.pip( - 'install', '--no-index', pkgB_path, - expect_stderr=True, - ) + result2 = script.pip('install', '--no-index', pkgB_path, expect_stderr=True) assert "pkga 1.0 has requirement pkgb==1.0" in result2.stderr, str(result2) assert "Successfully installed pkgB-2.0" in result2.stdout, str(result2) def test_install_conflict_warning_can_be_suppressed(script, data): pkgA_path = create_test_package_with_setup( - script, - name='pkgA', version='1.0', install_requires=['pkgb == 1.0'], - ) - pkgB_path = create_test_package_with_setup( - script, - name='pkgB', version='2.0', + script, name='pkgA', version='1.0', install_requires=['pkgb == 1.0'] ) + pkgB_path = create_test_package_with_setup(script, name='pkgB', version='2.0') # Install pkgA without its dependency result1 = script.pip('install', '--no-index', pkgA_path, '--no-deps') assert "Successfully installed pkgA-1.0" in result1.stdout, str(result1) # Then install an incorrect version of the dependency; suppressing warning - result2 = script.pip( - 'install', '--no-index', pkgB_path, '--no-warn-conflicts' - ) + result2 = script.pip('install', '--no-index', pkgB_path, '--no-warn-conflicts') assert "Successfully installed pkgB-2.0" in result2.stdout, str(result2) diff --git a/tests/functional/test_install_check.py b/tests/functional/test_install_check.py index 2259ce76818..8a90df18d79 100644 --- a/tests/functional/test_install_check.py +++ b/tests/functional/test_install_check.py @@ -24,15 +24,12 @@ def test_check_install_warnings(script): # Install the first missing dependency. Only an error for the # second dependency should remain. normal_path = create_test_package_with_setup( - script, - name='normal-missing', version='0.1', + script, name='normal-missing', version='0.1' ) result = script.pip( 'install', '--no-index', normal_path, '--quiet', expect_error=True ) - expected_lines = ( - "pkga 1.0 requires special.missing, which is not installed.", - ) + expected_lines = ("pkga 1.0 requires special.missing, which is not installed.",) assert matches_expected_lines(result.stderr, expected_lines) assert result.returncode == 0 @@ -40,20 +37,15 @@ def test_check_install_warnings(script): # during the installation. This is special as the package name requires # name normalization (as in https://github.com/pypa/pip/issues/5134) missing_path = create_test_package_with_setup( - script, - name='special.missing', version='0.1', - ) - result = script.pip( - 'install', '--no-index', missing_path, '--quiet', + script, name='special.missing', version='0.1' ) + result = script.pip('install', '--no-index', missing_path, '--quiet') assert matches_expected_lines(result.stdout, []) assert matches_expected_lines(result.stderr, []) assert result.returncode == 0 # Double check that all errors are resolved in the end result = script.pip('check') - expected_lines = ( - "No broken requirements found.", - ) + expected_lines = ("No broken requirements found.",) assert matches_expected_lines(result.stdout, expected_lines) assert result.returncode == 0 diff --git a/tests/functional/test_install_cleanup.py b/tests/functional/test_install_cleanup.py index 949477cb942..d19ff731c1f 100644 --- a/tests/functional/test_install_cleanup.py +++ b/tests/functional/test_install_cleanup.py @@ -13,9 +13,7 @@ def test_cleanup_after_install(script, data): """ Test clean up after installing a package. """ - script.pip( - 'install', '--no-index', '--find-links=%s' % data.find_links, 'simple' - ) + script.pip('install', '--no-index', '--find-links=%s' % data.find_links, 'simple') build = script.venv_path / "build" src = script.venv_path / "src" assert not exists(build), "build/ dir still exists: %s" % build @@ -30,8 +28,14 @@ def test_no_clean_option_blocks_cleaning_after_install(script, data): """ build = script.base_path / 'pip-build' script.pip( - 'install', '--no-clean', '--no-index', '--build', build, - '--find-links=%s' % data.find_links, 'simple', expect_temp=True, + 'install', + '--no-clean', + '--no-index', + '--build', + build, + '--find-links=%s' % data.find_links, + 'simple', + expect_temp=True, ) assert exists(build) @@ -46,10 +50,9 @@ def test_cleanup_after_install_editable_from_hg(script, tmpdir): script.pip( 'install', '-e', - '%s#egg=ScriptTest' % - local_checkout( - 'hg+https://bitbucket.org/ianb/scripttest', - tmpdir.join("cache"), + '%s#egg=ScriptTest' + % local_checkout( + 'hg+https://bitbucket.org/ianb/scripttest', tmpdir.join("cache") ), expect_error=True, ) @@ -99,7 +102,11 @@ def test_cleanup_after_install_exception(script, data): """ # broken==0.2broken fails during install; see packages readme file result = script.pip( - 'install', '-f', data.find_links, '--no-index', 'broken==0.2broken', + 'install', + '-f', + data.find_links, + '--no-index', + 'broken==0.2broken', expect_error=True, ) build = script.venv_path / 'build' @@ -113,7 +120,11 @@ def test_cleanup_after_egg_info_exception(script, data): """ # brokenegginfo fails during egg_info; see packages readme file result = script.pip( - 'install', '-f', data.find_links, '--no-index', 'brokenegginfo==0.1', + 'install', + '-f', + data.find_links, + '--no-index', + 'brokenegginfo==0.1', expect_error=True, ) build = script.venv_path / 'build' @@ -132,9 +143,15 @@ def test_cleanup_prevented_upon_build_dir_exception(script, data): write_delete_marker_file(build_simple) build_simple.join("setup.py").write("#") result = script.pip( - 'install', '-f', data.find_links, '--no-index', 'simple', - '--build', build, - expect_error=True, expect_temp=True, + 'install', + '-f', + data.find_links, + '--no-index', + 'simple', + '--build', + build, + expect_error=True, + expect_temp=True, ) assert result.returncode == PREVIOUS_BUILD_DIR_ERROR, str(result) diff --git a/tests/functional/test_install_compat.py b/tests/functional/test_install_compat.py index 6a36da334dd..4025cfc6104 100644 --- a/tests/functional/test_install_compat.py +++ b/tests/functional/test_install_compat.py @@ -24,7 +24,8 @@ def test_debian_egg_name_workaround(script): result = script.pip('install', 'INITools==0.2', expect_error=True) egg_info = os.path.join( - script.site_packages, "INITools-0.2-py%s.egg-info" % pyversion) + script.site_packages, "INITools-0.2-py%s.egg-info" % pyversion + ) # Debian only removes pyversion for global installs, not inside a venv # so even if this test runs on a Debian/Ubuntu system with broken diff --git a/tests/functional/test_install_config.py b/tests/functional/test_install_config.py index e5c5c633af2..c7708874f9e 100644 --- a/tests/functional/test_install_config.py +++ b/tests/functional/test_install_config.py @@ -26,13 +26,13 @@ def test_command_line_options_override_env_vars(script, virtualenv): """ script.environ['PIP_INDEX_URL'] = 'https://example.com/simple/' result = script.pip('install', '-vvv', 'INITools', expect_error=True) - assert ( - "Getting page https://example.com/simple/initools" - in result.stdout - ) + assert "Getting page https://example.com/simple/initools" in result.stdout virtualenv.clear() result = script.pip( - 'install', '-vvv', '--index-url', 'https://download.zope.org/ppix', + 'install', + '-vvv', + '--index-url', + 'https://download.zope.org/ppix', 'INITools', expect_error=True, ) @@ -63,10 +63,14 @@ def _test_env_vars_override_config_file(script, virtualenv, config_file): # because there is/was a bug which only shows up in cases in which # 'config-item' and 'config_item' hash to the same value modulo the size # of the config dictionary. - (script.scratch_path / config_file).write(textwrap.dedent("""\ + (script.scratch_path / config_file).write( + textwrap.dedent( + """\ [global] no-index = 1 - """)) + """ + ) + ) result = script.pip('install', '-vvv', 'INITools', expect_error=True) assert ( "DistributionNotFound: No matching distribution found for INITools" @@ -87,24 +91,28 @@ def test_command_line_append_flags(script, virtualenv, data): """ script.environ['PIP_FIND_LINKS'] = 'https://test.pypi.org' result = script.pip( - 'install', '-vvv', 'INITools', '--trusted-host', + 'install', + '-vvv', + 'INITools', + '--trusted-host', 'test.pypi.org', expect_error=True, ) - assert ( - "Analyzing links from page https://test.pypi.org" - in result.stdout - ), str(result) + assert "Analyzing links from page https://test.pypi.org" in result.stdout, str( + result + ) virtualenv.clear() result = script.pip( - 'install', '-vvv', '--find-links', data.find_links, 'INITools', - '--trusted-host', 'test.pypi.org', + 'install', + '-vvv', + '--find-links', + data.find_links, + 'INITools', + '--trusted-host', + 'test.pypi.org', expect_error=True, ) - assert ( - "Analyzing links from page https://test.pypi.org" - in result.stdout - ) + assert "Analyzing links from page https://test.pypi.org" in result.stdout assert "Skipping link %s" % data.find_links in result.stdout @@ -114,18 +122,18 @@ def test_command_line_appends_correctly(script, data): Test multiple appending options set by environmental variables. """ - script.environ['PIP_FIND_LINKS'] = ( - 'https://test.pypi.org %s' % data.find_links - ) + script.environ['PIP_FIND_LINKS'] = 'https://test.pypi.org %s' % data.find_links result = script.pip( - 'install', '-vvv', 'INITools', '--trusted-host', + 'install', + '-vvv', + 'INITools', + '--trusted-host', 'test.pypi.org', expect_error=True, ) assert ( - "Analyzing links from page https://test.pypi.org" - in result.stdout + "Analyzing links from page https://test.pypi.org" in result.stdout ), result.stdout assert "Skipping link %s" % data.find_links in result.stdout @@ -149,36 +157,40 @@ def test_config_file_override_stack(script, virtualenv): def _test_config_file_override_stack(script, virtualenv, config_file): # set this to make pip load it script.environ['PIP_CONFIG_FILE'] = config_file - (script.scratch_path / config_file).write(textwrap.dedent("""\ + (script.scratch_path / config_file).write( + textwrap.dedent( + """\ [global] index-url = https://download.zope.org/ppix - """)) - result = script.pip('install', '-vvv', 'INITools', expect_error=True) - assert ( - "Getting page https://download.zope.org/ppix/initools" in result.stdout + """ + ) ) + result = script.pip('install', '-vvv', 'INITools', expect_error=True) + assert "Getting page https://download.zope.org/ppix/initools" in result.stdout virtualenv.clear() - (script.scratch_path / config_file).write(textwrap.dedent("""\ + (script.scratch_path / config_file).write( + textwrap.dedent( + """\ [global] index-url = https://download.zope.org/ppix [install] index-url = https://pypi.gocept.com/ - """)) + """ + ) + ) result = script.pip('install', '-vvv', 'INITools', expect_error=True) assert "Getting page https://pypi.gocept.com/initools" in result.stdout result = script.pip( - 'install', '-vvv', '--index-url', 'https://pypi.org/simple/', + 'install', + '-vvv', + '--index-url', + 'https://pypi.org/simple/', 'INITools', expect_error=True, ) - assert ( - "Getting page http://download.zope.org/ppix/INITools" - not in result.stdout - ) + assert "Getting page http://download.zope.org/ppix/INITools" not in result.stdout assert "Getting page https://pypi.gocept.com/INITools" not in result.stdout - assert ( - "Getting page https://pypi.org/simple/initools" in result.stdout - ) + assert "Getting page https://pypi.org/simple/initools" in result.stdout def test_options_from_venv_config(script, virtualenv): @@ -187,6 +199,7 @@ def test_options_from_venv_config(script, virtualenv): """ from pip._internal.locations import config_basename + conf = "[global]\nno-index = true" ini = virtualenv.location / config_basename with open(ini, 'w') as f: @@ -201,19 +214,24 @@ def test_options_from_venv_config(script, virtualenv): @pytest.mark.network def test_install_no_binary_via_config_disables_cached_wheels( - script, data, common_wheels): + script, data, common_wheels +): script.pip('install', 'wheel', '--no-index', '-f', common_wheels) config_file = tempfile.NamedTemporaryFile(mode='wt', delete=False) try: script.environ['PIP_CONFIG_FILE'] = config_file.name - config_file.write(textwrap.dedent("""\ + config_file.write( + textwrap.dedent( + """\ [global] no-binary = :all: - """)) + """ + ) + ) config_file.close() res = script.pip( - 'install', '--no-index', '-f', data.find_links, - 'upper', expect_stderr=True) + 'install', '--no-index', '-f', data.find_links, 'upper', expect_stderr=True + ) finally: os.unlink(config_file.name) assert "Successfully installed upper-2.0" in str(res), str(res) diff --git a/tests/functional/test_install_extras.py b/tests/functional/test_install_extras.py index 3f6bdac6e83..f831fa6a27c 100644 --- a/tests/functional/test_install_extras.py +++ b/tests/functional/test_install_extras.py @@ -9,9 +9,7 @@ def test_simple_extras_install_from_pypi(script): """ Test installing a package from PyPI using extras dependency Paste[openid]. """ - result = script.pip( - 'install', 'Paste[openid]==1.7.5.1', expect_stderr=True, - ) + result = script.pip('install', 'Paste[openid]==1.7.5.1', expect_stderr=True) initools_folder = script.site_packages / 'openid' assert initools_folder in result.files_created, result.files_created @@ -23,14 +21,22 @@ def test_extras_after_wheel(script, data): simple = script.site_packages / 'simple' no_extra = script.pip( - 'install', '--no-index', '-f', data.find_links, - 'requires_simple_extra', expect_stderr=True, + 'install', + '--no-index', + '-f', + data.find_links, + 'requires_simple_extra', + expect_stderr=True, ) assert simple not in no_extra.files_created, no_extra.files_created extra = script.pip( - 'install', '--no-index', '-f', data.find_links, - 'requires_simple_extra[extra]', expect_stderr=True, + 'install', + '--no-index', + '-f', + data.find_links, + 'requires_simple_extra[extra]', + expect_stderr=True, ) assert simple in extra.files_created, extra.files_created @@ -40,14 +46,12 @@ def test_no_extras_uninstall(script): """ No extras dependency gets uninstalled when the root package is uninstalled """ - result = script.pip( - 'install', 'Paste[openid]==1.7.5.1', expect_stderr=True, + result = script.pip('install', 'Paste[openid]==1.7.5.1', expect_stderr=True) + assert join(script.site_packages, 'paste') in result.files_created, sorted( + result.files_created.keys() ) - assert join(script.site_packages, 'paste') in result.files_created, ( - sorted(result.files_created.keys()) - ) - assert join(script.site_packages, 'openid') in result.files_created, ( - sorted(result.files_created.keys()) + assert join(script.site_packages, 'openid') in result.files_created, sorted( + result.files_created.keys() ) result2 = script.pip('uninstall', 'Paste', '-y') # openid should not be uninstalled @@ -63,14 +67,16 @@ def test_nonexistent_extra_warns_user_no_wheel(script, data): This exercises source installs. """ result = script.pip( - 'install', '--no-binary=:all:', '--no-index', + 'install', + '--no-binary=:all:', + '--no-index', '--find-links=' + data.find_links, - 'simple[nonexistent]', expect_stderr=True, + 'simple[nonexistent]', + expect_stderr=True, + ) + assert "simple 3.0 does not provide the extra 'nonexistent'" in result.stderr, str( + result ) - assert ( - "simple 3.0 does not provide the extra 'nonexistent'" - in result.stderr - ), str(result) def test_nonexistent_extra_warns_user_with_wheel(script, data): @@ -81,14 +87,13 @@ def test_nonexistent_extra_warns_user_with_wheel(script, data): This exercises wheel installs. """ result = script.pip( - 'install', '--no-index', + 'install', + '--no-index', '--find-links=' + data.find_links, - 'simplewheel[nonexistent]', expect_stderr=True, - ) - assert ( - "simplewheel 2.0 does not provide the extra 'nonexistent'" - in result.stderr + 'simplewheel[nonexistent]', + expect_stderr=True, ) + assert "simplewheel 2.0 does not provide the extra 'nonexistent'" in result.stderr def test_nonexistent_options_listed_in_order(script, data): @@ -96,9 +101,11 @@ def test_nonexistent_options_listed_in_order(script, data): Warn the user for each extra that doesn't exist. """ result = script.pip( - 'install', '--no-index', + 'install', + '--no-index', '--find-links=' + data.find_links, - 'simplewheel[nonexistent, nope]', expect_stderr=True, + 'simplewheel[nonexistent, nope]', + expect_stderr=True, ) msg = ( " simplewheel 2.0 does not provide the extra 'nonexistent'\n" @@ -112,17 +119,21 @@ def test_install_special_extra(script): # make a dummy project pkga_path = script.scratch_path / 'pkga' pkga_path.mkdir() - pkga_path.join("setup.py").write(textwrap.dedent(""" + pkga_path.join("setup.py").write( + textwrap.dedent( + """ from setuptools import setup setup(name='pkga', version='0.1', extras_require={'Hop_hOp-hoP': ['missing_pkg']}, ) - """)) + """ + ) + ) result = script.pip( - 'install', '--no-index', '%s[Hop_hOp-hoP]' % pkga_path, - expect_error=True) + 'install', '--no-index', '%s[Hop_hOp-hoP]' % pkga_path, expect_error=True + ) assert ( "Could not find a version that satisfies the requirement missing_pkg" ) in result.stderr, str(result) diff --git a/tests/functional/test_install_index.py b/tests/functional/test_install_index.py index c75fa03046c..d667f926d87 100644 --- a/tests/functional/test_install_index.py +++ b/tests/functional/test_install_index.py @@ -16,9 +16,7 @@ def test_find_links_relative_path(script, data): 'packages/', cwd=data.root, ) - egg_info_folder = ( - script.site_packages / 'parent-0.1-py%s.egg-info' % pyversion - ) + egg_info_folder = script.site_packages / 'parent-0.1-py%s.egg-info' % pyversion initools_folder = script.site_packages / 'parent' assert egg_info_folder in result.files_created, str(result) assert initools_folder in result.files_created, str(result) @@ -26,20 +24,20 @@ def test_find_links_relative_path(script, data): def test_find_links_requirements_file_relative_path(script, data): """Test find-links as a relative path to a reqs file.""" - script.scratch_path.join("test-req.txt").write(textwrap.dedent(""" + script.scratch_path.join("test-req.txt").write( + textwrap.dedent( + """ --no-index --find-links=%s parent==0.1 - """ % data.packages.replace(os.path.sep, '/'))) - result = script.pip( - 'install', - '-r', - script.scratch_path / "test-req.txt", - cwd=data.root, + """ + % data.packages.replace(os.path.sep, '/') + ) ) - egg_info_folder = ( - script.site_packages / 'parent-0.1-py%s.egg-info' % pyversion + result = script.pip( + 'install', '-r', script.scratch_path / "test-req.txt", cwd=data.root ) + egg_info_folder = script.site_packages / 'parent-0.1-py%s.egg-info' % pyversion initools_folder = script.site_packages / 'parent' assert egg_info_folder in result.files_created, str(result) assert initools_folder in result.files_created, str(result) @@ -51,9 +49,7 @@ def test_install_from_file_index_hash_link(script, data): hash """ result = script.pip('install', '-i', data.index_url(), 'simple==1.0') - egg_info_folder = ( - script.site_packages / 'simple-1.0-py%s.egg-info' % pyversion - ) + egg_info_folder = script.site_packages / 'simple-1.0-py%s.egg-info' % pyversion assert egg_info_folder in result.files_created, str(result) @@ -63,12 +59,9 @@ def test_file_index_url_quoting(script, data): """ index_url = data.index_url(urllib_parse.quote("in dex")) result = script.pip( - 'install', '-vvv', '--index-url', index_url, 'simple', - expect_error=False, - ) - assert (script.site_packages / 'simple') in result.files_created, ( - str(result.stdout) + 'install', '-vvv', '--index-url', index_url, 'simple', expect_error=False ) + assert (script.site_packages / 'simple') in result.files_created, str(result.stdout) assert ( script.site_packages / 'simple-1.0-py%s.egg-info' % pyversion ) in result.files_created, str(result) diff --git a/tests/functional/test_install_reqs.py b/tests/functional/test_install_reqs.py index 582e17ed2a2..3687ee76604 100644 --- a/tests/functional/test_install_reqs.py +++ b/tests/functional/test_install_reqs.py @@ -4,7 +4,9 @@ import pytest from tests.lib import ( - _create_test_package_with_subdirectory, path_to_url, pyversion, + _create_test_package_with_subdirectory, + path_to_url, + pyversion, requirements_file, ) from tests.lib.local_repos import local_checkout @@ -17,17 +19,20 @@ def test_requirements_file(script): """ other_lib_name, other_lib_version = 'anyjson', '0.3' - script.scratch_path.join("initools-req.txt").write(textwrap.dedent("""\ + script.scratch_path.join("initools-req.txt").write( + textwrap.dedent( + """\ INITools==0.2 # and something else to test out: %s<=%s - """ % (other_lib_name, other_lib_version))) - result = script.pip( - 'install', '-r', script.scratch_path / 'initools-req.txt' + """ + % (other_lib_name, other_lib_version) + ) ) + result = script.pip('install', '-r', script.scratch_path / 'initools-req.txt') assert ( - script.site_packages / 'INITools-0.2-py%s.egg-info' % - pyversion in result.files_created + script.site_packages / 'INITools-0.2-py%s.egg-info' % pyversion + in result.files_created ) assert script.site_packages / 'initools' in result.files_created assert result.files_created[script.site_packages / other_lib_name].dir @@ -41,16 +46,15 @@ def test_schema_check_in_requirements_file(script): """ script.scratch_path.join("file-egg-req.txt").write( - "\n%s\n" % ( + "\n%s\n" + % ( "git://github.com/alex/django-fixture-generator.git" "#egg=fixture_generator" ) ) with pytest.raises(AssertionError): - script.pip( - "install", "-vvv", "-r", script.scratch_path / "file-egg-req.txt" - ) + script.pip("install", "-vvv", "-r", script.scratch_path / "file-egg-req.txt") def test_relative_requirements_file(script, data): @@ -59,12 +63,8 @@ def test_relative_requirements_file(script, data): URLs, use an egg= definition. """ - egg_info_file = ( - script.site_packages / 'FSPkg-0.1.dev0-py%s.egg-info' % pyversion - ) - egg_link_file = ( - script.site_packages / 'FSPkg.egg-link' - ) + egg_info_file = script.site_packages / 'FSPkg-0.1.dev0-py%s.egg-info' % pyversion + egg_link_file = script.site_packages / 'FSPkg.egg-link' package_folder = script.site_packages / 'fspkg' # Compute relative install path to FSPkg from scratch path. @@ -77,19 +77,21 @@ def test_relative_requirements_file(script, data): for req_path in (full_rel_path, full_rel_url, embedded_rel_path): req_path = req_path.replace(os.path.sep, '/') # Regular install. - with requirements_file(req_path + '\n', - script.scratch_path) as reqs_file: - result = script.pip('install', '-vvv', '-r', reqs_file.name, - cwd=script.scratch_path) + with requirements_file(req_path + '\n', script.scratch_path) as reqs_file: + result = script.pip( + 'install', '-vvv', '-r', reqs_file.name, cwd=script.scratch_path + ) assert egg_info_file in result.files_created, str(result) assert package_folder in result.files_created, str(result) script.pip('uninstall', '-y', 'fspkg') # Editable install. - with requirements_file('-e ' + req_path + '\n', - script.scratch_path) as reqs_file: - result = script.pip('install', '-vvv', '-r', reqs_file.name, - cwd=script.scratch_path) + with requirements_file( + '-e ' + req_path + '\n', script.scratch_path + ) as reqs_file: + result = script.pip( + 'install', '-vvv', '-r', reqs_file.name, cwd=script.scratch_path + ) assert egg_link_file in result.files_created, str(result) script.pip('uninstall', '-y', 'fspkg') @@ -102,24 +104,23 @@ def test_multiple_requirements_files(script, tmpdir): """ other_lib_name, other_lib_version = 'anyjson', '0.3' script.scratch_path.join("initools-req.txt").write( - textwrap.dedent(""" + textwrap.dedent( + """ -e %s@10#egg=INITools -r %s-req.txt - """) % - ( + """ + ) + % ( local_checkout( - 'svn+http://svn.colorstudy.com/INITools/trunk', - tmpdir.join("cache"), + 'svn+http://svn.colorstudy.com/INITools/trunk', tmpdir.join("cache") ), - other_lib_name - ), + other_lib_name, + ) ) script.scratch_path.join("%s-req.txt" % other_lib_name).write( "%s<=%s" % (other_lib_name, other_lib_version) ) - result = script.pip( - 'install', '-r', script.scratch_path / 'initools-req.txt' - ) + result = script.pip('install', '-r', script.scratch_path / 'initools-req.txt') assert result.files_created[script.site_packages / other_lib_name].dir fn = '%s-%s-py%s.egg-info' % (other_lib_name, other_lib_version, pyversion) assert result.files_created[script.site_packages / fn].dir @@ -130,36 +131,54 @@ def test_package_in_constraints_and_dependencies(script, data): script.scratch_path.join("constraints.txt").write( "TopoRequires2==0.0.1\nTopoRequires==0.0.1" ) - result = script.pip('install', '--no-index', '-f', - data.find_links, '-c', script.scratch_path / - 'constraints.txt', 'TopoRequires2') + result = script.pip( + 'install', + '--no-index', + '-f', + data.find_links, + '-c', + script.scratch_path / 'constraints.txt', + 'TopoRequires2', + ) assert 'installed TopoRequires-0.0.1' in result.stdout def test_multiple_constraints_files(script, data): script.scratch_path.join("outer.txt").write("-c inner.txt") - script.scratch_path.join("inner.txt").write( - "Upper==1.0") + script.scratch_path.join("inner.txt").write("Upper==1.0") result = script.pip( - 'install', '--no-index', '-f', data.find_links, '-c', - script.scratch_path / 'outer.txt', 'Upper') + 'install', + '--no-index', + '-f', + data.find_links, + '-c', + script.scratch_path / 'outer.txt', + 'Upper', + ) assert 'installed Upper-1.0' in result.stdout def test_respect_order_in_requirements_file(script, data): - script.scratch_path.join("frameworks-req.txt").write(textwrap.dedent("""\ + script.scratch_path.join("frameworks-req.txt").write( + textwrap.dedent( + """\ parent child simple - """)) + """ + ) + ) result = script.pip( - 'install', '--no-index', '-f', data.find_links, '-r', - script.scratch_path / 'frameworks-req.txt' + 'install', + '--no-index', + '-f', + data.find_links, + '-r', + script.scratch_path / 'frameworks-req.txt', ) - downloaded = [line for line in result.stdout.split('\n') - if 'Collecting' in line] + downloaded = [line for line in result.stdout.split('\n') if 'Collecting' in line] assert 'parent' in downloaded[0], ( 'First download should be "parent" but was "%s"' % downloaded[0] @@ -175,36 +194,32 @@ def test_respect_order_in_requirements_file(script, data): def test_install_local_editable_with_extras(script, data): to_install = data.packages.join("LocalExtras") res = script.pip( - 'install', '-e', to_install + '[bar]', '--process-dependency-links', + 'install', + '-e', + to_install + '[bar]', + '--process-dependency-links', expect_error=False, expect_stderr=True, ) - assert script.site_packages / 'easy-install.pth' in res.files_updated, ( - str(res) - ) - assert ( - script.site_packages / 'LocalExtras.egg-link' in res.files_created - ), str(res) + assert script.site_packages / 'easy-install.pth' in res.files_updated, str(res) + assert script.site_packages / 'LocalExtras.egg-link' in res.files_created, str(res) assert script.site_packages / 'simple' in res.files_created, str(res) def test_install_collected_dependencies_first(script): - result = script.pip_install_local( - 'toporequires2', - ) - text = [line for line in result.stdout.split('\n') - if 'Installing' in line][0] + result = script.pip_install_local('toporequires2') + text = [line for line in result.stdout.split('\n') if 'Installing' in line][0] assert text.endswith('toporequires2') @pytest.mark.network def test_install_local_editable_with_subdirectory(script): - version_pkg_path = _create_test_package_with_subdirectory(script, - 'version_subdir') + version_pkg_path = _create_test_package_with_subdirectory(script, 'version_subdir') result = script.pip( - 'install', '-e', - '%s#egg=version_subpkg&subdirectory=version_subdir' % - ('git+%s' % path_to_url(version_pkg_path),) + 'install', + '-e', + '%s#egg=version_subpkg&subdirectory=version_subdir' + % ('git+%s' % path_to_url(version_pkg_path),), ) result.assert_installed('version-subpkg', sub_dir='version_subdir') @@ -212,12 +227,11 @@ def test_install_local_editable_with_subdirectory(script): @pytest.mark.network def test_install_local_with_subdirectory(script): - version_pkg_path = _create_test_package_with_subdirectory(script, - 'version_subdir') + version_pkg_path = _create_test_package_with_subdirectory(script, 'version_subdir') result = script.pip( 'install', - '%s#egg=version_subpkg&subdirectory=version_subdir' % - ('git+' + path_to_url(version_pkg_path),) + '%s#egg=version_subpkg&subdirectory=version_subdir' + % ('git+' + path_to_url(version_pkg_path),), ) result.assert_installed('version_subpkg.py', editable=False) @@ -225,7 +239,8 @@ def test_install_local_with_subdirectory(script): @pytest.mark.network def test_wheel_user_with_prefix_in_pydistutils_cfg( - script, data, virtualenv, common_wheels): + script, data, virtualenv, common_wheels +): # Make sure wheel is available in the virtualenv script.pip('install', 'wheel', '--no-index', '-f', common_wheels) virtualenv.system_site_packages = True @@ -236,14 +251,25 @@ def test_wheel_user_with_prefix_in_pydistutils_cfg( user_cfg = os.path.join(os.path.expanduser('~'), user_filename) script.scratch_path.join("bin").mkdir() with open(user_cfg, "w") as cfg: - cfg.write(textwrap.dedent(""" + cfg.write( + textwrap.dedent( + """ [install] - prefix=%s""" % script.scratch_path)) + prefix=%s""" + % script.scratch_path + ) + ) result = script.pip( - 'install', '--user', '--no-index', - '-f', data.find_links, '-f', common_wheels, - 'requiresupper') + 'install', + '--user', + '--no-index', + '-f', + data.find_links, + '-f', + common_wheels, + 'requiresupper', + ) # Check that we are really installing a wheel assert 'Running setup.py install for requiresupper' not in result.stdout assert 'installed requiresupper' in result.stdout @@ -260,13 +286,20 @@ def test_install_option_in_requirements_file(script, data, virtualenv): script.scratch_path.join("reqs.txt").write( textwrap.dedent( """simple --install-option='--home=%s'""" - % script.scratch_path.join("home1"))) + % script.scratch_path.join("home1") + ) + ) result = script.pip( - 'install', '--no-index', '-f', data.find_links, '-r', + 'install', + '--no-index', + '-f', + data.find_links, + '-r', script.scratch_path / 'reqs.txt', '--install-option=--home=%s' % script.scratch_path.join("home2"), - expect_stderr=True) + expect_stderr=True, + ) package_dir = script.scratch / 'home1' / 'lib' / 'python' / 'simple' assert package_dir in result.files_created @@ -275,28 +308,45 @@ def test_install_option_in_requirements_file(script, data, virtualenv): def test_constraints_not_installed_by_default(script, data): script.scratch_path.join("c.txt").write("requiresupper") result = script.pip( - 'install', '--no-index', '-f', data.find_links, '-c', - script.scratch_path / 'c.txt', 'Upper') + 'install', + '--no-index', + '-f', + data.find_links, + '-c', + script.scratch_path / 'c.txt', + 'Upper', + ) assert 'requiresupper' not in result.stdout def test_constraints_only_causes_error(script, data): script.scratch_path.join("c.txt").write("requiresupper") result = script.pip( - 'install', '--no-index', '-f', data.find_links, '-c', - script.scratch_path / 'c.txt', expect_error=True) + 'install', + '--no-index', + '-f', + data.find_links, + '-c', + script.scratch_path / 'c.txt', + expect_error=True, + ) assert 'installed requiresupper' not in result.stdout def test_constraints_local_editable_install_causes_error(script, data): - script.scratch_path.join("constraints.txt").write( - "singlemodule==0.0.0" - ) + script.scratch_path.join("constraints.txt").write("singlemodule==0.0.0") to_install = data.src.join("singlemodule") result = script.pip( - 'install', '--no-index', '-f', data.find_links, '-c', - script.scratch_path / 'constraints.txt', '-e', - to_install, expect_error=True) + 'install', + '--no-index', + '-f', + data.find_links, + '-c', + script.scratch_path / 'constraints.txt', + '-e', + to_install, + expect_error=True, + ) assert 'Could not satisfy constraints for' in result.stderr @@ -304,19 +354,22 @@ def test_constraints_local_editable_install_pep518(script, data): to_install = data.src.join("pep518-3.0") script.pip('download', 'setuptools', 'wheel', '-d', data.packages) - script.pip( - 'install', '--no-index', '-f', data.find_links, '-e', to_install) + script.pip('install', '--no-index', '-f', data.find_links, '-e', to_install) def test_constraints_local_install_causes_error(script, data): - script.scratch_path.join("constraints.txt").write( - "singlemodule==0.0.0" - ) + script.scratch_path.join("constraints.txt").write("singlemodule==0.0.0") to_install = data.src.join("singlemodule") result = script.pip( - 'install', '--no-index', '-f', data.find_links, '-c', + 'install', + '--no-index', + '-f', + data.find_links, + '-c', script.scratch_path / 'constraints.txt', - to_install, expect_error=True) + to_install, + expect_error=True, + ) assert 'Could not satisfy constraints for' in result.stderr @@ -326,8 +379,14 @@ def test_constraints_constrain_to_local_editable(script, data): "-e %s#egg=singlemodule" % path_to_url(to_install) ) result = script.pip( - 'install', '--no-index', '-f', data.find_links, '-c', - script.scratch_path / 'constraints.txt', 'singlemodule') + 'install', + '--no-index', + '-f', + data.find_links, + '-c', + script.scratch_path / 'constraints.txt', + 'singlemodule', + ) assert 'Running setup.py develop for singlemodule' in result.stdout @@ -337,8 +396,14 @@ def test_constraints_constrain_to_local(script, data): "%s#egg=singlemodule" % path_to_url(to_install) ) result = script.pip( - 'install', '--no-index', '-f', data.find_links, '-c', - script.scratch_path / 'constraints.txt', 'singlemodule') + 'install', + '--no-index', + '-f', + data.find_links, + '-c', + script.scratch_path / 'constraints.txt', + 'singlemodule', + ) assert 'Running setup.py install for singlemodule' in result.stdout @@ -347,15 +412,19 @@ def test_constrained_to_url_install_same_url(script, data): constraints = path_to_url(to_install) + "#egg=singlemodule" script.scratch_path.join("constraints.txt").write(constraints) result = script.pip( - 'install', '--no-index', '-f', data.find_links, '-c', - script.scratch_path / 'constraints.txt', to_install) - assert ('Running setup.py install for singlemodule' - in result.stdout), str(result) + 'install', + '--no-index', + '-f', + data.find_links, + '-c', + script.scratch_path / 'constraints.txt', + to_install, + ) + assert 'Running setup.py install for singlemodule' in result.stdout, str(result) @pytest.mark.network -def test_double_install_spurious_hash_mismatch( - script, tmpdir, data, common_wheels): +def test_double_install_spurious_hash_mismatch(script, tmpdir, data, common_wheels): """Make sure installing the same hashed sdist twice doesn't throw hash mismatch errors. @@ -367,13 +436,21 @@ def test_double_install_spurious_hash_mismatch( """ # Install wheel package, otherwise, it won't try to build wheels. script.pip('install', 'wheel', '--no-index', '-f', common_wheels) - with requirements_file('simple==1.0 --hash=sha256:393043e672415891885c9a2a' - '0929b1af95fb866d6ca016b42d2e6ce53619b653', - tmpdir) as reqs_file: + with requirements_file( + 'simple==1.0 --hash=sha256:393043e672415891885c9a2a' + '0929b1af95fb866d6ca016b42d2e6ce53619b653', + tmpdir, + ) as reqs_file: # Install a package (and build its wheel): result = script.pip_install_local( - '--find-links', data.find_links, '-f', common_wheels, - '-r', reqs_file.abspath, expect_error=False) + '--find-links', + data.find_links, + '-f', + common_wheels, + '-r', + reqs_file.abspath, + expect_error=False, + ) assert 'Successfully installed simple-1.0' in str(result) # Uninstall it: @@ -382,8 +459,14 @@ def test_double_install_spurious_hash_mismatch( # Then install it again. We should not hit a hash mismatch, and the # package should install happily. result = script.pip_install_local( - '--find-links', data.find_links, '-f', common_wheels, - '-r', reqs_file.abspath, expect_error=False) + '--find-links', + data.find_links, + '-f', + common_wheels, + '-r', + reqs_file.abspath, + expect_error=False, + ) assert 'Successfully installed simple-1.0' in str(result) @@ -393,7 +476,8 @@ def test_install_with_extras_from_constraints(script, data): "%s#egg=LocalExtras[bar]" % path_to_url(to_install) ) result = script.pip_install_local( - '-c', script.scratch_path / 'constraints.txt', 'LocalExtras') + '-c', script.scratch_path / 'constraints.txt', 'LocalExtras' + ) assert script.site_packages / 'simple' in result.files_created @@ -403,8 +487,9 @@ def test_install_with_extras_from_install(script, data): "%s#egg=LocalExtras" % path_to_url(to_install) ) result = script.pip_install_local( - '-c', script.scratch_path / 'constraints.txt', 'LocalExtras[baz]') - assert script.site_packages / 'singlemodule.py'in result.files_created + '-c', script.scratch_path / 'constraints.txt', 'LocalExtras[baz]' + ) + assert script.site_packages / 'singlemodule.py' in result.files_created def test_install_with_extras_joined(script, data): @@ -416,7 +501,7 @@ def test_install_with_extras_joined(script, data): '-c', script.scratch_path / 'constraints.txt', 'LocalExtras[baz]' ) assert script.site_packages / 'simple' in result.files_created - assert script.site_packages / 'singlemodule.py'in result.files_created + assert script.site_packages / 'singlemodule.py' in result.files_created def test_install_with_extras_editable_joined(script, data): @@ -425,15 +510,17 @@ def test_install_with_extras_editable_joined(script, data): "-e %s#egg=LocalExtras[bar]" % path_to_url(to_install) ) result = script.pip_install_local( - '-c', script.scratch_path / 'constraints.txt', 'LocalExtras[baz]') + '-c', script.scratch_path / 'constraints.txt', 'LocalExtras[baz]' + ) assert script.site_packages / 'simple' in result.files_created - assert script.site_packages / 'singlemodule.py'in result.files_created + assert script.site_packages / 'singlemodule.py' in result.files_created def test_install_distribution_full_union(script, data): to_install = data.packages.join("LocalExtras") result = script.pip_install_local( - to_install, to_install + "[bar]", to_install + "[baz]") + to_install, to_install + "[bar]", to_install + "[baz]" + ) assert 'Running setup.py install for LocalExtras' in result.stdout assert script.site_packages / 'simple' in result.files_created assert script.site_packages / 'singlemodule.py' in result.files_created @@ -449,10 +536,10 @@ def test_install_distribution_duplicate_extras(script, data): def test_install_distribution_union_with_constraints(script, data): to_install = data.packages.join("LocalExtras") - script.scratch_path.join("constraints.txt").write( - "%s[bar]" % to_install) + script.scratch_path.join("constraints.txt").write("%s[bar]" % to_install) result = script.pip_install_local( - '-c', script.scratch_path / 'constraints.txt', to_install + '[baz]') + '-c', script.scratch_path / 'constraints.txt', to_install + '[baz]' + ) assert 'Running setup.py install for LocalExtras' in result.stdout assert script.site_packages / 'singlemodule.py' in result.files_created @@ -461,9 +548,12 @@ def test_install_distribution_union_with_versions(script, data): to_install_001 = data.packages.join("LocalExtras") to_install_002 = data.packages.join("LocalExtras-0.0.2") result = script.pip_install_local( - to_install_001 + "[bar]", to_install_002 + "[baz]") - assert ("Successfully installed LocalExtras-0.0.1 simple-3.0 " + - "singlemodule-0.0.1" in result.stdout) + to_install_001 + "[bar]", to_install_002 + "[baz]" + ) + assert ( + "Successfully installed LocalExtras-0.0.1 simple-3.0 " + "singlemodule-0.0.1" + in result.stdout + ) @pytest.mark.xfail @@ -473,45 +563,59 @@ def test_install_distribution_union_conflicting_extras(script, data): # and simple==2.0. Once a resolver is added, this conflict should be # detected. to_install = data.packages.join("LocalExtras-0.0.2") - result = script.pip_install_local(to_install, to_install + "[bar]", - expect_error=True) + result = script.pip_install_local( + to_install, to_install + "[bar]", expect_error=True + ) assert 'installed' not in result.stdout assert "Conflict" in result.stderr def test_install_unsupported_wheel_link_with_marker(script): script.scratch_path.join("with-marker.txt").write( - textwrap.dedent("""\ + textwrap.dedent( + """\ %s; %s - """) % - ( + """ + ) + % ( 'https://github.com/a/b/c/asdf-1.5.2-cp27-none-xyz.whl', - 'sys_platform == "xyz"' + 'sys_platform == "xyz"', ) ) result = script.pip( - 'install', '-r', script.scratch_path / 'with-marker.txt', - expect_error=False, + 'install', '-r', script.scratch_path / 'with-marker.txt', expect_error=False ) - assert ("Ignoring asdf: markers 'sys_platform == \"xyz\"' don't match " - "your environment") in result.stdout + assert ( + "Ignoring asdf: markers 'sys_platform == \"xyz\"' don't match " + "your environment" + ) in result.stdout assert len(result.files_created) == 0 def test_install_unsupported_wheel_file(script, data): # Trying to install a local wheel with an incompatible version/type # should fail. - script.scratch_path.join("wheel-file.txt").write(textwrap.dedent("""\ + script.scratch_path.join("wheel-file.txt").write( + textwrap.dedent( + """\ %s - """ % data.packages.join("simple.dist-0.1-py1-none-invalid.whl"))) + """ + % data.packages.join("simple.dist-0.1-py1-none-invalid.whl") + ) + ) result = script.pip( - 'install', '-r', script.scratch_path / 'wheel-file.txt', + 'install', + '-r', + script.scratch_path / 'wheel-file.txt', expect_error=True, expect_stderr=True, ) - assert ("simple.dist-0.1-py1-none-invalid.whl is not a supported " + - "wheel on this platform" in result.stderr) + assert ( + "simple.dist-0.1-py1-none-invalid.whl is not a supported " + + "wheel on this platform" + in result.stderr + ) assert len(result.files_created) == 0 @@ -528,14 +632,21 @@ def test_install_options_local_to_package(script, data): home_simple.mkdir() reqs_file = script.scratch_path.join("reqs.txt") reqs_file.write( - textwrap.dedent(""" + textwrap.dedent( + """ simple --install-option='--home=%s' INITools - """ % home_simple)) + """ + % home_simple + ) + ) result = script.pip( 'install', - '--no-index', '-f', data.find_links, - '-r', reqs_file, + '--no-index', + '-f', + data.find_links, + '-r', + reqs_file, expect_error=True, ) diff --git a/tests/functional/test_install_upgrade.py b/tests/functional/test_install_upgrade.py index 2902049687f..e15683d2ae7 100644 --- a/tests/functional/test_install_upgrade.py +++ b/tests/functional/test_install_upgrade.py @@ -15,9 +15,9 @@ def test_no_upgrade_unless_requested(script): """ script.pip('install', 'INITools==0.1', expect_error=True) result = script.pip('install', 'INITools', expect_error=True) - assert not result.files_created, ( - 'pip install INITools upgraded when it should not have' - ) + assert ( + not result.files_created + ), 'pip install INITools upgraded when it should not have' def test_invalid_upgrade_strategy_causes_error(script): @@ -26,8 +26,7 @@ def test_invalid_upgrade_strategy_causes_error(script): """ result = script.pip_install_local( - '--upgrade', '--upgrade-strategy=bazinga', 'simple', - expect_error=True + '--upgrade', '--upgrade-strategy=bazinga', 'simple', expect_error=True ) assert result.returncode @@ -41,18 +40,18 @@ def test_only_if_needed_does_not_upgrade_deps_when_satisfied(script): """ script.pip_install_local('simple==2.0', expect_error=True) result = script.pip_install_local( - '--upgrade', '--upgrade-strategy=only-if-needed', 'require_simple', - expect_error=True + '--upgrade', + '--upgrade-strategy=only-if-needed', + 'require_simple', + expect_error=True, ) assert ( - (script.site_packages / 'require_simple-1.0-py%s.egg-info' % pyversion) - not in result.files_deleted - ), "should have installed require_simple==1.0" + script.site_packages / 'require_simple-1.0-py%s.egg-info' % pyversion + ) not in result.files_deleted, "should have installed require_simple==1.0" assert ( - (script.site_packages / 'simple-2.0-py%s.egg-info' % pyversion) - not in result.files_deleted - ), "should not have uninstalled simple==2.0" + script.site_packages / 'simple-2.0-py%s.egg-info' % pyversion + ) not in result.files_deleted, "should not have uninstalled simple==2.0" def test_only_if_needed_does_upgrade_deps_when_no_longer_satisfied(script): @@ -62,21 +61,22 @@ def test_only_if_needed_does_upgrade_deps_when_no_longer_satisfied(script): """ script.pip_install_local('simple==1.0', expect_error=True) result = script.pip_install_local( - '--upgrade', '--upgrade-strategy=only-if-needed', 'require_simple', - expect_error=True + '--upgrade', + '--upgrade-strategy=only-if-needed', + 'require_simple', + expect_error=True, ) assert ( - (script.site_packages / 'require_simple-1.0-py%s.egg-info' % pyversion) - not in result.files_deleted - ), "should have installed require_simple==1.0" + script.site_packages / 'require_simple-1.0-py%s.egg-info' % pyversion + ) not in result.files_deleted, "should have installed require_simple==1.0" assert ( - script.site_packages / 'simple-3.0-py%s.egg-info' % - pyversion in result.files_created + script.site_packages / 'simple-3.0-py%s.egg-info' % pyversion + in result.files_created ), "should have installed simple==3.0" assert ( - script.site_packages / 'simple-1.0-py%s.egg-info' % - pyversion in result.files_deleted + script.site_packages / 'simple-1.0-py%s.egg-info' % pyversion + in result.files_deleted ), "should have uninstalled simple==1.0" @@ -87,18 +87,15 @@ def test_eager_does_upgrade_dependecies_when_currently_satisfied(script): """ script.pip_install_local('simple==2.0', expect_error=True) result = script.pip_install_local( - '--upgrade', '--upgrade-strategy=eager', 'require_simple', - expect_error=True + '--upgrade', '--upgrade-strategy=eager', 'require_simple', expect_error=True ) assert ( - (script.site_packages / 'require_simple-1.0-py%s.egg-info' % pyversion) - not in result.files_deleted - ), "should have installed require_simple==1.0" + script.site_packages / 'require_simple-1.0-py%s.egg-info' % pyversion + ) not in result.files_deleted, "should have installed require_simple==1.0" assert ( - (script.site_packages / 'simple-2.0-py%s.egg-info' % pyversion) - in result.files_deleted - ), "should have uninstalled simple==2.0" + script.site_packages / 'simple-2.0-py%s.egg-info' % pyversion + ) in result.files_deleted, "should have uninstalled simple==2.0" def test_eager_does_upgrade_dependecies_when_no_longer_satisfied(script): @@ -108,21 +105,19 @@ def test_eager_does_upgrade_dependecies_when_no_longer_satisfied(script): """ script.pip_install_local('simple==1.0', expect_error=True) result = script.pip_install_local( - '--upgrade', '--upgrade-strategy=eager', 'require_simple', - expect_error=True + '--upgrade', '--upgrade-strategy=eager', 'require_simple', expect_error=True ) assert ( - (script.site_packages / 'require_simple-1.0-py%s.egg-info' % pyversion) - not in result.files_deleted - ), "should have installed require_simple==1.0" + script.site_packages / 'require_simple-1.0-py%s.egg-info' % pyversion + ) not in result.files_deleted, "should have installed require_simple==1.0" assert ( - script.site_packages / 'simple-3.0-py%s.egg-info' % - pyversion in result.files_created + script.site_packages / 'simple-3.0-py%s.egg-info' % pyversion + in result.files_created ), "should have installed simple==3.0" assert ( - script.site_packages / 'simple-1.0-py%s.egg-info' % - pyversion in result.files_deleted + script.site_packages / 'simple-1.0-py%s.egg-info' % pyversion + in result.files_deleted ), "should have uninstalled simple==1.0" @@ -134,16 +129,14 @@ def test_upgrade_to_specific_version(script): """ script.pip('install', 'INITools==0.1', expect_error=True) result = script.pip('install', 'INITools==0.2', expect_error=True) - assert result.files_created, ( - 'pip install with specific version did not upgrade' - ) + assert result.files_created, 'pip install with specific version did not upgrade' assert ( - script.site_packages / 'INITools-0.1-py%s.egg-info' % - pyversion in result.files_deleted + script.site_packages / 'INITools-0.1-py%s.egg-info' % pyversion + in result.files_deleted ) assert ( - script.site_packages / 'INITools-0.2-py%s.egg-info' % - pyversion in result.files_created + script.site_packages / 'INITools-0.2-py%s.egg-info' % pyversion + in result.files_created ) @@ -157,8 +150,8 @@ def test_upgrade_if_requested(script): result = script.pip('install', '--upgrade', 'INITools', expect_error=True) assert result.files_created, 'pip install --upgrade did not upgrade' assert ( - script.site_packages / 'INITools-0.1-py%s.egg-info' % - pyversion not in result.files_created + script.site_packages / 'INITools-0.1-py%s.egg-info' % pyversion + not in result.files_created ) @@ -182,12 +175,10 @@ def test_upgrade_force_reinstall_newest(script): version if --force-reinstall is supplied. """ result = script.pip('install', 'INITools') - assert script.site_packages / 'initools' in result.files_created, ( - sorted(result.files_created.keys()) - ) - result2 = script.pip( - 'install', '--upgrade', '--force-reinstall', 'INITools' + assert script.site_packages / 'initools' in result.files_created, sorted( + result.files_created.keys() ) + result2 = script.pip('install', '--upgrade', '--force-reinstall', 'INITools') assert result2.files_updated, 'upgrade to INITools 0.3 failed' result3 = script.pip('uninstall', 'initools', '-y', expect_error=True) assert_all_changes(result, result3, [script.venv / 'build', 'cache']) @@ -200,8 +191,8 @@ def test_uninstall_before_upgrade(script): """ result = script.pip('install', 'INITools==0.2', expect_error=True) - assert script.site_packages / 'initools' in result.files_created, ( - sorted(result.files_created.keys()) + assert script.site_packages / 'initools' in result.files_created, sorted( + result.files_created.keys() ) result2 = script.pip('install', 'INITools==0.3', expect_error=True) assert result2.files_created, 'upgrade to INITools 0.3 failed' @@ -216,8 +207,8 @@ def test_uninstall_before_upgrade_from_url(script): """ result = script.pip('install', 'INITools==0.2', expect_error=True) - assert script.site_packages / 'initools' in result.files_created, ( - sorted(result.files_created.keys()) + assert script.site_packages / 'initools' in result.files_created, sorted( + result.files_created.keys() ) result2 = script.pip( 'install', @@ -238,8 +229,8 @@ def test_upgrade_to_same_version_from_url(script): """ result = script.pip('install', 'INITools==0.3', expect_error=True) - assert script.site_packages / 'initools' in result.files_created, ( - sorted(result.files_created.keys()) + assert script.site_packages / 'initools' in result.files_created, sorted( + result.files_created.keys() ) result2 = script.pip( 'install', @@ -258,22 +249,26 @@ def test_upgrade_from_reqs_file(script): Upgrade from a requirements file. """ - script.scratch_path.join("test-req.txt").write(textwrap.dedent("""\ + script.scratch_path.join("test-req.txt").write( + textwrap.dedent( + """\ PyLogo<0.4 # and something else to test out: INITools==0.3 - """)) - install_result = script.pip( - 'install', '-r', script.scratch_path / 'test-req.txt' + """ + ) ) - script.scratch_path.join("test-req.txt").write(textwrap.dedent("""\ + install_result = script.pip('install', '-r', script.scratch_path / 'test-req.txt') + script.scratch_path.join("test-req.txt").write( + textwrap.dedent( + """\ PyLogo # and something else to test out: INITools - """)) - script.pip( - 'install', '--upgrade', '-r', script.scratch_path / 'test-req.txt' + """ + ) ) + script.pip('install', '--upgrade', '-r', script.scratch_path / 'test-req.txt') uninstall_result = script.pip( 'uninstall', '-r', script.scratch_path / 'test-req.txt', '-y' ) @@ -290,25 +285,24 @@ def test_uninstall_rollback(script, data): crafted to fail on install). """ - result = script.pip( - 'install', '-f', data.find_links, '--no-index', 'broken==0.1' - ) + result = script.pip('install', '-f', data.find_links, '--no-index', 'broken==0.1') assert script.site_packages / 'broken.py' in result.files_created, list( result.files_created.keys() ) result2 = script.pip( - 'install', '-f', data.find_links, '--no-index', 'broken===0.2broken', + 'install', + '-f', + data.find_links, + '--no-index', + 'broken===0.2broken', expect_error=True, ) assert result2.returncode == 1, str(result2) - assert script.run( - 'python', '-c', "import broken; print(broken.VERSION)" - ).stdout == '0.1\n' - assert_all_changes( - result.files_after, - result2, - [script.venv / 'build'], + assert ( + script.run('python', '-c', "import broken; print(broken.VERSION)").stdout + == '0.1\n' ) + assert_all_changes(result.files_after, result2, [script.venv / 'build']) @pytest.mark.network @@ -321,12 +315,12 @@ def test_should_not_install_always_from_cache(script): script.pip('uninstall', '-y', 'INITools') result = script.pip('install', 'INITools==0.1', expect_error=True) assert ( - script.site_packages / 'INITools-0.2-py%s.egg-info' % - pyversion not in result.files_created + script.site_packages / 'INITools-0.2-py%s.egg-info' % pyversion + not in result.files_created ) assert ( - script.site_packages / 'INITools-0.1-py%s.egg-info' % - pyversion in result.files_created + script.site_packages / 'INITools-0.1-py%s.egg-info' % pyversion + in result.files_created ) @@ -351,8 +345,7 @@ def test_install_with_ignoreinstalled_requested(script): def test_upgrade_vcs_req_with_no_dists_found(script, tmpdir): """It can upgrade a VCS requirement that has no distributions otherwise.""" req = "%s#egg=pip-test-package" % local_checkout( - "git+https://github.com/pypa/pip-test-package.git", - tmpdir.join("cache"), + "git+https://github.com/pypa/pip-test-package.git", tmpdir.join("cache") ) script.pip("install", req) result = script.pip("install", "-U", req) @@ -364,12 +357,8 @@ def test_upgrade_vcs_req_with_dist_found(script): """It can upgrade a VCS requirement that has distributions on the index.""" # TODO(pnasrat) Using local_checkout fails on windows - oddness with the # test path urls/git. - req = ( - "%s#egg=pretend" % - ( - "git+git://github.com/alex/pretend@e7f26ad7dbcb4a02a4995aade4" - "743aad47656b27" - ) + req = "%s#egg=pretend" % ( + "git+git://github.com/alex/pretend@e7f26ad7dbcb4a02a4995aade4" "743aad47656b27" ) script.pip("install", req, expect_stderr=True) result = script.pip("install", "-U", req, expect_stderr=True) @@ -416,7 +405,9 @@ def prep_ve(self, script, version, pip_src, distribute=False): self.ve_bin = self.script.scratch_path / 'VE' / bindir self.script.run(self.ve_bin / 'pip', 'uninstall', '-y', 'pip') self.script.run( - self.ve_bin / 'python', 'setup.py', 'install', + self.ve_bin / 'python', + 'setup.py', + 'install', cwd=pip_src, expect_stderr=True, ) diff --git a/tests/functional/test_install_user.py b/tests/functional/test_install_user.py index 35bfedafa88..6b718c2bb7b 100644 --- a/tests/functional/test_install_user.py +++ b/tests/functional/test_install_user.py @@ -14,13 +14,17 @@ def _patch_dist_in_site_packages(script): sitecustomize_path = script.lib_path.join("sitecustomize.py") - sitecustomize_path.write(textwrap.dedent(""" + sitecustomize_path.write( + textwrap.dedent( + """ def dist_in_site_packages(dist): return False from pip._internal.req import req_install req_install.dist_in_site_packages = dist_in_site_packages - """)) + """ + ) + ) # Caught py32 with an outdated __pycache__ file after a sitecustomize # update (after python should have updated it) so will delete the cache @@ -33,7 +37,6 @@ def dist_in_site_packages(dist): class Tests_UserSite: - @pytest.mark.network def test_reset_env_system_site_packages_usersite(self, script, virtualenv): """ @@ -43,7 +46,8 @@ def test_reset_env_system_site_packages_usersite(self, script, virtualenv): virtualenv.system_site_packages = True script.pip('install', '--user', 'INITools==0.2') result = script.run( - 'python', '-c', + 'python', + '-c', "import pkg_resources; print(pkg_resources.get_distribution" "('initools').project_name)", ) @@ -52,25 +56,28 @@ def test_reset_env_system_site_packages_usersite(self, script, virtualenv): @pytest.mark.network def test_install_subversion_usersite_editable_with_distribute( - self, script, virtualenv, tmpdir): + self, script, virtualenv, tmpdir + ): """ Test installing current directory ('.') into usersite after installing distribute """ virtualenv.system_site_packages = True result = script.pip( - 'install', '--user', '-e', - '%s#egg=initools' % - local_checkout( - 'svn+http://svn.colorstudy.com/INITools/trunk', - tmpdir.join("cache"), - ) + 'install', + '--user', + '-e', + '%s#egg=initools' + % local_checkout( + 'svn+http://svn.colorstudy.com/INITools/trunk', tmpdir.join("cache") + ), ) result.assert_installed('INITools', use_user_site=True) @pytest.mark.network def test_install_from_current_directory_into_usersite( - self, script, virtualenv, data, common_wheels): + self, script, virtualenv, data, common_wheels + ): """ Test installing current directory ('.') into usersite """ @@ -79,17 +86,13 @@ def test_install_from_current_directory_into_usersite( run_from = data.packages.join("FSPkg") result = script.pip( - 'install', '-vvv', '--user', curdir, - cwd=run_from, - expect_error=False, + 'install', '-vvv', '--user', curdir, cwd=run_from, expect_error=False ) fspkg_folder = script.user_site / 'fspkg' assert fspkg_folder in result.files_created, result.stdout - dist_info_folder = ( - script.user_site / 'FSPkg-0.1.dev0.dist-info' - ) + dist_info_folder = script.user_site / 'FSPkg-0.1.dev0.dist-info' assert dist_info_folder in result.files_created def test_install_user_venv_nositepkgs_fails(self, script, data): @@ -98,9 +101,7 @@ def test_install_user_venv_nositepkgs_fails(self, script, data): """ run_from = data.packages.join("FSPkg") result = script.pip( - 'install', '--user', curdir, - cwd=run_from, - expect_error=True, + 'install', '--user', curdir, cwd=run_from, expect_error=True ) assert ( "Can not perform a '--user' install. User site-packages are not " @@ -116,17 +117,16 @@ def test_install_user_conflict_in_usersite(self, script, virtualenv): script.pip('install', '--user', 'INITools==0.3', '--no-binary=:all:') - result2 = script.pip( - 'install', '--user', 'INITools==0.1', '--no-binary=:all:') + result2 = script.pip('install', '--user', 'INITools==0.1', '--no-binary=:all:') # usersite has 0.1 - egg_info_folder = ( - script.user_site / 'INITools-0.1-py%s.egg-info' % pyversion - ) + egg_info_folder = script.user_site / 'INITools-0.1-py%s.egg-info' % pyversion initools_v3_file = ( # file only in 0.3 - script.base_path / script.user_site / 'initools' / - 'configparser.py' + script.base_path + / script.user_site + / 'initools' + / 'configparser.py' ) assert egg_info_folder in result2.files_created, str(result2) assert not isfile(initools_v3_file), initools_v3_file @@ -155,21 +155,20 @@ def test_install_user_conflict_in_globalsite(self, script, virtualenv): script.pip('install', 'INITools==0.2', '--no-binary=:all:') - result2 = script.pip( - 'install', '--user', 'INITools==0.1', '--no-binary=:all:') + result2 = script.pip('install', '--user', 'INITools==0.1', '--no-binary=:all:') # usersite has 0.1 - egg_info_folder = ( - script.user_site / 'INITools-0.1-py%s.egg-info' % pyversion - ) + egg_info_folder = script.user_site / 'INITools-0.1-py%s.egg-info' % pyversion initools_folder = script.user_site / 'initools' assert egg_info_folder in result2.files_created, str(result2) assert initools_folder in result2.files_created, str(result2) # site still has 0.2 (can't look in result1; have to check) egg_info_folder = ( - script.base_path / script.site_packages / - 'INITools-0.2-py%s.egg-info' % pyversion + script.base_path + / script.site_packages + / 'INITools-0.2-py%s.egg-info' + % pyversion ) initools_folder = script.base_path / script.site_packages / 'initools' assert isdir(egg_info_folder) @@ -199,28 +198,28 @@ def test_upgrade_user_conflict_in_globalsite(self, script, virtualenv): script.pip('install', 'INITools==0.2', '--no-binary=:all:') result2 = script.pip( - 'install', '--user', '--upgrade', 'INITools', '--no-binary=:all:') + 'install', '--user', '--upgrade', 'INITools', '--no-binary=:all:' + ) # usersite has 0.3.1 - egg_info_folder = ( - script.user_site / 'INITools-0.3.1-py%s.egg-info' % pyversion - ) + egg_info_folder = script.user_site / 'INITools-0.3.1-py%s.egg-info' % pyversion initools_folder = script.user_site / 'initools' assert egg_info_folder in result2.files_created, str(result2) assert initools_folder in result2.files_created, str(result2) # site still has 0.2 (can't look in result1; have to check) egg_info_folder = ( - script.base_path / script.site_packages / - 'INITools-0.2-py%s.egg-info' % pyversion + script.base_path + / script.site_packages + / 'INITools-0.2-py%s.egg-info' + % pyversion ) initools_folder = script.base_path / script.site_packages / 'initools' assert isdir(egg_info_folder), result2.stdout assert isdir(initools_folder) @pytest.mark.network - def test_install_user_conflict_in_globalsite_and_usersite( - self, script, virtualenv): + def test_install_user_conflict_in_globalsite_and_usersite(self, script, virtualenv): """ Test user install with conflict in globalsite and usersite ignores global site and updates usersite. @@ -244,25 +243,26 @@ def test_install_user_conflict_in_globalsite_and_usersite( script.pip('install', 'INITools==0.2', '--no-binary=:all:') script.pip('install', '--user', 'INITools==0.3', '--no-binary=:all:') - result3 = script.pip( - 'install', '--user', 'INITools==0.1', '--no-binary=:all:') + result3 = script.pip('install', '--user', 'INITools==0.1', '--no-binary=:all:') # usersite has 0.1 - egg_info_folder = ( - script.user_site / 'INITools-0.1-py%s.egg-info' % pyversion - ) + egg_info_folder = script.user_site / 'INITools-0.1-py%s.egg-info' % pyversion initools_v3_file = ( # file only in 0.3 - script.base_path / script.user_site / 'initools' / - 'configparser.py' + script.base_path + / script.user_site + / 'initools' + / 'configparser.py' ) assert egg_info_folder in result3.files_created, str(result3) assert not isfile(initools_v3_file), initools_v3_file # site still has 0.2 (can't just look in result1; have to check) egg_info_folder = ( - script.base_path / script.site_packages / - 'INITools-0.2-py%s.egg-info' % pyversion + script.base_path + / script.site_packages + / 'INITools-0.2-py%s.egg-info' + % pyversion ) initools_folder = script.base_path / script.site_packages / 'initools' assert isdir(egg_info_folder) @@ -270,7 +270,8 @@ def test_install_user_conflict_in_globalsite_and_usersite( @pytest.mark.network def test_install_user_in_global_virtualenv_with_conflict_fails( - self, script, virtualenv): + self, script, virtualenv + ): """ Test user install in --system-site-packages virtualenv with conflict in site fails. @@ -279,18 +280,15 @@ def test_install_user_in_global_virtualenv_with_conflict_fails( script.pip('install', 'INITools==0.2') - result2 = script.pip( - 'install', '--user', 'INITools==0.1', - expect_error=True, - ) + result2 = script.pip('install', '--user', 'INITools==0.1', expect_error=True) resultp = script.run( - 'python', '-c', + 'python', + '-c', "import pkg_resources; print(pkg_resources.get_distribution" "('initools').location)", ) dist_location = resultp.stdout.strip() assert ( "Will not install to the user site because it will lack sys.path " - "precedence to %s in %s" % - ('INITools', dist_location) in result2.stderr + "precedence to %s in %s" % ('INITools', dist_location) in result2.stderr ) diff --git a/tests/functional/test_install_vcs.py b/tests/functional/test_install_vcs.py index ab0d154fac6..a170e72c8da 100644 --- a/tests/functional/test_install_vcs.py +++ b/tests/functional/test_install_vcs.py @@ -1,8 +1,6 @@ import pytest -from tests.lib import ( - _change_test_package_version, _create_test_package, pyversion, -) +from tests.lib import _change_test_package_version, _create_test_package, pyversion from tests.lib.local_repos import local_checkout @@ -63,11 +61,11 @@ def test_install_editable_from_git_with_https(script, tmpdir): Test cloning from Git with https. """ result = script.pip( - 'install', '-e', - '%s#egg=pip-test-package' % - local_checkout( - 'git+https://github.com/pypa/pip-test-package.git', - tmpdir.join("cache"), + 'install', + '-e', + '%s#egg=pip-test-package' + % local_checkout( + 'git+https://github.com/pypa/pip-test-package.git', tmpdir.join("cache") ), expect_error=True, ) @@ -82,15 +80,12 @@ def test_install_noneditable_git(script, tmpdir): result = script.pip( 'install', 'git+https://github.com/pypa/pip-test-package.git' - '@0.1.1#egg=pip-test-package' + '@0.1.1#egg=pip-test-package', ) egg_info_folder = ( - script.site_packages / - 'pip_test_package-0.1.1-py%s.egg-info' % pyversion + script.site_packages / 'pip_test_package-0.1.1-py%s.egg-info' % pyversion ) - result.assert_installed('piptestpackage', - without_egg_link=True, - editable=False) + result.assert_installed('piptestpackage', without_egg_link=True, editable=False) assert egg_info_folder in result.files_created, str(result) @@ -101,15 +96,13 @@ def test_git_with_sha1_revisions(script): """ version_pkg_path = _create_test_package(script) _change_test_package_version(script, version_pkg_path) - sha1 = script.run( - 'git', 'rev-parse', 'HEAD~1', - cwd=version_pkg_path, - ).stdout.strip() + sha1 = script.run('git', 'rev-parse', 'HEAD~1', cwd=version_pkg_path).stdout.strip() script.pip( - 'install', '-e', - '%s@%s#egg=version_pkg' % - ('git+file://' + version_pkg_path.abspath.replace('\\', '/'), sha1), - expect_stderr=True + 'install', + '-e', + '%s@%s#egg=version_pkg' + % ('git+file://' + version_pkg_path.abspath.replace('\\', '/'), sha1), + expect_stderr=True, ) version = script.run('version_pkg') assert '0.1' in version.stdout, version.stdout @@ -123,14 +116,14 @@ def test_git_with_short_sha1_revisions(script): version_pkg_path = _create_test_package(script) _change_test_package_version(script, version_pkg_path) sha1 = script.run( - 'git', 'rev-parse', 'HEAD~1', - cwd=version_pkg_path, + 'git', 'rev-parse', 'HEAD~1', cwd=version_pkg_path ).stdout.strip()[:7] script.pip( - 'install', '-e', - '%s@%s#egg=version_pkg' % - ('git+file://' + version_pkg_path.abspath.replace('\\', '/'), sha1), - expect_stderr=True + 'install', + '-e', + '%s@%s#egg=version_pkg' + % ('git+file://' + version_pkg_path.abspath.replace('\\', '/'), sha1), + expect_stderr=True, ) version = script.run('version_pkg') assert '0.1' in version.stdout, version.stdout @@ -143,14 +136,14 @@ def test_git_with_branch_name_as_revision(script): """ version_pkg_path = _create_test_package(script) script.run( - 'git', 'checkout', '-b', 'test_branch', - expect_stderr=True, - cwd=version_pkg_path, + 'git', 'checkout', '-b', 'test_branch', expect_stderr=True, cwd=version_pkg_path ) _change_test_package_version(script, version_pkg_path) script.pip( - 'install', '-e', '%s@test_branch#egg=version_pkg' % - ('git+file://' + version_pkg_path.abspath.replace('\\', '/')) + 'install', + '-e', + '%s@test_branch#egg=version_pkg' + % ('git+file://' + version_pkg_path.abspath.replace('\\', '/')), ) version = script.run('version_pkg') assert 'some different version' in version.stdout @@ -162,15 +155,13 @@ def test_git_with_tag_name_as_revision(script): Git backend should be able to install from tag names """ version_pkg_path = _create_test_package(script) - script.run( - 'git', 'tag', 'test_tag', - expect_stderr=True, - cwd=version_pkg_path, - ) + script.run('git', 'tag', 'test_tag', expect_stderr=True, cwd=version_pkg_path) _change_test_package_version(script, version_pkg_path) script.pip( - 'install', '-e', '%s@test_tag#egg=version_pkg' % - ('git+file://' + version_pkg_path.abspath.replace('\\', '/')) + 'install', + '-e', + '%s@test_tag#egg=version_pkg' + % ('git+file://' + version_pkg_path.abspath.replace('\\', '/')), ) version = script.run('version_pkg') assert '0.1' in version.stdout @@ -183,15 +174,20 @@ def test_git_with_ref_as_revision(script): """ version_pkg_path = _create_test_package(script) script.run( - 'git', 'update-ref', 'refs/foo/bar', 'HEAD', + 'git', + 'update-ref', + 'refs/foo/bar', + 'HEAD', expect_stderr=True, cwd=version_pkg_path, ) _change_test_package_version(script, version_pkg_path) script.pip( - 'install', '-e', '%s@refs/foo/bar#egg=version_pkg' % - ('git+file://' + version_pkg_path.abspath.replace('\\', '/')), - expect_stderr=True + 'install', + '-e', + '%s@refs/foo/bar#egg=version_pkg' + % ('git+file://' + version_pkg_path.abspath.replace('\\', '/')), + expect_stderr=True, ) version = script.run('version_pkg') assert '0.1' in version.stdout @@ -203,20 +199,22 @@ def test_git_with_tag_name_and_update(script, tmpdir): Test cloning a git repository and updating to a different version. """ result = script.pip( - 'install', '-e', '%s#egg=pip-test-package' % - local_checkout( - 'git+https://github.com/pypa/pip-test-package.git', - tmpdir.join("cache"), + 'install', + '-e', + '%s#egg=pip-test-package' + % local_checkout( + 'git+https://github.com/pypa/pip-test-package.git', tmpdir.join("cache") ), expect_error=True, ) result.assert_installed('pip-test-package', with_files=['.git']) result = script.pip( - 'install', '--global-option=--version', '-e', - '%s@0.1.2#egg=pip-test-package' % - local_checkout( - 'git+https://github.com/pypa/pip-test-package.git', - tmpdir.join("cache"), + 'install', + '--global-option=--version', + '-e', + '%s@0.1.2#egg=pip-test-package' + % local_checkout( + 'git+https://github.com/pypa/pip-test-package.git', tmpdir.join("cache") ), expect_error=True, ) @@ -230,10 +228,11 @@ def test_git_branch_should_not_be_changed(script, tmpdir): related to issue #32 and #161 """ script.pip( - 'install', '-e', '%s#egg=pip-test-package' % - local_checkout( - 'git+https://github.com/pypa/pip-test-package.git', - tmpdir.join("cache"), + 'install', + '-e', + '%s#egg=pip-test-package' + % local_checkout( + 'git+https://github.com/pypa/pip-test-package.git', tmpdir.join("cache") ), expect_error=True, ) @@ -248,11 +247,12 @@ def test_git_with_non_editable_unpacking(script, tmpdir): Test cloning a git repository from a non-editable URL with a given tag. """ result = script.pip( - 'install', '--global-option=--version', + 'install', + '--global-option=--version', local_checkout( 'git+https://github.com/pypa/pip-test-package.git@0.1.2' '#egg=pip-test-package', - tmpdir.join("cache") + tmpdir.join("cache"), ), expect_error=True, ) @@ -266,12 +266,12 @@ def test_git_with_editable_where_egg_contains_dev_string(script, tmpdir): string """ result = script.pip( - 'install', '-e', - '%s#egg=django-devserver' % - local_checkout( - 'git+git://github.com/dcramer/django-devserver.git', - tmpdir.join("cache") - ) + 'install', + '-e', + '%s#egg=django-devserver' + % local_checkout( + 'git+git://github.com/dcramer/django-devserver.git', tmpdir.join("cache") + ), ) result.assert_installed('django-devserver', with_files=['.git']) @@ -284,10 +284,9 @@ def test_git_with_non_editable_where_egg_contains_dev_string(script, tmpdir): """ result = script.pip( 'install', - '%s#egg=django-devserver' % - local_checkout( - 'git+git://github.com/dcramer/django-devserver.git', - tmpdir.join("cache") + '%s#egg=django-devserver' + % local_checkout( + 'git+git://github.com/dcramer/django-devserver.git', tmpdir.join("cache") ), ) devserver_folder = script.site_packages / 'devserver' @@ -300,9 +299,8 @@ def test_git_with_ambiguous_revs(script): Test git with two "names" (tag/branch) pointing to the same commit """ version_pkg_path = _create_test_package(script) - package_url = ( - 'git+file://%s@0.1#egg=version_pkg' % - (version_pkg_path.abspath.replace('\\', '/')) + package_url = 'git+file://%s@0.1#egg=version_pkg' % ( + version_pkg_path.abspath.replace('\\', '/') ) script.run('git', 'tag', '0.1', cwd=version_pkg_path) result = script.pip('install', '-e', package_url) @@ -339,18 +337,20 @@ def test_reinstalling_works_with_editible_non_master_branch(script): script.run('git', 'branch', '-m', 'foobar', cwd=version_pkg_path) script.pip( - 'install', '-e', - '%s#egg=version_pkg' % - ('git+file://' + version_pkg_path.abspath.replace('\\', '/')), + 'install', + '-e', + '%s#egg=version_pkg' + % ('git+file://' + version_pkg_path.abspath.replace('\\', '/')), ) version = script.run('version_pkg') assert '0.1' in version.stdout _change_test_package_version(script, version_pkg_path) script.pip( - 'install', '-e', - '%s#egg=version_pkg' % - ('git+file://' + version_pkg_path.abspath.replace('\\', '/')), + 'install', + '-e', + '%s#egg=version_pkg' + % ('git+file://' + version_pkg_path.abspath.replace('\\', '/')), ) version = script.run('version_pkg') assert 'some different version' in version.stdout diff --git a/tests/functional/test_install_vcs_git.py b/tests/functional/test_install_vcs_git.py index f9b5310aecc..bdac090f1ec 100644 --- a/tests/functional/test_install_vcs_git.py +++ b/tests/functional/test_install_vcs_git.py @@ -4,7 +4,8 @@ from pip._internal.vcs.git import Git from tests.lib import _create_test_package from tests.lib.git_submodule_helpers import ( - _change_test_package_submodule, _create_test_package_with_submodule, + _change_test_package_submodule, + _create_test_package_with_submodule, _pull_in_submodule_changes_to_module, ) @@ -16,10 +17,7 @@ def test_is_commit_id_equal(script): """ version_pkg_path = _create_test_package(script) script.run('git', 'branch', 'branch0.1', cwd=version_pkg_path) - commit = script.run( - 'git', 'rev-parse', 'HEAD', - cwd=version_pkg_path - ).stdout.strip() + commit = script.run('git', 'rev-parse', 'HEAD', cwd=version_pkg_path).stdout.strip() git = Git() assert git.is_commit_id_equal(version_pkg_path, commit) assert not git.is_commit_id_equal(version_pkg_path, commit[:7]) @@ -93,7 +91,9 @@ def test_check_submodule_addition(script): # expect error because git may write to stderr update_result = script.pip( - 'install', '-e', 'git+' + module_path + '#egg=version_pkg', + 'install', + '-e', + 'git+' + module_path + '#egg=version_pkg', '--upgrade', expect_error=True, ) diff --git a/tests/functional/test_install_vcs_svn.py b/tests/functional/test_install_vcs_svn.py index 3a70886690a..76cc2288db0 100644 --- a/tests/functional/test_install_vcs_svn.py +++ b/tests/functional/test_install_vcs_svn.py @@ -10,8 +10,14 @@ def test_obtain_should_recognize_auth_info_url(call_subprocess_mock, script): svn = Subversion(url='svn+http://username:password@svn.example.com/') svn.obtain(script.scratch_path / 'test') assert call_subprocess_mock.call_args[0][0] == [ - svn.name, 'checkout', '-q', '--username', 'username', '--password', - 'password', 'http://svn.example.com/', + svn.name, + 'checkout', + '-q', + '--username', + 'username', + '--password', + 'password', + 'http://svn.example.com/', script.scratch_path / 'test', ] @@ -22,7 +28,12 @@ def test_export_should_recognize_auth_info_url(call_subprocess_mock, script): svn = Subversion(url='svn+http://username:password@svn.example.com/') svn.export(script.scratch_path / 'test') assert call_subprocess_mock.call_args[0][0] == [ - svn.name, 'export', '--username', 'username', '--password', - 'password', 'http://svn.example.com/', + svn.name, + 'export', + '--username', + 'username', + '--password', + 'password', + 'http://svn.example.com/', script.scratch_path / 'test', ] diff --git a/tests/functional/test_install_wheel.py b/tests/functional/test_install_wheel.py index c4a5bd29a46..86bc6ba3972 100644 --- a/tests/functional/test_install_wheel.py +++ b/tests/functional/test_install_wheel.py @@ -17,16 +17,13 @@ def test_install_from_future_wheel_version(script, data): package = data.packages.join("futurewheel-3.0-py2.py3-none-any.whl") result = script.pip('install', package, '--no-index', expect_error=True) with pytest.raises(TestFailure): - result.assert_installed('futurewheel', without_egg_link=True, - editable=False) + result.assert_installed('futurewheel', without_egg_link=True, editable=False) package = data.packages.join("futurewheel-1.9-py2.py3-none-any.whl") result = script.pip( - 'install', package, '--no-index', expect_error=False, - expect_stderr=True, + 'install', package, '--no-index', expect_error=False, expect_stderr=True ) - result.assert_installed('futurewheel', without_egg_link=True, - editable=False) + result.assert_installed('futurewheel', without_egg_link=True, editable=False) def test_install_from_broken_wheel(script, data): @@ -34,11 +31,11 @@ def test_install_from_broken_wheel(script, data): Test that installing a broken wheel fails properly """ from tests.lib import TestFailure + package = data.packages.join("brokenwheel-1.0-py2.py3-none-any.whl") result = script.pip('install', package, '--no-index', expect_error=True) with pytest.raises(TestFailure): - result.assert_installed('futurewheel', without_egg_link=True, - editable=False) + result.assert_installed('futurewheel', without_egg_link=True, editable=False) def test_basic_install_from_wheel(script, data): @@ -46,14 +43,18 @@ def test_basic_install_from_wheel(script, data): Test installing from a wheel (that has a script) """ result = script.pip( - 'install', 'has.script==1.0', '--no-index', + 'install', + 'has.script==1.0', + '--no-index', '--find-links=' + data.find_links, expect_error=False, ) dist_info_folder = script.site_packages / 'has.script-1.0.dist-info' - assert dist_info_folder in result.files_created, (dist_info_folder, - result.files_created, - result.stdout) + assert dist_info_folder in result.files_created, ( + dist_info_folder, + result.files_created, + result.stdout, + ) script_file = script.bin / 'script.py' assert script_file in result.files_created @@ -63,18 +64,24 @@ def test_basic_install_from_wheel_with_extras(script, data): Test installing from a wheel with extras. """ result = script.pip( - 'install', 'complex-dist[simple]', '--no-index', + 'install', + 'complex-dist[simple]', + '--no-index', '--find-links=' + data.find_links, expect_error=False, ) dist_info_folder = script.site_packages / 'complex_dist-0.1.dist-info' - assert dist_info_folder in result.files_created, (dist_info_folder, - result.files_created, - result.stdout) + assert dist_info_folder in result.files_created, ( + dist_info_folder, + result.files_created, + result.stdout, + ) dist_info_folder = script.site_packages / 'simple.dist-0.1.dist-info' - assert dist_info_folder in result.files_created, (dist_info_folder, - result.files_created, - result.stdout) + assert dist_info_folder in result.files_created, ( + dist_info_folder, + result.files_created, + result.stdout, + ) def test_basic_install_from_wheel_file(script, data): @@ -84,20 +91,26 @@ def test_basic_install_from_wheel_file(script, data): package = data.packages.join("simple.dist-0.1-py2.py3-none-any.whl") result = script.pip('install', package, '--no-index', expect_error=False) dist_info_folder = script.site_packages / 'simple.dist-0.1.dist-info' - assert dist_info_folder in result.files_created, (dist_info_folder, - result.files_created, - result.stdout) + assert dist_info_folder in result.files_created, ( + dist_info_folder, + result.files_created, + result.stdout, + ) installer = dist_info_folder / 'INSTALLER' - assert installer in result.files_created, (dist_info_folder, - result.files_created, - result.stdout) + assert installer in result.files_created, ( + dist_info_folder, + result.files_created, + result.stdout, + ) with open(script.base_path / installer, 'rb') as installer_file: installer_details = installer_file.read() assert installer_details == b'pip\n' installer_temp = dist_info_folder / 'INSTALLER.pip' - assert installer_temp not in result.files_created, (dist_info_folder, - result.files_created, - result.stdout) + assert installer_temp not in result.files_created, ( + dist_info_folder, + result.files_created, + result.stdout, + ) # header installs are broke in pypy virtualenvs @@ -110,9 +123,11 @@ def test_install_from_wheel_with_headers(script, data): package = data.packages.join("headers.dist-0.1-py2.py3-none-any.whl") result = script.pip('install', package, '--no-index', expect_error=False) dist_info_folder = script.site_packages / 'headers.dist-0.1.dist-info' - assert dist_info_folder in result.files_created, (dist_info_folder, - result.files_created, - result.stdout) + assert dist_info_folder in result.files_created, ( + dist_info_folder, + result.files_created, + result.stdout, + ) @pytest.mark.network @@ -123,11 +138,15 @@ def test_install_wheel_with_target(script, data, common_wheels): script.pip('install', 'wheel', '--no-index', '-f', common_wheels) target_dir = script.scratch_path / 'target' result = script.pip( - 'install', 'simple.dist==0.1', '-t', target_dir, - '--no-index', '--find-links=' + data.find_links, + 'install', + 'simple.dist==0.1', + '-t', + target_dir, + '--no-index', + '--find-links=' + data.find_links, ) - assert Path('scratch') / 'target' / 'simpledist' in result.files_created, ( - str(result) + assert Path('scratch') / 'target' / 'simpledist' in result.files_created, str( + result ) @@ -154,17 +173,26 @@ def test_install_wheel_with_target_and_data_files(script, data, common_wheels): script.pip('install', 'wheel', '--no-index', '-f', common_wheels) target_dir = script.scratch_path / 'prjwithdatafile' package = data.packages.join("prjwithdatafile-1.0-py2.py3-none-any.whl") - result = script.pip('install', package, - '-t', target_dir, - '--no-index', - expect_error=False) + result = script.pip( + 'install', package, '-t', target_dir, '--no-index', expect_error=False + ) - assert (Path('scratch') / 'prjwithdatafile' / 'packages1' / 'README.txt' - in result.files_created), str(result) - assert (Path('scratch') / 'prjwithdatafile' / 'packages2' / 'README.txt' - in result.files_created), str(result) - assert (Path('scratch') / 'prjwithdatafile' / 'lib' / 'python' - not in result.files_created), str(result) + assert ( + Path('scratch') / 'prjwithdatafile' / 'packages1' / 'README.txt' + in result.files_created + ), str( + result + ) + assert ( + Path('scratch') / 'prjwithdatafile' / 'packages2' / 'README.txt' + in result.files_created + ), str( + result + ) + assert ( + Path('scratch') / 'prjwithdatafile' / 'lib' / 'python' + not in result.files_created + ), str(result) def test_install_wheel_with_root(script, data): @@ -173,8 +201,12 @@ def test_install_wheel_with_root(script, data): """ root_dir = script.scratch_path / 'root' result = script.pip( - 'install', 'simple.dist==0.1', '--root', root_dir, - '--no-index', '--find-links=' + data.find_links, + 'install', + 'simple.dist==0.1', + '--root', + root_dir, + '--no-index', + '--find-links=' + data.find_links, ) assert Path('scratch') / 'root' in result.files_created @@ -185,8 +217,12 @@ def test_install_wheel_with_prefix(script, data): """ prefix_dir = script.scratch_path / 'prefix' result = script.pip( - 'install', 'simple.dist==0.1', '--prefix', prefix_dir, - '--no-index', '--find-links=' + data.find_links, + 'install', + 'simple.dist==0.1', + '--prefix', + prefix_dir, + '--no-index', + '--find-links=' + data.find_links, ) lib = distutils.sysconfig.get_python_lib(prefix=Path('scratch') / 'prefix') assert lib in result.files_created, str(result) @@ -199,7 +235,7 @@ def test_install_from_wheel_installs_deps(script, data): # 'requires_source' depends on the 'source' project package = data.packages.join("requires_source-1.0-py2.py3-none-any.whl") result = script.pip( - 'install', '--no-index', '--find-links', data.find_links, package, + 'install', '--no-index', '--find-links', data.find_links, package ) result.assert_installed('source', editable=False) @@ -211,8 +247,7 @@ def test_install_from_wheel_no_deps(script, data): # 'requires_source' depends on the 'source' project package = data.packages.join("requires_source-1.0-py2.py3-none-any.whl") result = script.pip( - 'install', '--no-index', '--find-links', data.find_links, '--no-deps', - package, + 'install', '--no-index', '--find-links', data.find_links, '--no-deps', package ) pkg_folder = script.site_packages / 'source' assert pkg_folder not in result.files_created @@ -226,7 +261,10 @@ def test_install_user_wheel(script, virtualenv, data, common_wheels): virtualenv.system_site_packages = True script.pip('install', 'wheel', '--no-index', '-f', common_wheels) result = script.pip( - 'install', 'has.script==1.0', '--user', '--no-index', + 'install', + 'has.script==1.0', + '--user', + '--no-index', '--find-links=' + data.find_links, ) egg_info_folder = script.user_site / 'has.script-1.0.dist-info' @@ -240,7 +278,9 @@ def test_install_from_wheel_gen_entrypoint(script, data): Test installing scripts (entry points are generated) """ result = script.pip( - 'install', 'script.wheel1a==0.1', '--no-index', + 'install', + 'script.wheel1a==0.1', + '--no-index', '--find-links=' + data.find_links, expect_error=False, ) @@ -259,7 +299,9 @@ def test_install_from_wheel_gen_uppercase_entrypoint(script, data): Test installing scripts with uppercase letters in entry point names """ result = script.pip( - 'install', 'console-scripts-uppercase==1.0', '--no-index', + 'install', + 'console-scripts-uppercase==1.0', + '--no-index', '--find-links=' + data.find_links, expect_error=False, ) @@ -279,7 +321,9 @@ def test_install_from_wheel_with_legacy(script, data): Test installing scripts (legacy scripts are preserved) """ result = script.pip( - 'install', 'script.wheel2a==0.1', '--no-index', + 'install', + 'script.wheel2a==0.1', + '--no-index', '--find-links=' + data.find_links, expect_error=False, ) @@ -297,7 +341,9 @@ def test_install_from_wheel_no_setuptools_entrypoint(script, data): the wheel are skipped. """ result = script.pip( - 'install', 'script.wheel1==0.1', '--no-index', + 'install', + 'script.wheel1==0.1', + '--no-index', '--find-links=' + data.find_links, expect_error=False, ) @@ -322,7 +368,9 @@ def test_skipping_setuptools_doesnt_skip_legacy(script, data): setuptools wrappers) """ result = script.pip( - 'install', 'script.wheel2==0.1', '--no-index', + 'install', + 'script.wheel2==0.1', + '--no-index', '--find-links=' + data.find_links, expect_error=False, ) @@ -341,7 +389,9 @@ def test_install_from_wheel_gui_entrypoint(script, data): Test installing scripts (gui entry points are generated) """ result = script.pip( - 'install', 'script.wheel3==0.1', '--no-index', + 'install', + 'script.wheel3==0.1', + '--no-index', '--find-links=' + data.find_links, expect_error=False, ) @@ -357,14 +407,15 @@ def test_wheel_compiles_pyc(script, data): Test installing from wheel with --compile on """ script.pip( - "install", "--compile", "simple.dist==0.1", "--no-index", - "--find-links=" + data.find_links + "install", + "--compile", + "simple.dist==0.1", + "--no-index", + "--find-links=" + data.find_links, ) # There are many locations for the __init__.pyc file so attempt to find # any of them - exists = [ - os.path.exists(script.site_packages_path / "simpledist/__init__.pyc"), - ] + exists = [os.path.exists(script.site_packages_path / "simpledist/__init__.pyc")] exists += glob.glob( script.site_packages_path / "simpledist/__pycache__/__init__*.pyc" @@ -378,14 +429,15 @@ def test_wheel_no_compiles_pyc(script, data): Test installing from wheel with --compile on """ script.pip( - "install", "--no-compile", "simple.dist==0.1", "--no-index", - "--find-links=" + data.find_links + "install", + "--no-compile", + "simple.dist==0.1", + "--no-index", + "--find-links=" + data.find_links, ) # There are many locations for the __init__.pyc file so attempt to find # any of them - exists = [ - os.path.exists(script.site_packages_path / "simpledist/__init__.pyc"), - ] + exists = [os.path.exists(script.site_packages_path / "simpledist/__init__.pyc")] exists += glob.glob( script.site_packages_path / "simpledist/__pycache__/__init__*.pyc" diff --git a/tests/functional/test_list.py b/tests/functional/test_list.py index 234119b95c1..145a71907fe 100644 --- a/tests/functional/test_list.py +++ b/tests/functional/test_list.py @@ -10,8 +10,7 @@ def test_basic_list(script, data): """ script.pip( - 'install', '-f', data.find_links, '--no-index', 'simple==1.0', - 'simple2==3.0', + 'install', '-f', data.find_links, '--no-index', 'simple==1.0', 'simple2==3.0' ) result = script.pip('list') assert 'simple 1.0' in result.stdout, str(result) @@ -23,8 +22,7 @@ def test_verbose_flag(script, data): Test the list command with the '-v' option """ script.pip( - 'install', '-f', data.find_links, '--no-index', 'simple==1.0', - 'simple2==3.0', + 'install', '-f', data.find_links, '--no-index', 'simple==1.0', 'simple2==3.0' ) result = script.pip('list', '-v', '--format=columns') assert 'Package' in result.stdout, str(result) @@ -40,8 +38,7 @@ def test_columns_flag(script, data): Test the list command with the '--format=columns' option """ script.pip( - 'install', '-f', data.find_links, '--no-index', 'simple==1.0', - 'simple2==3.0', + 'install', '-f', data.find_links, '--no-index', 'simple==1.0', 'simple2==3.0' ) result = script.pip('list', '--format=columns') assert 'Package' in result.stdout, str(result) @@ -56,8 +53,7 @@ def test_legacy_format(script, data): Test that legacy format """ script.pip( - 'install', '-f', data.find_links, '--no-index', 'simple==1.0', - 'simple2==3.0', + 'install', '-f', data.find_links, '--no-index', 'simple==1.0', 'simple2==3.0' ) result = script.pip('list', '--format=legacy', expect_stderr=True) assert 'simple (1.0)' in result.stdout, str(result) @@ -69,11 +65,11 @@ def test_format_priority(script, data): Test that latest format has priority over previous ones. """ script.pip( - 'install', '-f', data.find_links, '--no-index', 'simple==1.0', - 'simple2==3.0', + 'install', '-f', data.find_links, '--no-index', 'simple==1.0', 'simple2==3.0' + ) + result = script.pip( + 'list', '--format=columns', '--format=legacy', expect_stderr=True ) - result = script.pip('list', '--format=columns', '--format=legacy', - expect_stderr=True) assert 'simple (1.0)' in result.stdout, str(result) assert 'simple2 (3.0)' in result.stdout, str(result) assert 'simple 1.0' not in result.stdout, str(result) @@ -117,8 +113,7 @@ def test_local_legacy_flag(script, data): command. """ script.pip('install', '-f', data.find_links, '--no-index', 'simple==1.0') - result = script.pip('list', '--local', '--format=legacy', - expect_stderr=True) + result = script.pip('list', '--local', '--format=legacy', expect_stderr=True) assert 'simple (1.0)' in result.stdout @@ -131,11 +126,9 @@ def test_user_flag(script, data, virtualenv): virtualenv.system_site_packages = True script.pip('download', 'setuptools', 'wheel', '-d', data.packages) script.pip('install', '-f', data.find_links, '--no-index', 'simple==1.0') - script.pip('install', '-f', data.find_links, '--no-index', - '--user', 'simple2==2.0') + script.pip('install', '-f', data.find_links, '--no-index', '--user', 'simple2==2.0') result = script.pip('list', '--user', '--format=json') - assert {"name": "simple", "version": "1.0"} \ - not in json.loads(result.stdout) + assert {"name": "simple", "version": "1.0"} not in json.loads(result.stdout) assert {"name": "simple2", "version": "2.0"} in json.loads(result.stdout) @@ -148,8 +141,7 @@ def test_user_columns_flag(script, data, virtualenv): virtualenv.system_site_packages = True script.pip('download', 'setuptools', 'wheel', '-d', data.packages) script.pip('install', '-f', data.find_links, '--no-index', 'simple==1.0') - script.pip('install', '-f', data.find_links, '--no-index', - '--user', 'simple2==2.0') + script.pip('install', '-f', data.find_links, '--no-index', '--user', 'simple2==2.0') result = script.pip('list', '--user', '--format=columns') assert 'Package' in result.stdout assert 'Version' in result.stdout @@ -166,10 +158,8 @@ def test_user_legacy(script, data, virtualenv): virtualenv.system_site_packages = True script.pip('download', 'setuptools', 'wheel', '-d', data.packages) script.pip('install', '-f', data.find_links, '--no-index', 'simple==1.0') - script.pip('install', '-f', data.find_links, '--no-index', - '--user', 'simple2==2.0') - result = script.pip('list', '--user', '--format=legacy', - expect_stderr=True) + script.pip('install', '-f', data.find_links, '--no-index', '--user', 'simple2==2.0') + result = script.pip('list', '--user', '--format=legacy', expect_stderr=True) assert 'simple (1.0)' not in result.stdout assert 'simple2 (2.0)' in result.stdout, str(result) @@ -181,21 +171,22 @@ def test_uptodate_flag(script, data): """ script.pip( - 'install', '-f', data.find_links, '--no-index', 'simple==1.0', - 'simple2==3.0', + 'install', '-f', data.find_links, '--no-index', 'simple==1.0', 'simple2==3.0' ) script.pip( - 'install', '-e', - 'git+https://github.com/pypa/pip-test-package.git#egg=pip-test-package' + 'install', + '-e', + 'git+https://github.com/pypa/pip-test-package.git#egg=pip-test-package', ) result = script.pip( - 'list', '-f', data.find_links, '--no-index', '--uptodate', - '--format=json', - ) - assert {"name": "simple", "version": "1.0"} \ - not in json.loads(result.stdout) # 3.0 is latest - assert {"name": "pip-test-package", "version": "0.1.1"} \ - in json.loads(result.stdout) # editables included + 'list', '-f', data.find_links, '--no-index', '--uptodate', '--format=json' + ) + assert {"name": "simple", "version": "1.0"} not in json.loads( + result.stdout + ) # 3.0 is latest + assert {"name": "pip-test-package", "version": "0.1.1"} in json.loads( + result.stdout + ) # editables included assert {"name": "simple2", "version": "3.0"} in json.loads(result.stdout) @@ -206,20 +197,19 @@ def test_uptodate_columns_flag(script, data): """ script.pip( - 'install', '-f', data.find_links, '--no-index', 'simple==1.0', - 'simple2==3.0', + 'install', '-f', data.find_links, '--no-index', 'simple==1.0', 'simple2==3.0' ) script.pip( - 'install', '-e', - 'git+https://github.com/pypa/pip-test-package.git#egg=pip-test-package' + 'install', + '-e', + 'git+https://github.com/pypa/pip-test-package.git#egg=pip-test-package', ) result = script.pip( - 'list', '-f', data.find_links, '--no-index', '--uptodate', - '--format=columns', + 'list', '-f', data.find_links, '--no-index', '--uptodate', '--format=columns' ) assert 'Package' in result.stdout assert 'Version' in result.stdout - assert 'Location' in result.stdout # editables included + assert 'Location' in result.stdout # editables included assert 'pip-test-package (0.1.1,' not in result.stdout assert 'pip-test-package 0.1.1' in result.stdout, str(result) assert 'simple2 3.0' in result.stdout, str(result) @@ -232,15 +222,19 @@ def test_uptodate_legacy_flag(script, data): """ script.pip( - 'install', '-f', data.find_links, '--no-index', 'simple==1.0', - 'simple2==3.0', + 'install', '-f', data.find_links, '--no-index', 'simple==1.0', 'simple2==3.0' ) script.pip( - 'install', '-e', - 'git+https://github.com/pypa/pip-test-package.git#egg=pip-test-package' + 'install', + '-e', + 'git+https://github.com/pypa/pip-test-package.git#egg=pip-test-package', ) result = script.pip( - 'list', '-f', data.find_links, '--no-index', '--uptodate', + 'list', + '-f', + data.find_links, + '--no-index', + '--uptodate', '--format=legacy', expect_stderr=True, ) @@ -256,27 +250,37 @@ def test_outdated_flag(script, data): """ script.pip( - 'install', '-f', data.find_links, '--no-index', 'simple==1.0', - 'simple2==3.0', 'simplewheel==1.0', + 'install', + '-f', + data.find_links, + '--no-index', + 'simple==1.0', + 'simple2==3.0', + 'simplewheel==1.0', ) script.pip( - 'install', '-e', - 'git+https://github.com/pypa/pip-test-package.git' - '@0.1#egg=pip-test-package' + 'install', + '-e', + 'git+https://github.com/pypa/pip-test-package.git' '@0.1#egg=pip-test-package', ) result = script.pip( - 'list', '-f', data.find_links, '--no-index', '--outdated', - '--format=json', - ) - assert {"name": "simple", "version": "1.0", - "latest_version": "3.0", "latest_filetype": "sdist"} \ - in json.loads(result.stdout) - assert dict(name="simplewheel", version="1.0", - latest_version="2.0", latest_filetype="wheel") \ - in json.loads(result.stdout) - assert dict(name="pip-test-package", version="0.1", - latest_version="0.1.1", latest_filetype="sdist") \ - in json.loads(result.stdout) + 'list', '-f', data.find_links, '--no-index', '--outdated', '--format=json' + ) + assert { + "name": "simple", + "version": "1.0", + "latest_version": "3.0", + "latest_filetype": "sdist", + } in json.loads(result.stdout) + assert dict( + name="simplewheel", version="1.0", latest_version="2.0", latest_filetype="wheel" + ) in json.loads(result.stdout) + assert dict( + name="pip-test-package", + version="0.1", + latest_version="0.1.1", + latest_filetype="sdist", + ) in json.loads(result.stdout) assert "simple2" not in {p["name"] for p in json.loads(result.stdout)} @@ -287,17 +291,21 @@ def test_outdated_columns_flag(script, data): """ script.pip( - 'install', '-f', data.find_links, '--no-index', 'simple==1.0', - 'simple2==3.0', 'simplewheel==1.0', + 'install', + '-f', + data.find_links, + '--no-index', + 'simple==1.0', + 'simple2==3.0', + 'simplewheel==1.0', ) script.pip( - 'install', '-e', - 'git+https://github.com/pypa/pip-test-package.git' - '@0.1#egg=pip-test-package' + 'install', + '-e', + 'git+https://github.com/pypa/pip-test-package.git' '@0.1#egg=pip-test-package', ) result = script.pip( - 'list', '-f', data.find_links, '--no-index', '--outdated', - '--format=columns', + 'list', '-f', data.find_links, '--no-index', '--outdated', '--format=columns' ) assert 'Package' in result.stdout assert 'Version' in result.stdout @@ -305,12 +313,8 @@ def test_outdated_columns_flag(script, data): assert 'Type' in result.stdout assert 'simple (1.0) - Latest: 3.0 [sdist]' not in result.stdout assert 'simplewheel (1.0) - Latest: 2.0 [wheel]' not in result.stdout - assert 'simple 1.0 3.0 sdist' in result.stdout, ( - str(result) - ) - assert 'simplewheel 1.0 2.0 wheel' in result.stdout, ( - str(result) - ) + assert 'simple 1.0 3.0 sdist' in result.stdout, str(result) + assert 'simplewheel 1.0 2.0 wheel' in result.stdout, str(result) assert 'simple2' not in result.stdout, str(result) # 3.0 is latest @@ -321,16 +325,25 @@ def test_outdated_legacy(script, data): """ script.pip( - 'install', '-f', data.find_links, '--no-index', 'simple==1.0', - 'simple2==3.0', 'simplewheel==1.0', + 'install', + '-f', + data.find_links, + '--no-index', + 'simple==1.0', + 'simple2==3.0', + 'simplewheel==1.0', ) script.pip( - 'install', '-e', - 'git+https://github.com/pypa/pip-test-package.git' - '@0.1#egg=pip-test-package' + 'install', + '-e', + 'git+https://github.com/pypa/pip-test-package.git' '@0.1#egg=pip-test-package', ) result = script.pip( - 'list', '-f', data.find_links, '--no-index', '--outdated', + 'list', + '-f', + data.find_links, + '--no-index', + '--outdated', '--format=legacy', expect_stderr=True, ) @@ -348,13 +361,13 @@ def test_editables_flag(script, data): """ script.pip('install', '-f', data.find_links, '--no-index', 'simple==1.0') result = script.pip( - 'install', '-e', - 'git+https://github.com/pypa/pip-test-package.git#egg=pip-test-package' + 'install', + '-e', + 'git+https://github.com/pypa/pip-test-package.git#egg=pip-test-package', ) result = script.pip('list', '--editable', '--format=json') result2 = script.pip('list', '--editable') - assert {"name": "simple", "version": "1.0"} \ - not in json.loads(result.stdout) + assert {"name": "simple", "version": "1.0"} not in json.loads(result.stdout) assert os.path.join('src', 'pip-test-package') in result2.stdout @@ -365,13 +378,13 @@ def test_exclude_editable_flag(script, data): """ script.pip('install', '-f', data.find_links, '--no-index', 'simple==1.0') result = script.pip( - 'install', '-e', - 'git+https://github.com/pypa/pip-test-package.git#egg=pip-test-package' + 'install', + '-e', + 'git+https://github.com/pypa/pip-test-package.git#egg=pip-test-package', ) result = script.pip('list', '--exclude-editable', '--format=json') assert {"name": "simple", "version": "1.0"} in json.loads(result.stdout) - assert "pip-test-package" \ - not in {p["name"] for p in json.loads(result.stdout)} + assert "pip-test-package" not in {p["name"] for p in json.loads(result.stdout)} @pytest.mark.network @@ -381,16 +394,15 @@ def test_editables_columns_flag(script, data): """ script.pip('install', '-f', data.find_links, '--no-index', 'simple==1.0') result = script.pip( - 'install', '-e', - 'git+https://github.com/pypa/pip-test-package.git#egg=pip-test-package' + 'install', + '-e', + 'git+https://github.com/pypa/pip-test-package.git#egg=pip-test-package', ) result = script.pip('list', '--editable', '--format=columns') assert 'Package' in result.stdout assert 'Version' in result.stdout assert 'Location' in result.stdout - assert os.path.join('src', 'pip-test-package') in result.stdout, ( - str(result) - ) + assert os.path.join('src', 'pip-test-package') in result.stdout, str(result) @pytest.mark.network @@ -400,16 +412,13 @@ def test_editables_legacy(script, data): """ script.pip('install', '-f', data.find_links, '--no-index', 'simple==1.0') script.pip( - 'install', '-e', - 'git+https://github.com/pypa/pip-test-package.git#egg=pip-test-package' - ) - result = script.pip( - 'list', '--editable', '--format=legacy', expect_stderr=True, + 'install', + '-e', + 'git+https://github.com/pypa/pip-test-package.git#egg=pip-test-package', ) + result = script.pip('list', '--editable', '--format=legacy', expect_stderr=True) assert 'simple (1.0)' not in result.stdout, str(result) - assert os.path.join('src', 'pip-test-package') in result.stdout, ( - str(result) - ) + assert os.path.join('src', 'pip-test-package') in result.stdout, str(result) @pytest.mark.network @@ -419,17 +428,15 @@ def test_uptodate_editables_flag(script, data): """ script.pip('install', '-f', data.find_links, '--no-index', 'simple==1.0') result = script.pip( - 'install', '-e', - 'git+https://github.com/pypa/pip-test-package.git#egg=pip-test-package' + 'install', + '-e', + 'git+https://github.com/pypa/pip-test-package.git#egg=pip-test-package', ) result = script.pip( - 'list', '-f', data.find_links, '--no-index', - '--editable', '--uptodate', + 'list', '-f', data.find_links, '--no-index', '--editable', '--uptodate' ) assert 'simple' not in result.stdout - assert os.path.join('src', 'pip-test-package') in result.stdout, ( - str(result) - ) + assert os.path.join('src', 'pip-test-package') in result.stdout, str(result) @pytest.mark.network @@ -440,19 +447,23 @@ def test_uptodate_editables_columns_flag(script, data): """ script.pip('install', '-f', data.find_links, '--no-index', 'simple==1.0') result = script.pip( - 'install', '-e', - 'git+https://github.com/pypa/pip-test-package.git#egg=pip-test-package' + 'install', + '-e', + 'git+https://github.com/pypa/pip-test-package.git#egg=pip-test-package', ) result = script.pip( - 'list', '-f', data.find_links, '--no-index', - '--editable', '--uptodate', '--format=columns', + 'list', + '-f', + data.find_links, + '--no-index', + '--editable', + '--uptodate', + '--format=columns', ) assert 'Package' in result.stdout assert 'Version' in result.stdout assert 'Location' in result.stdout - assert os.path.join('src', 'pip-test-package') in result.stdout, ( - str(result) - ) + assert os.path.join('src', 'pip-test-package') in result.stdout, str(result) @pytest.mark.network @@ -463,18 +474,22 @@ def test_uptodate_editables_legacy(script, data): """ script.pip('install', '-f', data.find_links, '--no-index', 'simple==1.0') script.pip( - 'install', '-e', - 'git+https://github.com/pypa/pip-test-package.git#egg=pip-test-package' + 'install', + '-e', + 'git+https://github.com/pypa/pip-test-package.git#egg=pip-test-package', ) result = script.pip( - 'list', '-f', data.find_links, '--no-index', '--editable', - '--uptodate', '--format=legacy', + 'list', + '-f', + data.find_links, + '--no-index', + '--editable', + '--uptodate', + '--format=legacy', expect_stderr=True, ) assert 'simple (1.0)' not in result.stdout, str(result) - assert os.path.join('src', 'pip-test-package') in result.stdout, ( - str(result) - ) + assert os.path.join('src', 'pip-test-package') in result.stdout, str(result) @pytest.mark.network @@ -484,13 +499,12 @@ def test_outdated_editables_flag(script, data): """ script.pip('install', '-f', data.find_links, '--no-index', 'simple==1.0') result = script.pip( - 'install', '-e', - 'git+https://github.com/pypa/pip-test-package.git' - '@0.1#egg=pip-test-package' + 'install', + '-e', + 'git+https://github.com/pypa/pip-test-package.git' '@0.1#egg=pip-test-package', ) result = script.pip( - 'list', '-f', data.find_links, '--no-index', - '--editable', '--outdated', + 'list', '-f', data.find_links, '--no-index', '--editable', '--outdated' ) assert 'simple' not in result.stdout assert os.path.join('src', 'pip-test-package') in result.stdout @@ -503,20 +517,23 @@ def test_outdated_editables_columns_flag(script, data): """ script.pip('install', '-f', data.find_links, '--no-index', 'simple==1.0') result = script.pip( - 'install', '-e', - 'git+https://github.com/pypa/pip-test-package.git' - '@0.1#egg=pip-test-package' + 'install', + '-e', + 'git+https://github.com/pypa/pip-test-package.git' '@0.1#egg=pip-test-package', ) result = script.pip( - 'list', '-f', data.find_links, '--no-index', - '--editable', '--outdated', '--format=columns', + 'list', + '-f', + data.find_links, + '--no-index', + '--editable', + '--outdated', + '--format=columns', ) assert 'Package' in result.stdout assert 'Version' in result.stdout assert 'Location' in result.stdout - assert os.path.join('src', 'pip-test-package') in result.stdout, ( - str(result) - ) + assert os.path.join('src', 'pip-test-package') in result.stdout, str(result) @pytest.mark.network @@ -526,19 +543,22 @@ def test_outdated_editables_legacy(script, data): """ script.pip('install', '-f', data.find_links, '--no-index', 'simple==1.0') script.pip( - 'install', '-e', - 'git+https://github.com/pypa/pip-test-package.git' - '@0.1#egg=pip-test-package' + 'install', + '-e', + 'git+https://github.com/pypa/pip-test-package.git' '@0.1#egg=pip-test-package', ) result = script.pip( - 'list', '-f', data.find_links, '--no-index', - '--editable', '--outdated', '--format=legacy', + 'list', + '-f', + data.find_links, + '--no-index', + '--editable', + '--outdated', + '--format=legacy', expect_stderr=True, ) assert 'simple (1.0)' not in result.stdout, str(result) - assert os.path.join('src', 'pip-test-package') in result.stdout, ( - str(result) - ) + assert os.path.join('src', 'pip-test-package') in result.stdout, str(result) def test_outdated_pre(script, data): @@ -550,23 +570,38 @@ def test_outdated_pre(script, data): wheelhouse_path.join('simple-1.1-py2.py3-none-any.whl').write('') wheelhouse_path.join('simple-2.0.dev0-py2.py3-none-any.whl').write('') result = script.pip( - 'list', '--no-index', '--find-links', wheelhouse_path, - '--format=json', + 'list', '--no-index', '--find-links', wheelhouse_path, '--format=json' ) assert {"name": "simple", "version": "1.0"} in json.loads(result.stdout) result = script.pip( - 'list', '--no-index', '--find-links', wheelhouse_path, '--outdated', + 'list', + '--no-index', + '--find-links', + wheelhouse_path, + '--outdated', + '--format=json', + ) + assert { + "name": "simple", + "version": "1.0", + "latest_version": "1.1", + "latest_filetype": "wheel", + } in json.loads(result.stdout) + result_pre = script.pip( + 'list', + '--no-index', + '--find-links', + wheelhouse_path, + '--outdated', + '--pre', '--format=json', ) - assert {"name": "simple", "version": "1.0", - "latest_version": "1.1", "latest_filetype": "wheel"} \ - in json.loads(result.stdout) - result_pre = script.pip('list', '--no-index', - '--find-links', wheelhouse_path, - '--outdated', '--pre', '--format=json') - assert {"name": "simple", "version": "1.0", - "latest_version": "2.0.dev0", "latest_filetype": "wheel"} \ - in json.loads(result_pre.stdout) + assert { + "name": "simple", + "version": "1.0", + "latest_version": "2.0.dev0", + "latest_filetype": "wheel", + } in json.loads(result_pre.stdout) def test_outdated_formats(script, data): @@ -578,45 +613,67 @@ def test_outdated_formats(script, data): wheelhouse_path = script.scratch_path / 'wheelhouse' wheelhouse_path.join('simple-1.1-py2.py3-none-any.whl').write('') result = script.pip( - 'list', '--no-index', '--find-links', wheelhouse_path, - '--format=freeze', + 'list', '--no-index', '--find-links', wheelhouse_path, '--format=freeze' ) assert 'simple==1.0' in result.stdout # Check legacy - result = script.pip('list', '--no-index', '--find-links', wheelhouse_path, - '--outdated', '--format=legacy', expect_stderr=True) + result = script.pip( + 'list', + '--no-index', + '--find-links', + wheelhouse_path, + '--outdated', + '--format=legacy', + expect_stderr=True, + ) assert 'simple (1.0) - Latest: 1.1 [wheel]' in result.stdout # Check columns result = script.pip( - 'list', '--no-index', '--find-links', wheelhouse_path, - '--outdated', '--format=columns', + 'list', + '--no-index', + '--find-links', + wheelhouse_path, + '--outdated', + '--format=columns', ) assert 'Package Version Latest Type' in result.stdout assert 'simple 1.0 1.1 wheel' in result.stdout # Check freeze result = script.pip( - 'list', '--no-index', '--find-links', wheelhouse_path, - '--outdated', '--format=freeze', + 'list', + '--no-index', + '--find-links', + wheelhouse_path, + '--outdated', + '--format=freeze', ) assert 'simple==1.0' in result.stdout # Check json result = script.pip( - 'list', '--no-index', '--find-links', wheelhouse_path, - '--outdated', '--format=json', + 'list', + '--no-index', + '--find-links', + wheelhouse_path, + '--outdated', + '--format=json', ) data = json.loads(result.stdout) - assert data == [{'name': 'simple', 'version': '1.0', - 'latest_version': '1.1', 'latest_filetype': 'wheel'}] + assert data == [ + { + 'name': 'simple', + 'version': '1.0', + 'latest_version': '1.1', + 'latest_filetype': 'wheel', + } + ] def test_not_required_flag(script, data): - script.pip( - 'install', '-f', data.find_links, '--no-index', 'TopoRequires4' - ) + script.pip('install', '-f', data.find_links, '--no-index', 'TopoRequires4') result = script.pip('list', '--not-required', expect_stderr=True) assert 'TopoRequires4 ' in result.stdout, str(result) assert 'TopoRequires ' not in result.stdout @@ -630,8 +687,7 @@ def test_list_freeze(script, data): """ script.pip( - 'install', '-f', data.find_links, '--no-index', 'simple==1.0', - 'simple2==3.0', + 'install', '-f', data.find_links, '--no-index', 'simple==1.0', 'simple2==3.0' ) result = script.pip('list', '--format=freeze') assert 'simple==1.0' in result.stdout, str(result) @@ -644,8 +700,7 @@ def test_list_json(script, data): """ script.pip( - 'install', '-f', data.find_links, '--no-index', 'simple==1.0', - 'simple2==3.0', + 'install', '-f', data.find_links, '--no-index', 'simple==1.0', 'simple2==3.0' ) result = script.pip('list', '--format=json') data = json.loads(result.stdout) diff --git a/tests/functional/test_no_color.py b/tests/functional/test_no_color.py index f3202573bff..a060f37015d 100644 --- a/tests/functional/test_no_color.py +++ b/tests/functional/test_no_color.py @@ -28,7 +28,7 @@ def test_no_color(script): def get_run_output(option): cmd = command.format(option) proc = subprocess.Popen( - cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, + cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE ) proc.communicate() if proc.returncode: @@ -42,5 +42,6 @@ def get_run_output(option): os.unlink("/tmp/pip-test-no-color.txt") assert "\x1b" in get_run_output(option=""), "Expected color in output" - assert "\x1b" not in get_run_output(option="--no-color"), \ - "Expected no color in output" + assert "\x1b" not in get_run_output( + option="--no-color" + ), "Expected no color in output" diff --git a/tests/functional/test_requests.py b/tests/functional/test_requests.py index f8eef787c95..4bf71b99ffd 100644 --- a/tests/functional/test_requests.py +++ b/tests/functional/test_requests.py @@ -4,14 +4,10 @@ @pytest.mark.skipif def test_timeout(script): result = script.pip( - "--timeout", "0.01", "install", "-vvv", "INITools", - expect_error=True, + "--timeout", "0.01", "install", "-vvv", "INITools", expect_error=True ) assert ( "Could not fetch URL https://pypi.org/simple/INITools/: " "timed out" in result.stdout ) - assert ( - "Could not fetch URL https://pypi.org/simple/: " - "timed out" in result.stdout - ) + assert "Could not fetch URL https://pypi.org/simple/: " "timed out" in result.stdout diff --git a/tests/functional/test_search.py b/tests/functional/test_search.py index 2c5393cc34c..9ca446e28c4 100644 --- a/tests/functional/test_search.py +++ b/tests/functional/test_search.py @@ -1,7 +1,10 @@ import pytest from pip._internal.commands.search import ( - SearchCommand, highest_version, print_results, transform_hits, + SearchCommand, + highest_version, + print_results, + transform_hits, ) from pip._internal.status_codes import NO_MATCHES_FOUND, SUCCESS from tests.lib import pyversion @@ -27,16 +30,8 @@ def test_pypi_xml_transformation(): """ pypi_hits = [ - { - 'name': 'foo', - 'summary': 'foo summary', - 'version': '1.0', - }, - { - 'name': 'foo', - 'summary': 'foo summary v2', - 'version': '2.0', - }, + {'name': 'foo', 'summary': 'foo summary', 'version': '1.0'}, + {'name': 'foo', 'summary': 'foo summary v2', 'version': '2.0'}, { '_pypi_ordering': 50, 'name': 'bar', @@ -45,16 +40,8 @@ def test_pypi_xml_transformation(): }, ] expected = [ - { - 'versions': ['1.0', '2.0'], - 'name': 'foo', - 'summary': 'foo summary v2', - }, - { - 'versions': ['1.0'], - 'name': 'bar', - 'summary': 'bar summary', - }, + {'versions': ['1.0', '2.0'], 'name': 'foo', 'summary': 'foo summary v2'}, + {'versions': ['1.0'], 'name': 'bar', 'summary': 'bar summary'}, ] assert transform_hits(pypi_hits) == expected @@ -67,17 +54,18 @@ def test_basic_search(script): """ output = script.pip('search', 'pip') assert ( - 'The PyPA recommended tool for installing ' - 'Python packages.' in output.stdout + 'The PyPA recommended tool for installing ' 'Python packages.' in output.stdout ) @pytest.mark.network @pytest.mark.skip( - reason=("Warehouse search behavior is different and no longer returns " - "multiple results. See " - "https://github.com/pypa/warehouse/issues/3717 for more " - "information."), + reason=( + "Warehouse search behavior is different and no longer returns " + "multiple results. See " + "https://github.com/pypa/warehouse/issues/3717 for more " + "information." + ) ) def test_multiple_search(script): """ @@ -86,8 +74,7 @@ def test_multiple_search(script): """ output = script.pip('search', 'pip', 'INITools') assert ( - 'The PyPA recommended tool for installing ' - 'Python packages.' in output.stdout + 'The PyPA recommended tool for installing ' 'Python packages.' in output.stdout ) assert 'Tools for parsing and using INI-style files' in output.stdout @@ -150,13 +137,13 @@ def test_search_print_results_should_contain_latest_versions(caplog): { 'name': 'testlib1', 'summary': 'Test library 1.', - 'versions': ['1.0.5', '1.0.3'] + 'versions': ['1.0.5', '1.0.3'], }, { 'name': 'testlib2', 'summary': 'Test library 1.', - 'versions': ['2.0.1', '2.0.3'] - } + 'versions': ['2.0.1', '2.0.3'], + }, ] print_results(hits) log_messages = sorted([r.getMessage() for r in caplog.records]) diff --git a/tests/functional/test_show.py b/tests/functional/test_show.py index ec4b2b0f404..26b59480942 100644 --- a/tests/functional/test_show.py +++ b/tests/functional/test_show.py @@ -139,9 +139,18 @@ def test_all_fields(script): """ result = script.pip('show', 'pip') lines = result.stdout.splitlines() - expected = {'Name', 'Version', 'Summary', 'Home-page', 'Author', - 'Author-email', 'License', 'Location', 'Requires', - 'Required-by'} + expected = { + 'Name', + 'Version', + 'Summary', + 'Home-page', + 'Author', + 'Author-email', + 'License', + 'Location', + 'Requires', + 'Required-by', + } actual = {re.sub(':.*$', '', line) for line in lines} assert actual == expected @@ -159,16 +168,14 @@ def test_pip_show_divider(script, data): """ Expect a divider between packages """ - script.pip('install', 'pip-test-package', '--no-index', - '-f', data.packages) + script.pip('install', 'pip-test-package', '--no-index', '-f', data.packages) result = script.pip('show', 'pip', 'pip-test-package') lines = result.stdout.splitlines() assert "---" in lines def test_package_name_is_canonicalized(script, data): - script.pip('install', 'pip-test-package', '--no-index', '-f', - data.packages) + script.pip('install', 'pip-test-package', '--no-index', '-f', data.packages) dash_show_result = script.pip('show', 'pip-test-package') underscore_upper_show_result = script.pip('show', 'pip-test_Package') @@ -182,9 +189,7 @@ def test_show_required_by_packages(script, data): Test that installed packages that depend on this package are shown """ editable_path = os.path.join(data.src, 'requires_simple') - script.pip( - 'install', '--no-index', '-f', data.find_links, editable_path - ) + script.pip('install', '--no-index', '-f', data.find_links, editable_path) result = script.pip('show', 'simple') lines = result.stdout.splitlines() diff --git a/tests/functional/test_uninstall.py b/tests/functional/test_uninstall.py index e667d03cd54..ccc186269d4 100644 --- a/tests/functional/test_uninstall.py +++ b/tests/functional/test_uninstall.py @@ -23,8 +23,8 @@ def test_basic_uninstall(script): """ result = script.pip('install', 'INITools==0.2') - assert join(script.site_packages, 'initools') in result.files_created, ( - sorted(result.files_created.keys()) + assert join(script.site_packages, 'initools') in result.files_created, sorted( + result.files_created.keys() ) # the import forces the generation of __pycache__ if the version of python # supports it @@ -40,19 +40,23 @@ def test_basic_uninstall_distutils(script): """ script.scratch_path.join("distutils_install").mkdir() pkg_path = script.scratch_path / 'distutils_install' - pkg_path.join("setup.py").write(textwrap.dedent(""" + pkg_path.join("setup.py").write( + textwrap.dedent( + """ from distutils.core import setup setup( name='distutils-install', version='0.1', ) - """)) + """ + ) + ) result = script.run('python', pkg_path / 'setup.py', 'install') result = script.pip('list', '--format=json') - assert {"name": "distutils-install", "version": "0.1"} \ - in json.loads(result.stdout) - result = script.pip('uninstall', 'distutils_install', '-y', - expect_stderr=True, expect_error=True) + assert {"name": "distutils-install", "version": "0.1"} in json.loads(result.stdout) + result = script.pip( + 'uninstall', 'distutils_install', '-y', expect_stderr=True, expect_error=True + ) assert ( "Cannot uninstall 'distutils-install'. It is a distutils installed " "project and thus we cannot accurately determine which files belong " @@ -69,12 +73,10 @@ def test_basic_uninstall_with_scripts(script): result = script.run('easy_install', 'PyLogo', expect_stderr=True) easy_install_pth = script.site_packages / 'easy-install.pth' pylogo = sys.platform == 'win32' and 'pylogo' or 'PyLogo' - assert(pylogo in result.files_updated[easy_install_pth].bytes) + assert pylogo in result.files_updated[easy_install_pth].bytes result2 = script.pip('uninstall', 'pylogo', '-y') assert_all_changes( - result, - result2, - [script.venv / 'build', 'cache', easy_install_pth], + result, result2, [script.venv / 'build', 'cache', easy_install_pth] ) @@ -92,11 +94,7 @@ def test_uninstall_easy_install_after_import(script): assert_all_changes( result, result2, - [ - script.venv / 'build', - 'cache', - script.site_packages / 'easy-install.pth', - ] + [script.venv / 'build', 'cache', script.site_packages / 'easy-install.pth'], ) @@ -125,8 +123,7 @@ def test_uninstall_trailing_newline(script): # verify that only initools is removed before_without_initools = [ - line for line in pth_before.splitlines() - if 'initools' not in line.lower() + line for line in pth_before.splitlines() if 'initools' not in line.lower() ] lines_after = pth_after.splitlines() @@ -141,15 +138,15 @@ def test_basic_uninstall_namespace_package(script): """ result = script.pip('install', 'pd.requires==0.0.3', expect_error=True) - assert join(script.site_packages, 'pd') in result.files_created, ( - sorted(result.files_created.keys()) + assert join(script.site_packages, 'pd') in result.files_created, sorted( + result.files_created.keys() ) result2 = script.pip('uninstall', 'pd.find', '-y', expect_error=True) - assert join(script.site_packages, 'pd') not in result2.files_deleted, ( - sorted(result2.files_deleted.keys()) + assert join(script.site_packages, 'pd') not in result2.files_deleted, sorted( + result2.files_deleted.keys() ) - assert join(script.site_packages, 'pd', 'find') in result2.files_deleted, ( - sorted(result2.files_deleted.keys()) + assert join(script.site_packages, 'pd', 'find') in result2.files_deleted, sorted( + result2.files_deleted.keys() ) @@ -165,37 +162,39 @@ def test_uninstall_overlapping_package(script, data): child_pkg = data.packages.join("child-0.1.tar.gz") result1 = script.pip('install', parent_pkg, expect_error=False) - assert join(script.site_packages, 'parent') in result1.files_created, ( - sorted(result1.files_created.keys()) + assert join(script.site_packages, 'parent') in result1.files_created, sorted( + result1.files_created.keys() ) result2 = script.pip('install', child_pkg, expect_error=False) - assert join(script.site_packages, 'child') in result2.files_created, ( - sorted(result2.files_created.keys()) + assert join(script.site_packages, 'child') in result2.files_created, sorted( + result2.files_created.keys() ) - assert normpath( - join(script.site_packages, 'parent/plugins/child_plugin.py') - ) in result2.files_created, sorted(result2.files_created.keys()) + assert ( + normpath(join(script.site_packages, 'parent/plugins/child_plugin.py')) + in result2.files_created + ), sorted(result2.files_created.keys()) # The import forces the generation of __pycache__ if the version of python # supports it script.run('python', '-c', "import parent.plugins.child_plugin, child") result3 = script.pip('uninstall', '-y', 'child', expect_error=False) - assert join(script.site_packages, 'child') in result3.files_deleted, ( - sorted(result3.files_created.keys()) + assert join(script.site_packages, 'child') in result3.files_deleted, sorted( + result3.files_created.keys() ) - assert normpath( - join(script.site_packages, 'parent/plugins/child_plugin.py') - ) in result3.files_deleted, sorted(result3.files_deleted.keys()) - assert join(script.site_packages, 'parent') not in result3.files_deleted, ( - sorted(result3.files_deleted.keys()) + assert ( + normpath(join(script.site_packages, 'parent/plugins/child_plugin.py')) + in result3.files_deleted + ), sorted(result3.files_deleted.keys()) + assert join(script.site_packages, 'parent') not in result3.files_deleted, sorted( + result3.files_deleted.keys() ) # Additional check: uninstalling 'child' should return things to the # previous state, without unintended side effects. assert_all_changes(result2, result3, []) -@pytest.mark.parametrize("console_scripts", - ["test_ = distutils_install", - "test_:test_ = distutils_install"]) +@pytest.mark.parametrize( + "console_scripts", ["test_ = distutils_install", "test_:test_ = distutils_install"] +) def test_uninstall_entry_point(script, console_scripts): """ Test uninstall package with two or more entry points in the same section, @@ -206,11 +205,13 @@ def test_uninstall_entry_point(script, console_scripts): script, name=pkg_name, version='0.1', - entry_points={"console_scripts": [console_scripts, ], - "pip_test.ep": - ["ep:name1 = distutils_install", - "ep:name2 = distutils_install"] - } + entry_points={ + "console_scripts": [console_scripts], + "pip_test.ep": [ + "ep:name1 = distutils_install", + "ep:name2 = distutils_install", + ], + }, ) script_name = script.bin_path.join(console_scripts.split('=')[0].strip()) if sys.platform == 'win32': @@ -218,13 +219,11 @@ def test_uninstall_entry_point(script, console_scripts): result = script.pip('install', pkg_path) assert script_name.exists result = script.pip('list', '--format=json') - assert {"name": "ep-install", "version": "0.1"} \ - in json.loads(result.stdout) + assert {"name": "ep-install", "version": "0.1"} in json.loads(result.stdout) script.pip('uninstall', 'ep_install', '-y') assert not script_name.exists result2 = script.pip('list', '--format=json') - assert {"name": "ep-install", "version": "0.1"} \ - not in json.loads(result2.stdout) + assert {"name": "ep-install", "version": "0.1"} not in json.loads(result2.stdout) def test_uninstall_gui_scripts(script): @@ -236,7 +235,7 @@ def test_uninstall_gui_scripts(script): script, name=pkg_name, version='0.1', - entry_points={"gui_scripts": ["test_ = distutils_install", ], } + entry_points={"gui_scripts": ["test_ = distutils_install"]}, ) script_name = script.bin_path.join('test_') if sys.platform == 'win32': @@ -256,8 +255,8 @@ def test_uninstall_console_scripts(script): args = ['install'] args.append('discover') result = script.pip(*args, **{"expect_error": True}) - assert script.bin / 'discover' + script.exe in result.files_created, ( - sorted(result.files_created.keys()) + assert script.bin / 'discover' + script.exe in result.files_created, sorted( + result.files_created.keys() ) result2 = script.pip('uninstall', 'discover', '-y', expect_error=True) assert_all_changes(result, result2, [script.venv / 'build', 'cache']) @@ -271,18 +270,14 @@ def test_uninstall_easy_installed_console_scripts(script): args = ['easy_install'] args.append('discover') result = script.run(*args, **{"expect_stderr": True}) - assert script.bin / 'discover' + script.exe in result.files_created, ( - sorted(result.files_created.keys()) + assert script.bin / 'discover' + script.exe in result.files_created, sorted( + result.files_created.keys() ) result2 = script.pip('uninstall', 'discover', '-y') assert_all_changes( result, result2, - [ - script.venv / 'build', - 'cache', - script.site_packages / 'easy-install.pth', - ] + [script.venv / 'build', 'cache', script.site_packages / 'easy-install.pth'], ) @@ -292,22 +287,23 @@ def test_uninstall_editable_from_svn(script, tmpdir): Test uninstalling an editable installation from svn. """ result = script.pip( - 'install', '-e', - '%s#egg=initools' % local_checkout( - 'svn+http://svn.colorstudy.com/INITools/trunk', - tmpdir.join("cache"), + 'install', + '-e', + '%s#egg=initools' + % local_checkout( + 'svn+http://svn.colorstudy.com/INITools/trunk', tmpdir.join("cache") ), ) result.assert_installed('INITools') result2 = script.pip('uninstall', '-y', 'initools') - assert (script.venv / 'src' / 'initools' in result2.files_after) + assert script.venv / 'src' / 'initools' in result2.files_after assert_all_changes( result, result2, [ script.venv / 'src', script.venv / 'build', - script.site_packages / 'easy-install.pth' + script.site_packages / 'easy-install.pth', ], ) @@ -323,32 +319,24 @@ def test_uninstall_editable_with_source_outside_venv(script, tmpdir): try: temp = mkdtemp() tmpdir = join(temp, 'pip-test-package') - _test_uninstall_editable_with_source_outside_venv( - script, - tmpdir, - cache_dir, - ) + _test_uninstall_editable_with_source_outside_venv(script, tmpdir, cache_dir) finally: rmtree(temp) -def _test_uninstall_editable_with_source_outside_venv( - script, tmpdir, cache_dir): +def _test_uninstall_editable_with_source_outside_venv(script, tmpdir, cache_dir): result = script.run( - 'git', 'clone', - local_repo( - 'git+git://github.com/pypa/pip-test-package', - cache_dir, - ), + 'git', + 'clone', + local_repo('git+git://github.com/pypa/pip-test-package', cache_dir), tmpdir, expect_stderr=True, ) result2 = script.pip('install', '-e', tmpdir) - assert join( - script.site_packages, 'pip-test-package.egg-link' - ) in result2.files_created, list(result2.files_created.keys()) - result3 = script.pip('uninstall', '-y', - 'pip-test-package', expect_error=True) + assert ( + join(script.site_packages, 'pip-test-package.egg-link') in result2.files_created + ), list(result2.files_created.keys()) + result3 = script.pip('uninstall', '-y', 'pip-test-package', expect_error=True) assert_all_changes( result, result3, @@ -363,19 +351,21 @@ def test_uninstall_from_reqs_file(script, tmpdir): """ script.scratch_path.join("test-req.txt").write( - textwrap.dedent(""" + textwrap.dedent( + """ -e %s#egg=initools # and something else to test out: PyLogo<0.4 - """) % - local_checkout( - 'svn+http://svn.colorstudy.com/INITools/trunk', - tmpdir.join("cache") + """ + ) + % local_checkout( + 'svn+http://svn.colorstudy.com/INITools/trunk', tmpdir.join("cache") ) ) result = script.pip('install', '-r', 'test-req.txt') script.scratch_path.join("test-req.txt").write( - textwrap.dedent(""" + textwrap.dedent( + """ # -f, -i, and --extra-index-url should all be ignored by uninstall -f http://www.example.com -i http://www.example.com @@ -384,10 +374,10 @@ def test_uninstall_from_reqs_file(script, tmpdir): -e %s#egg=initools # and something else to test out: PyLogo<0.4 - """) % - local_checkout( - 'svn+http://svn.colorstudy.com/INITools/trunk', - tmpdir.join("cache") + """ + ) + % local_checkout( + 'svn+http://svn.colorstudy.com/INITools/trunk', tmpdir.join("cache") ) ) result2 = script.pip('uninstall', '-r', 'test-req.txt', '-y') @@ -410,14 +400,12 @@ def test_uninstallpathset_no_paths(caplog): """ from pip._internal.req.req_uninstall import UninstallPathSet from pkg_resources import get_distribution + test_dist = get_distribution('pip') uninstall_set = UninstallPathSet(test_dist) uninstall_set.remove() # with no files added to set - assert ( - "Can't uninstall 'pip'. No files were found to uninstall." - in caplog.text - ) + assert "Can't uninstall 'pip'. No files were found to uninstall." in caplog.text def test_uninstall_non_local_distutils(caplog, monkeypatch, tmpdir): @@ -456,21 +444,19 @@ def test_uninstall_wheel(script, data): def test_uninstall_setuptools_develop_install(script, data): """Try uninstall after setup.py develop followed of setup.py install""" pkg_path = data.packages.join("FSPkg") - script.run('python', 'setup.py', 'develop', - expect_stderr=True, cwd=pkg_path) - script.run('python', 'setup.py', 'install', - expect_stderr=True, cwd=pkg_path) + script.run('python', 'setup.py', 'develop', expect_stderr=True, cwd=pkg_path) + script.run('python', 'setup.py', 'install', expect_stderr=True, cwd=pkg_path) list_result = script.pip('list', '--format=json') - assert {"name": os.path.normcase("FSPkg"), "version": "0.1.dev0"} \ - in json.loads(list_result.stdout), str(list_result) + assert {"name": os.path.normcase("FSPkg"), "version": "0.1.dev0"} in json.loads( + list_result.stdout + ), str(list_result) # Uninstall both develop and install uninstall = script.pip('uninstall', 'FSPkg', '-y') - assert any(filename.endswith('.egg') - for filename in uninstall.files_deleted.keys()) + assert any(filename.endswith('.egg') for filename in uninstall.files_deleted.keys()) uninstall2 = script.pip('uninstall', 'FSPkg', '-y') - assert join( - script.site_packages, 'FSPkg.egg-link' - ) in uninstall2.files_deleted, list(uninstall2.files_deleted.keys()) + assert ( + join(script.site_packages, 'FSPkg.egg-link') in uninstall2.files_deleted + ), list(uninstall2.files_deleted.keys()) list_result2 = script.pip('list', '--format=json') assert "FSPkg" not in {p["name"] for p in json.loads(list_result2.stdout)} @@ -483,22 +469,20 @@ def test_uninstall_editable_and_pip_install(script, data): script.environ['SETUPTOOLS_SYS_PATH_TECHNIQUE'] = 'raw' pkg_path = data.packages.join("FSPkg") - script.pip('install', '-e', '.', - expect_stderr=True, cwd=pkg_path) + script.pip('install', '-e', '.', expect_stderr=True, cwd=pkg_path) # ensure both are installed with --ignore-installed: - script.pip('install', '--ignore-installed', '.', - expect_stderr=True, cwd=pkg_path) + script.pip('install', '--ignore-installed', '.', expect_stderr=True, cwd=pkg_path) list_result = script.pip('list', '--format=json') - assert {"name": "FSPkg", "version": "0.1.dev0"} \ - in json.loads(list_result.stdout) + assert {"name": "FSPkg", "version": "0.1.dev0"} in json.loads(list_result.stdout) # Uninstall both develop and install uninstall = script.pip('uninstall', 'FSPkg', '-y') - assert not any(filename.endswith('.egg-link') - for filename in uninstall.files_deleted.keys()) + assert not any( + filename.endswith('.egg-link') for filename in uninstall.files_deleted.keys() + ) uninstall2 = script.pip('uninstall', 'FSPkg', '-y') - assert join( - script.site_packages, 'FSPkg.egg-link' - ) in uninstall2.files_deleted, list(uninstall2.files_deleted.keys()) + assert ( + join(script.site_packages, 'FSPkg.egg-link') in uninstall2.files_deleted + ), list(uninstall2.files_deleted.keys()) list_result2 = script.pip('list', '--format=json') assert "FSPkg" not in {p["name"] for p in json.loads(list_result2.stdout)} @@ -506,9 +490,7 @@ def test_uninstall_editable_and_pip_install(script, data): def test_uninstall_ignores_missing_packages(script, data): """Uninstall of a non existent package prints a warning and exits cleanly """ - result = script.pip( - 'uninstall', '-y', 'non-existent-pkg', expect_stderr=True, - ) + result = script.pip('uninstall', '-y', 'non-existent-pkg', expect_stderr=True) assert "Skipping non-existent-pkg as it is not installed." in result.stderr assert result.returncode == 0, "Expected clean exit" @@ -517,7 +499,7 @@ def test_uninstall_ignores_missing_packages(script, data): def test_uninstall_ignores_missing_packages_and_uninstalls_rest(script, data): script.pip_install_local('simple') result = script.pip( - 'uninstall', '-y', 'non-existent-pkg', 'simple', expect_stderr=True, + 'uninstall', '-y', 'non-existent-pkg', 'simple', expect_stderr=True ) assert "Skipping non-existent-pkg as it is not installed." in result.stderr diff --git a/tests/functional/test_uninstall_user.py b/tests/functional/test_uninstall_user.py index eaa213f7714..5dbb253b523 100644 --- a/tests/functional/test_uninstall_user.py +++ b/tests/functional/test_uninstall_user.py @@ -10,7 +10,6 @@ class Tests_UninstallUserSite: - @pytest.mark.network def test_uninstall_from_usersite(self, script, virtualenv): """ @@ -21,8 +20,7 @@ def test_uninstall_from_usersite(self, script, virtualenv): result2 = script.pip('uninstall', '-y', 'INITools') assert_all_changes(result1, result2, [script.venv / 'build', 'cache']) - def test_uninstall_from_usersite_with_dist_in_global_site( - self, script, virtualenv): + def test_uninstall_from_usersite_with_dist_in_global_site(self, script, virtualenv): """ Test uninstall from usersite (with same dist in global site) """ @@ -45,7 +43,8 @@ def test_uninstall_from_usersite_with_dist_in_global_site( script.pip_install_local('pip-test-package==0.1', '--no-binary=:all:') result2 = script.pip_install_local( - '--user', 'pip-test-package==0.1.1', '--no-binary=:all:') + '--user', 'pip-test-package==0.1.1', '--no-binary=:all:' + ) result3 = script.pip('uninstall', '-vy', 'pip-test-package') # uninstall console is mentioning user scripts, but not global scripts @@ -57,8 +56,10 @@ def test_uninstall_from_usersite_with_dist_in_global_site( # site still has 0.2 (can't look in result1; have to check) egg_info_folder = ( - script.base_path / script.site_packages / - 'pip_test_package-0.1-py%s.egg-info' % pyversion + script.base_path + / script.site_packages + / 'pip_test_package-0.1-py%s.egg-info' + % pyversion ) assert isdir(egg_info_folder) @@ -71,9 +72,7 @@ def test_uninstall_editable_from_usersite(self, script, virtualenv, data): # install to_install = data.packages.join("FSPkg") - result1 = script.pip( - 'install', '--user', '-e', to_install, expect_error=False, - ) + result1 = script.pip('install', '--user', '-e', to_install, expect_error=False) egg_link = script.user_site / 'FSPkg.egg-link' assert egg_link in result1.files_created, str(result1.stdout) @@ -84,9 +83,5 @@ def test_uninstall_editable_from_usersite(self, script, virtualenv, data): assert_all_changes( result1, result2, - [ - script.venv / 'build', - 'cache', - script.user_site / 'easy-install.pth', - ] + [script.venv / 'build', 'cache', script.user_site / 'easy-install.pth'], ) diff --git a/tests/functional/test_vcs_git.py b/tests/functional/test_vcs_git.py index bdcb9c217da..c8bcbdfd1cc 100644 --- a/tests/functional/test_vcs_git.py +++ b/tests/functional/test_vcs_git.py @@ -16,8 +16,15 @@ def get_head_sha(script, dest): def do_commit(script, dest): script.run( - 'git', 'commit', '-q', '--author', 'pip <pypa-dev@googlegroups.com>', - '--allow-empty', '-m', 'test commit', cwd=dest + 'git', + 'commit', + '-q', + '--author', + 'pip <pypa-dev@googlegroups.com>', + '--allow-empty', + '-m', + 'test commit', + cwd=dest, ) return get_head_sha(script, dest) @@ -51,14 +58,15 @@ def test_get_revision_sha(script): origin_ref = 'refs/remotes/origin/origin-branch' generic_ref = 'refs/generic-ref' - script.run( - 'git', 'branch', 'local-branch', head_sha, cwd=repo_dir - ) + script.run('git', 'branch', 'local-branch', head_sha, cwd=repo_dir) script.run('git', 'tag', 'v1.0', tag_sha, cwd=repo_dir) script.run('git', 'update-ref', origin_ref, origin_sha, cwd=repo_dir) script.run( - 'git', 'update-ref', 'refs/remotes/upstream/upstream-branch', - head_sha, cwd=repo_dir + 'git', + 'update-ref', + 'refs/remotes/upstream/upstream-branch', + head_sha, + cwd=repo_dir, ) script.run('git', 'update-ref', generic_ref, head_sha, cwd=repo_dir) diff --git a/tests/functional/test_warning.py b/tests/functional/test_warning.py index 20f246795c3..53d19182af9 100644 --- a/tests/functional/test_warning.py +++ b/tests/functional/test_warning.py @@ -1,8 +1,8 @@ - def test_environ(script, tmpdir): """$PYTHONWARNINGS was added in python2.7""" demo = tmpdir.join('warnings_demo.py') - demo.write(''' + demo.write( + ''' from pip._internal.utils import deprecation deprecation.install_warning_logger() @@ -11,11 +11,13 @@ def test_environ(script, tmpdir): from warnings import warn warn("deprecated!", deprecation.PipDeprecationWarning) -''') +''' + ) result = script.run('python', demo, expect_stderr=True) - assert result.stderr == \ - 'ERROR:pip._internal.deprecations:DEPRECATION: deprecated!\n' + assert ( + result.stderr == 'ERROR:pip._internal.deprecations:DEPRECATION: deprecated!\n' + ) script.environ['PYTHONWARNINGS'] = 'ignore' result = script.run('python', demo) diff --git a/tests/functional/test_wheel.py b/tests/functional/test_wheel.py index c1777437d45..2fedf6b69fa 100644 --- a/tests/functional/test_wheel.py +++ b/tests/functional/test_wheel.py @@ -19,8 +19,7 @@ def test_wheel_exit_status_code_when_no_requirements(script, common_wheels): assert result.returncode == ERROR -def test_wheel_exit_status_code_when_blank_requirements_file( - script, common_wheels): +def test_wheel_exit_status_code_when_blank_requirements_file(script, common_wheels): """ Test wheel exit status code when blank requirements file specified """ @@ -36,8 +35,7 @@ def test_pip_wheel_success(script, data, common_wheels): """ script.pip('install', 'wheel', '--no-index', '-f', common_wheels) result = script.pip( - 'wheel', '--no-index', '-f', data.find_links, '-f', common_wheels, - 'simple==3.0', + 'wheel', '--no-index', '-f', data.find_links, '-f', common_wheels, 'simple==3.0' ) wheel_file_name = 'simple-3.0-py%s-none-any.whl' % pyversion[0] wheel_file_path = script.scratch / wheel_file_name @@ -51,9 +49,7 @@ def test_basic_pip_wheel_downloads_wheels(script, data, common_wheels): Test 'pip wheel' downloads wheels """ script.pip('install', 'wheel', '--no-index', '-f', common_wheels) - result = script.pip( - 'wheel', '--no-index', '-f', data.find_links, 'simple.dist', - ) + result = script.pip('wheel', '--no-index', '-f', data.find_links, 'simple.dist') wheel_file_name = 'simple.dist-0.1-py2.py3-none-any.whl' wheel_file_path = script.scratch / wheel_file_name assert wheel_file_path in result.files_created, result.stdout @@ -66,9 +62,16 @@ def test_pip_wheel_builds_when_no_binary_set(script, data, common_wheels): data.packages.join('simple-3.0-py2.py3-none-any.whl').touch() # Check that the wheel package is ignored res = script.pip( - 'wheel', '--no-index', '--no-binary', ':all:', - '-f', data.find_links, '-f', common_wheels, - 'simple==3.0') + 'wheel', + '--no-index', + '--no-binary', + ':all:', + '-f', + data.find_links, + '-f', + common_wheels, + 'simple==3.0', + ) assert "Running setup.py bdist_wheel for simple" in str(res), str(res) @@ -80,8 +83,14 @@ def test_pip_wheel_builds_editable_deps(script, data, common_wheels): script.pip('install', 'wheel', '--no-index', '-f', common_wheels) editable_path = os.path.join(data.src, 'requires_simple') result = script.pip( - 'wheel', '--no-index', '-f', data.find_links, '-f', common_wheels, - '-e', editable_path + 'wheel', + '--no-index', + '-f', + data.find_links, + '-f', + common_wheels, + '-e', + editable_path, ) wheel_file_name = 'simple-1.0-py%s-none-any.whl' % pyversion[0] wheel_file_path = script.scratch / wheel_file_name @@ -96,8 +105,14 @@ def test_pip_wheel_builds_editable(script, data, common_wheels): script.pip('install', 'wheel', '--no-index', '-f', common_wheels) editable_path = os.path.join(data.src, 'simplewheel-1.0') result = script.pip( - 'wheel', '--no-index', '-f', data.find_links, '-f', common_wheels, - '-e', editable_path + 'wheel', + '--no-index', + '-f', + data.find_links, + '-f', + common_wheels, + '-e', + editable_path, ) wheel_file_name = 'simplewheel-1.0-py%s-none-any.whl' % pyversion[0] wheel_file_path = script.scratch / wheel_file_name @@ -111,7 +126,12 @@ def test_pip_wheel_fail(script, data, common_wheels): """ script.pip('install', 'wheel', '--no-index', '-f', common_wheels) result = script.pip( - 'wheel', '--no-index', '-f', data.find_links, '-f', common_wheels, + 'wheel', + '--no-index', + '-f', + data.find_links, + '-f', + common_wheels, 'wheelbroken==0.1', expect_error=True, ) @@ -127,16 +147,21 @@ def test_pip_wheel_fail(script, data, common_wheels): @pytest.mark.network -def test_no_clean_option_blocks_cleaning_after_wheel( - script, data, common_wheels): +def test_no_clean_option_blocks_cleaning_after_wheel(script, data, common_wheels): """ Test --no-clean option blocks cleaning after wheel build """ script.pip('install', 'wheel', '--no-index', '-f', common_wheels) build = script.venv_path / 'build' result = script.pip( - 'wheel', '--no-clean', '--no-index', '--build', build, - '--find-links=%s' % data.find_links, '-f', common_wheels, + 'wheel', + '--no-clean', + '--no-index', + '--build', + build, + '--find-links=%s' % data.find_links, + '-f', + common_wheels, 'simple', expect_temp=True, ) @@ -153,7 +178,12 @@ def test_pip_wheel_source_deps(script, data, common_wheels): # 'requires_source' is a wheel that depends on the 'source' project script.pip('install', 'wheel', '--no-index', '-f', common_wheels) result = script.pip( - 'wheel', '--no-index', '-f', data.find_links, '-f', common_wheels, + 'wheel', + '--no-index', + '-f', + data.find_links, + '-f', + common_wheels, 'requires_source', ) wheel_file_name = 'source-1.0-py%s-none-any.whl' % pyversion[0] @@ -163,8 +193,7 @@ def test_pip_wheel_source_deps(script, data, common_wheels): @pytest.mark.network -def test_pip_wheel_fail_cause_of_previous_build_dir( - script, data, common_wheels): +def test_pip_wheel_fail_cause_of_previous_build_dir(script, data, common_wheels): """ Test when 'pip wheel' tries to install a package that has a previous build directory @@ -180,9 +209,14 @@ def test_pip_wheel_fail_cause_of_previous_build_dir( # When I call pip trying to install things again result = script.pip( - 'wheel', '--no-index', '--find-links=%s' % data.find_links, - '--build', script.venv_path / 'build', - 'simple==3.0', expect_error=True, expect_temp=True, + 'wheel', + '--no-index', + '--find-links=%s' % data.find_links, + '--build', + script.venv_path / 'build', + 'simple==3.0', + expect_error=True, + expect_temp=True, ) # Then I see that the error code is the right one @@ -202,8 +236,9 @@ def test_wheel_package_with_latin1_setup(script, data, common_wheels): @pytest.mark.network def test_pip_wheel_with_pep518_build_reqs(script, data, common_wheels): script.pip_install_local('-f', common_wheels, 'wheel') - result = script.pip('wheel', '--no-index', '-f', data.find_links, - '-f', common_wheels, 'pep518==3.0',) + result = script.pip( + 'wheel', '--no-index', '-f', data.find_links, '-f', common_wheels, 'pep518==3.0' + ) wheel_file_name = 'pep518-3.0-py%s-none-any.whl' % pyversion[0] wheel_file_path = script.scratch / wheel_file_name assert wheel_file_path in result.files_created, result.stdout @@ -212,12 +247,15 @@ def test_pip_wheel_with_pep518_build_reqs(script, data, common_wheels): @pytest.mark.network -def test_pip_wheel_with_pep518_build_reqs_no_isolation(script, data, - common_wheels): +def test_pip_wheel_with_pep518_build_reqs_no_isolation(script, data, common_wheels): script.pip_install_local('-f', common_wheels, 'wheel', 'simplewheel==2.0') result = script.pip( - 'wheel', '--no-index', '-f', data.find_links, - '--no-build-isolation', 'pep518==3.0', + 'wheel', + '--no-index', + '-f', + data.find_links, + '--no-build-isolation', + 'pep518==3.0', ) wheel_file_name = 'pep518-3.0-py%s-none-any.whl' % pyversion[0] wheel_file_path = script.scratch / wheel_file_name @@ -233,7 +271,6 @@ def test_pip_wheel_with_user_set_in_config(script, data, common_wheels): script.environ['PIP_CONFIG_FILE'] = str(config_file) config_file.write("[install]\nuser = true") result = script.pip( - 'wheel', data.src / 'withpyproject', - '--no-index', '-f', common_wheels + 'wheel', data.src / 'withpyproject', '--no-index', '-f', common_wheels ) assert "Successfully built withpyproject" in result.stdout, result.stdout diff --git a/tests/functional/test_yaml.py b/tests/functional/test_yaml.py index 00c8ea658c3..69b5851d6d8 100644 --- a/tests/functional/test_yaml.py +++ b/tests/functional/test_yaml.py @@ -20,12 +20,11 @@ (?P<selector>.+?) (?=,|\.$) """, - re.X + re.X, ) def _convert_to_dict(string): - def stripping_split(my_str, splitwith, count=None): if count is None: return [x.strip() for x in my_str.strip().split(splitwith)] @@ -50,13 +49,13 @@ def stripping_split(my_str, splitwith, count=None): def handle_install_request(script, requirement): - assert isinstance(requirement, str), ( - "Need install requirement to be a string only" - ) + assert isinstance(requirement, str), "Need install requirement to be a string only" result = script.pip( "install", - "--no-index", "--find-links", path_to_url(script.scratch_path), - requirement + "--no-index", + "--find-links", + path_to_url(script.scratch_path), + requirement, ) retval = {} @@ -66,9 +65,9 @@ def handle_install_request(script, requirement): for path in result.files_created: if path.endswith(".dist-info"): - name, version = ( - os.path.basename(path)[:-len(".dist-info")] - ).rsplit("-", 1) + name, version = (os.path.basename(path)[: -len(".dist-info")]).rsplit( + "-", 1 + ) # TODO: information about extras. @@ -90,7 +89,7 @@ def handle_install_request(script, requirement): retval["conflicting"].append( { "required_by": "{} {}".format(di["name"], di["version"]), - "selector": di["selector"] + "selector": di["selector"], } ) @@ -106,9 +105,9 @@ def test_yaml_based(script, case): requests = case.get("request", []) transaction = case.get("transaction", []) - assert len(requests) == len(transaction), ( - "Expected requests and transaction counts to be same" - ) + assert len(requests) == len( + transaction + ), "Expected requests and transaction counts to be same" # Create a custom index of all the packages that are supposed to be # available @@ -121,9 +120,7 @@ def test_yaml_based(script, case): create_basic_wheel_for_package(script, **package) - available_actions = { - "install": handle_install_request - } + available_actions = {"install": handle_install_request} # use scratch path for index for request, expected in zip(requests, transaction): @@ -133,8 +130,8 @@ def test_yaml_based(script, case): # Get the only key action = list(request.keys())[0] - assert action in available_actions.keys(), ( - "Unsupported action {!r}".format(action) + assert action in available_actions.keys(), "Unsupported action {!r}".format( + action ) # Perform the requested action diff --git a/tests/lib/__init__.py b/tests/lib/__init__.py index 7f1dd5d0c0d..95651acceb9 100644 --- a/tests/lib/__init__.py +++ b/tests/lib/__init__.py @@ -140,11 +140,11 @@ class TestFailure(AssertionError): """ An "assertion" failed during testing. """ + pass class TestPipResult(object): - def __init__(self, impl, verbose=False): self._impl = impl @@ -170,15 +170,23 @@ def stderr(self): def __str__(self): return str(self._impl).replace('\r\n', '\n') + else: # Python doesn't automatically forward __str__ through __getattr__ def __str__(self): return str(self._impl) - def assert_installed(self, pkg_name, editable=True, with_files=[], - without_files=[], without_egg_link=False, - use_user_site=False, sub_dir=False): + def assert_installed( + self, + pkg_name, + editable=True, + with_files=[], + without_files=[], + without_egg_link=False, + use_user_site=False, + sub_dir=False, + ): e = self.test_env if editable: @@ -198,32 +206,33 @@ def assert_installed(self, pkg_name, editable=True, with_files=[], if without_egg_link: if egg_link_path in self.files_created: raise TestFailure( - 'unexpected egg link file created: %r\n%s' % - (egg_link_path, self) + 'unexpected egg link file created: %r\n%s' % (egg_link_path, self) ) else: if egg_link_path not in self.files_created: raise TestFailure( - 'expected egg link file missing: %r\n%s' % - (egg_link_path, self) + 'expected egg link file missing: %r\n%s' % (egg_link_path, self) ) egg_link_file = self.files_created[egg_link_path] egg_link_contents = egg_link_file.bytes.replace(os.linesep, '\n') # FIXME: I don't understand why there's a trailing . here - if not (egg_link_contents.endswith('\n.') and - egg_link_contents[:-2].endswith(pkg_dir)): - raise TestFailure(textwrap.dedent(u'''\ + if not ( + egg_link_contents.endswith('\n.') + and egg_link_contents[:-2].endswith(pkg_dir) + ): + raise TestFailure( + textwrap.dedent( + u'''\ Incorrect egg_link file %r Expected ending: %r ------- Actual contents ------- %s - -------------------------------''' % ( - egg_link_file, - pkg_dir + '\n.', - repr(egg_link_contents)) - )) + -------------------------------''' + % (egg_link_file, pkg_dir + '\n.', repr(egg_link_contents)) + ) + ) if use_user_site: pth_file = e.user_site / 'easy-install.pth' @@ -231,31 +240,37 @@ def assert_installed(self, pkg_name, editable=True, with_files=[], pth_file = e.site_packages / 'easy-install.pth' if (pth_file in self.files_updated) == without_egg_link: - raise TestFailure('%r unexpectedly %supdated by install' % ( - pth_file, (not without_egg_link and 'not ' or ''))) + raise TestFailure( + '%r unexpectedly %supdated by install' + % (pth_file, (not without_egg_link and 'not ' or '')) + ) if (pkg_dir in self.files_created) == (curdir in without_files): - raise TestFailure(textwrap.dedent('''\ + raise TestFailure( + textwrap.dedent( + '''\ expected package directory %r %sto be created actually created: %s - ''') % ( - pkg_dir, - (curdir in without_files and 'not ' or ''), - sorted(self.files_created.keys()))) + ''' + ) + % ( + pkg_dir, + (curdir in without_files and 'not ' or ''), + sorted(self.files_created.keys()), + ) + ) for f in with_files: if not (pkg_dir / f).normpath in self.files_created: raise TestFailure( - 'Package directory %r missing expected content %r' % - (pkg_dir, f) + 'Package directory %r missing expected content %r' % (pkg_dir, f) ) for f in without_files: if (pkg_dir / f).normpath in self.files_created: raise TestFailure( - 'Package directory %r has unexpected content %f' % - (pkg_dir, f) + 'Package directory %r has unexpected content %f' % (pkg_dir, f) ) @@ -297,8 +312,7 @@ def __init__(self, base_path, *args, **kwargs): self.user_base_path = self.venv_path.join("user") self.user_site_path = self.venv_path.join( - "user", - site.USER_SITE[len(site.USER_BASE) + 1:], + "user", site.USER_SITE[len(site.USER_BASE) + 1 :] ) if sys.platform == 'win32': if sys.version_info >= (3, 5): @@ -322,9 +336,7 @@ def __init__(self, base_path, *args, **kwargs): if environ is None: environ = os.environ.copy() - environ["PATH"] = Path.pathsep.join( - [self.bin_path] + [environ.get("PATH", [])], - ) + environ["PATH"] = Path.pathsep.join([self.bin_path] + [environ.get("PATH", [])]) environ["PYTHONUSERBASE"] = self.user_base_path # Writing bytecode can mess up updated file detection environ["PYTHONDONTWRITEBYTECODE"] = "1" @@ -336,8 +348,18 @@ def __init__(self, base_path, *args, **kwargs): super(PipTestEnvironment, self).__init__(base_path, *args, **kwargs) # Expand our absolute path directories into relative - for name in ["base", "venv", "lib", "include", "bin", "site_packages", - "user_base", "user_site", "user_bin", "scratch"]: + for name in [ + "base", + "venv", + "lib", + "include", + "bin", + "site_packages", + "user_base", + "user_site", + "user_bin", + "scratch", + ]: real_name = "%s_path" % name setattr(self, name, getattr(self, real_name) - self.base_path) @@ -377,8 +399,11 @@ def pip(self, *args, **kwargs): # On old versions of Python, urllib3/requests will raise a warning # about the lack of an SSLContext. Expect it when running commands # that will touch the outside world. - if (pyversion_tuple < (2, 7, 9) and - args and args[0] in ('search', 'install', 'download')): + if ( + pyversion_tuple < (2, 7, 9) + and args + and args[0] in ('search', 'install', 'download') + ): kwargs['expect_stderr'] = True if kwargs.pop('use_module', False): exe = 'python' @@ -389,9 +414,12 @@ def pip(self, *args, **kwargs): def pip_install_local(self, *args, **kwargs): return self.pip( - "install", "--no-index", - "--find-links", path_to_url(os.path.join(DATA_DIR, "packages")), - *args, **kwargs + "install", + "--no-index", + "--find-links", + path_to_url(os.path.join(DATA_DIR, "packages")), + *args, + **kwargs ) @@ -430,15 +458,15 @@ def prefix_match(path, prefix): prefix = prefix.rstrip(os.path.sep) + os.path.sep return path.startswith(prefix) - start_keys = {k for k in start.keys() - if not any([prefix_match(k, i) for i in ignore])} - end_keys = {k for k in end.keys() - if not any([prefix_match(k, i) for i in ignore])} + start_keys = { + k for k in start.keys() if not any([prefix_match(k, i) for i in ignore]) + } + end_keys = {k for k in end.keys() if not any([prefix_match(k, i) for i in ignore])} deleted = {k: start[k] for k in start_keys.difference(end_keys)} created = {k: end[k] for k in end_keys.difference(start_keys)} updated = {} for k in start_keys.intersection(end_keys): - if (start[k].size != end[k].size): + if start[k].size != end[k].size: updated[k] = end[k] return dict(deleted=deleted, created=created, updated=updated) @@ -467,8 +495,10 @@ def assert_all_changes(start_state, end_state, expected_changes): diff = diff_states(start_files, end_files, ignore=expected_changes) if list(diff.values()) != [{}, {}, {}]: - raise TestFailure('Unexpected changes:\n' + '\n'.join( - [k + ': ' + ', '.join(v.keys()) for k, v in diff.items()])) + raise TestFailure( + 'Unexpected changes:\n' + + '\n'.join([k + ': ' + ', '.join(v.keys()) for k, v in diff.items()]) + ) # Don't throw away this potentially useful information return diff @@ -477,43 +507,62 @@ def assert_all_changes(start_state, end_state, expected_changes): def _create_test_package_with_subdirectory(script, subdirectory): script.scratch_path.join("version_pkg").mkdir() version_pkg_path = script.scratch_path / 'version_pkg' - version_pkg_path.join("version_pkg.py").write(textwrap.dedent(""" + version_pkg_path.join("version_pkg.py").write( + textwrap.dedent( + """ def main(): print('0.1') - """)) + """ + ) + ) version_pkg_path.join("setup.py").write( - textwrap.dedent(""" + textwrap.dedent( + """ from setuptools import setup, find_packages setup(name='version_pkg', version='0.1', packages=find_packages(), py_modules=['version_pkg'], entry_points=dict(console_scripts=['version_pkg=version_pkg:main'])) - """)) + """ + ) + ) subdirectory_path = version_pkg_path.join(subdirectory) subdirectory_path.mkdir() - subdirectory_path.join('version_subpkg.py').write(textwrap.dedent(""" + subdirectory_path.join('version_subpkg.py').write( + textwrap.dedent( + """ def main(): print('0.1') - """)) + """ + ) + ) subdirectory_path.join('setup.py').write( - textwrap.dedent(""" + textwrap.dedent( + """ from setuptools import setup, find_packages setup(name='version_subpkg', version='0.1', packages=find_packages(), py_modules=['version_subpkg'], entry_points=dict(console_scripts=['version_pkg=version_subpkg:main'])) - """)) + """ + ) + ) script.run('git', 'init', cwd=version_pkg_path) script.run('git', 'add', '.', cwd=version_pkg_path) script.run( - 'git', 'commit', '-q', - '--author', 'pip <pypa-dev@googlegroups.com>', - '-am', 'initial version', cwd=version_pkg_path + 'git', + 'commit', + '-q', + '--author', + 'pip <pypa-dev@googlegroups.com>', + '-am', + 'initial version', + cwd=version_pkg_path, ) return version_pkg_path @@ -529,7 +578,9 @@ def _create_test_package_with_srcdir(script, name='version_pkg', vcs='git'): pkg_path = src_path.join('pkg') pkg_path.mkdir() pkg_path.join('__init__.py').write('') - subdir_path.join("setup.py").write(textwrap.dedent(""" + subdir_path.join("setup.py").write( + textwrap.dedent( + """ from setuptools import setup, find_packages setup( name='{name}', @@ -537,18 +588,28 @@ def _create_test_package_with_srcdir(script, name='version_pkg', vcs='git'): packages=find_packages(), package_dir={{'': 'src'}}, ) - """.format(name=name))) + """.format( + name=name + ) + ) + ) return _vcs_add(script, version_pkg_path, vcs) def _create_test_package(script, name='version_pkg', vcs='git'): script.scratch_path.join(name).mkdir() version_pkg_path = script.scratch_path / name - version_pkg_path.join("%s.py" % name).write(textwrap.dedent(""" + version_pkg_path.join("%s.py" % name).write( + textwrap.dedent( + """ def main(): print('0.1') - """)) - version_pkg_path.join("setup.py").write(textwrap.dedent(""" + """ + ) + ) + version_pkg_path.join("setup.py").write( + textwrap.dedent( + """ from setuptools import setup, find_packages setup( name='{name}', @@ -557,7 +618,11 @@ def main(): py_modules=['{name}'], entry_points=dict(console_scripts=['{name}={name}:main']) ) - """.format(name=name))) + """.format( + name=name + ) + ) + ) return _vcs_add(script, version_pkg_path, vcs) @@ -566,23 +631,32 @@ def _vcs_add(script, version_pkg_path, vcs='git'): script.run('git', 'init', cwd=version_pkg_path) script.run('git', 'add', '.', cwd=version_pkg_path) script.run( - 'git', 'commit', '-q', - '--author', 'pip <pypa-dev@googlegroups.com>', - '-am', 'initial version', cwd=version_pkg_path, + 'git', + 'commit', + '-q', + '--author', + 'pip <pypa-dev@googlegroups.com>', + '-am', + 'initial version', + cwd=version_pkg_path, ) elif vcs == 'hg': script.run('hg', 'init', cwd=version_pkg_path) script.run('hg', 'add', '.', cwd=version_pkg_path) script.run( - 'hg', 'commit', '-q', - '--user', 'pip <pypa-dev@googlegroups.com>', - '-m', 'initial version', cwd=version_pkg_path, + 'hg', + 'commit', + '-q', + '--user', + 'pip <pypa-dev@googlegroups.com>', + '-m', + 'initial version', + cwd=version_pkg_path, ) elif vcs == 'svn': repo_url = _create_svn_repo(script, version_pkg_path) script.run( - 'svn', 'checkout', repo_url, 'pip-test-package', - cwd=script.scratch_path + 'svn', 'checkout', repo_url, 'pip-test-package', cwd=script.scratch_path ) checkout_path = script.scratch_path / 'pip-test-package' @@ -594,12 +668,17 @@ def _vcs_add(script, version_pkg_path, vcs='git'): script.run('bzr', 'init', cwd=version_pkg_path) script.run('bzr', 'add', '.', cwd=version_pkg_path) script.run( - 'bzr', 'whoami', 'pip <pypa-dev@googlegroups.com>', - cwd=version_pkg_path) + 'bzr', 'whoami', 'pip <pypa-dev@googlegroups.com>', cwd=version_pkg_path + ) script.run( - 'bzr', 'commit', '-q', - '--author', 'pip <pypa-dev@googlegroups.com>', - '-m', 'initial version', cwd=version_pkg_path, + 'bzr', + 'commit', + '-q', + '--author', + 'pip <pypa-dev@googlegroups.com>', + '-m', + 'initial version', + cwd=version_pkg_path, ) else: raise ValueError('Unknown vcs: %r' % vcs) @@ -607,33 +686,37 @@ def _vcs_add(script, version_pkg_path, vcs='git'): def _create_svn_repo(script, version_pkg_path): - repo_url = path_to_url( - script.scratch_path / 'pip-test-package-repo' / 'trunk') - script.run( - 'svnadmin', 'create', 'pip-test-package-repo', - cwd=script.scratch_path - ) + repo_url = path_to_url(script.scratch_path / 'pip-test-package-repo' / 'trunk') + script.run('svnadmin', 'create', 'pip-test-package-repo', cwd=script.scratch_path) script.run( - 'svn', 'import', version_pkg_path, repo_url, - '-m', 'Initial import of pip-test-package', - cwd=script.scratch_path + 'svn', + 'import', + version_pkg_path, + repo_url, + '-m', + 'Initial import of pip-test-package', + cwd=script.scratch_path, ) return repo_url def _change_test_package_version(script, version_pkg_path): - version_pkg_path.join("version_pkg.py").write(textwrap.dedent('''\ + version_pkg_path.join("version_pkg.py").write( + textwrap.dedent( + '''\ def main(): - print("some different version")''')) - script.run( - 'git', 'clean', '-qfdx', - cwd=version_pkg_path, - expect_stderr=True, + print("some different version")''' + ) ) + script.run('git', 'clean', '-qfdx', cwd=version_pkg_path, expect_stderr=True) script.run( - 'git', 'commit', '-q', - '--author', 'pip <pypa-dev@googlegroups.com>', - '-am', 'messed version', + 'git', + 'commit', + '-q', + '--author', + 'pip <pypa-dev@googlegroups.com>', + '-am', + 'messed version', cwd=version_pkg_path, expect_stderr=True, ) @@ -671,11 +754,16 @@ def create_test_package_with_setup(script, **setup_kwargs): assert 'name' in setup_kwargs, setup_kwargs pkg_path = script.scratch_path / setup_kwargs['name'] pkg_path.mkdir() - pkg_path.join("setup.py").write(textwrap.dedent(""" + pkg_path.join("setup.py").write( + textwrap.dedent( + """ from setuptools import setup kwargs = %r setup(**kwargs) - """) % setup_kwargs) + """ + ) + % setup_kwargs + ) return pkg_path @@ -715,33 +803,34 @@ def hello(): {name} """, # Have an empty RECORD because we don't want to be checking hashes. - "{dist_info}/RECORD": "" + "{dist_info}/RECORD": "", } # Some useful shorthands archive_name = "{name}-{version}-py2.py3-none-any.whl".format( name=name, version=version ) - dist_info = "{name}-{version}.dist-info".format( - name=name, version=version + dist_info = "{name}-{version}.dist-info".format(name=name, version=version) + + requires_dist = "\n".join( + ["Requires-Dist: {}".format(pkg) for pkg in depends] + + ["Provides-Extra: {}".format(pkg) for pkg in extras.keys()] + + [ + "Requires-Dist: {}; extra == \"{}\"".format(pkg, extra) + for extra in extras + for pkg in extras[extra] + ] ) - requires_dist = "\n".join([ - "Requires-Dist: {}".format(pkg) for pkg in depends - ] + [ - "Provides-Extra: {}".format(pkg) for pkg in extras.keys() - ] + [ - "Requires-Dist: {}; extra == \"{}\"".format(pkg, extra) - for extra in extras for pkg in extras[extra] - ]) - # Replace key-values with formatted values for key, value in list(files.items()): del files[key] key = key.format(name=name, dist_info=dist_info) - files[key] = textwrap.dedent(value).format( - name=name, version=version, requires_dist=requires_dist - ).strip() + files[key] = ( + textwrap.dedent(value) + .format(name=name, version=version, requires_dist=requires_dist) + .strip() + ) for fname in files: path = script.temp_path / fname @@ -765,16 +854,13 @@ def wrapper(fn): except OSError: return pytest.mark.skip(reason='%s is not available' % name)(fn) return fn + return wrapper def need_bzr(fn): - return pytest.mark.bzr(need_executable( - 'Bazaar', ('bzr', 'version', '--short') - )(fn)) + return pytest.mark.bzr(need_executable('Bazaar', ('bzr', 'version', '--short'))(fn)) def need_mercurial(fn): - return pytest.mark.mercurial(need_executable( - 'Mercurial', ('hg', 'version') - )(fn)) + return pytest.mark.mercurial(need_executable('Mercurial', ('hg', 'version'))(fn)) diff --git a/tests/lib/configuration_helpers.py b/tests/lib/configuration_helpers.py index 1164be8a78a..f0a1f6cfcc1 100644 --- a/tests/lib/configuration_helpers.py +++ b/tests/lib/configuration_helpers.py @@ -15,11 +15,8 @@ class ConfigurationMixin(object): - def setup(self): - self.configuration = pip._internal.configuration.Configuration( - isolated=False, - ) + self.configuration = pip._internal.configuration.Configuration(isolated=False) self._files_to_clear = [] self._old_environ = os.environ.copy() @@ -45,9 +42,7 @@ def overidden(): @contextlib.contextmanager def tmpfile(self, contents): # Create a temporary file - fd, path = tempfile.mkstemp( - prefix="pip_", suffix="_config.ini", text=True - ) + fd, path = tempfile.mkstemp(prefix="pip_", suffix="_config.ini", text=True) os.close(fd) contents = textwrap.dedent(contents).lstrip() diff --git a/tests/lib/git_submodule_helpers.py b/tests/lib/git_submodule_helpers.py index d5ec20045aa..8248db53cee 100644 --- a/tests/lib/git_submodule_helpers.py +++ b/tests/lib/git_submodule_helpers.py @@ -9,9 +9,16 @@ def _create_test_package_submodule(env): env.run('touch', 'testfile', cwd=submodule_path) env.run('git', 'init', cwd=submodule_path) env.run('git', 'add', '.', cwd=submodule_path) - env.run('git', 'commit', '-q', - '--author', 'pip <pypa-dev@googlegroups.com>', - '-am', 'initial version / submodule', cwd=submodule_path) + env.run( + 'git', + 'commit', + '-q', + '--author', + 'pip <pypa-dev@googlegroups.com>', + '-am', + 'initial version / submodule', + cwd=submodule_path, + ) return submodule_path @@ -19,23 +26,32 @@ def _change_test_package_submodule(env, submodule_path): submodule_path.join("testfile").write("this is a changed file") submodule_path.join("testfile2").write("this is an added file") env.run('git', 'add', '.', cwd=submodule_path) - env.run('git', 'commit', '-q', - '--author', 'pip <pypa-dev@googlegroups.com>', - '-am', 'submodule change', cwd=submodule_path) + env.run( + 'git', + 'commit', + '-q', + '--author', + 'pip <pypa-dev@googlegroups.com>', + '-am', + 'submodule change', + cwd=submodule_path, + ) def _pull_in_submodule_changes_to_module(env, module_path): + env.run( + 'git', 'pull', '-q', 'origin', 'master', cwd=module_path / 'testpkg/static/' + ) env.run( 'git', - 'pull', + 'commit', '-q', - 'origin', - 'master', - cwd=module_path / 'testpkg/static/', + '--author', + 'pip <pypa-dev@googlegroups.com>', + '-am', + 'submodule change', + cwd=module_path, ) - env.run('git', 'commit', '-q', - '--author', 'pip <pypa-dev@googlegroups.com>', - '-am', 'submodule change', cwd=module_path) def _create_test_package_with_submodule(env): @@ -45,23 +61,38 @@ def _create_test_package_with_submodule(env): pkg_path = version_pkg_path / 'testpkg' pkg_path.join("__init__.py").write("# hello there") - pkg_path.join("version_pkg.py").write(textwrap.dedent('''\ + pkg_path.join("version_pkg.py").write( + textwrap.dedent( + '''\ def main(): print('0.1') - ''')) - version_pkg_path.join("setup.py").write(textwrap.dedent('''\ + ''' + ) + ) + version_pkg_path.join("setup.py").write( + textwrap.dedent( + '''\ from setuptools import setup, find_packages setup(name='version_pkg', version='0.1', packages=find_packages(), ) - ''')) + ''' + ) + ) env.run('git', 'init', cwd=version_pkg_path, expect_error=True) env.run('git', 'add', '.', cwd=version_pkg_path, expect_error=True) - env.run('git', 'commit', '-q', - '--author', 'pip <pypa-dev@googlegroups.com>', - '-am', 'initial version', cwd=version_pkg_path, - expect_error=True) + env.run( + 'git', + 'commit', + '-q', + '--author', + 'pip <pypa-dev@googlegroups.com>', + '-am', + 'initial version', + cwd=version_pkg_path, + expect_error=True, + ) submodule_path = _create_test_package_submodule(env) @@ -74,9 +105,16 @@ def main(): cwd=version_pkg_path, expect_error=True, ) - env.run('git', 'commit', '-q', - '--author', 'pip <pypa-dev@googlegroups.com>', - '-am', 'initial version w submodule', cwd=version_pkg_path, - expect_error=True) + env.run( + 'git', + 'commit', + '-q', + '--author', + 'pip <pypa-dev@googlegroups.com>', + '-am', + 'initial version w submodule', + cwd=version_pkg_path, + expect_error=True, + ) return version_pkg_path, submodule_path diff --git a/tests/lib/local_repos.py b/tests/lib/local_repos.py index 54a330bb2f7..8f59cf89f14 100644 --- a/tests/lib/local_repos.py +++ b/tests/lib/local_repos.py @@ -26,11 +26,7 @@ def _dump_initools_repository(directory): initools_folder = os.path.join(directory, 'INITools') devnull = open(os.devnull, 'w') dump = open(filename) - subprocess_call( - ['svnadmin', 'load', initools_folder], - stdin=dump, - stdout=devnull, - ) + subprocess_call(['svnadmin', 'load', initools_folder], stdin=dump, stdout=devnull) dump.close() devnull.close() os.remove(filename) @@ -43,10 +39,12 @@ def _create_svn_repository_for_initools(directory): def _get_vcs_and_checkout_url(remote_repository, directory): - vcs_classes = {'svn': subversion.Subversion, - 'git': git.Git, - 'bzr': bazaar.Bazaar, - 'hg': mercurial.Mercurial} + vcs_classes = { + 'svn': subversion.Subversion, + 'git': git.Git, + 'bzr': bazaar.Bazaar, + 'hg': mercurial.Mercurial, + } default_vcs = 'svn' if '+' not in remote_repository: remote_repository = '%s+%s' % (default_vcs, remote_repository) @@ -56,19 +54,14 @@ def _get_vcs_and_checkout_url(remote_repository, directory): if vcs == 'svn': branch = os.path.basename(remote_repository) # remove the slash - repository_name = os.path.basename( - remote_repository[:-len(branch) - 1] - ) + repository_name = os.path.basename(remote_repository[: -len(branch) - 1]) else: repository_name = os.path.basename(remote_repository) destination_path = os.path.join(directory, repository_name) if not os.path.exists(destination_path): vcs_class(remote_repository).obtain(destination_path) - return '%s+%s' % ( - vcs, - path_to_url('/'.join([directory, repository_name, branch])), - ) + return '%s+%s' % (vcs, path_to_url('/'.join([directory, repository_name, branch]))) def local_checkout(remote_repo, directory): diff --git a/tests/lib/options_helpers.py b/tests/lib/options_helpers.py index fef74d3aeb1..3e872a9ee3f 100644 --- a/tests/lib/options_helpers.py +++ b/tests/lib/options_helpers.py @@ -13,16 +13,12 @@ class FakeCommand(Command): summary = name def main(self, args): - index_opts = cmdoptions.make_option_group( - cmdoptions.index_group, - self.parser, - ) + index_opts = cmdoptions.make_option_group(cmdoptions.index_group, self.parser) self.parser.add_option_group(index_opts) return self.parse_args(args) class AddFakeCommandMixin(object): - def setup(self): self.environ_before = os.environ.copy() commands_dict[FakeCommand.name] = FakeCommand diff --git a/tests/lib/path.py b/tests/lib/path.py index ecbb0d6ca1c..f4a49aee5c6 100644 --- a/tests/lib/path.py +++ b/tests/lib/path.py @@ -16,7 +16,6 @@ supports_fd = set() - _base = six.text_type if os.path.supports_unicode_filenames else str @@ -297,4 +296,5 @@ def touch(self, times=None): with open(self, "a") as fp: os.utime(fp.fileno() if os.utime in supports_fd else self, times) + curdir = Path(os.path.curdir) diff --git a/tests/lib/test_lib.py b/tests/lib/test_lib.py index a8ed3c9cd86..7347465e1f9 100644 --- a/tests/lib/test_lib.py +++ b/tests/lib/test_lib.py @@ -33,7 +33,7 @@ def test_correct_pip_version(script): pip_folder_outputed = re.match( r'pip \d+(\.[\d]+)+(\.?(b|rc|dev|pre|post)\d+)? from (.*) ' r'\(python \d(.[\d])+\)$', - result.stdout + result.stdout, ).group(4) pip_folder = join(SRC_DIR, 'src', 'pip') @@ -44,12 +44,14 @@ def test_correct_pip_version(script): # primary resources other than .py files, this code will need # maintenance mismatch_py = [ - x for x in diffs.left_only + diffs.right_only + diffs.diff_files + x + for x in diffs.left_only + diffs.right_only + diffs.diff_files if x.endswith('.py') ] - assert not mismatch_py, ( - 'mismatched source files in %r and %r: %r' % - (pip_folder, pip_folder_outputed, mismatch_py) + assert not mismatch_py, 'mismatched source files in %r and %r: %r' % ( + pip_folder, + pip_folder_outputed, + mismatch_py, ) @@ -58,4 +60,5 @@ def test_as_import(script): the command submodule with a dictionary """ import pip._internal.commands.install as inst + assert inst is not None diff --git a/tests/lib/venv.py b/tests/lib/venv.py index ce0b1059dcd..0e3ddba38a4 100644 --- a/tests/lib/venv.py +++ b/tests/lib/venv.py @@ -25,25 +25,17 @@ def __repr__(self): return "<VirtualEnvironment {}>".format(self.location) @classmethod - def create(cls, location, clear=False, - pip_source_dir=None, relocatable=False): + def create(cls, location, clear=False, pip_source_dir=None, relocatable=False): obj = cls(location) - obj._create(clear=clear, - pip_source_dir=pip_source_dir, - relocatable=relocatable) + obj._create(clear=clear, pip_source_dir=pip_source_dir, relocatable=relocatable) return obj def _create(self, clear=False, pip_source_dir=None, relocatable=False): # Create the actual virtual environment _virtualenv.create_environment( - self.location, - clear=clear, - download=False, - no_pip=True, - no_wheel=True, + self.location, clear=clear, download=False, no_pip=True, no_wheel=True ) - _virtualenv.install_wheel([pip_source_dir or '.'], - self.bin.join("python")) + _virtualenv.install_wheel([pip_source_dir or '.'], self.bin.join("python")) if relocatable: _virtualenv.make_environment_relocatable(self.location) # FIXME: some tests rely on 'easy-install.pth' being already present. diff --git a/tests/lib/yaml_helpers.py b/tests/lib/yaml_helpers.py index 73770632099..d1354f61889 100644 --- a/tests/lib/yaml_helpers.py +++ b/tests/lib/yaml_helpers.py @@ -12,7 +12,7 @@ def generate_yaml_tests(directory): # Strip the parts of the directory to only get a name without # extension and resolver directory - base_name = str(yml_file)[len(str(directory)) + 1:-4] + base_name = str(yml_file)[len(str(directory)) + 1 : -4] base = data.get("base", {}) cases = data["cases"] diff --git a/tests/scripts/test_all_pip.py b/tests/scripts/test_all_pip.py index 18c97f1c819..9a3c11b172a 100644 --- a/tests/scripts/test_all_pip.py +++ b/tests/scripts/test_all_pip.py @@ -53,37 +53,27 @@ def _test_packages(output, pending_fn): print('Creating virtualenv in %s' % dest_dir) create_venv(dest_dir) print('Uninstalling actual pip') - code = subprocess.check_call([ - os.path.join(dest_dir, bin_dir, 'pip'), - 'uninstall', - '-y', - 'pip', - ]) + code = subprocess.check_call( + [os.path.join(dest_dir, bin_dir, 'pip'), 'uninstall', '-y', 'pip'] + ) assert not code, 'pip uninstallation failed' print('Installing development pip') code = subprocess.check_call( - [ - os.path.join(dest_dir, bin_dir, 'python'), - 'setup.py', - 'install' - ], + [os.path.join(dest_dir, bin_dir, 'python'), 'setup.py', 'install'], cwd=src_folder, ) assert not code, 'pip installation failed' print('Trying installation of %s' % dest_dir) - code = subprocess.check_call([ - os.path.join(dest_dir, bin_dir, 'pip'), - 'install', - package, - ]) + code = subprocess.check_call( + [os.path.join(dest_dir, bin_dir, 'pip'), 'install', package] + ) if code: print('Installation of %s failed' % package) print('Now checking easy_install...') create_venv(dest_dir) - code = subprocess.check_call([ - os.path.join(dest_dir, bin_dir, 'easy_install'), - package, - ]) + code = subprocess.check_call( + [os.path.join(dest_dir, bin_dir, 'easy_install'), package] + ) if code: print('easy_install also failed') add_package(os.path.join(output, 'easy-failure.txt'), package) @@ -102,11 +92,7 @@ def create_venv(dest_dir): if os.path.exists(dest_dir): rmtree(dest_dir) print('Creating virtualenv in %s' % dest_dir) - code = subprocess.check_call([ - 'virtualenv', - '--no-site-packages', - dest_dir, - ]) + code = subprocess.check_call(['virtualenv', '--no-site-packages', dest_dir]) assert not code, "virtualenv failed" diff --git a/tests/unit/test_appdirs.py b/tests/unit/test_appdirs.py index a306d56cffe..692a7919dc6 100644 --- a/tests/unit/test_appdirs.py +++ b/tests/unit/test_appdirs.py @@ -9,23 +9,19 @@ class TestUserCacheDir: - def test_user_cache_dir_win(self, monkeypatch): @pretend.call_recorder def _get_win_folder(base): return "C:\\Users\\test\\AppData\\Local" - monkeypatch.setattr( - appdirs, - "_get_win_folder", - _get_win_folder, - raising=False, - ) + monkeypatch.setattr(appdirs, "_get_win_folder", _get_win_folder, raising=False) monkeypatch.setattr(appdirs, "WINDOWS", True) monkeypatch.setattr(os, "path", ntpath) - assert (appdirs.user_cache_dir("pip") == - "C:\\Users\\test\\AppData\\Local\\pip\\Cache") + assert ( + appdirs.user_cache_dir("pip") + == "C:\\Users\\test\\AppData\\Local\\pip\\Cache" + ) assert _get_win_folder.calls == [pretend.call("CSIDL_LOCAL_APPDATA")] def test_user_cache_dir_osx(self, monkeypatch): @@ -81,22 +77,17 @@ def my_get_win_folder(csidl_name): # Test against regression #3463 from pip._internal import create_main_parser + create_main_parser().print_help() # This should not crash class TestSiteConfigDirs: - def test_site_config_dirs_win(self, monkeypatch): @pretend.call_recorder def _get_win_folder(base): return "C:\\ProgramData" - monkeypatch.setattr( - appdirs, - "_get_win_folder", - _get_win_folder, - raising=False, - ) + monkeypatch.setattr(appdirs, "_get_win_folder", _get_win_folder, raising=False) monkeypatch.setattr(appdirs, "WINDOWS", True) monkeypatch.setattr(os, "path", ntpath) @@ -109,8 +100,7 @@ def test_site_config_dirs_osx(self, monkeypatch): monkeypatch.setenv("HOME", "/home/test") monkeypatch.setattr(sys, "platform", "darwin") - assert appdirs.site_config_dirs("pip") == \ - ["/Library/Application Support/pip"] + assert appdirs.site_config_dirs("pip") == ["/Library/Application Support/pip"] def test_site_config_dirs_linux(self, monkeypatch): monkeypatch.setattr(appdirs, "WINDOWS", False) @@ -118,10 +108,7 @@ def test_site_config_dirs_linux(self, monkeypatch): monkeypatch.delenv("XDG_CONFIG_DIRS", raising=False) monkeypatch.setattr(sys, "platform", "linux2") - assert appdirs.site_config_dirs("pip") == [ - '/etc/xdg/pip', - '/etc' - ] + assert appdirs.site_config_dirs("pip") == ['/etc/xdg/pip', '/etc'] def test_site_config_dirs_linux_override(self, monkeypatch): monkeypatch.setattr(appdirs, "WINDOWS", False) @@ -134,28 +121,21 @@ def test_site_config_dirs_linux_override(self, monkeypatch): '/spam/pip', '/etc/pip', '/etc/xdg/pip', - '/etc' + '/etc', ] class TestUserDataDir: - def test_user_data_dir_win_no_roaming(self, monkeypatch): @pretend.call_recorder def _get_win_folder(base): return "C:\\Users\\test\\AppData\\Local" - monkeypatch.setattr( - appdirs, - "_get_win_folder", - _get_win_folder, - raising=False, - ) + monkeypatch.setattr(appdirs, "_get_win_folder", _get_win_folder, raising=False) monkeypatch.setattr(appdirs, "WINDOWS", True) monkeypatch.setattr(os, "path", ntpath) - assert (appdirs.user_data_dir("pip") == - "C:\\Users\\test\\AppData\\Local\\pip") + assert appdirs.user_data_dir("pip") == "C:\\Users\\test\\AppData\\Local\\pip" assert _get_win_folder.calls == [pretend.call("CSIDL_LOCAL_APPDATA")] def test_user_data_dir_win_yes_roaming(self, monkeypatch): @@ -163,18 +143,13 @@ def test_user_data_dir_win_yes_roaming(self, monkeypatch): def _get_win_folder(base): return "C:\\Users\\test\\AppData\\Roaming" - monkeypatch.setattr( - appdirs, - "_get_win_folder", - _get_win_folder, - raising=False, - ) + monkeypatch.setattr(appdirs, "_get_win_folder", _get_win_folder, raising=False) monkeypatch.setattr(appdirs, "WINDOWS", True) monkeypatch.setattr(os, "path", ntpath) assert ( - appdirs.user_data_dir("pip", roaming=True) == - "C:\\Users\\test\\AppData\\Roaming\\pip" + appdirs.user_data_dir("pip", roaming=True) + == "C:\\Users\\test\\AppData\\Roaming\\pip" ) assert _get_win_folder.calls == [pretend.call("CSIDL_APPDATA")] @@ -185,11 +160,12 @@ def test_user_data_dir_osx(self, monkeypatch): monkeypatch.setattr(sys, "platform", "darwin") if os.path.isdir('/home/test/Library/Application Support/'): - assert (appdirs.user_data_dir("pip") == - "/home/test/Library/Application Support/pip") + assert ( + appdirs.user_data_dir("pip") + == "/home/test/Library/Application Support/pip" + ) else: - assert (appdirs.user_data_dir("pip") == - "/home/test/.config/pip") + assert appdirs.user_data_dir("pip") == "/home/test/.config/pip" def test_user_data_dir_linux(self, monkeypatch): monkeypatch.setattr(appdirs, "WINDOWS", False) @@ -221,24 +197,18 @@ def test_user_data_dir_linux_home_slash(self, monkeypatch): class TestUserConfigDir: - def test_user_config_dir_win_no_roaming(self, monkeypatch): @pretend.call_recorder def _get_win_folder(base): return "C:\\Users\\test\\AppData\\Local" - monkeypatch.setattr( - appdirs, - "_get_win_folder", - _get_win_folder, - raising=False, - ) + monkeypatch.setattr(appdirs, "_get_win_folder", _get_win_folder, raising=False) monkeypatch.setattr(appdirs, "WINDOWS", True) monkeypatch.setattr(os, "path", ntpath) assert ( - appdirs.user_config_dir("pip", roaming=False) == - "C:\\Users\\test\\AppData\\Local\\pip" + appdirs.user_config_dir("pip", roaming=False) + == "C:\\Users\\test\\AppData\\Local\\pip" ) assert _get_win_folder.calls == [pretend.call("CSIDL_LOCAL_APPDATA")] @@ -247,17 +217,13 @@ def test_user_config_dir_win_yes_roaming(self, monkeypatch): def _get_win_folder(base): return "C:\\Users\\test\\AppData\\Roaming" - monkeypatch.setattr( - appdirs, - "_get_win_folder", - _get_win_folder, - raising=False, - ) + monkeypatch.setattr(appdirs, "_get_win_folder", _get_win_folder, raising=False) monkeypatch.setattr(appdirs, "WINDOWS", True) monkeypatch.setattr(os, "path", ntpath) - assert (appdirs.user_config_dir("pip") == - "C:\\Users\\test\\AppData\\Roaming\\pip") + assert ( + appdirs.user_config_dir("pip") == "C:\\Users\\test\\AppData\\Roaming\\pip" + ) assert _get_win_folder.calls == [pretend.call("CSIDL_APPDATA")] def test_user_config_dir_osx(self, monkeypatch): @@ -267,11 +233,12 @@ def test_user_config_dir_osx(self, monkeypatch): monkeypatch.setattr(sys, "platform", "darwin") if os.path.isdir('/home/test/Library/Application Support/'): - assert (appdirs.user_data_dir("pip") == - "/home/test/Library/Application Support/pip") + assert ( + appdirs.user_data_dir("pip") + == "/home/test/Library/Application Support/pip" + ) else: - assert (appdirs.user_data_dir("pip") == - "/home/test/.config/pip") + assert appdirs.user_data_dir("pip") == "/home/test/.config/pip" def test_user_config_dir_linux(self, monkeypatch): monkeypatch.setattr(appdirs, "WINDOWS", False) diff --git a/tests/unit/test_basecommand.py b/tests/unit/test_basecommand.py index c234c731c0c..d00de0c3234 100644 --- a/tests/unit/test_basecommand.py +++ b/tests/unit/test_basecommand.py @@ -27,9 +27,7 @@ class FakeCommandWithUnicode(FakeCommand): def run(self, options, args): logging.getLogger("pip.tests").info(b"bytes here \xE9") - logging.getLogger("pip.tests").info( - b"unicode here \xC3\xA9".decode("utf-8") - ) + logging.getLogger("pip.tests").info(b"unicode here \xC3\xA9".decode("utf-8")) class Test_basecommand_logging(object): diff --git a/tests/unit/test_cache.py b/tests/unit/test_cache.py index 0f080b6570b..436190342c7 100644 --- a/tests/unit/test_cache.py +++ b/tests/unit/test_cache.py @@ -3,7 +3,6 @@ class TestWheelCache: - def test_expands_path(self): wc = WheelCache("~/.foo/", None) assert wc.cache_dir == expanduser("~/.foo/") diff --git a/tests/unit/test_check.py b/tests/unit/test_check.py index 4dc893ada91..f61b28ee5d5 100644 --- a/tests/unit/test_check.py +++ b/tests/unit/test_check.py @@ -6,7 +6,6 @@ class TestInstalledDistributionsCall(object): - def test_passes_correct_default_kwargs(self, monkeypatch): my_mock = mock.MagicMock(return_value=[]) monkeypatch.setattr(check, "get_installed_distributions", my_mock) diff --git a/tests/unit/test_cmdoptions.py b/tests/unit/test_cmdoptions.py index 7daf7cca959..634c416448e 100644 --- a/tests/unit/test_cmdoptions.py +++ b/tests/unit/test_cmdoptions.py @@ -38,9 +38,7 @@ def test_none_resets(): def test_none_preserves_other_side(): cmd = SimpleCommand() - cmd.main( - ['fake', '--no-binary=:all:', '--only-binary=fred', - '--no-binary=:none:']) + cmd.main(['fake', '--no-binary=:all:', '--only-binary=fred', '--no-binary=:none:']) expected = index.FormatControl(set(), {'fred'}) assert cmd.options.format_control == expected diff --git a/tests/unit/test_compat.py b/tests/unit/test_compat.py index 37af0f95092..873f2ded8c4 100644 --- a/tests/unit/test_compat.py +++ b/tests/unit/test_compat.py @@ -4,9 +4,7 @@ import pytest import pip._internal.compat -from pip._internal.compat import ( - console_to_str, expanduser, get_path_uid, native_str, -) +from pip._internal.compat import console_to_str, expanduser, get_path_uid, native_str def test_get_path_uid(): @@ -47,8 +45,7 @@ def test_get_path_uid_symlink_without_NOFOLLOW(tmpdir, monkeypatch): def test_console_to_str(monkeypatch): some_bytes = b"a\xE9\xC3\xE9b" - encodings = ('ascii', 'utf-8', 'iso-8859-1', 'iso-8859-5', - 'koi8_r', 'cp850') + encodings = ('ascii', 'utf-8', 'iso-8859-1', 'iso-8859-5', 'koi8_r', 'cp850') for e in encodings: monkeypatch.setattr(locale, 'getpreferredencoding', lambda: e) result = console_to_str(some_bytes) @@ -60,8 +57,7 @@ def test_console_to_str_warning(monkeypatch): some_bytes = b"a\xE9b" def check_warning(msg, *args, **kwargs): - assert msg.startswith( - "Subprocess output does not appear to be encoded as") + assert msg.startswith("Subprocess output does not appear to be encoded as") monkeypatch.setattr(locale, 'getpreferredencoding', lambda: 'utf-8') monkeypatch.setattr(pip._internal.compat.logger, 'warning', check_warning) @@ -75,13 +71,16 @@ def test_to_native_str_type(): assert isinstance(native_str(some_unicode, True), str) -@pytest.mark.parametrize("home,path,expanded", [ - ("/Users/test", "~", "/Users/test"), - ("/Users/test", "~/.cache", "/Users/test/.cache"), - # Verify that we are not affected by http://bugs.python.org/issue14768 - ("/", "~", "/"), - ("/", "~/.cache", "/.cache"), -]) +@pytest.mark.parametrize( + "home,path,expanded", + [ + ("/Users/test", "~", "/Users/test"), + ("/Users/test", "~/.cache", "/Users/test/.cache"), + # Verify that we are not affected by http://bugs.python.org/issue14768 + ("/", "~", "/"), + ("/", "~/.cache", "/.cache"), + ], +) def test_expanduser(home, path, expanded, monkeypatch): monkeypatch.setenv("HOME", home) assert expanduser(path) == expanded diff --git a/tests/unit/test_configuration.py b/tests/unit/test_configuration.py index ef1ddf96a25..16b0fe789c3 100644 --- a/tests/unit/test_configuration.py +++ b/tests/unit/test_configuration.py @@ -7,14 +7,11 @@ from mock import MagicMock from pip._internal.exceptions import ConfigurationError -from pip._internal.locations import ( - new_config_file, site_config_files, venv_config_file, -) +from pip._internal.locations import new_config_file, site_config_files, venv_config_file from tests.lib.configuration_helpers import ConfigurationMixin, kinds class TestConfigurationLoading(ConfigurationMixin): - def test_global_loading(self): self.patch_configuration(kinds.GLOBAL, {"test.hello": "1"}) @@ -43,8 +40,9 @@ def test_environment_config_loading(self): os.environ["PIP_CONFIG_FILE"] = config_file self.configuration.load() - assert self.configuration.get_value("test.hello") == "4", \ - self.configuration._config + assert ( + self.configuration.get_value("test.hello") == "4" + ), self.configuration._config def test_environment_var_loading(self): os.environ["PIP_HELLO"] = "5" diff --git a/tests/unit/test_download.py b/tests/unit/test_download.py index 93f768aabd8..58333dca50a 100644 --- a/tests/unit/test_download.py +++ b/tests/unit/test_download.py @@ -10,8 +10,13 @@ import pip from pip._internal.download import ( - MultiDomainBasicAuth, PipSession, SafeFileCache, path_to_url, - unpack_file_url, unpack_http_url, url_to_path, + MultiDomainBasicAuth, + PipSession, + SafeFileCache, + path_to_url, + unpack_file_url, + unpack_http_url, + url_to_path, ) from pip._internal.exceptions import HashMismatch from pip._internal.index import Link @@ -37,14 +42,13 @@ def _fake_session_get(*args, **kwargs): link = Link(uri) temp_dir = mkdtemp() try: - unpack_http_url( - link, - temp_dir, - download_dir=None, - session=session, - ) + unpack_http_url(link, temp_dir, download_dir=None, session=session) assert set(os.listdir(temp_dir)) == { - 'PKG-INFO', 'setup.cfg', 'setup.py', 'simple', 'simple.egg-info' + 'PKG-INFO', + 'setup.cfg', + 'setup.py', + 'simple', + 'simple.egg-info', } finally: rmtree(temp_dir) @@ -55,7 +59,6 @@ def test_user_agent(): class FakeStream(object): - def __init__(self, contents): self._io = BytesIO(contents) @@ -67,7 +70,6 @@ def stream(self, size, decode_content=None): class MockResponse(object): - def __init__(self, contents): self.raw = FakeStream(contents) @@ -101,7 +103,7 @@ def test_unpack_http_url_bad_downloaded_checksum(mock_unpack_file): 'location', download_dir=download_dir, session=session, - hashes=Hashes({'sha1': [download_hash.hexdigest()]}) + hashes=Hashes({'sha1': [download_hash.hexdigest()]}), ) # despite existence of downloaded file with bad hash, downloaded again @@ -155,7 +157,6 @@ def test_url_to_path_path_to_url_symmetry_win(): class Test_unpack_file_url(object): - def prep(self, tmpdir, data): self.build_dir = tmpdir.join('build') self.download_dir = tmpdir.join('download') @@ -172,18 +173,15 @@ def test_unpack_file_url_no_download(self, tmpdir, data): self.prep(tmpdir, data) unpack_file_url(self.dist_url, self.build_dir) assert os.path.isdir(os.path.join(self.build_dir, 'simple')) - assert not os.path.isfile( - os.path.join(self.download_dir, self.dist_file)) + assert not os.path.isfile(os.path.join(self.download_dir, self.dist_file)) def test_unpack_file_url_and_download(self, tmpdir, data): self.prep(tmpdir, data) - unpack_file_url(self.dist_url, self.build_dir, - download_dir=self.download_dir) + unpack_file_url(self.dist_url, self.build_dir, download_dir=self.download_dir) assert os.path.isdir(os.path.join(self.build_dir, 'simple')) assert os.path.isfile(os.path.join(self.download_dir, self.dist_file)) - def test_unpack_file_url_download_already_exists(self, tmpdir, - data, monkeypatch): + def test_unpack_file_url_download_already_exists(self, tmpdir, data, monkeypatch): self.prep(tmpdir, data) # add in previous download (copy simple-2.0 as simple-1.0) # so we can tell it didn't get overwritten @@ -192,26 +190,23 @@ def test_unpack_file_url_download_already_exists(self, tmpdir, with open(self.dist_path2, 'rb') as f: dist_path2_md5 = hashlib.md5(f.read()).hexdigest() - unpack_file_url(self.dist_url, self.build_dir, - download_dir=self.download_dir) + unpack_file_url(self.dist_url, self.build_dir, download_dir=self.download_dir) # our hash should be the same, i.e. not overwritten by simple-1.0 hash with open(dest_file, 'rb') as f: assert dist_path2_md5 == hashlib.md5(f.read()).hexdigest() - def test_unpack_file_url_bad_hash(self, tmpdir, data, - monkeypatch): + def test_unpack_file_url_bad_hash(self, tmpdir, data, monkeypatch): """ Test when the file url hash fragment is wrong """ self.prep(tmpdir, data) self.dist_url.url = "%s#md5=bogus" % self.dist_url.url with pytest.raises(HashMismatch): - unpack_file_url(self.dist_url, - self.build_dir, - hashes=Hashes({'md5': ['bogus']})) + unpack_file_url( + self.dist_url, self.build_dir, hashes=Hashes({'md5': ['bogus']}) + ) - def test_unpack_file_url_download_bad_hash(self, tmpdir, data, - monkeypatch): + def test_unpack_file_url_download_bad_hash(self, tmpdir, data, monkeypatch): """ Test when existing download has different hash from the file url fragment @@ -230,13 +225,13 @@ def test_unpack_file_url_download_bad_hash(self, tmpdir, data, assert dist_path_md5 != dist_path2_md5 - self.dist_url.url = "%s#md5=%s" % ( - self.dist_url.url, - dist_path_md5 + self.dist_url.url = "%s#md5=%s" % (self.dist_url.url, dist_path_md5) + unpack_file_url( + self.dist_url, + self.build_dir, + download_dir=self.download_dir, + hashes=Hashes({'md5': [dist_path_md5]}), ) - unpack_file_url(self.dist_url, self.build_dir, - download_dir=self.download_dir, - hashes=Hashes({'md5': [dist_path_md5]})) # confirm hash is for simple1-1.0 # the previous bad download has been removed @@ -247,8 +242,7 @@ def test_unpack_file_url_thats_a_dir(self, tmpdir, data): self.prep(tmpdir, data) dist_path = data.packages.join("FSPkg") dist_url = Link(path_to_url(dist_path)) - unpack_file_url(dist_url, self.build_dir, - download_dir=self.download_dir) + unpack_file_url(dist_url, self.build_dir, download_dir=self.download_dir) assert os.path.isdir(os.path.join(self.build_dir, 'fspkg')) @@ -301,7 +295,6 @@ def test_safe_delete_no_perms(self, tmpdir): class TestPipSession: - def test_cache_defaults_off(self): session = PipSession() @@ -313,8 +306,7 @@ def test_cache_is_enabled(self, tmpdir): assert hasattr(session.adapters["https://"], "cache") - assert (session.adapters["https://"].cache.directory == - tmpdir.join("test-cache")) + assert session.adapters["https://"].cache.directory == tmpdir.join("test-cache") def test_http_cache_is_not_enabled(self, tmpdir): session = PipSession(cache=tmpdir.join("test-cache")) @@ -323,8 +315,7 @@ def test_http_cache_is_not_enabled(self, tmpdir): def test_insecure_host_cache_is_not_enabled(self, tmpdir): session = PipSession( - cache=tmpdir.join("test-cache"), - insecure_hosts=["example.com"], + cache=tmpdir.join("test-cache"), insecure_hosts=["example.com"] ) assert not hasattr(session.adapters["https://example.com/"], "cache") @@ -337,5 +328,7 @@ def test_parse_credentials(): assert auth.parse_credentials("example.com") == (None, None) # URL-encoded reserved characters: - assert auth.parse_credentials("user%3Aname:%23%40%5E@example.com") \ - == ("user:name", "#@^") + assert auth.parse_credentials("user%3Aname:%23%40%5E@example.com") == ( + "user:name", + "#@^", + ) diff --git a/tests/unit/test_finder.py b/tests/unit/test_finder.py index 51fccfae1f1..5f0e317fb28 100644 --- a/tests/unit/test_finder.py +++ b/tests/unit/test_finder.py @@ -8,11 +8,13 @@ import pip._internal.pep425tags import pip._internal.wheel from pip._internal.download import PipSession -from pip._internal.exceptions import ( - BestVersionAlreadyInstalled, DistributionNotFound, -) +from pip._internal.exceptions import BestVersionAlreadyInstalled, DistributionNotFound from pip._internal.index import ( - FormatControl, InstallationCandidate, Link, PackageFinder, fmt_ctl_formats, + FormatControl, + InstallationCandidate, + Link, + PackageFinder, + fmt_ctl_formats, ) from pip._internal.req import InstallRequirement @@ -49,9 +51,7 @@ def test_duplicates_sort_ok(data): """Finder successfully finds one of a set of duplicates in different locations""" finder = PackageFinder( - [data.find_links, data.find_links2], - [], - session=PipSession(), + [data.find_links, data.find_links2], [], session=PipSession() ) req = InstallRequirement.from_line("duplicate") found = finder.find_requirement(req, False) @@ -84,7 +84,7 @@ def test_finder_detects_latest_already_satisfied_find_links(data): satisfied_by = Mock( location="/path", parsed_version=parse_version(latest_version), - version=latest_version + version=latest_version, ) req.satisfied_by = satisfied_by finder = PackageFinder([data.find_links], [], session=PipSession()) @@ -105,18 +105,13 @@ def test_finder_detects_latest_already_satisfied_pypi_links(): version=latest_version, ) req.satisfied_by = satisfied_by - finder = PackageFinder( - [], - ["http://pypi.org/simple/"], - session=PipSession(), - ) + finder = PackageFinder([], ["http://pypi.org/simple/"], session=PipSession()) with pytest.raises(BestVersionAlreadyInstalled): finder.find_requirement(req, True) class TestWheel: - def test_skip_invalid_wheel_link(self, caplog, data): """ Test if PackageFinder skips invalid wheel filenames @@ -125,18 +120,11 @@ def test_skip_invalid_wheel_link(self, caplog, data): req = InstallRequirement.from_line("invalid") # data.find_links contains "invalid.whl", which is an invalid wheel - finder = PackageFinder( - [data.find_links], - [], - session=PipSession(), - ) + finder = PackageFinder([data.find_links], [], session=PipSession()) with pytest.raises(DistributionNotFound): finder.find_requirement(req, True) - assert ( - "invalid.whl; invalid wheel filename" - in caplog.text - ) + assert "invalid.whl; invalid wheel filename" in caplog.text def test_not_find_wheel_not_supported(self, data, monkeypatch): """ @@ -149,11 +137,7 @@ def test_not_find_wheel_not_supported(self, data, monkeypatch): ) req = InstallRequirement.from_line("simple.dist") - finder = PackageFinder( - [data.find_links], - [], - session=PipSession(), - ) + finder = PackageFinder([data.find_links], [], session=PipSession()) finder.valid_tags = pip._internal.pep425tags.get_supported() with pytest.raises(DistributionNotFound): @@ -170,15 +154,9 @@ def test_find_wheel_supported(self, data, monkeypatch): ) req = InstallRequirement.from_line("simple.dist") - finder = PackageFinder( - [data.find_links], - [], - session=PipSession(), - ) + finder = PackageFinder([data.find_links], [], session=PipSession()) found = finder.find_requirement(req, True) - assert ( - found.url.endswith("simple.dist-0.1-py2.py3-none-any.whl") - ), found + assert found.url.endswith("simple.dist-0.1-py2.py3-none-any.whl"), found def test_wheel_over_sdist_priority(self, data): """ @@ -186,11 +164,7 @@ def test_wheel_over_sdist_priority(self, data): `test_link_sorting` also covers this at lower level """ req = InstallRequirement.from_line("priority") - finder = PackageFinder( - [data.find_links], - [], - session=PipSession(), - ) + finder = PackageFinder([data.find_links], [], session=PipSession()) found = finder.find_requirement(req, True) assert found.url.endswith("priority-1.0-py2.py3-none-any.whl"), found @@ -207,11 +181,7 @@ def test_existing_over_wheel_priority(self, data): version=latest_version, ) req.satisfied_by = satisfied_by - finder = PackageFinder( - [data.find_links], - [], - session=PipSession(), - ) + finder = PackageFinder([data.find_links], [], session=PipSession()) with pytest.raises(BestVersionAlreadyInstalled): finder.find_requirement(req, True) @@ -223,25 +193,11 @@ def test_link_sorting(self): links = [ InstallationCandidate("simple", "2.0", Link('simple-2.0.tar.gz')), InstallationCandidate( - "simple", - "1.0", - Link('simple-1.0-pyT-none-TEST.whl'), - ), - InstallationCandidate( - "simple", - '1.0', - Link('simple-1.0-pyT-TEST-any.whl'), - ), - InstallationCandidate( - "simple", - '1.0', - Link('simple-1.0-pyT-none-any.whl'), - ), - InstallationCandidate( - "simple", - '1.0', - Link('simple-1.0.tar.gz'), + "simple", "1.0", Link('simple-1.0-pyT-none-TEST.whl') ), + InstallationCandidate("simple", '1.0', Link('simple-1.0-pyT-TEST-any.whl')), + InstallationCandidate("simple", '1.0', Link('simple-1.0-pyT-none-any.whl')), + InstallationCandidate("simple", '1.0', Link('simple-1.0.tar.gz')), ] finder = PackageFinder([], [], session=PipSession()) finder.valid_tags = [ @@ -249,10 +205,8 @@ def test_link_sorting(self): ('pyT', 'TEST', 'any'), ('pyT', 'none', 'any'), ] - results = sorted(links, - key=finder._candidate_sort_key, reverse=True) - results2 = sorted(reversed(links), - key=finder._candidate_sort_key, reverse=True) + results = sorted(links, key=finder._candidate_sort_key, reverse=True) + results2 = sorted(reversed(links), key=finder._candidate_sort_key, reverse=True) assert links == results == results2, results2 @@ -260,25 +214,18 @@ def test_link_sorting_wheels_with_build_tags(self): """Verify build tags affect sorting.""" links = [ InstallationCandidate( - "simplewheel", - "2.0", - Link("simplewheel-2.0-1-py2.py3-none-any.whl"), + "simplewheel", "2.0", Link("simplewheel-2.0-1-py2.py3-none-any.whl") ), InstallationCandidate( - "simplewheel", - "2.0", - Link("simplewheel-2.0-py2.py3-none-any.whl"), + "simplewheel", "2.0", Link("simplewheel-2.0-py2.py3-none-any.whl") ), InstallationCandidate( - "simplewheel", - "1.0", - Link("simplewheel-1.0-py2.py3-none-any.whl"), + "simplewheel", "1.0", Link("simplewheel-1.0-py2.py3-none-any.whl") ), ] finder = PackageFinder([], [], session=PipSession()) results = sorted(links, key=finder._candidate_sort_key, reverse=True) - results2 = sorted(reversed(links), key=finder._candidate_sort_key, - reverse=True) + results2 = sorted(reversed(links), key=finder._candidate_sort_key, reverse=True) assert links == results == results2, results2 @@ -286,15 +233,14 @@ def test_finder_priority_file_over_page(data): """Test PackageFinder prefers file links over equivalent page links""" req = InstallRequirement.from_line('gmpy==1.15', None) finder = PackageFinder( - [data.find_links], - ["http://pypi.org/simple/"], - session=PipSession(), + [data.find_links], ["http://pypi.org/simple/"], session=PipSession() ) all_versions = finder.find_all_candidates(req.name) # 1 file InstallationCandidate followed by all https ones assert all_versions[0].location.scheme == 'file' - assert all(version.location.scheme == 'https' - for version in all_versions[1:]), all_versions + assert all( + version.location.scheme == 'https' for version in all_versions[1:] + ), all_versions link = finder.find_requirement(req, False) assert link.url.startswith("file://") @@ -305,12 +251,7 @@ def test_finder_deplink(): Test PackageFinder with dependency links only """ req = InstallRequirement.from_line('gmpy==1.15', None) - finder = PackageFinder( - [], - [], - process_dependency_links=True, - session=PipSession(), - ) + finder = PackageFinder([], [], process_dependency_links=True, session=PipSession()) finder.add_dependency_links( ['https://files.pythonhosted.org/packages/source/g/gmpy/gmpy-1.15.zip'] ) @@ -330,14 +271,12 @@ def test_finder_priority_page_over_deplink(): process_dependency_links=True, session=PipSession(), ) - finder.add_dependency_links([ - 'https://files.pythonhosted.org/packages/source/p/pip/pip-1.5.6.tar.gz' - ]) + finder.add_dependency_links( + ['https://files.pythonhosted.org/packages/source/p/pip/pip-1.5.6.tar.gz'] + ) all_versions = finder.find_all_candidates(req.name) # Check that the dependency_link is last - assert all_versions[-1].location.url.startswith( - 'https://files.pythonhosted.org/' - ) + assert all_versions[-1].location.url.startswith('https://files.pythonhosted.org/') link = finder.find_requirement(req, False) assert link.url.startswith( "https://files.pythonhosted.org/packages/3f/08/7347ca4" @@ -412,9 +351,7 @@ def test_finder_only_installs_data_require(data): """ # using a local index (that has pre & dev releases) - finder = PackageFinder([], - [data.index_url("datarequire")], - session=PipSession()) + finder = PackageFinder([], [data.index_url("datarequire")], session=PipSession()) links = finder.find_all_candidates("fakepackage") expected = ['1.0.0', '9.9.9'] @@ -435,31 +372,21 @@ def test_finder_installs_pre_releases(data): # using a local index (that has pre & dev releases) finder = PackageFinder( - [], [data.index_url("pre")], - allow_all_prereleases=True, - session=PipSession(), + [], [data.index_url("pre")], allow_all_prereleases=True, session=PipSession() ) link = finder.find_requirement(req, False) assert link.url.endswith("bar-2.0b1.tar.gz"), link.url # using find-links links = ["https://foo/bar-1.0.tar.gz", "https://foo/bar-2.0b1.tar.gz"] - finder = PackageFinder( - links, [], - allow_all_prereleases=True, - session=PipSession(), - ) + finder = PackageFinder(links, [], allow_all_prereleases=True, session=PipSession()) with patch.object(finder, "_get_pages", lambda x, y: []): link = finder.find_requirement(req, False) assert link.url == "https://foo/bar-2.0b1.tar.gz" links.reverse() - finder = PackageFinder( - links, [], - allow_all_prereleases=True, - session=PipSession(), - ) + finder = PackageFinder(links, [], allow_all_prereleases=True, session=PipSession()) with patch.object(finder, "_get_pages", lambda x, y: []): link = finder.find_requirement(req, False) @@ -475,9 +402,7 @@ def test_finder_installs_dev_releases(data): # using a local index (that has dev releases) finder = PackageFinder( - [], [data.index_url("dev")], - allow_all_prereleases=True, - session=PipSession(), + [], [data.index_url("dev")], allow_all_prereleases=True, session=PipSession() ) link = finder.find_requirement(req, False) assert link.url.endswith("bar-2.0.dev1.tar.gz"), link.url @@ -509,17 +434,13 @@ class test_link_package_versions(object): # patch this for travis which has distribute in its base env for now @patch( 'pip._internal.wheel.pkg_resources.get_distribution', - lambda x: Distribution(project_name='setuptools', version='0.9') + lambda x: Distribution(project_name='setuptools', version='0.9'), ) def setup(self): self.version = '1.0' self.parsed_version = parse_version(self.version) self.search_name = 'pytest' - self.finder = PackageFinder( - [], - [], - session=PipSession(), - ) + self.finder = PackageFinder([], [], session=PipSession()) def test_link_package_versions_match_wheel(self): """Test that 'pytest' archives match for 'pytest'""" @@ -553,11 +474,12 @@ def test_link_package_versions_substring_fails(self): def test_get_index_urls_locations(): """Check that the canonical name is on all indexes""" finder = PackageFinder( - [], ['file://index1/', 'file://index2'], session=PipSession()) + [], ['file://index1/', 'file://index2'], session=PipSession() + ) locations = finder._get_index_urls_locations( - InstallRequirement.from_line('Complex_Name').name) - assert locations == ['file://index1/complex-name/', - 'file://index2/complex-name/'] + InstallRequirement.from_line('Complex_Name').name + ) + assert locations == ['file://index1/complex-name/', 'file://index2/complex-name/'] def test_find_all_candidates_nothing(): @@ -567,22 +489,21 @@ def test_find_all_candidates_nothing(): def test_find_all_candidates_find_links(data): - finder = PackageFinder( - [data.find_links], [], session=PipSession()) + finder = PackageFinder([data.find_links], [], session=PipSession()) versions = finder.find_all_candidates('simple') assert [str(v.version) for v in versions] == ['3.0', '2.0', '1.0'] def test_find_all_candidates_index(data): - finder = PackageFinder( - [], [data.index_url('simple')], session=PipSession()) + finder = PackageFinder([], [data.index_url('simple')], session=PipSession()) versions = finder.find_all_candidates('simple') assert [str(v.version) for v in versions] == ['1.0'] def test_find_all_candidates_find_links_and_index(data): finder = PackageFinder( - [data.find_links], [data.index_url('simple')], session=PipSession()) + [data.find_links], [data.index_url('simple')], session=PipSession() + ) versions = finder.find_all_candidates('simple') # first the find-links versions then the page versions assert [str(v.version) for v in versions] == ['3.0', '2.0', '1.0', '1.0'] diff --git a/tests/unit/test_index.py b/tests/unit/test_index.py index 4ede2958975..d872303a258 100644 --- a/tests/unit/test_index.py +++ b/tests/unit/test_index.py @@ -13,8 +13,8 @@ def test_sort_locations_file_expand_dir(data): finder = PackageFinder([data.find_links], [], session=PipSession()) files, urls = finder._sort_locations([data.find_links], expand_dir=True) assert files and not urls, ( - "files and not urls should have been found at find-links url: %s" % - data.find_links + "files and not urls should have been found at find-links url: %s" + % data.find_links ) @@ -33,13 +33,11 @@ def test_sort_locations_non_existing_path(): Test that a non-existing path is ignored. """ finder = PackageFinder([], [], session=PipSession()) - files, urls = finder._sort_locations( - [os.path.join('this', 'doesnt', 'exist')]) + files, urls = finder._sort_locations([os.path.join('this', 'doesnt', 'exist')]) assert not urls and not files, "nothing should have been found" class TestLink(object): - def test_splitext(self): assert ('wheel', '.whl') == Link('http://yo/wheel.whl').splitext() @@ -146,10 +144,7 @@ def test_get_formatted_locations_basic_auth(): Test that basic authentication credentials defined in URL is not included in formatted output. """ - index_urls = [ - 'https://pypi.org/simple', - 'https://user:pass@repo.domain.com', - ] + index_urls = ['https://pypi.org/simple', 'https://user:pass@repo.domain.com'] finder = PackageFinder([], index_urls, session=[]) result = finder.get_formatted_locations() diff --git a/tests/unit/test_locations.py b/tests/unit/test_locations.py index 5bdfb8e6fc5..482bacf662e 100644 --- a/tests/unit/test_locations.py +++ b/tests/unit/test_locations.py @@ -76,12 +76,12 @@ def get_mock_getpwuid(self, uid): class TestDisutilsScheme: - def test_root_modifies_appropriately(self, monkeypatch): # This deals with nt/posix path differences # root is c:\somewhere\else or /somewhere/else - root = os.path.normcase(os.path.abspath( - os.path.join(os.path.sep, 'somewhere', 'else'))) + root = os.path.normcase( + os.path.abspath(os.path.join(os.path.sep, 'somewhere', 'else')) + ) norm_scheme = distutils_scheme("example") root_scheme = distutils_scheme("example", root=root) @@ -92,17 +92,15 @@ def test_root_modifies_appropriately(self, monkeypatch): def test_distutils_config_file_read(self, tmpdir, monkeypatch): # This deals with nt/posix path differences - install_scripts = os.path.normcase(os.path.abspath( - os.path.join(os.path.sep, 'somewhere', 'else'))) + install_scripts = os.path.normcase( + os.path.abspath(os.path.join(os.path.sep, 'somewhere', 'else')) + ) f = tmpdir.mkdir("config").join("setup.cfg") f.write("[install]\ninstall-scripts=" + install_scripts) from distutils.dist import Distribution + # patch the function that returns what config files are present - monkeypatch.setattr( - Distribution, - 'find_config_files', - lambda self: [f], - ) + monkeypatch.setattr(Distribution, 'find_config_files', lambda self: [f]) scheme = distutils_scheme('example') assert scheme['scripts'] == install_scripts @@ -111,17 +109,15 @@ def test_distutils_config_file_read(self, tmpdir, monkeypatch): # this path def test_install_lib_takes_precedence(self, tmpdir, monkeypatch): # This deals with nt/posix path differences - install_lib = os.path.normcase(os.path.abspath( - os.path.join(os.path.sep, 'somewhere', 'else'))) + install_lib = os.path.normcase( + os.path.abspath(os.path.join(os.path.sep, 'somewhere', 'else')) + ) f = tmpdir.mkdir("config").join("setup.cfg") f.write("[install]\ninstall-lib=" + install_lib) from distutils.dist import Distribution + # patch the function that returns what config files are present - monkeypatch.setattr( - Distribution, - 'find_config_files', - lambda self: [f], - ) + monkeypatch.setattr(Distribution, 'find_config_files', lambda self: [f]) scheme = distutils_scheme('example') assert scheme['platlib'] == install_lib + os.path.sep assert scheme['purelib'] == install_lib + os.path.sep diff --git a/tests/unit/test_options.py b/tests/unit/test_options.py index b6a1bf85453..be4bd14517e 100644 --- a/tests/unit/test_options.py +++ b/tests/unit/test_options.py @@ -15,17 +15,11 @@ class TestOptionPrecedence(AddFakeCommandMixin): """ def get_config_section(self, section): - config = { - 'global': [('timeout', '-3')], - 'fake': [('timeout', '-2')], - } + config = {'global': [('timeout', '-3')], 'fake': [('timeout', '-2')]} return config[section] def get_config_section_global(self, section): - config = { - 'global': [('timeout', '-3')], - 'fake': [], - } + config = {'global': [('timeout', '-3')], 'fake': []} return config[section] def test_env_override_default_int(self): @@ -83,7 +77,6 @@ def test_cli_override_environment(self): class TestOptionsInterspersed(AddFakeCommandMixin): - def test_general_option_after_subcommand(self): options, args = main(['fake', '--timeout', '-1']) assert options.timeout == -1 @@ -184,7 +177,6 @@ def test_client_cert(self): class TestOptionsConfigFiles(object): - def test_venv_config_file_found(self, monkeypatch): # strict limit on the site_config_files list monkeypatch.setattr( @@ -194,9 +186,7 @@ def test_venv_config_file_found(self, monkeypatch): # If we are running in a virtualenv and all files appear to exist, # we should see two config files. monkeypatch.setattr( - pip._internal.configuration, - 'running_under_virtualenv', - lambda: True, + pip._internal.configuration, 'running_under_virtualenv', lambda: True ) monkeypatch.setattr(os.path, 'exists', lambda filename: True) cp = pip._internal.configuration.Configuration(isolated=False) diff --git a/tests/unit/test_pep425tags.py b/tests/unit/test_pep425tags.py index d55353adbcd..9998870b962 100644 --- a/tests/unit/test_pep425tags.py +++ b/tests/unit/test_pep425tags.py @@ -6,7 +6,6 @@ class TestPEP425Tags(object): - def mock_get_config_var(self, **kwd): """ Patch sysconfig.get_config_var for arbitrary keys. @@ -19,6 +18,7 @@ def _mock_get_config_var(var): if var in kwd: return kwd[var] return get_config_var(var) + return _mock_get_config_var def abi_tag_unicode(self, flags, config_vars): @@ -28,21 +28,21 @@ def abi_tag_unicode(self, flags, config_vars): import pip._internal.pep425tags config_vars.update({'SOABI': None}) - base = pip._internal.pep425tags.get_abbr_impl() + \ - pip._internal.pep425tags.get_impl_ver() + base = ( + pip._internal.pep425tags.get_abbr_impl() + + pip._internal.pep425tags.get_impl_ver() + ) if sys.version_info < (3, 3): config_vars.update({'Py_UNICODE_SIZE': 2}) mock_gcf = self.mock_get_config_var(**config_vars) - with patch('pip._internal.pep425tags.sysconfig.get_config_var', - mock_gcf): + with patch('pip._internal.pep425tags.sysconfig.get_config_var', mock_gcf): abi_tag = pip._internal.pep425tags.get_abi_tag() assert abi_tag == base + flags config_vars.update({'Py_UNICODE_SIZE': 4}) mock_gcf = self.mock_get_config_var(**config_vars) - with patch('pip._internal.pep425tags.sysconfig.get_config_var', - mock_gcf): + with patch('pip._internal.pep425tags.sysconfig.get_config_var', mock_gcf): abi_tag = pip._internal.pep425tags.get_abi_tag() assert abi_tag == base + flags + 'u' @@ -52,8 +52,7 @@ def abi_tag_unicode(self, flags, config_vars): # the 'u' so manual SOABI detection should not do so either. config_vars.update({'Py_UNICODE_SIZE': None}) mock_gcf = self.mock_get_config_var(**config_vars) - with patch('pip._internal.pep425tags.sysconfig.get_config_var', - mock_gcf): + with patch('pip._internal.pep425tags.sysconfig.get_config_var', mock_gcf): abi_tag = pip._internal.pep425tags.get_abi_tag() assert abi_tag == base + flags @@ -68,8 +67,7 @@ def test_broken_sysconfig(self): def raises_ioerror(var): raise IOError("I have the wrong path!") - with patch('pip._internal.pep425tags.sysconfig.get_config_var', - raises_ioerror): + with patch('pip._internal.pep425tags.sysconfig.get_config_var', raises_ioerror): assert len(pip._internal.pep425tags.get_supported()) def test_no_hyphen_tag(self): @@ -80,8 +78,7 @@ def test_no_hyphen_tag(self): mock_gcf = self.mock_get_config_var(SOABI='cpython-35m-darwin') - with patch('pip._internal.pep425tags.sysconfig.get_config_var', - mock_gcf): + with patch('pip._internal.pep425tags.sysconfig.get_config_var', mock_gcf): supported = pip._internal.pep425tags.get_supported() for (py, abi, plat) in supported: @@ -115,10 +112,8 @@ def test_manual_abi_dm_flags(self): class TestManylinux1Tags(object): - @patch('pip._internal.pep425tags.get_platform', lambda: 'linux_x86_64') - @patch('pip._internal.utils.glibc.have_compatible_glibc', - lambda major, minor: True) + @patch('pip._internal.utils.glibc.have_compatible_glibc', lambda major, minor: True) def test_manylinux1_compatible_on_linux_x86_64(self): """ Test that manylinux1 is enabled on linux_x86_64 @@ -126,8 +121,7 @@ def test_manylinux1_compatible_on_linux_x86_64(self): assert pep425tags.is_manylinux1_compatible() @patch('pip._internal.pep425tags.get_platform', lambda: 'linux_i686') - @patch('pip._internal.utils.glibc.have_compatible_glibc', - lambda major, minor: True) + @patch('pip._internal.utils.glibc.have_compatible_glibc', lambda major, minor: True) def test_manylinux1_compatible_on_linux_i686(self): """ Test that manylinux1 is enabled on linux_i686 @@ -135,8 +129,9 @@ def test_manylinux1_compatible_on_linux_i686(self): assert pep425tags.is_manylinux1_compatible() @patch('pip._internal.pep425tags.get_platform', lambda: 'linux_x86_64') - @patch('pip._internal.utils.glibc.have_compatible_glibc', - lambda major, minor: False) + @patch( + 'pip._internal.utils.glibc.have_compatible_glibc', lambda major, minor: False + ) def test_manylinux1_2(self): """ Test that manylinux1 is disabled with incompatible glibc @@ -144,8 +139,7 @@ def test_manylinux1_2(self): assert not pep425tags.is_manylinux1_compatible() @patch('pip._internal.pep425tags.get_platform', lambda: 'arm6vl') - @patch('pip._internal.utils.glibc.have_compatible_glibc', - lambda major, minor: True) + @patch('pip._internal.utils.glibc.have_compatible_glibc', lambda major, minor: True) def test_manylinux1_3(self): """ Test that manylinux1 is disabled on arm6vl @@ -153,8 +147,7 @@ def test_manylinux1_3(self): assert not pep425tags.is_manylinux1_compatible() @patch('pip._internal.pep425tags.get_platform', lambda: 'linux_x86_64') - @patch('pip._internal.utils.glibc.have_compatible_glibc', - lambda major, minor: True) + @patch('pip._internal.utils.glibc.have_compatible_glibc', lambda major, minor: True) @patch('sys.platform', 'linux2') def test_manylinux1_tag_is_first(self): """ diff --git a/tests/unit/test_req.py b/tests/unit/test_req.py index f9e73afc323..b2ceab80b81 100644 --- a/tests/unit/test_req.py +++ b/tests/unit/test_req.py @@ -12,7 +12,10 @@ from pip._internal.commands.install import InstallCommand from pip._internal.download import PipSession, path_to_url from pip._internal.exceptions import ( - HashErrors, InstallationError, InvalidWheelFilename, PreviousBuildDirError, + HashErrors, + InstallationError, + InvalidWheelFilename, + PreviousBuildDirError, ) from pip._internal.index import PackageFinder from pip._internal.operations.prepare import RequirementPreparer @@ -49,11 +52,16 @@ def _basic_resolver(self, finder): build_isolation=True, ) return Resolver( - preparer=preparer, wheel_cache=None, - session=PipSession(), finder=finder, - use_user_site=False, upgrade_strategy="to-satisfy-only", - ignore_dependencies=False, ignore_installed=False, - ignore_requires_python=False, force_reinstall=False, + preparer=preparer, + wheel_cache=None, + session=PipSession(), + finder=finder, + use_user_site=False, + upgrade_strategy="to-satisfy-only", + ignore_dependencies=False, + ignore_installed=False, + ignore_requires_python=False, + force_reinstall=False, isolated=False, ) @@ -71,8 +79,8 @@ def test_no_reuse_existing_build_dir(self, data): resolver = self._basic_resolver(finder) assert_raises_regexp( PreviousBuildDirError, - r"pip can't proceed with [\s\S]*%s[\s\S]*%s" % - (req, build_dir.replace('\\', '\\\\')), + r"pip can't proceed with [\s\S]*%s[\s\S]*%s" + % (req, build_dir.replace('\\', '\\\\')), resolver.resolve, reqset, ) @@ -83,9 +91,7 @@ def test_environment_marker_extras(self, data): non-wheel installs. """ reqset = RequirementSet() - req = InstallRequirement.from_editable( - data.packages.join("LocalEnvironMarker") - ) + req = InstallRequirement.from_editable(data.packages.join("LocalEnvironMarker")) req.is_direct = True reqset.add_requirement(req) finder = PackageFinder([data.find_links], [], session=PipSession()) @@ -105,31 +111,31 @@ def test_missing_hash_checking(self): reqset = RequirementSet() # No flags here. This tests that detection of later flags nonetheless # requires earlier packages to have hashes: - reqset.add_requirement(get_processed_req_from_line( - 'blessings==1.0', lineno=1 - )) + reqset.add_requirement(get_processed_req_from_line('blessings==1.0', lineno=1)) # This flag activates --require-hashes mode: - reqset.add_requirement(get_processed_req_from_line( - 'tracefront==0.1 --hash=sha256:somehash', lineno=2, - )) + reqset.add_requirement( + get_processed_req_from_line( + 'tracefront==0.1 --hash=sha256:somehash', lineno=2 + ) + ) # This hash should be accepted because it came from the reqs file, not # from the internet: - reqset.add_requirement(get_processed_req_from_line( - 'https://files.pythonhosted.org/packages/source/m/more-itertools/' - 'more-itertools-1.0.tar.gz#md5=b21850c3cfa7efbb70fd662ab5413bdd', - lineno=3, - )) + reqset.add_requirement( + get_processed_req_from_line( + 'https://files.pythonhosted.org/packages/source/m/more-itertools/' + 'more-itertools-1.0.tar.gz#md5=b21850c3cfa7efbb70fd662ab5413bdd', + lineno=3, + ) + ) # The error text should list this as a URL and not `peep==3.1.1`: - reqset.add_requirement(get_processed_req_from_line( - 'https://files.pythonhosted.org/' - 'packages/source/p/peep/peep-3.1.1.tar.gz', - lineno=4, - )) - finder = PackageFinder( - [], - ['https://pypi.org/simple/'], - session=PipSession(), + reqset.add_requirement( + get_processed_req_from_line( + 'https://files.pythonhosted.org/' + 'packages/source/p/peep/peep-3.1.1.tar.gz', + lineno=4, + ) ) + finder = PackageFinder([], ['https://pypi.org/simple/'], session=PipSession()) resolver = self._basic_resolver(finder) assert_raises_regexp( HashErrors, @@ -143,7 +149,7 @@ def test_missing_hash_checking(self): r' Expected sha256 somehash\n' r' Got [0-9a-f]+$', resolver.resolve, - reqset + reqset, ) def test_missing_hash_with_require_hashes(self, data): @@ -151,9 +157,7 @@ def test_missing_hash_with_require_hashes(self, data): are missing. """ reqset = RequirementSet(require_hashes=True) - reqset.add_requirement(get_processed_req_from_line( - 'simple==1.0', lineno=1 - )) + reqset.add_requirement(get_processed_req_from_line('simple==1.0', lineno=1)) finder = PackageFinder([data.find_links], [], session=PipSession()) resolver = self._basic_resolver(finder) @@ -165,7 +169,7 @@ def test_missing_hash_with_require_hashes(self, data): r' simple==1.0 --hash=sha256:393043e672415891885c9a2a0929b1af95' r'fb866d6ca016b42d2e6ce53619b653$', resolver.resolve, - reqset + reqset, ) def test_missing_hash_with_require_hashes_in_reqs_file(self, data, tmpdir): @@ -179,8 +183,7 @@ def test_missing_hash_with_require_hashes_in_reqs_file(self, data, tmpdir): with requirements_file('--require-hashes', tmpdir) as reqs_file: options, args = command.parse_args(['-r', reqs_file]) command.populate_requirement_set( - req_set, args, options, finder, session, command.name, - wheel_cache=None, + req_set, args, options, finder, session, command.name, wheel_cache=None ) assert req_set.require_hashes @@ -193,15 +196,15 @@ def test_unsupported_hashes(self, data): """ reqset = RequirementSet(require_hashes=True) - reqset.add_requirement(get_processed_req_from_line( - 'git+git://github.com/pypa/pip-test-package --hash=sha256:123', - lineno=1, - )) + reqset.add_requirement( + get_processed_req_from_line( + 'git+git://github.com/pypa/pip-test-package --hash=sha256:123', lineno=1 + ) + ) dir_path = data.packages.join('FSPkg') - reqset.add_requirement(get_processed_req_from_line( - 'file://%s' % (dir_path,), - lineno=2, - )) + reqset.add_requirement( + get_processed_req_from_line('file://%s' % (dir_path,), lineno=2) + ) finder = PackageFinder([data.find_links], [], session=PipSession()) resolver = self._basic_resolver(finder) sep = os.path.sep @@ -218,7 +221,8 @@ def test_unsupported_hashes(self, data): r" file://.*{sep}data{sep}packages{sep}FSPkg " r"\(from -r file \(line 2\)\)".format(sep=sep), resolver.resolve, - reqset) + reqset, + ) def test_unpinned_hash_checking(self, data): """Make sure prepare_files() raises an error when a requirement is not @@ -226,16 +230,21 @@ def test_unpinned_hash_checking(self, data): """ reqset = RequirementSet() # Test that there must be exactly 1 specifier: - reqset.add_requirement(get_processed_req_from_line( - 'simple --hash=sha256:a90427ae31f5d1d0d7ec06ee97d9fcf2d0fc9a786985' - '250c1c83fd68df5911dd', lineno=1, - )) + reqset.add_requirement( + get_processed_req_from_line( + 'simple --hash=sha256:a90427ae31f5d1d0d7ec06ee97d9fcf2d0fc9a786985' + '250c1c83fd68df5911dd', + lineno=1, + ) + ) # Test that the operator must be ==: - reqset.add_requirement(get_processed_req_from_line( - 'simple2>1.0 --hash=sha256:3ad45e1e9aa48b4462af0' - '123f6a7e44a9115db1ef945d4d92c123dfe21815a06', - lineno=2, - )) + reqset.add_requirement( + get_processed_req_from_line( + 'simple2>1.0 --hash=sha256:3ad45e1e9aa48b4462af0' + '123f6a7e44a9115db1ef945d4d92c123dfe21815a06', + lineno=2, + ) + ) finder = PackageFinder([data.find_links], [], session=PipSession()) resolver = self._basic_resolver(finder) assert_raises_regexp( @@ -245,16 +254,16 @@ def test_unpinned_hash_checking(self, data): r' simple .* \(from -r file \(line 1\)\)\n' r' simple2>1.0 .* \(from -r file \(line 2\)\)', resolver.resolve, - reqset) + reqset, + ) def test_hash_mismatch(self, data): """A hash mismatch should raise an error.""" - file_url = path_to_url( - (data.packages / 'simple-1.0.tar.gz').abspath) + file_url = path_to_url((data.packages / 'simple-1.0.tar.gz').abspath) reqset = RequirementSet(require_hashes=True) - reqset.add_requirement(get_processed_req_from_line( - '%s --hash=sha256:badbad' % file_url, lineno=1, - )) + reqset.add_requirement( + get_processed_req_from_line('%s --hash=sha256:badbad' % file_url, lineno=1) + ) finder = PackageFinder([data.find_links], [], session=PipSession()) resolver = self._basic_resolver(finder) assert_raises_regexp( @@ -265,7 +274,8 @@ def test_hash_mismatch(self, data): r' Got 393043e672415891885c9a2a0929b1af95fb866d' r'6ca016b42d2e6ce53619b653$', resolver.resolve, - reqset) + reqset, + ) def test_unhashed_deps_on_require_hashes(self, data): """Make sure unhashed, unpinned, or otherwise unrepeatable @@ -273,19 +283,22 @@ def test_unhashed_deps_on_require_hashes(self, data): reqset = RequirementSet() finder = PackageFinder([data.find_links], [], session=PipSession()) resolver = self._basic_resolver(finder) - reqset.add_requirement(get_processed_req_from_line( - 'TopoRequires2==0.0.1 ' # requires TopoRequires - '--hash=sha256:eaf9a01242c9f2f42cf2bd82a6a848cd' - 'e3591d14f7896bdbefcf48543720c970', - lineno=1 - )) + reqset.add_requirement( + get_processed_req_from_line( + 'TopoRequires2==0.0.1 ' # requires TopoRequires + '--hash=sha256:eaf9a01242c9f2f42cf2bd82a6a848cd' + 'e3591d14f7896bdbefcf48543720c970', + lineno=1, + ) + ) assert_raises_regexp( HashErrors, r'In --require-hashes mode, all requirements must have their ' r'versions pinned.*\n' r' TopoRequires from .*$', resolver.resolve, - reqset) + reqset, + ) def test_hashed_deps_on_require_hashes(self): """Make sure hashed dependencies get installed when --require-hashes @@ -297,25 +310,32 @@ def test_hashed_deps_on_require_hashes(self): """ reqset = RequirementSet() - reqset.add_requirement(get_processed_req_from_line( - 'TopoRequires2==0.0.1 ' # requires TopoRequires - '--hash=sha256:eaf9a01242c9f2f42cf2bd82a6a848cd' - 'e3591d14f7896bdbefcf48543720c970', - lineno=1 - )) - reqset.add_requirement(get_processed_req_from_line( - 'TopoRequires==0.0.1 ' - '--hash=sha256:d6dd1e22e60df512fdcf3640ced3039b3b02a56ab2cee81ebcb' - '3d0a6d4e8bfa6', - lineno=2 - )) - - -@pytest.mark.parametrize(('file_contents', 'expected'), [ - (b'\xf6\x80', b'\xc3\xb6\xe2\x82\xac'), # cp1252 - (b'\xc3\xb6\xe2\x82\xac', b'\xc3\xb6\xe2\x82\xac'), # utf-8 - (b'\xc3\xb6\xe2', b'\xc3\x83\xc2\xb6\xc3\xa2'), # Garbage -]) + reqset.add_requirement( + get_processed_req_from_line( + 'TopoRequires2==0.0.1 ' # requires TopoRequires + '--hash=sha256:eaf9a01242c9f2f42cf2bd82a6a848cd' + 'e3591d14f7896bdbefcf48543720c970', + lineno=1, + ) + ) + reqset.add_requirement( + get_processed_req_from_line( + 'TopoRequires==0.0.1 ' + '--hash=sha256:d6dd1e22e60df512fdcf3640ced3039b3b02a56ab2cee81ebcb' + '3d0a6d4e8bfa6', + lineno=2, + ) + ) + + +@pytest.mark.parametrize( + ('file_contents', 'expected'), + [ + (b'\xf6\x80', b'\xc3\xb6\xe2\x82\xac'), # cp1252 + (b'\xc3\xb6\xe2\x82\xac', b'\xc3\xb6\xe2\x82\xac'), # utf-8 + (b'\xc3\xb6\xe2', b'\xc3\x83\xc2\xb6\xc3\xa2'), # Garbage + ], +) def test_egg_info_data(file_contents, expected): om = mock_open(read_data=file_contents) em = Mock() @@ -343,7 +363,7 @@ def test_url_with_query(self): def test_unsupported_wheel_link_requirement_raises(self): reqset = RequirementSet() req = InstallRequirement.from_line( - 'https://whatever.com/peppercorn-0.4-py2.py3-bogus-any.whl', + 'https://whatever.com/peppercorn-0.4-py2.py3-bogus-any.whl' ) assert req.link is not None assert req.link.is_wheel @@ -355,7 +375,7 @@ def test_unsupported_wheel_link_requirement_raises(self): def test_unsupported_wheel_local_file_requirement_raises(self, data): reqset = RequirementSet() req = InstallRequirement.from_line( - data.packages.join('simple.dist-0.1-py1-none-invalid.whl'), + data.packages.join('simple.dist-0.1-py1-none-invalid.whl') ) assert req.link is not None assert req.link.is_wheel @@ -374,9 +394,7 @@ def test_str(self): def test_repr(self): req = InstallRequirement.from_line('simple==0.1') - assert repr(req) == ( - '<InstallRequirement object: simple==0.1 editable=False>' - ) + assert repr(req) == ('<InstallRequirement object: simple==0.1 editable=False>') def test_invalid_wheel_requirement_raises(self): with pytest.raises(InvalidWheelFilename): @@ -399,11 +417,14 @@ def test_url_preserved_editable_req(self): req = InstallRequirement.from_editable(url) assert req.link.url == url - @pytest.mark.parametrize('path', ( - '/path/to/foo.egg-info'.replace('/', os.path.sep), - # Tests issue fixed by https://github.com/pypa/pip/pull/2530 - '/path/to/foo.egg-info/'.replace('/', os.path.sep), - )) + @pytest.mark.parametrize( + 'path', + ( + '/path/to/foo.egg-info'.replace('/', os.path.sep), + # Tests issue fixed by https://github.com/pypa/pip/pull/2530 + '/path/to/foo.egg-info/'.replace('/', os.path.sep), + ), + ) def test_get_dist(self, path): req = InstallRequirement.from_line('foo') req.egg_info_path = Mock(return_value=path) @@ -450,20 +471,14 @@ def test_markers_url(self): def test_markers_match_from_line(self): # match - for markers in ( - 'python_version >= "1.0"', - 'sys_platform == %r' % sys.platform, - ): + for markers in ('python_version >= "1.0"', 'sys_platform == %r' % sys.platform): line = 'name; ' + markers req = InstallRequirement.from_line(line) assert str(req.markers) == str(Marker(markers)) assert req.match_markers() # don't match - for markers in ( - 'python_version >= "5.0"', - 'sys_platform != %r' % sys.platform, - ): + for markers in ('python_version >= "5.0"', 'sys_platform != %r' % sys.platform): line = 'name; ' + markers req = InstallRequirement.from_line(line) assert str(req.markers) == str(Marker(markers)) @@ -471,20 +486,14 @@ def test_markers_match_from_line(self): def test_markers_match(self): # match - for markers in ( - 'python_version >= "1.0"', - 'sys_platform == %r' % sys.platform, - ): + for markers in ('python_version >= "1.0"', 'sys_platform == %r' % sys.platform): line = 'name; ' + markers req = InstallRequirement.from_line(line, comes_from='') assert str(req.markers) == str(Marker(markers)) assert req.match_markers() # don't match - for markers in ( - 'python_version >= "5.0"', - 'sys_platform != %r' % sys.platform, - ): + for markers in ('python_version >= "5.0"', 'sys_platform != %r' % sys.platform): line = 'name; ' + markers req = InstallRequirement.from_line(line, comes_from='') assert str(req.markers) == str(Marker(markers)) @@ -525,7 +534,8 @@ def test_extras_for_editable_url_requirement(self): def test_unexisting_path(self): with pytest.raises(InstallationError) as e: InstallRequirement.from_line( - os.path.join('this', 'path', 'does', 'not', 'exist')) + os.path.join('this', 'path', 'does', 'not', 'exist') + ) err_msg = e.value.args[0] assert "Invalid requirement" in err_msg assert "It looks like a path." in err_msg @@ -560,16 +570,13 @@ def test_requirement_file(self): @patch('pip._internal.req.req_install.os.path.abspath') @patch('pip._internal.req.req_install.os.path.exists') @patch('pip._internal.req.req_install.os.path.isdir') -def test_parse_editable_local( - isdir_mock, exists_mock, abspath_mock): +def test_parse_editable_local(isdir_mock, exists_mock, abspath_mock): exists_mock.return_value = isdir_mock.return_value = True # mocks needed to support path operations on windows tests abspath_mock.return_value = "/some/path" assert parse_editable('.') == (None, 'file:///some/path', None) abspath_mock.return_value = "/some/path/foo" - assert parse_editable('foo') == ( - None, 'file:///some/path/foo', None, - ) + assert parse_editable('foo') == (None, 'file:///some/path/foo', None) def test_parse_editable_explicit_vcs(): @@ -591,26 +598,23 @@ def test_parse_editable_vcs_extras(): @patch('pip._internal.req.req_install.os.path.abspath') @patch('pip._internal.req.req_install.os.path.exists') @patch('pip._internal.req.req_install.os.path.isdir') -def test_parse_editable_local_extras( - isdir_mock, exists_mock, abspath_mock): +def test_parse_editable_local_extras(isdir_mock, exists_mock, abspath_mock): exists_mock.return_value = isdir_mock.return_value = True abspath_mock.return_value = "/some/path" - assert parse_editable('.[extras]') == ( - None, 'file://' + "/some/path", {'extras'}, - ) + assert parse_editable('.[extras]') == (None, 'file://' + "/some/path", {'extras'}) abspath_mock.return_value = "/some/path/foo" assert parse_editable('foo[bar,baz]') == ( - None, 'file:///some/path/foo', {'bar', 'baz'}, + None, + 'file:///some/path/foo', + {'bar', 'baz'}, ) def test_exclusive_environment_markers(): """Make sure RequirementSet accepts several excluding env markers""" - eq26 = InstallRequirement.from_line( - "Django>=1.6.10,<1.7 ; python_version == '2.6'") + eq26 = InstallRequirement.from_line("Django>=1.6.10,<1.7 ; python_version == '2.6'") eq26.is_direct = True - ne26 = InstallRequirement.from_line( - "Django>=1.6.10,<1.8 ; python_version != '2.6'") + ne26 = InstallRequirement.from_line("Django>=1.6.10,<1.8 ; python_version != '2.6'") ne26.is_direct = True req_set = RequirementSet() @@ -623,11 +627,11 @@ def test_mismatched_versions(caplog, tmpdir): original_source = os.path.join(DATA_DIR, 'src', 'simplewheel-1.0') source_dir = os.path.join(tmpdir, 'simplewheel') shutil.copytree(original_source, source_dir) - req = InstallRequirement(req=Requirement('simplewheel==2.0'), - comes_from=None, source_dir=source_dir) + req = InstallRequirement( + req=Requirement('simplewheel==2.0'), comes_from=None, source_dir=source_dir + ) req.run_egg_info() req.assert_source_matches_version() assert caplog.records[-1].message == ( - 'Requested simplewheel==2.0, ' - 'but installing version 1.0' + 'Requested simplewheel==2.0, ' 'but installing version 1.0' ) diff --git a/tests/unit/test_req_file.py b/tests/unit/test_req_file.py index 93fec8e7345..9dd144253ec 100644 --- a/tests/unit/test_req_file.py +++ b/tests/unit/test_req_file.py @@ -8,13 +8,16 @@ import pip._internal.index from pip._internal.download import PipSession -from pip._internal.exceptions import ( - InstallationError, RequirementsFileParseError, -) +from pip._internal.exceptions import InstallationError, RequirementsFileParseError from pip._internal.index import PackageFinder from pip._internal.req.req_file import ( - break_args_options, ignore_comments, join_lines, parse_requirements, - preprocess, process_line, skip_regex, + break_args_options, + ignore_comments, + join_lines, + parse_requirements, + preprocess, + process_line, + skip_regex, ) from pip._internal.req.req_install import InstallRequirement from tests.lib import requirements_file @@ -33,56 +36,68 @@ def finder(session): @pytest.fixture def options(session): return stub( - isolated_mode=False, index_url='default_url', + isolated_mode=False, + index_url='default_url', skip_requirements_regex=False, - format_control=pip._internal.index.FormatControl(set(), set())) + format_control=pip._internal.index.FormatControl(set(), set()), + ) class TestPreprocess(object): """tests for `preprocess`""" def test_comments_and_joins_case1(self): - content = textwrap.dedent("""\ + content = textwrap.dedent( + """\ req1 \\ # comment \\ req2 - """) + """ + ) result = preprocess(content, None) assert list(result) == [(1, 'req1'), (3, 'req2')] def test_comments_and_joins_case2(self): - content = textwrap.dedent("""\ + content = textwrap.dedent( + """\ req1\\ # comment - """) + """ + ) result = preprocess(content, None) assert list(result) == [(1, 'req1')] def test_comments_and_joins_case3(self): - content = textwrap.dedent("""\ + content = textwrap.dedent( + """\ req1 \\ # comment req2 - """) + """ + ) result = preprocess(content, None) assert list(result) == [(1, 'req1'), (3, 'req2')] def test_skip_regex_after_joining_case1(self, options): - content = textwrap.dedent("""\ + content = textwrap.dedent( + """\ patt\\ ern line2 - """) + """ + ) options.skip_requirements_regex = 'pattern' result = preprocess(content, options) assert list(result) == [(3, 'line2')] def test_skip_regex_after_joining_case2(self, options): - content = textwrap.dedent("""\ + content = textwrap.dedent( + """\ pattern \\ line2 line3 - """) + """ + ) options.skip_requirements_regex = 'pattern' result = preprocess(content, options) assert list(result) == [(3, 'line3')] @@ -111,15 +126,18 @@ class TestJoinLines(object): """tests for `join_lines`""" def test_join_lines(self): - lines = enumerate([ - 'line 1', - 'line 2:1 \\', - 'line 2:2', - 'line 3:1 \\', - 'line 3:2 \\', - 'line 3:3', - 'line 4' - ], start=1) + lines = enumerate( + [ + 'line 1', + 'line 2:1 \\', + 'line 2:2', + 'line 3:1 \\', + 'line 3:2 \\', + 'line 3:3', + 'line 4', + ], + start=1, + ) expect = [ (1, 'line 1'), (2, 'line 2:1 line 2:2'), @@ -129,14 +147,8 @@ def test_join_lines(self): assert expect == list(join_lines(lines)) def test_last_line_with_escape(self): - lines = enumerate([ - 'line 1', - 'line 2 \\', - ], start=1) - expect = [ - (1, 'line 1'), - (2, 'line 2 '), - ] + lines = enumerate(['line 1', 'line 2 \\'], start=1) + expect = [(1, 'line 1'), (2, 'line 2 ')] assert expect == list(join_lines(lines)) @@ -199,8 +211,7 @@ def test_yield_line_constraint(self): line = 'SomeProject' filename = 'filename' comes_from = '-c %s (line %s)' % (filename, 1) - req = InstallRequirement.from_line( - line, comes_from=comes_from, constraint=True) + req = InstallRequirement.from_line(line, comes_from=comes_from, constraint=True) found_req = list(process_line(line, filename, 1, constraint=True))[0] assert repr(found_req) == repr(req) assert found_req.constraint is True @@ -227,7 +238,8 @@ def test_yield_editable_constraint(self): filename = 'filename' comes_from = '-c %s (line %s)' % (filename, 1) req = InstallRequirement.from_editable( - url, comes_from=comes_from, constraint=True) + url, comes_from=comes_from, constraint=True + ) found_req = list(process_line(line, filename, 1, constraint=True))[0] assert repr(found_req) == repr(req) assert found_req.constraint is True @@ -237,12 +249,17 @@ def test_nested_requirements_file(self, monkeypatch): req = InstallRequirement.from_line('SomeProject') import pip._internal.req.req_file - def stub_parse_requirements(req_url, finder, comes_from, options, - session, wheel_cache, constraint): + def stub_parse_requirements( + req_url, finder, comes_from, options, session, wheel_cache, constraint + ): return [(req, constraint)] + parse_requirements_stub = stub(call=stub_parse_requirements) - monkeypatch.setattr(pip._internal.req.req_file, 'parse_requirements', - parse_requirements_stub.call) + monkeypatch.setattr( + pip._internal.req.req_file, + 'parse_requirements', + parse_requirements_stub.call, + ) assert list(process_line(line, 'filename', 1)) == [(req, False)] def test_nested_constraints_file(self, monkeypatch): @@ -250,22 +267,30 @@ def test_nested_constraints_file(self, monkeypatch): req = InstallRequirement.from_line('SomeProject') import pip._internal.req.req_file - def stub_parse_requirements(req_url, finder, comes_from, options, - session, wheel_cache, constraint): + def stub_parse_requirements( + req_url, finder, comes_from, options, session, wheel_cache, constraint + ): return [(req, constraint)] + parse_requirements_stub = stub(call=stub_parse_requirements) - monkeypatch.setattr(pip._internal.req.req_file, 'parse_requirements', - parse_requirements_stub.call) + monkeypatch.setattr( + pip._internal.req.req_file, + 'parse_requirements', + parse_requirements_stub.call, + ) assert list(process_line(line, 'filename', 1)) == [(req, True)] def test_options_on_a_requirement_line(self): - line = 'SomeProject --install-option=yo1 --install-option yo2 '\ - '--global-option="yo3" --global-option "yo4"' + line = ( + 'SomeProject --install-option=yo1 --install-option yo2 ' + '--global-option="yo3" --global-option "yo4"' + ) filename = 'filename' req = list(process_line(line, filename, 1))[0] assert req.options == { 'global_options': ['yo3', 'yo4'], - 'install_options': ['yo1', 'yo2']} + 'install_options': ['yo1', 'yo2'], + } def test_hash_options(self): """Test the --hash option: mostly its value storage. @@ -273,21 +298,30 @@ def test_hash_options(self): Make sure it reads and preserve multiple hashes. """ - line = ('SomeProject --hash=sha256:2cf24dba5fb0a30e26e83b2ac5b9e29e1b1' - '61e5c1fa7425e73043362938b9824 ' - '--hash=sha384:59e1748777448c69de6b800d7a33bbfb9ff1b463e44354c' - '3553bcdb9c666fa90125a3c79f90397bdf5f6a13de828684f ' - '--hash=sha256:486ea46224d1bb4fb680f34f7c9ad96a8f24ec88be73ea8' - 'e5a6c65260e9cb8a7') + line = ( + 'SomeProject --hash=sha256:2cf24dba5fb0a30e26e83b2ac5b9e29e1b1' + '61e5c1fa7425e73043362938b9824 ' + '--hash=sha384:59e1748777448c69de6b800d7a33bbfb9ff1b463e44354c' + '3553bcdb9c666fa90125a3c79f90397bdf5f6a13de828684f ' + '--hash=sha256:486ea46224d1bb4fb680f34f7c9ad96a8f24ec88be73ea8' + 'e5a6c65260e9cb8a7' + ) filename = 'filename' req = list(process_line(line, filename, 1))[0] - assert req.options == {'hashes': { - 'sha256': ['2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e730433' - '62938b9824', - '486ea46224d1bb4fb680f34f7c9ad96a8f24ec88be73ea8e5a6c65' - '260e9cb8a7'], - 'sha384': ['59e1748777448c69de6b800d7a33bbfb9ff1b463e44354c3553bcd' - 'b9c666fa90125a3c79f90397bdf5f6a13de828684f']}} + assert req.options == { + 'hashes': { + 'sha256': [ + '2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e730433' + '62938b9824', + '486ea46224d1bb4fb680f34f7c9ad96a8f24ec88be73ea8e5a6c65' + '260e9cb8a7', + ], + 'sha384': [ + '59e1748777448c69de6b800d7a33bbfb9ff1b463e44354c3553bcd' + 'b9c666fa90125a3c79f90397bdf5f6a13de828684f' + ], + } + } def test_set_isolated(self, options): line = 'SomeProject' @@ -329,10 +363,12 @@ def test_relative_local_find_links(self, finder, monkeypatch): Test a relative find_links path is joined with the req file directory """ # Make sure the test also passes on windows - req_file = os.path.normcase(os.path.abspath( - os.path.normpath('/path/req_file.txt'))) - nested_link = os.path.normcase(os.path.abspath( - os.path.normpath('/path/rel_path'))) + req_file = os.path.normcase( + os.path.abspath(os.path.normpath('/path/req_file.txt')) + ) + nested_link = os.path.normcase( + os.path.abspath(os.path.normpath('/path/rel_path')) + ) exists_ = os.path.exists def exists(path): @@ -340,9 +376,9 @@ def exists(path): return True else: exists_(path) + monkeypatch.setattr(os.path, 'exists', exists) - list(process_line("--find-links=rel_path", req_file, 1, - finder=finder)) + list(process_line("--find-links=rel_path", req_file, 1, finder=finder)) assert finder.find_links == [nested_link] def test_relative_http_nested_req_files(self, finder, monkeypatch): @@ -353,10 +389,12 @@ def test_relative_http_nested_req_files(self, finder, monkeypatch): def parse(*args, **kwargs): return iter([]) + mock_parse = Mock() mock_parse.side_effect = parse - monkeypatch.setattr(pip._internal.req.req_file, 'parse_requirements', - mock_parse) + monkeypatch.setattr( + pip._internal.req.req_file, 'parse_requirements', mock_parse + ) list(process_line("-r reqs.txt", req_file, 1, finder=finder)) call = mock_parse.mock_calls[0] assert call[1][0] == 'http://me.com/me/reqs.txt' @@ -369,10 +407,12 @@ def test_relative_local_nested_req_files(self, finder, monkeypatch): def parse(*args, **kwargs): return iter([]) + mock_parse = Mock() mock_parse.side_effect = parse - monkeypatch.setattr(pip._internal.req.req_file, 'parse_requirements', - mock_parse) + monkeypatch.setattr( + pip._internal.req.req_file, 'parse_requirements', mock_parse + ) list(process_line("-r reqs.txt", req_file, 1, finder=finder)) call = mock_parse.mock_calls[0] assert call[1][0] == os.path.normpath('/path/reqs.txt') @@ -385,10 +425,12 @@ def test_absolute_local_nested_req_files(self, finder, monkeypatch): def parse(*args, **kwargs): return iter([]) + mock_parse = Mock() mock_parse.side_effect = parse - monkeypatch.setattr(pip._internal.req.req_file, 'parse_requirements', - mock_parse) + monkeypatch.setattr( + pip._internal.req.req_file, 'parse_requirements', mock_parse + ) list(process_line("-r /other/reqs.txt", req_file, 1, finder=finder)) call = mock_parse.mock_calls[0] assert call[1][0] == '/other/reqs.txt' @@ -401,23 +443,22 @@ def test_absolute_http_nested_req_file_in_local(self, finder, monkeypatch): def parse(*args, **kwargs): return iter([]) + mock_parse = Mock() mock_parse.side_effect = parse - monkeypatch.setattr(pip._internal.req.req_file, 'parse_requirements', - mock_parse) - list(process_line("-r http://me.com/me/reqs.txt", req_file, 1, - finder=finder)) + monkeypatch.setattr( + pip._internal.req.req_file, 'parse_requirements', mock_parse + ) + list(process_line("-r http://me.com/me/reqs.txt", req_file, 1, finder=finder)) call = mock_parse.mock_calls[0] assert call[1][0] == 'http://me.com/me/reqs.txt' def test_set_finder_process_dependency_links(self, finder): - list(process_line( - "--process-dependency-links", "file", 1, finder=finder)) + list(process_line("--process-dependency-links", "file", 1, finder=finder)) assert finder.process_dependency_links class TestBreakOptionsArgs(object): - def test_no_args(self): assert ('', '--option') == break_args_options('--option') @@ -469,9 +510,11 @@ def test_remote_reqs_parse(self): # this requirements file just contains a comment previously this has # failed in py3: https://github.com/pypa/pip/issues/760 for req in parse_requirements( - 'https://raw.githubusercontent.com/pypa/' - 'pip-test-package/master/' - 'tests/req_just_comment.txt', session=PipSession()): + 'https://raw.githubusercontent.com/pypa/' + 'pip-test-package/master/' + 'tests/req_just_comment.txt', + session=PipSession(), + ): pass def test_multiple_appending_options(self, tmpdir, finder, options): @@ -479,8 +522,14 @@ def test_multiple_appending_options(self, tmpdir, finder, options): fp.write("--extra-index-url url1 \n") fp.write("--extra-index-url url2 ") - list(parse_requirements(tmpdir.join("req1.txt"), finder=finder, - session=PipSession(), options=options)) + list( + parse_requirements( + tmpdir.join("req1.txt"), + finder=finder, + session=PipSession(), + options=options, + ) + ) assert finder.index_urls == ['url1', 'url2'] @@ -490,20 +539,21 @@ def test_skip_regex(self, tmpdir, finder, options): fp.write("--extra-index-url Bad \n") fp.write("--extra-index-url Good ") - list(parse_requirements(tmpdir.join("req1.txt"), finder=finder, - options=options, session=PipSession())) + list( + parse_requirements( + tmpdir.join("req1.txt"), + finder=finder, + options=options, + session=PipSession(), + ) + ) assert finder.index_urls == ['Good'] def test_expand_existing_env_variables(self, tmpdir, finder): - template = ( - 'https://%s:x-oauth-basic@github.com/user/%s/archive/master.zip' - ) + template = 'https://%s:x-oauth-basic@github.com/user/%s/archive/master.zip' - env_vars = ( - ('GITHUB_TOKEN', 'notarealtoken'), - ('DO_12_FACTOR', 'awwyeah'), - ) + env_vars = (('GITHUB_TOKEN', 'notarealtoken'), ('DO_12_FACTOR', 'awwyeah')) with open(tmpdir.join('req1.txt'), 'w') as fp: fp.write(template % tuple(['${%s}' % k for k, _ in env_vars])) @@ -511,18 +561,18 @@ def test_expand_existing_env_variables(self, tmpdir, finder): with patch('pip._internal.req.req_file.os.getenv') as getenv: getenv.side_effect = lambda n: dict(env_vars)[n] - reqs = list(parse_requirements( - tmpdir.join('req1.txt'), - finder=finder, - session=PipSession() - )) + reqs = list( + parse_requirements( + tmpdir.join('req1.txt'), finder=finder, session=PipSession() + ) + ) - assert len(reqs) == 1, \ - 'parsing requirement file with env variable failed' + assert len(reqs) == 1, 'parsing requirement file with env variable failed' expected_url = template % tuple([v for _, v in env_vars]) - assert reqs[0].link.url == expected_url, \ - 'variable expansion in req file failed' + assert ( + reqs[0].link.url == expected_url + ), 'variable expansion in req file failed' def test_expand_missing_env_variables(self, tmpdir, finder): req_url = ( @@ -536,32 +586,38 @@ def test_expand_missing_env_variables(self, tmpdir, finder): with patch('pip._internal.req.req_file.os.getenv') as getenv: getenv.return_value = '' - reqs = list(parse_requirements( - tmpdir.join('req1.txt'), - finder=finder, - session=PipSession() - )) + reqs = list( + parse_requirements( + tmpdir.join('req1.txt'), finder=finder, session=PipSession() + ) + ) - assert len(reqs) == 1, \ - 'parsing requirement file with env variable failed' - assert reqs[0].link.url == req_url, \ - 'ignoring invalid env variable in req file failed' + assert len(reqs) == 1, 'parsing requirement file with env variable failed' + assert ( + reqs[0].link.url == req_url + ), 'ignoring invalid env variable in req file failed' def test_join_lines(self, tmpdir, finder): with open(tmpdir.join("req1.txt"), "w") as fp: fp.write("--extra-index-url url1 \\\n--extra-index-url url2") - list(parse_requirements(tmpdir.join("req1.txt"), finder=finder, - session=PipSession())) + list( + parse_requirements( + tmpdir.join("req1.txt"), finder=finder, session=PipSession() + ) + ) assert finder.index_urls == ['url1', 'url2'] def test_req_file_parse_no_only_binary(self, data, finder): - list(parse_requirements( - data.reqfiles.join("supported_options2.txt"), finder, - session=PipSession())) - expected = pip._internal.index.FormatControl( - {'fred'}, {'wilma'}) + list( + parse_requirements( + data.reqfiles.join("supported_options2.txt"), + finder, + session=PipSession(), + ) + ) + expected = pip._internal.index.FormatControl({'fred'}, {'wilma'}) assert finder.format_control == expected def test_req_file_parse_comment_start_of_line(self, tmpdir, finder): @@ -571,8 +627,9 @@ def test_req_file_parse_comment_start_of_line(self, tmpdir, finder): with open(tmpdir.join("req1.txt"), "w") as fp: fp.write("# Comment ") - reqs = list(parse_requirements(tmpdir.join("req1.txt"), finder, - session=PipSession())) + reqs = list( + parse_requirements(tmpdir.join("req1.txt"), finder, session=PipSession()) + ) assert not reqs @@ -583,8 +640,9 @@ def test_req_file_parse_comment_end_of_line_with_url(self, tmpdir, finder): with open(tmpdir.join("req1.txt"), "w") as fp: fp.write("https://example.com/foo.tar.gz # Comment ") - reqs = list(parse_requirements(tmpdir.join("req1.txt"), finder, - session=PipSession())) + reqs = list( + parse_requirements(tmpdir.join("req1.txt"), finder, session=PipSession()) + ) assert len(reqs) == 1 assert reqs[0].link.url == "https://example.com/foo.tar.gz" @@ -596,8 +654,9 @@ def test_req_file_parse_egginfo_end_of_line_with_url(self, tmpdir, finder): with open(tmpdir.join("req1.txt"), "w") as fp: fp.write("https://example.com/foo.tar.gz#egg=wat") - reqs = list(parse_requirements(tmpdir.join("req1.txt"), finder, - session=PipSession())) + reqs = list( + parse_requirements(tmpdir.join("req1.txt"), finder, session=PipSession()) + ) assert len(reqs) == 1 assert reqs[0].name == "wat" @@ -607,18 +666,19 @@ def test_req_file_no_finder(self, tmpdir): Test parsing a requirements file without a finder """ with open(tmpdir.join("req.txt"), "w") as fp: - fp.write(""" + fp.write( + """ --find-links https://example.com/ --index-url https://example.com/ --extra-index-url https://two.example.com/ --no-use-wheel --no-index - """) + """ + ) parse_requirements(tmpdir.join("req.txt"), session=PipSession()) - def test_install_requirements_with_options(self, tmpdir, finder, session, - options): + def test_install_requirements_with_options(self, tmpdir, finder, session, options): global_option = '--dry-run' install_option = '--prefix=/opt' @@ -626,13 +686,16 @@ def test_install_requirements_with_options(self, tmpdir, finder, session, --only-binary :all: INITools==2.0 --global-option="{global_option}" \ --install-option "{install_option}" - '''.format(global_option=global_option, install_option=install_option) + '''.format( + global_option=global_option, install_option=install_option + ) with requirements_file(content, tmpdir) as reqs_file: - req = next(parse_requirements(reqs_file.abspath, - finder=finder, - options=options, - session=session)) + req = next( + parse_requirements( + reqs_file.abspath, finder=finder, options=options, session=session + ) + ) req.source_dir = os.curdir with patch.object(subprocess, 'Popen') as popen: @@ -645,8 +708,10 @@ def test_install_requirements_with_options(self, tmpdir, finder, session, last_call = popen.call_args_list[-1] args = last_call[0][0] assert ( - 0 < args.index(global_option) < args.index('install') < - args.index(install_option) + 0 + < args.index(global_option) + < args.index('install') + < args.index(install_option) ) assert options.format_control.no_binary == {':all:'} assert options.format_control.only_binary == set() diff --git a/tests/unit/test_req_install.py b/tests/unit/test_req_install.py index 17af7d5f526..7efa5beb0b3 100644 --- a/tests/unit/test_req_install.py +++ b/tests/unit/test_req_install.py @@ -15,9 +15,8 @@ def test_tmp_build_directory(self): requirement = InstallRequirement(None, None) tmp_dir = tempfile.mkdtemp('-build', 'pip-') tmp_build_dir = requirement.build_location(tmp_dir) - assert ( - os.path.dirname(tmp_build_dir) == - os.path.realpath(os.path.dirname(tmp_dir)) + assert os.path.dirname(tmp_build_dir) == os.path.realpath( + os.path.dirname(tmp_dir) ) # are we on a system where /tmp is a symlink if os.path.realpath(tmp_dir) != os.path.abspath(tmp_dir): diff --git a/tests/unit/test_req_uninstall.py b/tests/unit/test_req_uninstall.py index e0c2fee367d..b7d63c3b603 100644 --- a/tests/unit/test_req_uninstall.py +++ b/tests/unit/test_req_uninstall.py @@ -5,7 +5,9 @@ import pip._internal.req.req_uninstall from pip._internal.req.req_uninstall import ( - UninstallPathSet, compact, compress_for_output_listing, + UninstallPathSet, + compact, + compress_for_output_listing, uninstallation_paths, ) from tests.lib import create_file @@ -20,21 +22,15 @@ def mock_is_local(path): def test_uninstallation_paths(): class dist(object): def get_metadata_lines(self, record): - return ['file.py,,', - 'file.pyc,,', - 'file.so,,', - 'nopyc.py'] + return ['file.py,,', 'file.pyc,,', 'file.so,,', 'nopyc.py'] + location = '' d = dist() paths = list(uninstallation_paths(d)) - expected = ['file.py', - 'file.pyc', - 'file.so', - 'nopyc.py', - 'nopyc.pyc'] + expected = ['file.py', 'file.pyc', 'file.so', 'nopyc.py', 'nopyc.pyc'] assert paths == expected @@ -48,26 +44,32 @@ def test_compressed_listing(tmpdir): def in_tmpdir(paths): li = [] for path in paths: - li.append(str(os.path.normcase( - os.path.join(tmpdir, path.replace("/", os.path.sep)) - ))) + li.append( + str( + os.path.normcase( + os.path.join(tmpdir, path.replace("/", os.path.sep)) + ) + ) + ) return li - sample = in_tmpdir([ - "lib/mypkg.dist-info/METADATA", - "lib/mypkg.dist-info/PKG-INFO", - "lib/mypkg/would_be_removed.txt", - "lib/mypkg/would_be_skipped.skip.txt", - "lib/mypkg/__init__.py", - "lib/mypkg/my_awesome_code.py", - "lib/mypkg/__pycache__/my_awesome_code-magic.pyc", - "lib/mypkg/support/support_file.py", - "lib/mypkg/support/more_support.py", - "lib/mypkg/support/would_be_skipped.skip.py", - "lib/mypkg/support/__pycache__/support_file-magic.pyc", - "lib/random_other_place/file_without_a_dot_pyc", - "bin/mybin", - ]) + sample = in_tmpdir( + [ + "lib/mypkg.dist-info/METADATA", + "lib/mypkg.dist-info/PKG-INFO", + "lib/mypkg/would_be_removed.txt", + "lib/mypkg/would_be_skipped.skip.txt", + "lib/mypkg/__init__.py", + "lib/mypkg/my_awesome_code.py", + "lib/mypkg/__pycache__/my_awesome_code-magic.pyc", + "lib/mypkg/support/support_file.py", + "lib/mypkg/support/more_support.py", + "lib/mypkg/support/would_be_skipped.skip.py", + "lib/mypkg/support/__pycache__/support_file-magic.pyc", + "lib/random_other_place/file_without_a_dot_pyc", + "bin/mybin", + ] + ) # Create the required files for fname in sample: @@ -76,17 +78,21 @@ def in_tmpdir(paths): # Remove the files to be skipped from the paths sample = [path for path in sample if ".skip." not in path] - expected_remove = in_tmpdir([ - "bin/mybin", - "lib/mypkg.dist-info/*", - "lib/mypkg/*", - "lib/random_other_place/file_without_a_dot_pyc", - ]) - - expected_skip = in_tmpdir([ - "lib/mypkg/would_be_skipped.skip.txt", - "lib/mypkg/support/would_be_skipped.skip.py", - ]) + expected_remove = in_tmpdir( + [ + "bin/mybin", + "lib/mypkg.dist-info/*", + "lib/mypkg/*", + "lib/random_other_place/file_without_a_dot_pyc", + ] + ) + + expected_skip = in_tmpdir( + [ + "lib/mypkg/would_be_skipped.skip.txt", + "lib/mypkg/support/would_be_skipped.skip.py", + ] + ) will_remove, will_skip = compress_for_output_listing(sample) assert sorted(expected_skip) == sorted(compact(will_skip)) @@ -95,12 +101,10 @@ def in_tmpdir(paths): class TestUninstallPathSet(object): def test_add(self, tmpdir, monkeypatch): - monkeypatch.setattr(pip._internal.req.req_uninstall, 'is_local', - mock_is_local) + monkeypatch.setattr(pip._internal.req.req_uninstall, 'is_local', mock_is_local) # Fix case for windows tests file_extant = os.path.normcase(os.path.join(tmpdir, 'foo')) - file_nonexistent = os.path.normcase( - os.path.join(tmpdir, 'nonexistent')) + file_nonexistent = os.path.normcase(os.path.join(tmpdir, 'nonexistent')) with open(file_extant, 'w'): pass @@ -114,8 +118,7 @@ def test_add(self, tmpdir, monkeypatch): @pytest.mark.skipif("sys.platform == 'win32'") def test_add_symlink(self, tmpdir, monkeypatch): - monkeypatch.setattr(pip._internal.req.req_uninstall, 'is_local', - mock_is_local) + monkeypatch.setattr(pip._internal.req.req_uninstall, 'is_local', mock_is_local) f = os.path.join(tmpdir, 'foo') with open(f, 'w'): pass @@ -127,12 +130,12 @@ def test_add_symlink(self, tmpdir, monkeypatch): assert ups.paths == {l} def test_compact_shorter_path(self, monkeypatch): - monkeypatch.setattr(pip._internal.req.req_uninstall, 'is_local', - lambda p: True) + monkeypatch.setattr(pip._internal.req.req_uninstall, 'is_local', lambda p: True) monkeypatch.setattr('os.path.exists', lambda p: True) # This deals with nt/posix path differences - short_path = os.path.normcase(os.path.abspath( - os.path.join(os.path.sep, 'path'))) + short_path = os.path.normcase( + os.path.abspath(os.path.join(os.path.sep, 'path')) + ) ups = UninstallPathSet(dist=Mock()) ups.add(short_path) ups.add(os.path.join(short_path, 'longer')) @@ -140,8 +143,7 @@ def test_compact_shorter_path(self, monkeypatch): @pytest.mark.skipif("sys.platform == 'win32'") def test_detect_symlink_dirs(self, monkeypatch, tmpdir): - monkeypatch.setattr(pip._internal.req.req_uninstall, 'is_local', - lambda p: True) + monkeypatch.setattr(pip._internal.req.req_uninstall, 'is_local', lambda p: True) # construct 2 paths: # tmpdir/dir/file diff --git a/tests/unit/test_unit_outdated.py b/tests/unit/test_unit_outdated.py index 853531db541..fcb1589eeb2 100644 --- a/tests/unit/test_unit_outdated.py +++ b/tests/unit/test_unit_outdated.py @@ -18,12 +18,9 @@ class MockPackageFinder(object): BASE_URL = 'https://pypi.org/simple/pip-{0}.tar.gz' PIP_PROJECT_NAME = 'pip' INSTALLATION_CANDIDATES = [ - InstallationCandidate(PIP_PROJECT_NAME, '6.9.0', - BASE_URL.format('6.9.0')), - InstallationCandidate(PIP_PROJECT_NAME, '3.3.1', - BASE_URL.format('3.3.1')), - InstallationCandidate(PIP_PROJECT_NAME, '1.0', - BASE_URL.format('1.0')), + InstallationCandidate(PIP_PROJECT_NAME, '6.9.0', BASE_URL.format('6.9.0')), + InstallationCandidate(PIP_PROJECT_NAME, '3.3.1', BASE_URL.format('3.3.1')), + InstallationCandidate(PIP_PROJECT_NAME, '1.0', BASE_URL.format('1.0')), ] def __init__(self, *args, **kwargs): @@ -50,8 +47,12 @@ def get_metadata_lines(self, name): def _options(): ''' Some default options that we pass to outdated.pip_version_check ''' return pretend.stub( - find_links=False, extra_index_urls=[], index_url='default_url', - pre=False, trusted_hosts=False, process_dependency_links=False, + find_links=False, + extra_index_urls=[], + index_url='default_url', + pre=False, + trusted_hosts=False, + process_dependency_links=False, cache_dir='', ) @@ -74,28 +75,34 @@ def _options(): ('1970-01-01T10:00:00Z', '1.0', '6.9.0', 'rpm', True, False), # No upgrade - upgrade warning should not print ('1970-01-9T10:00:00Z', '6.9.0', '6.9.0', 'pip', False, False), - ] + ], ) -def test_pip_version_check(monkeypatch, stored_time, installed_ver, new_ver, - installer, check_if_upgrade_required, - check_warn_logs): - monkeypatch.setattr(outdated, 'get_installed_version', - lambda name: installed_ver) +def test_pip_version_check( + monkeypatch, + stored_time, + installed_ver, + new_ver, + installer, + check_if_upgrade_required, + check_warn_logs, +): + monkeypatch.setattr(outdated, 'get_installed_version', lambda name: installed_ver) monkeypatch.setattr(outdated, 'PackageFinder', MockPackageFinder) - monkeypatch.setattr(outdated.logger, 'warning', - pretend.call_recorder(lambda *a, **kw: None)) - monkeypatch.setattr(outdated.logger, 'debug', - pretend.call_recorder(lambda s, exc_info=None: None)) - monkeypatch.setattr(pkg_resources, 'get_distribution', - lambda name: MockDistribution(installer)) + monkeypatch.setattr( + outdated.logger, 'warning', pretend.call_recorder(lambda *a, **kw: None) + ) + monkeypatch.setattr( + outdated.logger, 'debug', pretend.call_recorder(lambda s, exc_info=None: None) + ) + monkeypatch.setattr( + pkg_resources, 'get_distribution', lambda name: MockDistribution(installer) + ) fake_state = pretend.stub( state={"last_check": stored_time, 'pypi_version': installed_ver}, save=pretend.call_recorder(lambda v, t: None), ) - monkeypatch.setattr( - outdated, 'SelfCheckState', lambda **kw: fake_state - ) + monkeypatch.setattr(outdated, 'SelfCheckState', lambda **kw: fake_state) with freezegun.freeze_time( "1970-01-09 10:00:00", @@ -103,7 +110,7 @@ def test_pip_version_check(monkeypatch, stored_time, installed_ver, new_ver, "six.moves", "pip._vendor.six.moves", "pip._vendor.requests.packages.urllib3.packages.six.moves", - ] + ], ): latest_pypi_version = outdated.pip_version_check(None, _options()) @@ -113,7 +120,7 @@ def test_pip_version_check(monkeypatch, stored_time, installed_ver, new_ver, # See that we saved the correct version elif check_if_upgrade_required: assert fake_state.save.calls == [ - pretend.call(new_ver, datetime.datetime(1970, 1, 9, 10, 00, 00)), + pretend.call(new_ver, datetime.datetime(1970, 1, 9, 10, 00, 00)) ] else: # Make sure no Exceptions diff --git a/tests/unit/test_utils.py b/tests/unit/test_utils.py index 63d076610c3..7da55d9ab4e 100644 --- a/tests/unit/test_utils.py +++ b/tests/unit/test_utils.py @@ -17,14 +17,24 @@ from pip._vendor.six import BytesIO from pip._internal.exceptions import ( - HashMismatch, HashMissing, InstallationError, UnsupportedPythonVersion, + HashMismatch, + HashMissing, + InstallationError, + UnsupportedPythonVersion, ) from pip._internal.utils.encoding import auto_decode from pip._internal.utils.glibc import check_glibc_version from pip._internal.utils.hashes import Hashes, MissingHashes from pip._internal.utils.misc import ( - call_subprocess, egg_link_path, ensure_dir, get_installed_distributions, - get_prog, normalize_path, remove_auth_from_url, rmtree, untar_file, + call_subprocess, + egg_link_path, + ensure_dir, + get_installed_distributions, + get_prog, + normalize_path, + remove_auth_from_url, + rmtree, + untar_file, unzip_file, ) from pip._internal.utils.packaging import check_dist_requires_python @@ -41,37 +51,36 @@ def setup(self): self.mock_dist = Mock(project_name=project) self.site_packages = 'SITE_PACKAGES' self.user_site = 'USER_SITE' - self.user_site_egglink = os.path.join( - self.user_site, - '%s.egg-link' % project - ) + self.user_site_egglink = os.path.join(self.user_site, '%s.egg-link' % project) self.site_packages_egglink = os.path.join( - self.site_packages, - '%s.egg-link' % project, + self.site_packages, '%s.egg-link' % project ) # patches from pip._internal.utils import misc as utils + self.old_site_packages = utils.site_packages self.mock_site_packages = utils.site_packages = 'SITE_PACKAGES' self.old_running_under_virtualenv = utils.running_under_virtualenv - self.mock_running_under_virtualenv = utils.running_under_virtualenv = \ - Mock() + self.mock_running_under_virtualenv = utils.running_under_virtualenv = Mock() self.old_virtualenv_no_global = utils.virtualenv_no_global self.mock_virtualenv_no_global = utils.virtualenv_no_global = Mock() self.old_user_site = utils.user_site self.mock_user_site = utils.user_site = self.user_site from os import path + self.old_isfile = path.isfile self.mock_isfile = path.isfile = Mock() def teardown(self): from pip._internal.utils import misc as utils + utils.site_packages = self.old_site_packages utils.running_under_virtualenv = self.old_running_under_virtualenv utils.virtualenv_no_global = self.old_virtualenv_no_global utils.user_site = self.old_user_site from os import path + path.isfile = self.old_isfile def eggLinkInUserSite(self, egglink): @@ -180,13 +189,13 @@ class Tests_get_installed_distributions: workingset_stdlib = [ Mock(test_name='normal', key='argparse'), - Mock(test_name='normal', key='wsgiref') + Mock(test_name='normal', key='wsgiref'), ] workingset_freeze = [ Mock(test_name='normal', key='pip'), Mock(test_name='normal', key='setuptools'), - Mock(test_name='normal', key='distribute') + Mock(test_name='normal', key='distribute'), ] def dist_is_editable(self, dist): @@ -199,9 +208,9 @@ def dist_in_usersite(self, dist): return dist.test_name == "user" @patch('pip._vendor.pkg_resources.working_set', workingset) - def test_editables_only(self, mock_dist_is_editable, - mock_dist_is_local, - mock_dist_in_usersite): + def test_editables_only( + self, mock_dist_is_editable, mock_dist_is_local, mock_dist_in_usersite + ): mock_dist_is_editable.side_effect = self.dist_is_editable mock_dist_is_local.side_effect = self.dist_is_local mock_dist_in_usersite.side_effect = self.dist_in_usersite @@ -210,9 +219,9 @@ def test_editables_only(self, mock_dist_is_editable, assert dists[0].test_name == "editable" @patch('pip._vendor.pkg_resources.working_set', workingset) - def test_exclude_editables(self, mock_dist_is_editable, - mock_dist_is_local, - mock_dist_in_usersite): + def test_exclude_editables( + self, mock_dist_is_editable, mock_dist_is_local, mock_dist_in_usersite + ): mock_dist_is_editable.side_effect = self.dist_is_editable mock_dist_is_local.side_effect = self.dist_is_local mock_dist_in_usersite.side_effect = self.dist_in_usersite @@ -221,9 +230,9 @@ def test_exclude_editables(self, mock_dist_is_editable, assert dists[0].test_name == "normal" @patch('pip._vendor.pkg_resources.working_set', workingset) - def test_include_globals(self, mock_dist_is_editable, - mock_dist_is_local, - mock_dist_in_usersite): + def test_include_globals( + self, mock_dist_is_editable, mock_dist_is_local, mock_dist_in_usersite + ): mock_dist_is_editable.side_effect = self.dist_is_editable mock_dist_is_local.side_effect = self.dist_is_local mock_dist_in_usersite.side_effect = self.dist_in_usersite @@ -231,21 +240,20 @@ def test_include_globals(self, mock_dist_is_editable, assert len(dists) == 4 @patch('pip._vendor.pkg_resources.working_set', workingset) - def test_user_only(self, mock_dist_is_editable, - mock_dist_is_local, - mock_dist_in_usersite): + def test_user_only( + self, mock_dist_is_editable, mock_dist_is_local, mock_dist_in_usersite + ): mock_dist_is_editable.side_effect = self.dist_is_editable mock_dist_is_local.side_effect = self.dist_is_local mock_dist_in_usersite.side_effect = self.dist_in_usersite - dists = get_installed_distributions(local_only=False, - user_only=True) + dists = get_installed_distributions(local_only=False, user_only=True) assert len(dists) == 1 assert dists[0].test_name == "user" @patch('pip._vendor.pkg_resources.working_set', workingset_stdlib) - def test_gte_py27_excludes(self, mock_dist_is_editable, - mock_dist_is_local, - mock_dist_in_usersite): + def test_gte_py27_excludes( + self, mock_dist_is_editable, mock_dist_is_local, mock_dist_in_usersite + ): mock_dist_is_editable.side_effect = self.dist_is_editable mock_dist_is_local.side_effect = self.dist_is_local mock_dist_in_usersite.side_effect = self.dist_in_usersite @@ -253,14 +261,13 @@ def test_gte_py27_excludes(self, mock_dist_is_editable, assert len(dists) == 0 @patch('pip._vendor.pkg_resources.working_set', workingset_freeze) - def test_freeze_excludes(self, mock_dist_is_editable, - mock_dist_is_local, - mock_dist_in_usersite): + def test_freeze_excludes( + self, mock_dist_is_editable, mock_dist_is_local, mock_dist_in_usersite + ): mock_dist_is_editable.side_effect = self.dist_is_editable mock_dist_is_local.side_effect = self.dist_is_local mock_dist_in_usersite.side_effect = self.dist_in_usersite - dists = get_installed_distributions( - skip=('setuptools', 'pip', 'distribute')) + dists = get_installed_distributions(skip=('setuptools', 'pip', 'distribute')) assert len(dists) == 0 @@ -298,13 +305,14 @@ def confirm_files(self): # expectations based on 022 umask set above and the unpack logic that # sets execute permissions, not preservation for fname, expected_mode, test in [ - ('file.txt', 0o644, os.path.isfile), - ('symlink.txt', 0o644, os.path.isfile), - ('script_owner.sh', 0o755, os.path.isfile), - ('script_group.sh', 0o755, os.path.isfile), - ('script_world.sh', 0o755, os.path.isfile), - ('dir', 0o755, os.path.isdir), - (os.path.join('dir', 'dirfile'), 0o644, os.path.isfile)]: + ('file.txt', 0o644, os.path.isfile), + ('symlink.txt', 0o644, os.path.isfile), + ('script_owner.sh', 0o755, os.path.isfile), + ('script_group.sh', 0o755, os.path.isfile), + ('script_world.sh', 0o755, os.path.isfile), + ('dir', 0o755, os.path.isdir), + (os.path.join('dir', 'dirfile'), 0o644, os.path.isfile), + ]: path = os.path.join(self.tempdir, fname) if path.endswith('symlink.txt') and sys.platform == 'win32': # no symlinks created on windows @@ -315,8 +323,9 @@ def confirm_files(self): # due to os.chmod being a noop continue mode = self.mode(path) - assert mode == expected_mode, ( - "mode: %s, expected mode: %s" % (mode, expected_mode) + assert mode == expected_mode, "mode: %s, expected mode: %s" % ( + mode, + expected_mode, ) def test_unpack_tgz(self, data): @@ -394,12 +403,12 @@ def test_resolve_symlinks(self, tmpdir): 'dir_link/file1', resolve_symlinks=False ) == os.path.join(tmpdir, 'dir_link', 'file1') - assert normalize_path( - 'file_link', resolve_symlinks=True - ) == os.path.join(tmpdir, f) - assert normalize_path( - 'file_link', resolve_symlinks=False - ) == os.path.join(tmpdir, 'file_link') + assert normalize_path('file_link', resolve_symlinks=True) == os.path.join( + tmpdir, f + ) + assert normalize_path('file_link', resolve_symlinks=False) == os.path.join( + tmpdir, 'file_link' + ) finally: os.chdir(orig_working_dir) @@ -415,11 +424,16 @@ def test_success(self, tmpdir): """ file = tmpdir / 'to_hash' file.write('hello') - hashes = Hashes({ - 'sha256': ['2cf24dba5fb0a30e26e83b2ac5b9e29e' - '1b161e5c1fa7425e73043362938b9824'], - 'sha224': ['wrongwrong'], - 'md5': ['5d41402abc4b2a76b9719d911017c592']}) + hashes = Hashes( + { + 'sha256': [ + '2cf24dba5fb0a30e26e83b2ac5b9e29e' + '1b161e5c1fa7425e73043362938b9824' + ], + 'sha224': ['wrongwrong'], + 'md5': ['5d41402abc4b2a76b9719d911017c592'], + } + ) hashes.check_against_path(file) def test_failure(self): @@ -485,21 +499,14 @@ def test_symlinked_path(self): assert os.path.exists(tmp_dir.path) alt_tmp_dir = tempfile.mkdtemp(prefix="pip-test-") - assert ( - os.path.dirname(tmp_dir.path) == - os.path.dirname(os.path.realpath(alt_tmp_dir)) + assert os.path.dirname(tmp_dir.path) == os.path.dirname( + os.path.realpath(alt_tmp_dir) ) # are we on a system where /tmp is a symlink if os.path.realpath(alt_tmp_dir) != os.path.abspath(alt_tmp_dir): - assert ( - os.path.dirname(tmp_dir.path) != - os.path.dirname(alt_tmp_dir) - ) + assert os.path.dirname(tmp_dir.path) != os.path.dirname(alt_tmp_dir) else: - assert ( - os.path.dirname(tmp_dir.path) == - os.path.dirname(alt_tmp_dir) - ) + assert os.path.dirname(tmp_dir.path) == os.path.dirname(alt_tmp_dir) os.rmdir(tmp_dir.path) assert not os.path.exists(tmp_dir.path) @@ -545,14 +552,15 @@ def test_manylinux1_check_glibc_version(self): Test that the check_glibc_version function is robust against weird glibc version strings. """ - for two_twenty in ["2.20", - # used by "linaro glibc", see gh-3588 - "2.20-2014.11", - # weird possibilities that I just made up - "2.20+dev", - "2.20-custom", - "2.20.1", - ]: + for two_twenty in [ + "2.20", + # used by "linaro glibc", see gh-3588 + "2.20-2014.11", + # weird possibilities that I just made up + "2.20+dev", + "2.20-custom", + "2.20.1", + ]: assert check_glibc_version(two_twenty, 2, 15) assert check_glibc_version(two_twenty, 2, 20) assert not check_glibc_version(two_twenty, 2, 21) @@ -574,7 +582,6 @@ def test_manylinux1_check_glibc_version(self): class TestCheckRequiresPython(object): - @pytest.mark.parametrize( ("metadata", "should_raise"), [ @@ -585,9 +592,7 @@ class TestCheckRequiresPython(object): ], ) def test_check_requires(self, metadata, should_raise): - fake_dist = Mock( - has_metadata=lambda _: True, - get_metadata=lambda _: metadata) + fake_dist = Mock(has_metadata=lambda _: True, get_metadata=lambda _: metadata) if should_raise: with pytest.raises(UnsupportedPythonVersion): check_dist_requires_python(fake_dist) @@ -596,7 +601,6 @@ def test_check_requires(self, metadata, should_raise): class TestGetProg(object): - @pytest.mark.parametrize( ("argv", "executable", "expected"), [ @@ -604,14 +608,11 @@ class TestGetProg(object): ('-c', '/usr/bin/python', '/usr/bin/python -m pip'), ('__main__.py', '/usr/bin/python', '/usr/bin/python -m pip'), ('/usr/bin/pip3', '', 'pip3'), - ] + ], ) def test_get_prog(self, monkeypatch, argv, executable, expected): monkeypatch.setattr('pip._internal.utils.misc.sys.argv', [argv]) - monkeypatch.setattr( - 'pip._internal.utils.misc.sys.executable', - executable - ) + monkeypatch.setattr('pip._internal.utils.misc.sys.executable', executable) assert get_prog() == expected @@ -627,22 +628,30 @@ def test_call_subprocess_closes_stdin(): call_subprocess([sys.executable, '-c', 'input()']) -@pytest.mark.parametrize('auth_url, expected_url', [ - ('https://user:pass@domain.tld/project/tags/v0.2', - 'https://domain.tld/project/tags/v0.2'), - ('https://domain.tld/project/tags/v0.2', - 'https://domain.tld/project/tags/v0.2',), - ('https://user:pass@domain.tld/svn/project/trunk@8181', - 'https://domain.tld/svn/project/trunk@8181'), - ('https://domain.tld/project/trunk@8181', - 'https://domain.tld/project/trunk@8181',), - ('git+https://pypi.org/something', - 'git+https://pypi.org/something'), - ('git+https://user:pass@pypi.org/something', - 'git+https://pypi.org/something'), - ('git+ssh://git@pypi.org/something', - 'git+ssh://pypi.org/something'), -]) +@pytest.mark.parametrize( + 'auth_url, expected_url', + [ + ( + 'https://user:pass@domain.tld/project/tags/v0.2', + 'https://domain.tld/project/tags/v0.2', + ), + ( + 'https://domain.tld/project/tags/v0.2', + 'https://domain.tld/project/tags/v0.2', + ), + ( + 'https://user:pass@domain.tld/svn/project/trunk@8181', + 'https://domain.tld/svn/project/trunk@8181', + ), + ( + 'https://domain.tld/project/trunk@8181', + 'https://domain.tld/project/trunk@8181', + ), + ('git+https://pypi.org/something', 'git+https://pypi.org/something'), + ('git+https://user:pass@pypi.org/something', 'git+https://pypi.org/something'), + ('git+ssh://git@pypi.org/something', 'git+ssh://pypi.org/something'), + ], +) def test_remove_auth_from_url(auth_url, expected_url): url = remove_auth_from_url(auth_url) assert url == expected_url diff --git a/tests/unit/test_vcs.py b/tests/unit/test_vcs.py index 1cfd4c40963..62c60c61565 100644 --- a/tests/unit/test_vcs.py +++ b/tests/unit/test_vcs.py @@ -20,16 +20,23 @@ def test_rev_options_repr(): assert repr(rev_options) == "<RevOptions git: rev='develop'>" -@pytest.mark.parametrize(('vcs', 'expected1', 'expected2', 'kwargs'), [ - # First check VCS-specific RevOptions behavior. - (Bazaar(), [], ['-r', '123'], {}), - (Git(), ['HEAD'], ['123'], {}), - (Mercurial(), [], ['123'], {}), - (Subversion(), [], ['-r', '123'], {}), - # Test extra_args. For this, test using a single VersionControl class. - (Git(), ['HEAD', 'opt1', 'opt2'], ['123', 'opt1', 'opt2'], - dict(extra_args=['opt1', 'opt2'])), -]) +@pytest.mark.parametrize( + ('vcs', 'expected1', 'expected2', 'kwargs'), + [ + # First check VCS-specific RevOptions behavior. + (Bazaar(), [], ['-r', '123'], {}), + (Git(), ['HEAD'], ['123'], {}), + (Mercurial(), [], ['123'], {}), + (Subversion(), [], ['-r', '123'], {}), + # Test extra_args. For this, test using a single VersionControl class. + ( + Git(), + ['HEAD', 'opt1', 'opt2'], + ['123', 'opt1', 'opt2'], + dict(extra_args=['opt1', 'opt2']), + ), + ], +) def test_rev_options_to_args(vcs, expected1, expected2, kwargs): """ Test RevOptions.to_args(). @@ -100,21 +107,26 @@ def test_looks_like_hash(): def test_git_get_src_requirements(git, dist): ret = git.get_src_requirement(dist, location='.') - assert ret == ''.join([ - 'git+https://github.com/pypa/pip-test-package', - '@5547fa909e83df8bd743d3978d6667497983a4b7', - '#egg=pip_test_package' - ]) - - -@pytest.mark.parametrize('rev_name,result', ( - ('5547fa909e83df8bd743d3978d6667497983a4b7', True), - ('5547fa909', False), - ('5678', False), - ('abc123', False), - ('foo', False), - (None, False), -)) + assert ret == ''.join( + [ + 'git+https://github.com/pypa/pip-test-package', + '@5547fa909e83df8bd743d3978d6667497983a4b7', + '#egg=pip_test_package', + ] + ) + + +@pytest.mark.parametrize( + 'rev_name,result', + ( + ('5547fa909e83df8bd743d3978d6667497983a4b7', True), + ('5547fa909', False), + ('5678', False), + ('abc123', False), + ('foo', False), + (None, False), + ), +) def test_git_is_commit_id_equal(git, rev_name, result): """ Test Git.is_commit_id_equal(). @@ -150,28 +162,29 @@ def test_bazaar_simple_urls(): sftp_bzr_repo = Bazaar( url='bzr+sftp://bzr.myproject.org/MyProject/trunk/#egg=MyProject' ) - launchpad_bzr_repo = Bazaar( - url='bzr+lp:MyLaunchpadProject#egg=MyLaunchpadProject' - ) + launchpad_bzr_repo = Bazaar(url='bzr+lp:MyLaunchpadProject#egg=MyLaunchpadProject') assert http_bzr_repo.get_url_rev() == ( - 'http://bzr.myproject.org/MyProject/trunk/', None, + 'http://bzr.myproject.org/MyProject/trunk/', + None, ) assert https_bzr_repo.get_url_rev() == ( - 'https://bzr.myproject.org/MyProject/trunk/', None, + 'https://bzr.myproject.org/MyProject/trunk/', + None, ) assert ssh_bzr_repo.get_url_rev() == ( - 'bzr+ssh://bzr.myproject.org/MyProject/trunk/', None, + 'bzr+ssh://bzr.myproject.org/MyProject/trunk/', + None, ) assert ftp_bzr_repo.get_url_rev() == ( - 'ftp://bzr.myproject.org/MyProject/trunk/', None, + 'ftp://bzr.myproject.org/MyProject/trunk/', + None, ) assert sftp_bzr_repo.get_url_rev() == ( - 'sftp://bzr.myproject.org/MyProject/trunk/', None, - ) - assert launchpad_bzr_repo.get_url_rev() == ( - 'lp:MyLaunchpadProject', None, + 'sftp://bzr.myproject.org/MyProject/trunk/', + None, ) + assert launchpad_bzr_repo.get_url_rev() == ('lp:MyLaunchpadProject', None) def test_get_git_version(): diff --git a/tests/unit/test_wheel.py b/tests/unit/test_wheel.py index 6d3c1c7a781..4dc910cb79f 100644 --- a/tests/unit/test_wheel.py +++ b/tests/unit/test_wheel.py @@ -12,19 +12,24 @@ from tests.lib import DATA_DIR -@pytest.mark.parametrize("console_scripts", - ["pip = pip._internal.main:pip", - "pip:pip = pip._internal.main:pip"]) +@pytest.mark.parametrize( + "console_scripts", + ["pip = pip._internal.main:pip", "pip:pip = pip._internal.main:pip"], +) def test_get_entrypoints(tmpdir, console_scripts): entry_points = tmpdir.join("entry_points.txt") with open(str(entry_points), "w") as fp: - fp.write(""" + fp.write( + """ [console_scripts] {} [section] common:one = module:func common:two = module:other_func - """.format(console_scripts)) + """.format( + console_scripts + ) + ) assert wheel.get_entrypoints(str(entry_points)) == ( dict([console_scripts.split(' = ')]), @@ -37,10 +42,8 @@ def test_wheel_version(tmpdir, data): broken_wheel = 'brokenwheel-1.0-py2.py3-none-any.whl' future_version = (1, 9) - unpack_file(data.packages.join(future_wheel), - tmpdir + 'future', None, None) - unpack_file(data.packages.join(broken_wheel), - tmpdir + 'broken', None, None) + unpack_file(data.packages.join(future_wheel), tmpdir + 'future', None, None) + unpack_file(data.packages.join(broken_wheel), tmpdir + 'broken', None, None) assert wheel.wheel_version(tmpdir + 'future') == future_version assert not wheel.wheel_version(tmpdir + 'broken') @@ -71,7 +74,6 @@ def test_check_compatibility(): class TestWheelFile(object): - def test_std_wheel_pattern(self): w = wheel.Wheel('simple-1.1.1-py2-none-any.whl') assert w.name == 'simple' @@ -137,8 +139,7 @@ def test_not_supported_version(self): @patch('sys.platform', 'darwin') @patch('pip._internal.pep425tags.get_abbr_impl', lambda: 'cp') - @patch('pip._internal.pep425tags.get_platform', - lambda: 'macosx_10_9_intel') + @patch('pip._internal.pep425tags.get_platform', lambda: 'macosx_10_9_intel') def test_supported_osx_version(self): """ Wheels built for macOS 10.6 are supported on 10.9 @@ -151,8 +152,7 @@ def test_supported_osx_version(self): @patch('sys.platform', 'darwin') @patch('pip._internal.pep425tags.get_abbr_impl', lambda: 'cp') - @patch('pip._internal.pep425tags.get_platform', - lambda: 'macosx_10_6_intel') + @patch('pip._internal.pep425tags.get_platform', lambda: 'macosx_10_6_intel') def test_not_supported_osx_version(self): """ Wheels built for macOS 10.9 are not supported on 10.6 @@ -167,23 +167,25 @@ def test_supported_multiarch_darwin(self): """ Multi-arch wheels (intel) are supported on components (i386, x86_64) """ - with patch('pip._internal.pep425tags.get_platform', - lambda: 'macosx_10_5_universal'): + with patch( + 'pip._internal.pep425tags.get_platform', lambda: 'macosx_10_5_universal' + ): universal = pep425tags.get_supported(['27'], False) - with patch('pip._internal.pep425tags.get_platform', - lambda: 'macosx_10_5_intel'): + with patch( + 'pip._internal.pep425tags.get_platform', lambda: 'macosx_10_5_intel' + ): intel = pep425tags.get_supported(['27'], False) - with patch('pip._internal.pep425tags.get_platform', - lambda: 'macosx_10_5_x86_64'): + with patch( + 'pip._internal.pep425tags.get_platform', lambda: 'macosx_10_5_x86_64' + ): x64 = pep425tags.get_supported(['27'], False) - with patch('pip._internal.pep425tags.get_platform', - lambda: 'macosx_10_5_i386'): + with patch('pip._internal.pep425tags.get_platform', lambda: 'macosx_10_5_i386'): i386 = pep425tags.get_supported(['27'], False) - with patch('pip._internal.pep425tags.get_platform', - lambda: 'macosx_10_5_ppc'): + with patch('pip._internal.pep425tags.get_platform', lambda: 'macosx_10_5_ppc'): ppc = pep425tags.get_supported(['27'], False) - with patch('pip._internal.pep425tags.get_platform', - lambda: 'macosx_10_5_ppc64'): + with patch( + 'pip._internal.pep425tags.get_platform', lambda: 'macosx_10_5_ppc64' + ): ppc64 = pep425tags.get_supported(['27'], False) w = wheel.Wheel('simple-0.1-cp27-none-macosx_10_5_intel.whl') @@ -207,11 +209,13 @@ def test_not_supported_multiarch_darwin(self): """ Single-arch wheels (x86_64) are not supported on multi-arch (intel) """ - with patch('pip._internal.pep425tags.get_platform', - lambda: 'macosx_10_5_universal'): + with patch( + 'pip._internal.pep425tags.get_platform', lambda: 'macosx_10_5_universal' + ): universal = pep425tags.get_supported(['27'], False) - with patch('pip._internal.pep425tags.get_platform', - lambda: 'macosx_10_5_intel'): + with patch( + 'pip._internal.pep425tags.get_platform', lambda: 'macosx_10_5_intel' + ): intel = pep425tags.get_supported(['27'], False) w = wheel.Wheel('simple-0.1-cp27-none-macosx_10_5_i386.whl') @@ -225,11 +229,7 @@ def test_support_index_min(self): """ Test results from `support_index_min` """ - tags = [ - ('py2', 'none', 'TEST'), - ('py2', 'TEST', 'any'), - ('py2', 'none', 'any'), - ] + tags = [('py2', 'none', 'TEST'), ('py2', 'TEST', 'any'), ('py2', 'none', 'any')] w = wheel.Wheel('simple-0.1-py2-none-any.whl') assert w.support_index_min(tags=tags) == 2 w = wheel.Wheel('simple-0.1-py2-none-TEST.whl') @@ -247,8 +247,7 @@ def test_unpack_wheel_no_flatten(self): from tempfile import mkdtemp from shutil import rmtree - filepath = os.path.join(DATA_DIR, 'packages', - 'meta-1.0-py2.py3-none-any.whl') + filepath = os.path.join(DATA_DIR, 'packages', 'meta-1.0-py2.py3-none-any.whl') try: tmpdir = mkdtemp() utils.unpack_file(filepath, tmpdir, 'application/zip', None) @@ -264,10 +263,8 @@ def test_purelib_platlib(self, data): packages = [ ("pure_wheel", data.packages.join("pure_wheel-1.7"), True), ("plat_wheel", data.packages.join("plat_wheel-1.7"), False), - ("pure_wheel", data.packages.join( - "pure_wheel-_invalidversion_"), True), - ("plat_wheel", data.packages.join( - "plat_wheel-_invalidversion_"), False), + ("pure_wheel", data.packages.join("pure_wheel-_invalidversion_"), True), + ("plat_wheel", data.packages.join("plat_wheel-_invalidversion_"), False), ] for name, path, expected in packages: @@ -289,8 +286,7 @@ class TestMoveWheelFiles(object): def prep(self, data, tmpdir): self.name = 'sample' - self.wheelpath = data.packages.join( - 'sample-1.2.0-py2.py3-none-any.whl') + self.wheelpath = data.packages.join('sample-1.2.0-py2.py3-none-any.whl') self.req = Requirement('sample') self.src = os.path.join(tmpdir, 'src') self.dest = os.path.join(tmpdir, 'dest') @@ -300,15 +296,14 @@ def prep(self, data, tmpdir): 'purelib': os.path.join(self.dest, 'lib'), 'data': os.path.join(self.dest, 'data'), } - self.src_dist_info = os.path.join( - self.src, 'sample-1.2.0.dist-info') + self.src_dist_info = os.path.join(self.src, 'sample-1.2.0.dist-info') self.dest_dist_info = os.path.join( - self.scheme['purelib'], 'sample-1.2.0.dist-info') + self.scheme['purelib'], 'sample-1.2.0.dist-info' + ) def assert_installed(self): # lib - assert os.path.isdir( - os.path.join(self.scheme['purelib'], 'sample')) + assert os.path.isdir(os.path.join(self.scheme['purelib'], 'sample')) # dist-info metadata = os.path.join(self.dest_dist_info, 'METADATA') assert os.path.isfile(metadata) @@ -316,25 +311,19 @@ def assert_installed(self): data_file = os.path.join(self.scheme['data'], 'my_data', 'data_file') assert os.path.isfile(data_file) # package data - pkg_data = os.path.join( - self.scheme['purelib'], 'sample', 'package_data.dat') + pkg_data = os.path.join(self.scheme['purelib'], 'sample', 'package_data.dat') assert os.path.isfile(pkg_data) def test_std_install(self, data, tmpdir): self.prep(data, tmpdir) - wheel.move_wheel_files( - self.name, self.req, self.src, scheme=self.scheme) + wheel.move_wheel_files(self.name, self.req, self.src, scheme=self.scheme) self.assert_installed() def test_install_prefix(self, data, tmpdir): prefix = os.path.join(os.path.sep, 'some', 'path') self.prep(data, tmpdir) wheel.move_wheel_files( - self.name, - self.req, - self.src, - root=tmpdir, - prefix=prefix, + self.name, self.req, self.src, root=tmpdir, prefix=prefix ) bin_dir = 'Scripts' if WINDOWS else 'bin' @@ -347,57 +336,42 @@ def test_dist_info_contains_empty_dir(self, data, tmpdir): """ # e.g. https://github.com/pypa/pip/issues/1632#issuecomment-38027275 self.prep(data, tmpdir) - src_empty_dir = os.path.join( - self.src_dist_info, 'empty_dir', 'empty_dir') + src_empty_dir = os.path.join(self.src_dist_info, 'empty_dir', 'empty_dir') os.makedirs(src_empty_dir) assert os.path.isdir(src_empty_dir) - wheel.move_wheel_files( - self.name, self.req, self.src, scheme=self.scheme) + wheel.move_wheel_files(self.name, self.req, self.src, scheme=self.scheme) self.assert_installed() - assert not os.path.isdir( - os.path.join(self.dest_dist_info, 'empty_dir')) + assert not os.path.isdir(os.path.join(self.dest_dist_info, 'empty_dir')) class TestWheelBuilder(object): - def test_skip_building_wheels(self, caplog): - with patch('pip._internal.wheel.WheelBuilder._build_one') \ - as mock_build_one: + with patch('pip._internal.wheel.WheelBuilder._build_one') as mock_build_one: wheel_req = Mock(is_wheel=True, editable=False, constraint=False) - wb = wheel.WheelBuilder( - finder=Mock(), preparer=Mock(), wheel_cache=None, - ) + wb = wheel.WheelBuilder(finder=Mock(), preparer=Mock(), wheel_cache=None) wb.build([wheel_req], session=Mock()) assert "due to already being wheel" in caplog.text assert mock_build_one.mock_calls == [] class TestMessageAboutScriptsNotOnPATH(object): - def _template(self, paths, scripts): with patch.dict('os.environ', {'PATH': os.pathsep.join(paths)}): return wheel.message_about_scripts_not_on_PATH(scripts) def test_no_script(self): - retval = self._template( - paths=['/a/b', '/c/d/bin'], - scripts=[] - ) + retval = self._template(paths=['/a/b', '/c/d/bin'], scripts=[]) assert retval is None def test_single_script__single_dir_not_on_PATH(self): - retval = self._template( - paths=['/a/b', '/c/d/bin'], - scripts=['/c/d/foo'] - ) + retval = self._template(paths=['/a/b', '/c/d/bin'], scripts=['/c/d/foo']) assert retval is not None assert "--no-warn-script-location" in retval assert "foo is installed in '/c/d'" in retval def test_two_script__single_dir_not_on_PATH(self): retval = self._template( - paths=['/a/b', '/c/d/bin'], - scripts=['/c/d/foo', '/c/d/baz'] + paths=['/a/b', '/c/d/bin'], scripts=['/c/d/foo', '/c/d/baz'] ) assert retval is not None assert "--no-warn-script-location" in retval @@ -406,7 +380,7 @@ def test_two_script__single_dir_not_on_PATH(self): def test_multi_script__multi_dir_not_on_PATH(self): retval = self._template( paths=['/a/b', '/c/d/bin'], - scripts=['/c/d/foo', '/c/d/bar', '/c/d/baz', '/a/b/c/spam'] + scripts=['/c/d/foo', '/c/d/bar', '/c/d/baz', '/a/b/c/spam'], ) assert retval is not None assert "--no-warn-script-location" in retval @@ -416,10 +390,7 @@ def test_multi_script__multi_dir_not_on_PATH(self): def test_multi_script_all__multi_dir_not_on_PATH(self): retval = self._template( paths=['/a/b', '/c/d/bin'], - scripts=[ - '/c/d/foo', '/c/d/bar', '/c/d/baz', - '/a/b/c/spam', '/a/b/c/eggs' - ] + scripts=['/c/d/foo', '/c/d/bar', '/c/d/baz', '/a/b/c/spam', '/a/b/c/eggs'], ) assert retval is not None assert "--no-warn-script-location" in retval @@ -428,37 +399,29 @@ def test_multi_script_all__multi_dir_not_on_PATH(self): def test_two_script__single_dir_on_PATH(self): retval = self._template( - paths=['/a/b', '/c/d/bin'], - scripts=['/a/b/foo', '/a/b/baz'] + paths=['/a/b', '/c/d/bin'], scripts=['/a/b/foo', '/a/b/baz'] ) assert retval is None def test_multi_script__multi_dir_on_PATH(self): retval = self._template( paths=['/a/b', '/c/d/bin'], - scripts=['/a/b/foo', '/a/b/bar', '/a/b/baz', '/c/d/bin/spam'] + scripts=['/a/b/foo', '/a/b/bar', '/a/b/baz', '/c/d/bin/spam'], ) assert retval is None def test_multi_script__single_dir_on_PATH(self): retval = self._template( - paths=['/a/b', '/c/d/bin'], - scripts=['/a/b/foo', '/a/b/bar', '/a/b/baz'] + paths=['/a/b', '/c/d/bin'], scripts=['/a/b/foo', '/a/b/bar', '/a/b/baz'] ) assert retval is None def test_single_script__single_dir_on_PATH(self): - retval = self._template( - paths=['/a/b', '/c/d/bin'], - scripts=['/a/b/foo'] - ) + retval = self._template(paths=['/a/b', '/c/d/bin'], scripts=['/a/b/foo']) assert retval is None def test_PATH_check_case_insensitive_on_windows(self): - retval = self._template( - paths=['C:\\A\\b'], - scripts=['c:\\a\\b\\c', 'C:/A/b/d'] - ) + retval = self._template(paths=['C:\\A\\b'], scripts=['c:\\a\\b\\c', 'C:/A/b/d']) if WINDOWS: assert retval is None else: @@ -466,7 +429,6 @@ def test_PATH_check_case_insensitive_on_windows(self): def test_trailing_ossep_removal(self): retval = self._template( - paths=[os.path.join('a', 'b', '')], - scripts=[os.path.join('a', 'b', 'c')] + paths=[os.path.join('a', 'b', '')], scripts=[os.path.join('a', 'b', 'c')] ) assert retval is None diff --git a/tox.ini b/tox.ini index 789fad8d85a..cae3e45474a 100644 --- a/tox.ini +++ b/tox.ini @@ -36,10 +36,12 @@ commands = [lint] deps = flake8==3.3.0 - isort==4.2.5 + isort==4.3.4 + black==18.6b1 commands = flake8 . - isort --recursive --check-only --diff src/pip tests + #isort --recursive --check-only --diff src/pip tests + black --check --diff -S --exclude /(\.git|\.mypy_cache|\.tox|build|dist|src/pip/_vendor)/ . [testenv:lint-py2] basepython = python2 @@ -51,6 +53,12 @@ basepython = python3 deps = {[lint]deps} commands = {[lint]commands} +[testenv:format] +deps = + black==18.6b1 +commands = + black -S --exclude /(\.git|\.mypy_cache|\.tox|build|dist|src/pip/_vendor)/ . + [testenv:mypy] basepython = python3 deps = mypy