1
1
Fork 0
mirror of https://github.com/pypa/pip synced 2023-12-13 21:30:23 +01:00

Merge branch 'develop'

This commit is contained in:
Donald Stufft 2015-08-20 17:09:22 -04:00
commit 0001b1b6ef
34 changed files with 817 additions and 438 deletions

View file

@ -13,7 +13,7 @@ matrix:
env: TOXENV=py33
- python: 3.4
env: TOXENV=py34
- python: nightly
- python: 3.5-dev
env: TOXENV=py35
- python: pypy
env: TOXENV=pypy

View file

@ -46,7 +46,7 @@ if [[ $VENDOR = "no" ]]; then
fi
# Run the unit tests
tox -- -m unit --cov pip/ --cov-report xml $TOXARGS
tox -- -m unit $TOXARGS
# Run our integration tests
# Note: There is an issue with Python 3.2 where concurrent imports will corrupt

View file

@ -88,7 +88,7 @@ Ionel Cristian Mărieș <contact@ionelmc.ro>
Ionel Maries Cristian <ionel.mc@gmail.com>
Jakub Stasiak <kuba.stasiak@gmail.com>
Jakub Vysoky <jakub@borka.cz>
James Cleveland <jamescleveland@gmail.com>
James Cleveland <jc@blit.cc>
James Polley <jp@jamezpolley.com>
Jan Pokorný <jpokorny@redhat.com>
Jannis Leidel <jannis@leidel.info>

View file

@ -1,9 +1,37 @@
**7.1.1 (unreleased)**
* Check that the wheel cache directory is writable before we attempt to write
cached files to them.
* Move the pip version check until *after* any installs have been performed,
thus removing the extraenous warning when upgrading pip.
* Added debug logging when using a cached wheel.
* Respect platlib by default on platforms that have it separated from purlib.
* Upgrade packaging to 15.3.
* Normalize post-release spellings for rev/r prefixes.
* Upgrade distlib to 0.2.1.
* Updated launchers to decode shebangs using UTF-8. This allows non-ASCII
pathnames to be correctly handled.
* Ensured that the executable written to shebangs is normcased.
* Changed ScriptMaker to work better under Jython.
* Upgrade ipaddress to 1.0.13.
**7.1.0 (2015-06-30)**
* Allow constraining versions globally without having to know exactly what will
be installed by the pip command. :issue:`2731`.
* Accept --no-binary and --only-binary via pip.conf. :issue`2867`.
* Accept --no-binary and --only-binary via pip.conf. :issue:`2867`.
* Allow ``--allow-all-external`` within a requirements file.

View file

@ -2,9 +2,8 @@ https://github.com/spulec/freezegun/archive/master.zip#egg=freezegun
pretend
pytest
pytest-capturelog
pytest-cov
pytest-timeout
pytest-xdist
mock
mock<1.1
scripttest>=1.3
https://github.com/pypa/virtualenv/archive/develop.zip#egg=virtualenv

View file

@ -124,7 +124,7 @@ If you wish, you can refer to other requirements files, like this::
-r more_requirements.txt
You can also refer to constraints files, like this::
You can also refer to :ref:`constraints files <Constraints Files>`, like this::
-c some_constraints.txt
@ -386,7 +386,7 @@ similarly to that of a web browser. While the cache is on by default and is
designed do the right thing by default you can disable the cache and always
access PyPI by utilizing the ``--no-cache-dir`` option.
When making any HTTP request pip will first check it's local cache to determine
When making any HTTP request pip will first check its local cache to determine
if it has a suitable response stored for that request which has not expired. If
it does then it simply returns that response and doesn't make the request.
@ -396,13 +396,13 @@ response telling pip to simply use the cached item (and refresh the expiration
timer) or it will return a whole new response which pip can then store in the
cache.
When storing items in the cache pip will respect the ``CacheControl`` header
When storing items in the cache, pip will respect the ``CacheControl`` header
if it exists, or it will fall back to the ``Expires`` header if that exists.
This allows pip to function as a browser would, and allows the index server
to communicate to pip how long it is reasonable to cache any particular item.
While this cache attempts to minimize network activity, it does not prevent
network access all together. If you want a fast/local install solution that
network access altogether. If you want a fast/local install solution that
circumvents accessing PyPI, see :ref:`Fast & Local Installs`.
The default location for the cache directory depends on the Operating System:
@ -421,15 +421,15 @@ Wheel cache
Pip will read from the subdirectory ``wheels`` within the pip cache dir and use
any packages found there. This is disabled via the same ``no-cache-dir`` option
that disables the HTTP cache. The internal structure of that cache is not part
of the Pip API. As of 7.0 pip uses a subdirectory per sdist that wheels were
of the pip API. As of 7.0 pip uses a subdirectory per sdist that wheels were
built from, and wheels within that subdirectory.
Pip attempts to choose the best wheels from those built in preference to
building a new wheel. Note that this means when a package has both optional
C extensions and builds `py` tagged wheels when the C extension can't be built
that pip will not attempt to build a better wheel for Python's that would have
that pip will not attempt to build a better wheel for Pythons that would have
supported it, once any generic wheel is built. To correct this, make sure that
the wheel's are built with Python specific tags - e.g. pp on Pypy.
the wheels are built with Python specific tags - e.g. pp on Pypy.
When no wheels are found for an sdist, pip will attempt to build a wheel
automatically and insert it into the wheel cache.

View file

@ -30,7 +30,7 @@ import pip.cmdoptions
cmdoptions = pip.cmdoptions
# The version as used in the setup.py and the docs conf.py
__version__ = "7.1.0"
__version__ = "7.1.1.dev0"
logger = logging.getLogger(__name__)

View file

@ -18,7 +18,7 @@ Modifications
_markerlib and pkg_resources
============================
_markerlib and pkg_resources has been pulled in from setuptools 18.0
_markerlib and pkg_resources has been pulled in from setuptools 18.2
Note to Downstream Distributors

View file

@ -6,7 +6,7 @@
#
import logging
__version__ = '0.2.0'
__version__ = '0.2.1'
class DistlibException(Exception):
pass

View file

@ -10,7 +10,7 @@ import os
import re
import sys
if sys.version_info[0] < 3:
if sys.version_info[0] < 3: # pragma: no cover
from StringIO import StringIO
string_types = basestring,
text_type = unicode
@ -53,7 +53,7 @@ if sys.version_info[0] < 3:
if match: return match.group(1, 2)
return None, host
else:
else: # pragma: no cover
from io import StringIO
string_types = str,
text_type = str
@ -81,7 +81,7 @@ else:
try:
from ssl import match_hostname, CertificateError
except ImportError:
except ImportError: # pragma: no cover
class CertificateError(ValueError):
pass
@ -181,7 +181,7 @@ except ImportError:
try:
from types import SimpleNamespace as Container
except ImportError:
except ImportError: # pragma: no cover
class Container(object):
"""
A generic container for when multiple values need to be returned
@ -192,7 +192,7 @@ except ImportError:
try:
from shutil import which
except ImportError:
except ImportError: # pragma: no cover
# Implementation from Python 3.3
def which(cmd, mode=os.F_OK | os.X_OK, path=None):
"""Given a command, mode, and a PATH string, return the path which
@ -261,7 +261,7 @@ except ImportError:
from zipfile import ZipFile as BaseZipFile
if hasattr(BaseZipFile, '__enter__'):
if hasattr(BaseZipFile, '__enter__'): # pragma: no cover
ZipFile = BaseZipFile
else:
from zipfile import ZipExtFile as BaseZipExtFile

View file

@ -366,9 +366,11 @@ class Distribution(object):
return plist
def _get_requirements(self, req_attr):
reqts = getattr(self.metadata, req_attr)
return set(self.metadata.get_requirements(reqts, extras=self.extras,
env=self.context))
md = self.metadata
logger.debug('Getting requirements from metadata %r', md.todict())
reqts = getattr(md, req_attr)
return set(md.get_requirements(reqts, extras=self.extras,
env=self.context))
@property
def run_requires(self):

View file

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2012-2014 Vinay Sajip.
# Copyright (C) 2012-2015 Vinay Sajip.
# Licensed to the Python Software Foundation under a contributor agreement.
# See LICENSE.txt and CONTRIBUTORS.txt.
#
@ -165,8 +165,13 @@ class Locator(object):
for a given project release.
"""
t = urlparse(url)
basename = posixpath.basename(t.path)
compatible = True
is_wheel = basename.endswith('.whl')
if is_wheel:
compatible = is_compatible(Wheel(basename), self.wheel_tags)
return (t.scheme != 'https', 'pypi.python.org' in t.netloc,
posixpath.basename(t.path))
is_wheel, compatible, basename)
def prefer_url(self, url1, url2):
"""
@ -174,8 +179,9 @@ class Locator(object):
archives for the same version of a distribution (for example,
.tar.gz vs. zip).
The current implement favours http:// URLs over https://, archives
from PyPI over those from other locations and then the archive name.
The current implementation favours https:// URLs over http://, archives
from PyPI over those from other locations, wheel compatibility (if a
wheel) and then the archive name.
"""
result = url2
if url1:
@ -332,11 +338,13 @@ class Locator(object):
self.matcher = matcher = scheme.matcher(r.requirement)
logger.debug('matcher: %s (%s)', matcher, type(matcher).__name__)
versions = self.get_project(r.name)
if versions:
if len(versions) > 2: # urls and digests keys are present
# sometimes, versions are invalid
slist = []
vcls = matcher.version_class
for k in versions:
if k in ('urls', 'digests'):
continue
try:
if not matcher.match(k):
logger.debug('%s did not match %r', matcher, k)
@ -447,17 +455,39 @@ class PyPIJSONLocator(Locator):
md.keywords = data.get('keywords', [])
md.summary = data.get('summary')
dist = Distribution(md)
dist.locator = self
urls = d['urls']
if urls:
info = urls[0]
md.source_url = info['url']
dist.digest = self._get_digest(info)
dist.locator = self
result[md.version] = dist
for info in urls:
result[md.version] = dist
for info in d['urls']:
url = info['url']
dist.download_urls.add(url)
dist.digests[url] = self._get_digest(info)
result['urls'].setdefault(md.version, set()).add(url)
result['digests'][url] = self._get_digest(info)
# Now get other releases
for version, infos in d['releases'].items():
if version == md.version:
continue # already done
omd = Metadata(scheme=self.scheme)
omd.name = md.name
omd.version = version
odist = Distribution(omd)
odist.locator = self
result[version] = odist
for info in infos:
url = info['url']
result['urls'].setdefault(md.version, set()).add(url)
result['digests'][url] = digest
odist.download_urls.add(url)
odist.digests[url] = self._get_digest(info)
result['urls'].setdefault(version, set()).add(url)
result['digests'][url] = self._get_digest(info)
# for info in urls:
# md.source_url = info['url']
# dist.digest = self._get_digest(info)
# dist.locator = self
# for info in urls:
# url = info['url']
# result['urls'].setdefault(md.version, set()).add(url)
# result['digests'][url] = self._get_digest(info)
except Exception as e:
logger.exception('JSON fetch failed: %s', e)
return result
@ -885,11 +915,12 @@ class DistPathLocator(Locator):
def _get_project(self, name):
dist = self.distpath.get_distribution(name)
if dist is None:
result = {}
result = {'urls': {}, 'digests': {}}
else:
result = {
dist.version: dist,
'urls': {dist.version: set([dist.source_url])}
'urls': {dist.version: set([dist.source_url])},
'digests': {dist.version: set([None])}
}
return result

View file

@ -120,6 +120,12 @@ class ResourceFinder(object):
"""
Resource finder for file system resources.
"""
if sys.platform.startswith('java'):
skipped_extensions = ('.pyc', '.pyo', '.class')
else:
skipped_extensions = ('.pyc', '.pyo')
def __init__(self, module):
self.module = module
self.loader = getattr(module, '__loader__', None)
@ -170,7 +176,8 @@ class ResourceFinder(object):
def get_resources(self, resource):
def allowed(f):
return f != '__pycache__' and not f.endswith(('.pyc', '.pyo'))
return (f != '__pycache__' and not
f.endswith(self.skipped_extensions))
return set([f for f in os.listdir(resource.path) if allowed(f)])
def is_container(self, resource):
@ -178,6 +185,26 @@ class ResourceFinder(object):
_is_directory = staticmethod(os.path.isdir)
def iterator(self, resource_name):
resource = self.find(resource_name)
if resource is not None:
todo = [resource]
while todo:
resource = todo.pop(0)
yield resource
if resource.is_container:
rname = resource.name
for name in resource.resources:
if not rname:
new_name = name
else:
new_name = '/'.join([rname, name])
child = self.find(new_name)
if child.is_container:
todo.append(child)
else:
yield child
class ZipResourceFinder(ResourceFinder):
"""

View file

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2013-2014 Vinay Sajip.
# Copyright (C) 2013-2015 Vinay Sajip.
# Licensed to the Python Software Foundation under a contributor agreement.
# See LICENSE.txt and CONTRIBUTORS.txt.
#
@ -80,7 +80,8 @@ class ScriptMaker(object):
self.force = False
self.clobber = False
# It only makes sense to set mode bits on POSIX.
self.set_mode = (os.name == 'posix')
self.set_mode = (os.name == 'posix') or (os.name == 'java' and
os._name == 'posix')
self.variants = set(('', 'X.Y'))
self._fileop = fileop or FileOperator(dry_run)
@ -91,6 +92,31 @@ class ScriptMaker(object):
executable = os.path.join(dn, fn)
return executable
if sys.platform.startswith('java'): # pragma: no cover
def _is_shell(self, executable):
"""
Determine if the specified executable is a script
(contains a #! line)
"""
try:
with open(executable) as fp:
return fp.read(2) == '#!'
except (OSError, IOError):
logger.warning('Failed to open %s', executable)
return False
def _fix_jython_executable(self, executable):
if self._is_shell(executable):
# Workaround for Jython is not needed on Linux systems.
import java
if java.lang.System.getProperty('os.name') == 'Linux':
return executable
elif executable.lower().endswith('jython.exe'):
# Use wrapper exe for Jython on Windows
return executable
return '/usr/bin/env %s' % executable
def _get_shebang(self, encoding, post_interp=b'', options=None):
enquote = True
if self.executable:
@ -109,6 +135,10 @@ class ScriptMaker(object):
if options:
executable = self._get_alternate_executable(executable, options)
if sys.platform.startswith('java'): # pragma: no cover
executable = self._fix_jython_executable(executable)
# Normalise case for Windows
executable = os.path.normcase(executable)
# If the user didn't specify an executable, it may be necessary to
# cater for executable paths with spaces (not uncommon on Windows)
if enquote and ' ' in executable:

Binary file not shown.

Binary file not shown.

View file

@ -163,7 +163,7 @@ def get_executable():
# else:
# result = sys.executable
# return result
return sys.executable
return os.path.normcase(sys.executable)
def proceed(prompt, allowed_chars, error_prompt=None, default=None):
@ -397,7 +397,7 @@ class FileOperator(object):
self.record_as_written(path)
def set_mode(self, bits, mask, files):
if os.name == 'posix':
if os.name == 'posix' or (os.name == 'java' and os._name == 'posix'):
# Set the executable bits (owner, group, and world) on
# all the files specified.
for f in files:

Binary file not shown.

Binary file not shown.

View file

@ -74,7 +74,7 @@ FILENAME_RE = re.compile(r'''
(-(?P<bn>\d+[^-]*))?
-(?P<py>\w+\d+(\.\w+\d+)*)
-(?P<bi>\w+)
-(?P<ar>\w+)
-(?P<ar>\w+(\.\w+)*)
\.whl$
''', re.IGNORECASE | re.VERBOSE)

File diff suppressed because it is too large Load diff

View file

@ -22,7 +22,7 @@ __title__ = "packaging"
__summary__ = "Core utilities for Python packages"
__uri__ = "https://github.com/pypa/packaging"
__version__ = "15.2"
__version__ = "15.3"
__author__ = "Donald Stufft"
__email__ = "donald@stufft.io"

View file

@ -324,6 +324,8 @@ def _parse_letter_version(letter, number):
letter = "b"
elif letter in ["c", "pre", "preview"]:
letter = "rc"
elif letter in ["rev", "r"]:
letter = "post"
return letter, int(number)
if not letter and number:

View file

@ -1,4 +1,4 @@
distlib==0.2.0
distlib==0.2.1
html5lib==1.0b5
six==1.9.0
colorama==0.3.3
@ -6,6 +6,6 @@ requests==2.7.0
CacheControl==0.11.5
lockfile==0.10.2
progress==1.2
ipaddress==1.0.7 # Only needed on 2.6, 2.7, and 3.2
packaging==15.2
ipaddress==1.0.14 # Only needed on 2.6, 2.7, and 3.2
packaging==15.3
retrying==1.3.3

View file

@ -4,12 +4,9 @@ from __future__ import absolute_import
import logging
import os
import sys
import traceback
import optparse
import warnings
from pip._vendor.six import StringIO
from pip import cmdoptions
from pip.locations import running_under_virtualenv
from pip.download import PipSession
@ -210,15 +207,6 @@ class Command(object):
)
sys.exit(VIRTUALENV_NOT_FOUND)
# 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)):
with self._build_session(
options,
retries=0,
timeout=min(5, options.timeout)) as session:
pip_version_check(session)
try:
status = self.run(options, args)
# FIXME: all commands should return an exit status
@ -227,28 +215,37 @@ class Command(object):
return status
except PreviousBuildDirError as exc:
logger.critical(str(exc))
logger.debug('Exception information:\n%s', format_exc())
logger.debug('Exception information:', exc_info=True)
return PREVIOUS_BUILD_DIR_ERROR
except (InstallationError, UninstallationError, BadCommand) as exc:
logger.critical(str(exc))
logger.debug('Exception information:\n%s', format_exc())
logger.debug('Exception information:', exc_info=True)
return ERROR
except CommandError as exc:
logger.critical('ERROR: %s', exc)
logger.debug('Exception information:\n%s', format_exc())
logger.debug('Exception information:', exc_info=True)
return ERROR
except KeyboardInterrupt:
logger.critical('Operation cancelled by user')
logger.debug('Exception information:\n%s', format_exc())
logger.debug('Exception information:', exc_info=True)
return ERROR
except:
logger.critical('Exception:\n%s', format_exc())
logger.critical('Exception:', exc_info=True)
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)):
with self._build_session(
options,
retries=0,
timeout=min(5, options.timeout)) as session:
pip_version_check(session)
return SUCCESS
@ -306,11 +303,3 @@ class RequirementCommand(Command):
msg = ('You must give at least one requirement '
'to %(name)s (see "pip help %(name)s")' % opts)
logger.warning(msg)
def format_exc(exc_info=None):
if exc_info is None:
exc_info = sys.exc_info()
out = StringIO()
traceback.print_exception(*exc_info, **dict(file=out))
return out.getvalue()

View file

@ -22,6 +22,7 @@ from pip import cmdoptions
from pip.utils import ensure_dir
from pip.utils.build import BuildDirectory
from pip.utils.deprecation import RemovedInPip8Warning
from pip.utils.filesystem import check_path_owner
from pip.wheel import WheelCache, WheelBuilder
@ -246,6 +247,17 @@ class InstallCommand(RequirementCommand):
finder = self._build_package_finder(options, index_urls, session)
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):
logger.warning(
"The directory '%s' or its parent directory is not owned "
"by the current user and caching wheels has been "
"disabled. check the permissions and owner of that "
"directory. If executing pip with sudo, you may want "
"sudo's -H flag.",
options.cache_dir,
)
options.cache_dir = None
with BuildDirectory(options.build_dir,
delete=build_delete) as build_dir:
requirement_set = RequirementSet(

View file

@ -193,8 +193,12 @@ def distutils_scheme(dist_name, user=False, home=None, root=None,
for key in SCHEME_KEYS:
scheme[key] = getattr(i, 'install_' + key)
if i.install_lib is not None:
# install_lib takes precedence over purelib and platlib
# install_lib specified in setup.cfg should install *everything*
# into there (i.e. it takes precedence over both purelib and
# platlib). Note, i.install_lib is *always* set after
# finalize_options(); we only want to override here if the user
# has explicitly requested it hence going back to the config
if 'install_lib' in d.get_option_dict('install'):
scheme.update(dict(purelib=i.install_lib, platlib=i.install_lib))
if running_under_virtualenv():

View file

@ -31,6 +31,7 @@ from pip.utils import (
display_path, rmtree, ask_path_exists, backup_dir, is_installable_dir,
dist_in_usersite, dist_in_site_packages, egg_link_path, make_path_relative,
call_subprocess, read_text_file, FakeFile, _make_build_dir, ensure_dir,
get_installed_version
)
from pip.utils.deprecation import RemovedInPip8Warning
from pip.utils.logging import indent_log
@ -259,6 +260,8 @@ class InstallRequirement(object):
self._link = link
else:
self._link = self._wheel_cache.cached_wheel(link, self.name)
if self._link != link:
logger.debug('Using cached wheel link: %s', self._link)
@property
def specifier(self):
@ -527,20 +530,7 @@ exec(compile(
@property
def installed_version(self):
# Create a requirement that we'll look for inside of setuptools.
req = pkg_resources.Requirement.parse(self.name)
# We want to avoid having this cached, so we need to construct a new
# working set each time.
working_set = pkg_resources.WorkingSet()
# Get the installed distribution from our working set
dist = working_set.find(req)
# Check to see if we got an installed distribution or not, if we did
# we want to return it's version.
if dist:
return dist.version
return get_installed_version(self.name)
def assert_source_matches_version(self):
assert self.source_dir

View file

@ -39,7 +39,8 @@ __all__ = ['rmtree', 'display_path', 'backup_dir',
'renames', 'get_terminal_size', 'get_prog',
'unzip_file', 'untar_file', 'unpack_file', 'call_subprocess',
'captured_stdout', 'remove_tracebacks', 'ensure_dir',
'ARCHIVE_EXTENSIONS', 'SUPPORTED_EXTENSIONS']
'ARCHIVE_EXTENSIONS', 'SUPPORTED_EXTENSIONS',
'get_installed_version']
logger = logging.getLogger(__name__)
@ -845,3 +846,20 @@ class cached_property(object):
return self
value = obj.__dict__[self.func.__name__] = self.func(obj)
return value
def get_installed_version(dist_name):
"""Get the installed version of dist_name avoiding pkg_resources cache"""
# Create a requirement that we'll look for inside of setuptools.
req = pkg_resources.Requirement.parse(dist_name)
# We want to avoid having this cached, so we need to construct a new
# working set each time.
working_set = pkg_resources.WorkingSet()
# Get the installed distribution from our working set
dist = working_set.find(req)
# Check to see if we got an installed distribution or not, if we did
# we want to return it's version.
return dist.version if dist else None

View file

@ -39,7 +39,7 @@ def indent_log(num=2):
def get_indentation():
return _log_state.indentation
return getattr(_log_state, 'indentation', 0)
class IndentingFormatter(logging.Formatter):

View file

@ -12,7 +12,7 @@ from pip._vendor.packaging import version as packaging_version
from pip.compat import total_seconds, WINDOWS
from pip.index import PyPI
from pip.locations import USER_CACHE_DIR, running_under_virtualenv
from pip.utils import ensure_dir
from pip.utils import ensure_dir, get_installed_version
from pip.utils.filesystem import check_path_owner
@ -99,7 +99,7 @@ def pip_version_check(session):
the active virtualenv or in the user's USER_CACHE_DIR keyed off the prefix
of the pip script path.
"""
import pip # imported here to prevent circular imports
pip_version = packaging_version.parse(get_installed_version('pip'))
pypi_version = None
try:
@ -133,7 +133,6 @@ def pip_version_check(session):
# save that we've performed a check
state.save(pypi_version, current_time)
pip_version = packaging_version.parse(pip.__version__)
remote_version = packaging_version.parse(pypi_version)
# Determine if our pypi_version is older
@ -148,7 +147,7 @@ def pip_version_check(session):
logger.warning(
"You are using pip version %s, however version %s is "
"available.\nYou should consider upgrading via the "
"'%s install --upgrade pip' command." % (pip.__version__,
"'%s install --upgrade pip' command." % (pip_version,
pypi_version,
pip_cmd)
)

View file

@ -753,7 +753,13 @@ class WheelBuilder(object):
for req in buildset:
if autobuilding:
output_dir = _cache_for_link(self._cache_root, req.link)
ensure_dir(output_dir)
try:
ensure_dir(output_dir)
except OSError as e:
logger.warn("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)

View file

@ -98,6 +98,9 @@ class TestDisutilsScheme:
scheme = distutils_scheme('example')
assert scheme['scripts'] == '/somewhere/else'
# when we request install-lib, we should install everything (.py &
# .so) into that path; i.e. ensure platlib & purelib are set to
# this path
def test_install_lib_takes_precedence(self, tmpdir, monkeypatch):
f = tmpdir.mkdir("config").join("setup.cfg")
f.write("[install]\ninstall-lib=/somewhere/else/")

View file

@ -7,7 +7,6 @@ import freezegun
import pytest
import pretend
import pip
from pip._vendor import lockfile
from pip.utils import outdated
@ -22,7 +21,7 @@ from pip.utils import outdated
]
)
def test_pip_version_check(monkeypatch, stored_time, newver, check, warn):
monkeypatch.setattr(pip, '__version__', '1.0')
monkeypatch.setattr(outdated, 'get_installed_version', lambda name: '1.0')
resp = pretend.stub(
raise_for_status=pretend.call_recorder(lambda: None),