wheel requirement checks with tests

This commit is contained in:
Marcus Smith 2013-04-05 14:21:11 -07:00
parent cf095c0c8f
commit f1fb4b4fda
5 changed files with 117 additions and 30 deletions

View File

@ -9,7 +9,7 @@ from pip.log import logger
from pip.exceptions import CommandError
from pip.req import InstallRequirement, RequirementSet, parse_requirements
from pip.util import normalize_path
from pip.wheel import WheelBuilder
from pip.wheel import WheelBuilder, wheel_distribute_support, distribute_requirement
from pip import cmdoptions
DEFAULT_WHEEL_DIR = os.path.join(normalize_path(os.curdir), 'wheelhouse')
@ -81,13 +81,15 @@ class WheelCommand(Command):
def run(self, options, args):
# requirements: py26, wheel, and distribute
if sys.version_info < (2, 6):
raise CommandError("'pip wheel' requires Python 2.6 or greater.")
try:
import wheel.bdist_wheel
except ImportError:
raise CommandError("'pip wheel' requires bdist_wheel from the 'wheel' distribution.")
if not wheel_distribute_support():
raise CommandError("'pip wheel' requires %s." % distribute_requirement)
index_urls = [options.index_url] + options.extra_index_urls
if options.no_index:

View File

@ -60,11 +60,17 @@ class PackageFinder(object):
else:
self.mirror_urls = []
self.use_wheel = use_wheel
if self.use_wheel:
if not pip.wheel.wheel_ok():
raise InstallationError("wheel runtime requirements not met.")
@property
def use_wheel(self):
return self._use_wheel
@use_wheel.setter
def use_wheel(self, value):
self._use_wheel = value
if self._use_wheel:
if not pip.wheel.wheel_distribute_support():
raise InstallationError("pip's wheel support requires %s." % pip.wheel.distribute_requirement)
def add_dependency_links(self, links):
## FIXME: this shouldn't be global list this, it should only

View File

@ -1389,8 +1389,6 @@ def parse_requirements(filename, finder=None, comes_from=None, options=None):
if finder:
finder.index_urls.append(line)
elif line.startswith('--use-wheel'):
if not pip.wheel.wheel_ok():
raise InstallationError("wheel runtime requirements not met.")
finder.use_wheel = True
elif line.startswith('--no-index'):
finder.index_urls = []

View File

@ -4,34 +4,35 @@ Support functions for installing and building the "wheel" binary package format.
from __future__ import with_statement
import csv
import os
import sys
import shutil
import functools
import hashlib
from pip.locations import distutils_scheme
from pip.log import logger
from pip.util import call_subprocess, normalize_path
import os
import pkg_resources
import shutil
import sys
from base64 import urlsafe_b64encode
from pip.util import make_path_relative
from pip.locations import distutils_scheme
from pip.log import logger
from pip.util import call_subprocess, normalize_path, make_path_relative
def wheel_ok(required_ver=None):
"""Return True if we have a distribute that supports wheel (.dist-info directories)."""
supported = False
if not required_ver:
import pkg_resources
required_ver = pkg_resources.Requirement.parse("distribute >= 0.6.34")
distribute_requirement = pkg_resources.Requirement.parse("distribute>=0.6.34")
def wheel_distribute_support(distribute_req=distribute_requirement):
"""
Return True if we have a distribute that supports wheel.
distribute_req: a pkg_resources.Requirement for distribute
"""
try:
installed_ver = pkg_resources.working_set.by_key['distribute']
supported = installed_ver in required_ver
except KeyError:
pass
installed_dist = pkg_resources.get_distribution('distribute')
supported = installed_dist in distribute_req
except pkg_resources.DistributionNotFound:
supported = False
if not supported:
logger.warn("%s is required for wheel installs.", required_ver)
logger.warn("%s is required for wheel installs.", distribute_req)
return supported
def rehash(path, algo='sha256', blocksize=1<<20):
"""Return (hash, length) for path using hashlib.new(algo)"""
h = hashlib.new(algo)

View File

@ -1,12 +1,17 @@
"""Tests for wheel binary packages and .dist-info."""
import os
import pkg_resources
import sys
import textwrap
from mock import patch
from nose import SkipTest
from pip.exceptions import InstallationError
from pip.index import PackageFinder
from pip import wheel
from pip.download import path_to_url as path_to_url_d
from tests.test_pip import here, reset_env, run_pip, pyversion_nodot, write_file, path_to_url
from tests.test_pip import (here, reset_env, run_pip, pyversion_nodot, write_file,
path_to_url, assert_raises_regexp)
FIND_LINKS = path_to_url(os.path.join(here, 'packages'))
@ -44,6 +49,26 @@ class TestPipWheel:
if sys.version_info < (2, 6):
raise SkipTest() #bdist_wheel fails in py25?
def test_pip_wheel_fails_without_wheel(self):
"""
Test 'pip wheel' fails without wheel
"""
env = reset_env(use_distribute=True)
result = run_pip('wheel', '--no-index', '-f', FIND_LINKS, 'simple==3.0', expect_error=True)
assert "'pip wheel' requires bdist_wheel" in result.stdout
def test_pip_wheel_setuptools_fails(self):
"""
Test 'pip wheel' fails with setuptools
"""
if sys.version_info >= (3, 0):
# virtualenv installs distribute in py3
raise SkipTest()
env = reset_env(use_distribute=False)
run_pip('install', 'wheel')
result = run_pip('wheel', '--no-index', '-f', FIND_LINKS, 'simple==3.0', expect_error=True)
assert "'pip wheel' requires %s" % wheel.distribute_requirement in result.stdout, result.stdout
def test_pip_wheel_success(self):
"""
Test 'pip wheel' success.
@ -111,3 +136,58 @@ class TestPipWheel:
assert wheel_file_path not in result.files_created, (wheel_file_path, result.files_created)
assert env.venv/'build'/'simple'/'setup.py' in result.files_created, result.files_created
class TestWheelSupported(object):
def raise_not_found(self, dist):
raise pkg_resources.DistributionNotFound()
def set_use_wheel_true(self, finder):
finder.use_wheel = True
@patch("pip.wheel.pkg_resources.get_distribution")
def test_wheel_supported_true(self, mock_get_distribution):
"""
Test wheel_supported returns true, when distribute is installed and requirement is met
"""
mock_get_distribution.return_value = pkg_resources.Distribution(project_name='distribute', version='0.6.34')
assert wheel.wheel_distribute_support()
@patch("pip.wheel.pkg_resources.get_distribution")
def test_wheel_supported_false_no_install(self, mock_get_distribution):
"""
Test wheel_supported returns false, when distribute not installed
"""
mock_get_distribution.side_effect = self.raise_not_found
assert not wheel.wheel_distribute_support()
@patch("pip.wheel.pkg_resources.get_distribution")
def test_wheel_supported_false_req_fail(self, mock_get_distribution):
"""
Test wheel_supported returns false, when distribute is installed, but req is not met
"""
mock_get_distribution.return_value = pkg_resources.Distribution(project_name='distribute', version='0.6.28')
assert not wheel.wheel_distribute_support()
@patch("pip.wheel.pkg_resources.get_distribution")
def test_finder_raises_error(self, mock_get_distribution):
"""
Test the PackageFinder raises an error when wheel is not supported
"""
mock_get_distribution.side_effect = self.raise_not_found
# on initialization
assert_raises_regexp(InstallationError, 'wheel support', PackageFinder, [], [], use_wheel=True)
# when setting property later
p = PackageFinder([], [])
assert_raises_regexp(InstallationError, 'wheel support', self.set_use_wheel_true, p)
@patch("pip.wheel.pkg_resources.get_distribution")
def test_finder_no_raises_error(self, mock_get_distribution):
"""
Test the PackageFinder doesn't raises an error when use_wheel is False, and wheel is supported
"""
mock_get_distribution.return_value = pkg_resources.Distribution(project_name='distribute', version='0.6.34')
p = PackageFinder( [], [], use_wheel=False)
p = PackageFinder([], [])
p.use_wheel = False