merged changes related to PEP 8 from hltbra's fork

This commit is contained in:
Hugo Lopes Tavares 2010-06-02 23:25:26 -03:00
parent 7854b2d266
commit d06c98dc6f
41 changed files with 527 additions and 323 deletions

View File

@ -11,6 +11,7 @@ from pip.basecommand import command_dict, load_command, load_all_commands
from pip.vcs import vcs, get_src_requirement, import_vcs_support
from pip.util import get_installed_distributions
def autocomplete():
"""Command and option completion for the main option parser (and options)
and its subcommands (and options).
@ -18,7 +19,7 @@ def autocomplete():
Enable by sourcing one of the completion shell scripts (bash or zsh).
"""
# Don't complete if user hasn't sourced bash_completion file.
if not os.environ.has_key('PIP_AUTO_COMPLETE'):
if 'PIP_AUTO_COMPLETE' not in os.environ:
return
cwords = os.environ['COMP_WORDS'].split()[1:]
cword = int(os.environ['COMP_CWORD'])
@ -75,6 +76,7 @@ def autocomplete():
print ' '.join(filter(lambda x: x.startswith(current), subcommands))
sys.exit(1)
def main(initial_args=None):
if initial_args is None:
initial_args = sys.argv[1:]

View File

@ -18,10 +18,12 @@ __all__ = ['command_dict', 'Command', 'load_all_commands',
command_dict = {}
class Command(object):
name = None
usage = None
hidden = False
def __init__(self):
assert self.name
self.parser = ConfigOptionParser(
@ -48,7 +50,7 @@ class Command(object):
def setup_logging(self):
pass
def main(self, complete_args, args, initial_options):
options, args = self.parser.parse_args(args)
self.merge_options(initial_options, options)
@ -65,7 +67,7 @@ class Command(object):
logger.explicit_levels = True
self.setup_logging()
if options.require_venv and not options.venv:
# If a venv is required check if it can really be found
if not os.environ.get('VIRTUAL_ENV'):
@ -141,6 +143,7 @@ class Command(object):
log_fp.close()
return exit
## FIXME: should get moved somewhere else:
def setup_proxy_handler(proxystr=''):
"""Set the proxy handler given the option passed on the command
@ -152,6 +155,7 @@ def setup_proxy_handler(proxystr=''):
opener = urllib2.build_opener(proxy_support, urllib2.CacheFTPHandler)
urllib2.install_opener(opener)
def get_proxy(proxystr=''):
"""Get the proxy given the option passed on the command line. If an
empty string is passed it looks at the HTTP_PROXY environment
@ -174,6 +178,7 @@ def get_proxy(proxystr=''):
else:
return None
def format_exc(exc_info=None):
if exc_info is None:
exc_info = sys.exc_info()
@ -181,6 +186,7 @@ def format_exc(exc_info=None):
traceback.print_exception(*exc_info, **dict(file=out))
return out.getvalue()
def open_logfile(filename, mode='a'):
"""Open the named log file in append mode.
@ -193,13 +199,14 @@ def open_logfile(filename, mode='a'):
if not os.path.exists(dirname):
os.makedirs(dirname)
exists = os.path.exists(filename)
log_fp = open(filename, mode)
if exists:
print >> log_fp, '-'*60
print >> log_fp, '%s run on %s' % (sys.argv[0], time.strftime('%c'))
return log_fp
def load_command(name):
full_name = 'pip.commands.%s' % name
if full_name in sys.modules:
@ -209,10 +216,12 @@ def load_command(name):
except ImportError:
pass
def load_all_commands():
for name in command_names():
load_command(name)
def command_names():
dir = os.path.join(os.path.dirname(__file__), 'commands')
names = []

View File

@ -8,6 +8,7 @@ import os
from distutils.util import strtobool
from pip.locations import default_config_file, default_log_file
class UpdatingDefaultsHelpFormatter(optparse.IndentedHelpFormatter):
"""Custom help formatter for use in ConfigOptionParser that updates
the defaults before expanding them, allowing them to show up correctly

View File

@ -4,6 +4,7 @@ from pip.log import logger
from pip.exceptions import InstallationError
from pip.commands.install import InstallCommand
class BundleCommand(InstallCommand):
name = 'bundle'
usage = '%prog [OPTIONS] BUNDLE_NAME.pybundle PACKAGE_NAMES...'
@ -28,4 +29,5 @@ class BundleCommand(InstallCommand):
requirement_set = super(BundleCommand, self).run(options, args)
return requirement_set
BundleCommand()

View File

@ -19,13 +19,13 @@ function _pip_completion {
local words cword
read -Ac words
read -cn cword
reply=( $( COMP_WORDS="$words[*]" \\
reply=( $( COMP_WORDS="$words[*]" \\
COMP_CWORD=$(( cword-1 )) \\
PIP_AUTO_COMPLETE=1 $words[1] ) )
}
compctl -K _pip_completion pip
"""
}
"""}
class CompletionCommand(Command):
name = 'completion'

View File

@ -7,6 +7,7 @@ from pip.log import logger
from pip.basecommand import Command
from pip.util import get_installed_distributions
class FreezeCommand(Command):
name = 'freeze'
usage = '%prog [OPTIONS]'
@ -37,7 +38,7 @@ class FreezeCommand(Command):
def setup_logging(self):
logger.move_stdout_to_stderr()
def run(self, options, args):
requirement = options.requirement
find_links = options.find_links or []
@ -104,4 +105,5 @@ class FreezeCommand(Command):
for installation in sorted(installations.values(), key=lambda x: x.name):
f.write(str(installation))
FreezeCommand()

View File

@ -2,6 +2,7 @@ from pip.basecommand import Command, command_dict, load_all_commands
from pip.exceptions import InstallationError
from pip.baseparser import parser
class HelpCommand(Command):
name = 'help'
usage = '%prog'
@ -27,4 +28,5 @@ class HelpCommand(Command):
continue
print ' %s: %s' % (command.name, command.summary)
HelpCommand()

View File

@ -6,6 +6,7 @@ from pip.locations import build_prefix, src_prefix
from pip.basecommand import Command
from pip.index import PackageFinder
class InstallCommand(Command):
name = 'install'
usage = '%prog [OPTIONS] PACKAGE_NAMES...'
@ -180,4 +181,5 @@ class InstallCommand(Command):
requirement_set.cleanup_files(bundle=self.bundle)
return requirement_set
InstallCommand()

View File

@ -7,6 +7,7 @@ from pip.util import get_terminal_size
from pip.log import logger
from distutils.version import StrictVersion, LooseVersion
class SearchCommand(Command):
name = 'search'
usage = '%prog QUERY'
@ -42,6 +43,7 @@ class SearchCommand(Command):
hits = pypi.search({'name': query, 'summary': query}, 'or')
return hits
def transform_hits(hits):
"""
The list from pypi is really a list of versions. We want a list of
@ -69,6 +71,7 @@ def transform_hits(hits):
package_list = sorted(packages.values(), lambda x, y: cmp(y['score'], x['score']))
return package_list
def print_results(hits, name_column_width=25, terminal_width=None):
installed_packages = [p.project_name for p in pkg_resources.working_set]
for hit in hits:
@ -96,6 +99,7 @@ def print_results(hits, name_column_width=25, terminal_width=None):
except UnicodeEncodeError:
pass
def compare_versions(version1, version2):
try:
return cmp(StrictVersion(version1), StrictVersion(version2))
@ -103,7 +107,9 @@ def compare_versions(version1, version2):
except ValueError:
return cmp(LooseVersion(version1), LooseVersion(version2))
def highest_version(versions):
return reduce((lambda v1, v2: compare_versions(v1, v2) == 1 and v1 or v2), versions)
SearchCommand()

View File

@ -2,6 +2,7 @@ from pip.req import InstallRequirement, RequirementSet
from pip.req import parse_requirements
from pip.basecommand import Command
class UninstallCommand(Command):
name = 'uninstall'
usage = '%prog [OPTIONS] PACKAGE_NAMES ...'

View File

@ -1,7 +1,9 @@
from pip.commands.zip import ZipCommand
class UnzipCommand(ZipCommand):
name = 'unzip'
summary = 'Unzip individual packages'
UnzipCommand()

View File

@ -9,6 +9,7 @@ from pip.log import logger
from pip.exceptions import InstallationError
from pip.basecommand import Command
class ZipCommand(Command):
name = 'zip'
usage = '%prog [OPTIONS] PACKAGE_NAMES...'
@ -263,7 +264,7 @@ class ZipCommand(Command):
if not os.path.isdir(path) and zipfile.is_zipfile(path):
zip = zipfile.ZipFile(path, 'r')
try:
zip.read(os.path.join(package,'__init__.py'))
zip.read(os.path.join(package, '__init__.py'))
except KeyError:
pass
else:
@ -341,4 +342,5 @@ class ZipCommand(Command):
total += len(filenames)
return total
ZipCommand()

View File

@ -1,13 +1,17 @@
"""Exceptions used throughout package"""
class InstallationError(Exception):
"""General exception during installation"""
class UninstallationError(Exception):
"""General exception during uninstallation"""
class DistributionNotFound(InstallationError):
"""Raised when a distribution cannot be found to satisfy a requirement"""
class BadCommand(Exception):
"""Raised when virtualenv or a command is not found"""

View File

@ -21,6 +21,7 @@ from pip.backwardcompat import WindowsError
__all__ = ['PackageFinder']
class PackageFinder(object):
"""This finds packages.
@ -77,7 +78,6 @@ class PackageFinder(object):
urls.append(url)
return files, urls
def find_requirement(self, req, upgrade):
url_name = req.url_name
# Only check main index if index URL is given:
@ -89,8 +89,9 @@ class PackageFinder(object):
page = self._get_page(main_index_url, req)
if page is None:
url_name = self._find_url_name(Link(self.index_urls[0]), url_name, req) or req.url_name
def mkurl_pypi_url(url):
loc = posixpath.join(url, url_name)
loc = posixpath.join(url, url_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
@ -331,6 +332,7 @@ class PageCache(object):
for url in urls:
self._pages[url] = page
class HTMLPage(object):
"""Represents one page, along with its URL"""
@ -385,7 +387,7 @@ class HTMLPage(object):
cache.set_is_archive(url)
return None
logger.debug('Getting page %s' % url)
# Tack index.html onto file:// URLs that point to directories
(scheme, netloc, path, params, query, fragment) = urlparse.urlparse(url)
if scheme == 'file' and os.path.isdir(urllib.url2pathname(path)):
@ -517,6 +519,7 @@ class HTMLPage(object):
return self._clean_re.sub(
lambda match: '%%%2x' % ord(match.group(0)), url)
class Link(object):
def __init__(self, url, comes_from=None):
@ -582,6 +585,7 @@ class Link(object):
def show_url(self):
return posixpath.basename(self.url.split('#', 1)[0].split('?', 1)[0])
def get_requirement_from_url(url):
"""Get a requirement from the URL, if possible. This looks for #egg
in the URL"""
@ -591,6 +595,7 @@ def get_requirement_from_url(url):
egg_info = splitext(link.filename)[0]
return package_to_requirement(egg_info)
def package_to_requirement(package_name):
"""Translate a name like Foo-1.2 to Foo==1.3"""
match = re.search(r'^(.*?)(-dev|-\d.*)', package_name)

View File

@ -4,6 +4,7 @@
import sys
import logging
class Logger(object):
"""
@ -30,16 +31,22 @@ class Logger(object):
def debug(self, msg, *args, **kw):
self.log(self.DEBUG, msg, *args, **kw)
def info(self, msg, *args, **kw):
self.log(self.INFO, msg, *args, **kw)
def notify(self, msg, *args, **kw):
self.log(self.NOTIFY, msg, *args, **kw)
def warn(self, msg, *args, **kw):
self.log(self.WARN, msg, *args, **kw)
def error(self, msg, *args, **kw):
self.log(self.WARN, msg, *args, **kw)
def fatal(self, msg, *args, **kw):
self.log(self.FATAL, msg, *args, **kw)
def log(self, level, msg, *args, **kw):
if args:
if kw:

View File

@ -30,6 +30,7 @@ from pip import call_subprocess
from pip.backwardcompat import any, md5
from pip.index import Link
class InstallRequirement(object):
def __init__(self, req, comes_from, source_dir=None, editable=False,
@ -695,6 +696,7 @@ execfile(__file__)
assert self.source_dir
return os.path.join(self.source_dir, 'pip-delete-this-directory.txt')
DELETE_MARKER_MESSAGE = '''\
This file is placed here by pip to indicate the source was put
here by pip.
@ -703,6 +705,7 @@ Once this package is successfully installed this source code will be
deleted (unless you remove this file).
'''
class RequirementSet(object):
def __init__(self, build_dir, src_dir, download_dir, download_cache=None,
@ -1334,8 +1337,10 @@ class RequirementSet(object):
name = name.replace(os.path.sep, '/')
return name
_scheme_re = re.compile(r'^(http|https|file):', re.I)
def parse_requirements(filename, finder=None, comes_from=None, options=None):
skip_match = None
skip_regex = options.skip_requirements_regex
@ -1372,16 +1377,19 @@ def parse_requirements(filename, finder=None, comes_from=None, options=None):
line = line[len('--find-links'):].strip().lstrip('=')
## FIXME: it would be nice to keep track of the source of
## the find_links:
if finder: finder.find_links.append(line)
if finder:
finder.find_links.append(line)
elif line.startswith('-i') or line.startswith('--index-url'):
if line.startswith('-i'):
line = line[2:].strip()
else:
line = line[len('--index-url'):].strip().lstrip('=')
if finder: finder.index_urls = [line]
if finder:
finder.index_urls = [line]
elif line.startswith('--extra-index-url'):
line = line[len('--extra-index-url'):].strip().lstrip('=')
if finder: finder.index_urls.append(line)
if finder:
finder.index_urls.append(line)
else:
comes_from = '-r %s (line %s)' % (filename, line_number)
if line.startswith('-e') or line.startswith('--editable'):
@ -1395,6 +1403,7 @@ def parse_requirements(filename, finder=None, comes_from=None, options=None):
req = InstallRequirement.from_line(line, comes_from)
yield req
def parse_editable(editable_req, default_vcs=None):
"""Parses svn+http://blahblah@rev#egg=Foobar into a requirement
(Foobar) and a URL"""
@ -1437,6 +1446,7 @@ def parse_editable(editable_req, default_vcs=None):
req = match.group(1)
return req, url
class UninstallPathSet(object):
"""A set of file paths to be removed in the uninstallation of a
requirement."""
@ -1498,7 +1508,6 @@ class UninstallPathSet(object):
return os.path.join(
self.save_dir, os.path.splitdrive(path)[1].lstrip(os.path.sep))
def remove(self, auto_confirm=False):
"""Remove paths in ``self.paths`` with confirmation (unless
``auto_confirm`` is True)."""
@ -1569,7 +1578,7 @@ class UninstallPthEntries(object):
# paths outside of site-packages, but all the others use forward
# slashes.
if sys.platform == 'win32' and not os.path.splitdrive(entry)[0]:
entry = entry.replace('\\','/')
entry = entry.replace('\\', '/')
self.entries.add(entry)
def remove(self):
@ -1601,6 +1610,7 @@ class UninstallPthEntries(object):
fh.close()
return True
class FakeFile(object):
"""Wrap a list of lines in an object with readline() to make
ConfigParser happy."""

View File

@ -1,6 +1,7 @@
import sys
import os
def run():
base = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
## FIXME: this is kind of crude; if we could create a fake pip
@ -10,6 +11,7 @@ def run():
import pip
return pip.main()
if __name__ == '__main__':
exit = run()
if exit:

View File

@ -23,10 +23,12 @@ __all__ = ['rmtree', 'display_path', 'backup_dir',
'make_path_relative', 'normalize_path',
'get_file_content', 'renames', 'get_terminal_size']
def rmtree(dir):
shutil.rmtree(dir, ignore_errors=True,
onerror=rmtree_errorhandler)
def rmtree_errorhandler(func, path, exc_info):
"""On Windows, the files in .svn are read-only, so when rmtree() tries to
remove them, an exception is thrown. We catch that here, remove the
@ -43,6 +45,7 @@ def rmtree_errorhandler(func, path, exc_info):
# use the original function to repeat the operation
func(path)
def display_path(path):
"""Gives the display value for a given path, making it relative to cwd
if possible."""
@ -51,6 +54,7 @@ def display_path(path):
path = '.' + path[len(os.getcwd()):]
return path
def backup_dir(dir, ext='.bak'):
"""Figure out the name of a directory to back up the given dir to
(adding .bak, .bak2, etc)"""
@ -61,6 +65,7 @@ def backup_dir(dir, ext='.bak'):
extension = ext + str(n)
return dir + extension
def splitext(path):
"""Like os.path.splitext, but take off .tar too"""
base, ext = posixpath.splitext(path)
@ -69,6 +74,7 @@ def splitext(path):
base = base[:-4]
return base, ext
def find_command(cmd, paths=None, pathext=None):
"""Searches the PATH for the given command and returns its path"""
if paths is None:
@ -95,6 +101,7 @@ def find_command(cmd, paths=None, pathext=None):
return cmd_path
return None
def ask(message, options):
"""Ask the message interactively, with the given possible responses"""
while 1:
@ -108,14 +115,17 @@ def ask(message, options):
else:
return response
class _Inf(object):
"""I am bigger than everything!"""
def __cmp__(self, a):
if self is a:
return 0
return 1
def __repr__(self):
return 'Inf'
Inf = _Inf()
del _Inf
@ -134,9 +144,11 @@ def url_to_path(url):
path = '/' + path
return path
_drive_re = re.compile('^([a-z]):', re.I)
_url_drive_re = re.compile('^([a-z])[:|]', re.I)
def path_to_url(path):
"""
Convert a path to a file: URL. The path will be made absolute.
@ -149,6 +161,7 @@ def path_to_url(path):
url = url.lstrip('/')
return 'file:///' + url
def path_to_url2(path):
"""
Convert a path to a file: URL. The path will be made absolute and have
@ -162,11 +175,14 @@ def path_to_url2(path):
url = url.lstrip('/')
return 'file:///' + drive + url
_normalize_re = re.compile(r'[^a-z]', re.I)
def normalize_name(name):
return _normalize_re.sub('-', name.lower())
def format_size(bytes):
if bytes > 1000*1000:
return '%.1fMb' % (bytes/1000.0/1000)
@ -177,6 +193,7 @@ def format_size(bytes):
else:
return '%ibytes' % bytes
def is_url(name):
"""Returns true if the name looks like a URL"""
from pip.vcs import vcs
@ -185,6 +202,7 @@ def is_url(name):
scheme = name.split(':', 1)[0].lower()
return scheme in ['http', 'https', 'file', 'ftp'] + vcs.all_schemes
def is_installable_dir(path):
"""Return True if `path` is a directory containing a setup.py file."""
if not os.path.isdir(path):
@ -194,6 +212,7 @@ def is_installable_dir(path):
return True
return False
def is_archive_file(name):
"""Return True if `name` is a considered as an archive file."""
archives = ('.zip', '.tar.gz', '.tar.bz2', '.tgz', '.tar', '.pybundle')
@ -202,11 +221,13 @@ def is_archive_file(name):
return True
return False
def is_svn_page(html):
"""Returns true if the page appears to be the index page of an svn repository"""
return (re.search(r'<title>[^<]*Revision \d+:', html)
and re.search(r'Powered by (?:<a[^>]*?>)?Subversion', html, re.I))
def file_contents(filename):
fp = open(filename, 'rb')
try:
@ -214,6 +235,7 @@ def file_contents(filename):
finally:
fp.close()
def split_leading_dir(path):
path = str(path)
path = path.lstrip('/').lstrip('\\')
@ -225,6 +247,7 @@ def split_leading_dir(path):
else:
return path, ''
def has_leading_dir(paths):
"""Returns true if all the paths have the same leading path name
(i.e., everything is in one subdirectory in an archive)"""
@ -239,6 +262,7 @@ def has_leading_dir(paths):
return False
return True
def make_path_relative(path, rel_to):
"""
Make a filename relative, where the filename path, and it is
@ -267,6 +291,7 @@ def make_path_relative(path, rel_to):
return '.' + os.path.sep
return os.path.sep.join(full_parts)
def normalize_path(path):
"""
Convert a path to its canonical, case-normalized, absolute version.
@ -274,9 +299,11 @@ def normalize_path(path):
"""
return os.path.normcase(os.path.realpath(path))
_scheme_re = re.compile(r'^(http|https|file):', re.I)
_url_slash_drive_re = re.compile(r'/*([a-z])\|', re.I)
def geturl(urllib2_resp):
"""
Use instead of urllib.addinfourl.geturl(), which appears to have
@ -293,6 +320,7 @@ def geturl(urllib2_resp):
else:
return '%s//%s' % (scheme, rest)
def get_file_content(url, comes_from=None):
"""Gets the content of a file; it may be a filename, file: URL, or
http: URL. Returns (location, content)"""
@ -323,6 +351,7 @@ def get_file_content(url, comes_from=None):
f.close()
return url, content
def renames(old, new):
"""Like os.renames(), but handles renaming across devices."""
# Implementation borrowed from os.renames().
@ -339,6 +368,7 @@ def renames(old, new):
except OSError:
pass
def in_venv():
"""
Return True if we're running inside a virtualenv, False otherwise.
@ -346,6 +376,7 @@ def in_venv():
"""
return hasattr(sys, 'real_prefix')
def is_local(path):
"""
Return True if path is within sys.prefix, if we're running in a virtualenv.
@ -357,6 +388,7 @@ def is_local(path):
return True
return normalize_path(path).startswith(normalize_path(sys.prefix))
def dist_is_local(dist):
"""
Return True if given Distribution object is installed locally
@ -367,6 +399,7 @@ def dist_is_local(dist):
"""
return is_local(dist_location(dist))
def get_installed_distributions(local_only=True, skip=('setuptools', 'pip', 'python')):
"""
Return a list of installed Distribution objects.
@ -385,6 +418,7 @@ def get_installed_distributions(local_only=True, skip=('setuptools', 'pip', 'pyt
local_test = lambda d: True
return [d for d in pkg_resources.working_set if local_test(d) and d.key not in skip]
def egg_link_path(dist):
"""
Return the path where we'd expect to find a .egg-link file for
@ -398,6 +432,7 @@ def egg_link_path(dist):
"""
return os.path.join(site_packages, dist.project_name) + '.egg-link'
def dist_location(dist):
"""
Get the site-packages location of this distribution. Generally
@ -411,12 +446,15 @@ def dist_location(dist):
return egg_link
return dist.location
def get_terminal_size():
"""Returns a tuple (x, y) representing the width(x) and the height(x)
in characters of the terminal window."""
def ioctl_GWINSZ(fd):
try:
import fcntl, termios, struct
import fcntl
import termios
import struct
cr = struct.unpack('hh', fcntl.ioctl(fd, termios.TIOCGWINSZ,
'1234'))
except:
@ -434,9 +472,10 @@ def get_terminal_size():
cr = (os.environ.get('LINES', 25), os.environ.get('COLUMNS', 80))
return int(cr[1]), int(cr[0])
# Insurance against "creative" interpretation of the RFC:
# http://bugs.python.org/issue8732
def urlopen(url):
if isinstance(url, basestring):
url = urllib2.Request(url, headers={'Accept-encoding':'identity'})
url = urllib2.Request(url, headers={'Accept-encoding': 'identity'})
return urllib2.urlopen(url)

View File

@ -10,6 +10,7 @@ from pip.log import logger
__all__ = ['vcs', 'get_source_requirement', 'import_vcs_support']
class VcsSupport(object):
_registry = {}
schemes = ['ssh', 'git', 'hg', 'bzr', 'sftp']
@ -75,8 +76,8 @@ class VcsSupport(object):
return self.get_backend(vc_type)
return None
vcs = VcsSupport()
vcs = VcsSupport()
class VersionControl(object):
@ -218,6 +219,7 @@ class VersionControl(object):
def get_src_requirement(self, dist, location, find_tags=False):
raise NotImplementedError
def get_src_requirement(dist, location, find_tags):
version_control = vcs.get_backend_from_location(location)
if version_control:
@ -225,6 +227,7 @@ def get_src_requirement(dist, location, find_tags):
logger.warn('cannot determine version of editable source in %s (is not SVN checkout, Git clone, Mercurial clone or Bazaar branch)' % location)
return dist.as_requirement()
def import_vcs_support():
# Import all the version control support modules:
here = os.path.dirname(__file__)

View File

@ -7,6 +7,7 @@ from pip.log import logger
from pip.util import rmtree, display_path
from pip.vcs import vcs, VersionControl
class Bazaar(VersionControl):
name = 'bzr'
dirname = '.bzr'
@ -130,4 +131,5 @@ class Bazaar(VersionControl):
full_egg_name = '%s-dev_r%s' % (dist.egg_name(), current_rev)
return '%s@%s#egg=%s' % (repo, current_rev, full_egg_name)
vcs.register(Bazaar)

View File

@ -9,6 +9,7 @@ from pip.log import logger
from urllib import url2pathname
from urlparse import urlsplit, urlunsplit
class Git(VersionControl):
name = 'git'
dirname = '.git'
@ -23,15 +24,15 @@ class Git(VersionControl):
# Works around an apparent Git bug
# (see http://article.gmane.org/gmane.comp.version-control.git/146500)
if url:
scheme,netloc,path,query,fragment = urlsplit(url)
scheme, netloc, path, query, fragment = urlsplit(url)
if scheme.endswith('file'):
initial_slashes = path[:-len(path.lstrip('/'))]
newpath = initial_slashes + url2pathname(path).replace('\\','/').lstrip('/')
newpath = initial_slashes + 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))
super(Git,self).__init__(url, *args, **kwargs)
super(Git, self).__init__(url, *args, **kwargs)
def parse_vcs_bundle_file(self, content):
url = rev = None
@ -86,7 +87,7 @@ class Git(VersionControl):
if rev in revisions:
# if rev is a sha
return [rev]
inverse_revisions = dict((v,k) for k, v in revisions.iteritems())
inverse_revisions = dict((v, k) for k, v in revisions.iteritems())
if rev not in inverse_revisions: # is rev a name or tag?
origin_rev = 'origin/%s' % rev
if origin_rev in inverse_revisions:
@ -197,9 +198,10 @@ class Git(VersionControl):
self.url = self.url.replace('git+', 'git+ssh://')
url, rev = super(Git, self).get_url_rev()
url = url.replace('ssh://', '')
else:
else:
url, rev = super(Git, self).get_url_rev()
return url,rev
return url, rev
vcs.register(Git)

View File

@ -11,6 +11,7 @@ _svn_rev_re = re.compile('committed-rev="(\d+)"')
_svn_url_re = re.compile(r'URL: (.+)')
_svn_revision_re = re.compile(r'Revision: (.+)')
class Subversion(VersionControl):
name = 'svn'
dirname = '.svn'
@ -140,7 +141,7 @@ class Subversion(VersionControl):
f.close()
if data.startswith('8') or data.startswith('9') or data.startswith('10'):
data = map(str.splitlines,data.split('\n\x0c\n'))
data = map(str.splitlines, data.split('\n\x0c\n'))
del data[0][0] # get rid of the '8'
dirurl = data[0][3]
revs = [int(d[9]) for d in data if len(d)>9 and d[9]]+[0]
@ -190,7 +191,7 @@ class Subversion(VersionControl):
data = f.read()
f.close()
if data.startswith('8') or data.startswith('9') or data.startswith('10'):
data = map(str.splitlines,data.split('\n\x0c\n'))
data = map(str.splitlines, data.split('\n\x0c\n'))
del data[0][0] # get rid of the '8'
return data[0][3]
elif data.startswith('<?xml'):

View File

@ -6,6 +6,7 @@ import subprocess
from pip.exceptions import BadCommand
from pip.log import logger
def restart_in_venv(venv, base, site_packages, args):
"""
Restart this script using the interpreter in the given virtual environment

View File

@ -32,5 +32,4 @@ setup(name='pip',
license='MIT',
packages=['pip', 'pip.commands', 'pip.vcs'],
entry_points=dict(console_scripts=['pip=pip:main']),
zip_safe=False
)
zip_safe=False)

View File

@ -1,12 +1,14 @@
import sys, os
from subprocess import check_call, PIPE
from path import Path
import shutil
from tempfile import mkdtemp, gettempdir
from test_pip import create_virtualenv
import sys
import os
import shutil
exe = sys.platform == 'win32' and '.EXE' or ''
def rmtree(path):
# From pathutils by Michael Foord: http://www.voidspace.org.uk/python/pathutils.html
def onerror(func, path, exc_info):
@ -32,9 +34,11 @@ def rmtree(path):
if Path(path).exists:
shutil.rmtree(path, onerror=onerror)
def system(*args):
check_call(args, stdout=PIPE, shell=(sys.platform=='win32'))
def call(*args):
if not '--distribute' in sys.argv:
check_call(args)
@ -43,9 +47,11 @@ def call(*args):
env['PIP_TEST_USE_DISTRIBUTE']='1'
check_call(args, env=env)
def assert_in_path(exe):
system(exe, '--version')
def clean(root):
print >> sys.stderr, 'Cleaning ...',
for dirpath, dirnames, filenames in os.walk(root):
@ -57,8 +63,10 @@ def clean(root):
rmtree(root/'pip.egg-info')
rmtree(root/'tests'/'test-scratch')
rmtree(root/'tests'/'test-cache')
try: os.unlink(root/'tests'/'packages'/'FSPkg'/'FSPkg.egg-info'/'PKG-INFO')
except: pass
try:
os.unlink(root/'tests'/'packages'/'FSPkg'/'FSPkg.egg-info'/'PKG-INFO')
except:
pass
print >> sys.stderr, 'ok'
@ -73,7 +81,7 @@ def main(argv):
# Make sure all external tools are set up to be used.
print >> sys.stderr, 'Checking for installed prerequisites in PATH:',
for tool in 'git', 'hg', 'bzr', 'svn':
print >> sys.stderr, tool,'...',
print >> sys.stderr, tool, '...',
assert_in_path(tool)
print >> sys.stderr, 'ok'
@ -82,8 +90,8 @@ def main(argv):
#
# Delete everything that could lead to stale test results
#
clean( pip_root )
clean(pip_root)
save_dir = os.getcwd()
temp_dir = mkdtemp('-pip_auto_test')
try:
@ -99,8 +107,7 @@ def main(argv):
# Make sure it's first in PATH
os.environ['PATH'] = str(
Path.pathsep.join(( abs_bin, os.environ['PATH'] ))
)
Path.pathsep.join((abs_bin, os.environ['PATH'])))
#
# Install python module testing prerequisites
@ -108,16 +115,18 @@ def main(argv):
pip = abs_bin/'pip'+exe
download_cache = '--download-cache=' \
+ Path(gettempdir())/'pip-test-download-cache'
def pip_install(*pkg):
print >> sys.stderr, ' pip install',' '.join(pkg), '...',
print >> sys.stderr, ' pip install', ' '.join(pkg), '...',
call(pip, 'install', '-q', download_cache, *pkg)
print >> sys.stderr, 'ok'
pip_install('virtualenv')
pip_install('--no-index', '-f', 'http://pypi.python.org/packages/source/n/nose/', 'nose')
pip_install('scripttest>=1.0.4')
print >> sys.stderr, 'ok'
nosetests = abs_bin/'nosetests'+exe
call( nosetests, '-w', pip_root/'tests', *(x for x in argv[1:] if x != '--distribute') )
call(nosetests, '-w', pip_root/'tests', *(x for x in argv[1:] if x != '--distribute'))
finally:
os.chdir(save_dir)
@ -127,4 +136,4 @@ def main(argv):
if __name__ == '__main__':
main( sys.argv )
main(sys.argv)

View File

@ -1,194 +1,194 @@
# -*- coding: utf-8 -*-
# Author: Aziz Köksal
import os, shutil, sys
import os
import shutil
import sys
_base = os.path.supports_unicode_filenames and unicode or str
class Path(_base):
""" Models a path in an object oriented way. """
sep = os.sep # File system path separator: '/' or '\'.
pathsep = os.pathsep # Separator in the PATH environment variable.
string = _base
""" Models a path in an object oriented way. """
def __new__(cls, *paths):
if len(paths):
return _base.__new__(cls, os.path.join(*paths))
return _base.__new__(cls)
sep = os.sep # File system path separator: '/' or '\'.
pathsep = os.pathsep # Separator in the PATH environment variable.
string = _base
def __div__(self, path):
""" Joins this path with another path. """
""" path_obj / 'bc.d' """
""" path_obj / path_obj2 """
return Path(self, path)
def __new__(cls, *paths):
if len(paths):
return _base.__new__(cls, os.path.join(*paths))
return _base.__new__(cls)
def __rdiv__(self, path):
""" Joins this path with another path. """
""" "/home/a" / path_obj """
return Path(path, self)
def __div__(self, path):
""" Joins this path with another path. """
""" path_obj / 'bc.d' """
""" path_obj / path_obj2 """
return Path(self, path)
def __idiv__(self, path):
""" Like __div__ but also assigns to the variable. """
""" path_obj /= 'bc.d' """
return Path(self, path)
def __rdiv__(self, path):
""" Joins this path with another path. """
""" "/home/a" / path_obj """
return Path(path, self)
def __floordiv__(self, paths):
""" Returns a list of paths prefixed with 'self'. """
""" '/home/a' // [bc.d, ef.g] -> [/home/a/bc.d, /home/a/ef.g] """
return [Path(self, path) for path in paths]
def __idiv__(self, path):
""" Like __div__ but also assigns to the variable. """
""" path_obj /= 'bc.d' """
return Path(self, path)
def __floordiv__(self, paths):
""" Returns a list of paths prefixed with 'self'. """
""" '/home/a' // [bc.d, ef.g] -> [/home/a/bc.d, /home/a/ef.g] """
return [Path(self, path) for path in paths]
def __sub__(self, path):
""" Makes this path relative to another path. """
""" path_obj - '/home/a' """
""" path_obj - path_obj2 """
return Path(os.path.relpath(self, path))
def __sub__(self, path):
""" Makes this path relative to another path. """
""" path_obj - '/home/a' """
""" path_obj - path_obj2 """
return Path(os.path.relpath(self, path))
def __rsub__(self, path):
""" Returns path relative to this path. """
""" "/home/a" - path_obj """
return Path(os.path.relpath(path, self))
def __rsub__(self, path):
""" Returns path relative to this path. """
""" "/home/a" - path_obj """
return Path(os.path.relpath(path, self))
def __add__(self, path):
""" Path('/home/a') + 'bc.d' -> '/home/abc.d' """
return Path(_base(self) + path)
def __radd__(self, path):
""" '/home/a' + Path('bc.d') -> '/home/abc.d' """
return Path(path + _base(self))
def __add__(self, path):
""" Path('/home/a') + 'bc.d' -> '/home/abc.d' """
return Path(_base(self) + path)
def __repr__(self):
return u"Path(%s)" % _base.__repr__(self)
def __radd__(self, path):
""" '/home/a' + Path('bc.d') -> '/home/abc.d' """
return Path(path + _base(self))
def __hash__(self):
return _base.__hash__(self)
def __repr__(self):
return u"Path(%s)" % _base.__repr__(self)
@property
def name(self):
""" '/home/a/bc.d' -> 'bc.d' """
return os.path.basename(self)
def __hash__(self):
return _base.__hash__(self)
@property
def namebase(self):
""" '/home/a/bc.d' -> 'bc' """
return self.noext.name
@property
def name(self):
""" '/home/a/bc.d' -> 'bc.d' """
return os.path.basename(self)
@property
def noext(self):
""" '/home/a/bc.d' -> '/home/a/bc' """
return Path(os.path.splitext(self)[0])
@property
def namebase(self):
""" '/home/a/bc.d' -> 'bc' """
return self.noext.name
@property
def ext(self):
""" '/home/a/bc.d' -> '.d' """
return Path(os.path.splitext(self)[1])
@property
def noext(self):
""" '/home/a/bc.d' -> '/home/a/bc' """
return Path(os.path.splitext(self)[0])
@property
def abspath(self):
""" './a/bc.d' -> '/home/a/bc.d' """
return Path(os.path.abspath(self))
@property
def ext(self):
""" '/home/a/bc.d' -> '.d' """
return Path(os.path.splitext(self)[1])
@property
def realpath(self):
""" Resolves symbolic links. """
return Path(os.path.realpath(self))
@property
def abspath(self):
""" './a/bc.d' -> '/home/a/bc.d' """
return Path(os.path.abspath(self))
@property
def normpath(self):
""" '/home/x/.././a//bc.d' -> '/home/a/bc.d' """
return Path(os.path.normpath(self))
@property
def realpath(self):
""" Resolves symbolic links. """
return Path(os.path.realpath(self))
@property
def normcase(self):
""" Deals with case-insensitive filesystems """
return Path(os.path.normcase(self))
@property
def normpath(self):
""" '/home/x/.././a//bc.d' -> '/home/a/bc.d' """
return Path(os.path.normpath(self))
@property
def folder(self):
""" Returns the folder of this path. """
""" '/home/a/bc.d' -> '/home/a' """
""" '/home/a/' -> '/home/a' """
""" '/home/a' -> '/home' """
return Path(os.path.dirname(self))
@property
def normcase(self):
""" Deals with case-insensitive filesystems """
return Path(os.path.normcase(self))
@property
def exists(self):
""" Returns True if the path exists. """
return os.path.exists(self)
@property
def folder(self):
""" Returns the folder of this path. """
""" '/home/a/bc.d' -> '/home/a' """
""" '/home/a/' -> '/home/a' """
""" '/home/a' -> '/home' """
return Path(os.path.dirname(self))
@property
def atime(self):
""" Returns last accessed time. """
return os.path.getatime(self)
@property
def exists(self):
""" Returns True if the path exists. """
return os.path.exists(self)
@property
def mtime(self):
""" Returns last modified time. """
return os.path.getmtime(self)
@property
def atime(self):
""" Returns last accessed time. """
return os.path.getatime(self)
@property
def ctime(self):
""" Returns last changed time. """
return os.path.getctime(self)
@property
def mtime(self):
""" Returns last modified time. """
return os.path.getmtime(self)
@classmethod
def supports_unicode(self):
""" Returns True if the system can handle Unicode file names. """
return os.path.supports_unicode_filenames()
@property
def ctime(self):
""" Returns last changed time. """
return os.path.getctime(self)
def walk(self, **kwargs):
""" Returns a generator that walks through a directory tree. """
if "followlinks" in kwargs:
from sys import version_info as vi
if vi[0]*10+vi[1] < 26: # Only Python 2.6 or newer supports followlinks
del kwargs["followlinks"]
return os.walk(self, **kwargs)
@classmethod
def supports_unicode(self):
""" Returns True if the system can handle Unicode file names. """
return os.path.supports_unicode_filenames()
def mkdir(self, mode=0777):
""" Creates a directory, if it doesn't exist already. """
if not self.exists:
os.mkdir(self, mode)
def walk(self, **kwargs):
""" Returns a generator that walks through a directory tree. """
if "followlinks" in kwargs:
from sys import version_info as vi
if vi[0]*10+vi[1] < 26: # Only Python 2.6 or newer supports followlinks.
del kwargs["followlinks"]
return os.walk(self, **kwargs)
def makedirs(self, mode=0777):
""" Like mkdir(), but also creates parent directories. """
if not self.exists:
os.makedirs(self, mode)
def mkdir(self, mode=0777):
""" Creates a directory, if it doesn't exist already. """
if not self.exists:
os.mkdir(self, mode)
def remove(self):
""" Removes a file. """
os.remove(self)
rm = remove # Alias.
def makedirs(self, mode=0777):
""" Like mkdir(), but also creates parent directories. """
if not self.exists:
os.makedirs(self, mode)
def rmdir(self):
""" Removes a directory. """
return os.rmdir(self)
def remove(self):
""" Removes a file. """
os.remove(self)
rm = remove # Alias.
def rmtree(self, noerrors=True):
""" Removes a directory tree. Ignores errors by default. """
return shutil.rmtree(self, ignore_errors=noerrors)
def rmdir(self):
""" Removes a directory. """
return os.rmdir(self)
def copy(self, to):
shutil.copy(self, to)
def rmtree(self, noerrors=True):
""" Removes a directory tree. Ignores errors by default. """
return shutil.rmtree(self, ignore_errors=noerrors)
def copytree(self, to):
""" Copies a directory tree to another path. """
shutil.copytree(self, to)
def copy(self, to):
shutil.copy(self, to)
def move(self, to):
""" Moves a file or directory to another path. """
shutil.move(self, to)
def copytree(self, to):
""" Copies a directory tree to another path. """
shutil.copytree(self, to)
def rename(self, to):
""" Renames a file or directory. May throw an OSError. """
os.rename(self, to)
def move(self, to):
""" Moves a file or directory to another path. """
shutil.move(self, to)
def renames(self, to):
os.renames(self, to)
def rename(self, to):
""" Renames a file or directory. May throw an OSError. """
os.rename(self, to)
def renames(self, to):
os.renames(self, to)
def glob(self, pattern):
from glob import glob
return map(Path, glob(_base(self/pattern)))
def glob(self, pattern):
from glob import glob
return map(Path, glob(_base(self/pattern)))
curdir = Path(os.path.curdir)

View File

@ -12,6 +12,7 @@ def all_projects():
projects = [m.group(1) for m in re.finditer(r'<a.*?>(.+)</a>', data)]
return projects
def main(args=None):
if args is None:
args = sys.argv[1:]
@ -36,6 +37,7 @@ def main(args=None):
_test_packages(output, pending_fn)
print 'Finished all pending!'
def _test_packages(output, pending_fn):
package = get_last_item(pending_fn)
print 'Testing package %s' % package
@ -72,13 +74,15 @@ def _test_packages(output, pending_fn):
add_package(os.path.join(output, 'success.txt'), package)
pop_last_item(pending_fn, package)
shutil.rmtree(dest_dir)
def get_last_item(fn):
f = open(fn, 'r')
lines = f.readlines()
f.close()
return lines[-1].strip()
def pop_last_item(fn, line=None):
f = open(fn, 'r')
lines = f.readlines()
@ -90,10 +94,12 @@ def pop_last_item(fn, line=None):
f.writelines(lines)
f.close()
def add_package(filename, package):
f = open(filename, 'a')
f.write(package + '\n')
f.close()
if __name__ == '__main__':
main()

View File

@ -2,10 +2,11 @@ from os.path import abspath, exists, join, dirname, curdir, pardir
from test_pip import here, reset_env, run_pip, pyversion, mkdir
from path import Path
def test_correct_pip_version():
"""
Check we are running proper version of pip in run_pip.
"""
reset_env()
@ -16,21 +17,23 @@ def test_correct_pip_version():
result = run_pip('--version')
# compare the directory tree of the invoked pip with that of this source distribution
import re,filecmp
import re
import filecmp
dir = re.match(r'\s*pip\s\S+\sfrom\s+(.*)\s\([^(]+\)$', result.stdout).group(1)
diffs = filecmp.dircmp(join(base,'pip'), join(dir,'pip'))
diffs = filecmp.dircmp(join(base, 'pip'), join(dir, 'pip'))
# If any non-matching .py files exist, we have a problem: run_pip
# is picking up some other version! N.B. if this project acquires
# 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 if x.endswith('.py')]
assert not mismatch_py, 'mismatched source files in %r and %r'% (join(base,'pip'), join(dir,'pip'))
assert not mismatch_py, 'mismatched source files in %r and %r'% (join(base, 'pip'), join(dir, 'pip'))
def test_distutils_configuration_setting():
"""
Test the distutils-configuration-setting command (which is distinct from other commands).
"""
#print run_pip('-vv', '--distutils-cfg=easy_install:index_url:http://download.zope.org/ppix/', expect_error=True)
#Script result: python ../../poacheggs.py -E .../poacheggs-tests/test-scratch -vv --distutils-cfg=easy_install:index_url:http://download.zope.org/ppix/
@ -42,20 +45,22 @@ def test_distutils_configuration_setting():
#-- updated: -------------------
# lib/python2.4/distutils/distutils.cfg (346 bytes)
def test_install_from_pypi():
"""
Test installing a package from PyPI.
"""
e = reset_env()
result = run_pip('install', '-vvv', 'INITools==0.2')
assert (e.site_packages / 'INITools-0.2-py%s.egg-info' % pyversion) in result.files_created, str(result)
assert (e.site_packages / 'initools') in result.files_created, str(result)
def test_editable_install():
"""
Test editable installation.
"""
reset_env()
result = run_pip('install', '-e', 'INITools==0.2', expect_error=True)
@ -63,19 +68,21 @@ def test_editable_install():
assert len(result.files_created) == 1, result.files_created
assert not result.files_updated, result.files_updated
def test_install_editable_from_svn():
"""
Test checking out from svn.
"""
e = reset_env()
result = run_pip('install', '-e', 'svn+http://svn.colorstudy.com/INITools/trunk#egg=initools-dev')
result.assert_installed('INITools', with_files=['.svn'])
def test_download_editable_to_custom_path():
"""
Test downloading an editable using a relative custom src folder.
"""
reset_env()
mkdir('customdl')
@ -84,14 +91,15 @@ def test_download_editable_to_custom_path():
customsrc = Path('scratch')/'customsrc'/'initools'
assert customsrc in result.files_created, sorted(result.files_created.keys())
assert customsrc/'setup.py' in result.files_created, sorted(result.files_created.keys())
customdl = Path('scratch')/'customdl'/'initools'
assert [filename for filename in result.files_created.keys() if filename.startswith(customdl)]
def test_editable_no_install_followed_by_no_download():
"""
Test installing an editable in two steps (first with --no-install, then with --no-download).
"""
reset_env()
@ -100,13 +108,14 @@ def test_editable_no_install_followed_by_no_download():
result.assert_installed('INITools', without_egg_link=True, with_files=['.svn'])
result = run_pip('install', '-e', 'svn+http://svn.colorstudy.com/INITools/trunk#egg=initools-dev',
'--no-download', expect_error=True)
'--no-download', expect_error=True)
result.assert_installed('INITools', without_files=[curdir, '.svn'])
def test_no_install_followed_by_no_download():
"""
Test installing in two steps (first with --no-install, then with --no-download).
"""
env = reset_env()
@ -117,62 +126,68 @@ def test_no_install_followed_by_no_download():
assert build_dir in result.files_created, result.files_created
assert build_dir/'INITools.egg-info' in result.files_created
result = run_pip('install', 'INITools==0.2', '--no-download', expect_error=True)
result = run_pip('install', 'INITools==0.2', '--no-download', expect_error=True)
assert (env.site_packages/'INITools-0.2-py%s.egg-info' % pyversion) in result.files_created, str(result)
assert (env.site_packages/'initools') in result.files_created, sorted(result.files_created.keys())
assert build_dir not in result.files_created
assert build_dir/'INITools.egg-info' not in result.files_created
def test_bad_install_with_no_download():
"""
Test that --no-download behaves sensibly if the package source can't be found.
"""
reset_env()
result = run_pip('install', 'INITools==0.2', '--no-download', expect_error=True)
result = run_pip('install', 'INITools==0.2', '--no-download', expect_error=True)
assert result.stdout.find("perhaps --no-download was used without first running an equivalent install with --no-install?") > 0
def test_install_dev_version_from_pypi():
"""
Test using package==dev.
"""
e = reset_env()
result = run_pip('install', 'INITools==dev', expect_error=True)
assert (e.site_packages / 'initools') in result.files_created, str(result.stdout)
def test_install_editable_from_git():
"""
Test cloning from Git.
"""
e = reset_env()
result = run_pip('install', '-e', 'git://github.com/jezdez/django-feedutil.git#egg=django-feedutil', expect_error=True)
result.assert_installed('django-feedutil', with_files=['.git'])
def test_install_editable_from_hg():
"""
Test cloning from Mercurial.
"""
e = reset_env()
result = run_pip('install', '-e', 'hg+http://bitbucket.org/ubernostrum/django-registration/#egg=django-registration', expect_error=True)
result.assert_installed('django-registration', with_files=['.hg'])
def test_vcs_url_final_slash_normalization():
"""
Test that presence or absence of final slash in VCS URL is normalized.
"""
reset_env()
result = run_pip('install', '-e', 'hg+http://bitbucket.org/ubernostrum/django-registration#egg=django-registration', expect_error=True)
assert 'pip-log.txt' not in result.files_created, result.files_created['pip-log.txt'].bytes
def test_install_editable_from_bazaar():
"""
Test checking out from Bazaar.
"""
e = reset_env()
result = run_pip('install', '-e', 'bzr+http://bazaar.launchpad.net/%7Edjango-wikiapp/django-wikiapp/release-0.1/@174#egg=django-wikiapp', expect_error=True)
@ -182,12 +197,13 @@ def test_install_editable_from_bazaar():
def test_vcs_url_urlquote_normalization():
"""
Test that urlquoted characters are normalized for repo URL comparison.
"""
reset_env()
result = run_pip('install', '-e', 'bzr+http://bazaar.launchpad.net/~django-wikiapp/django-wikiapp/release-0.1#egg=django-wikiapp', expect_error=True)
assert 'pip-log.txt' not in result.files_created, result.files_created['pip-log.txt'].bytes
def test_install_from_local_directory():
"""
Test installing from a local directory.
@ -199,17 +215,19 @@ def test_install_from_local_directory():
assert (env.site_packages/'fspkg') in result.files_created, str(result.stdout)
assert (env.site_packages/'FSPkg-0.1dev-py%s.egg-info' % pyversion) in result.files_created, str(result)
def test_install_from_local_directory_with_no_setup_py():
"""
Test installing from a local directory with no 'setup.py'.
"""
reset_env()
result = run_pip('install', here, expect_error=True)
assert len(result.files_created) == 1, result.files_created
assert 'pip-log.txt' in result.files_created, result.files_created
assert "is not installable. File 'setup.py' not found." in result.stdout
def test_install_curdir():
"""
Test installing current directory ('.').
@ -221,6 +239,7 @@ def test_install_curdir():
assert (env.site_packages/'fspkg') in result.files_created, str(result.stdout)
assert (env.site_packages/'FSPkg-0.1dev-py%s.egg-info' % pyversion) in result.files_created, str(result)
def test_install_pardir():
"""
Test installing parent directory ('..').

View File

@ -1,11 +1,11 @@
import zipfile
import textwrap
from os.path import abspath, join, dirname, pardir
from test_pip import here, reset_env, run_pip, write_file
from test_pip import here, reset_env, run_pip, write_file
from path import Path
from pip.util import path_to_url2
def test_create_bundle():
"""
Test making a bundle. We'll grab one package from the filesystem

View File

@ -1,15 +1,14 @@
import zipfile
import textwrap
from os.path import abspath, exists, join
from test_pip import here, reset_env, run_pip, write_file
from path import Path;
from path import Path
def test_cleanup_after_install_from_pypi():
"""
Test clean up after installing a package from PyPI.
"""
env = reset_env()
result = run_pip('install', 'INITools==0.2', expect_error=True)
@ -18,10 +17,11 @@ def test_cleanup_after_install_from_pypi():
assert not exists(build), "build/ dir still exists: %s" % build
assert not exists(src), "unexpected src/ dir exists: %s" % src
def test_cleanup_after_install_editable_from_hg():
"""
Test clean up after cloning from Mercurial.
"""
env = reset_env()
result = run_pip('install', '-e', 'hg+http://bitbucket.org/ubernostrum/django-registration/#egg=django-registration', expect_error=True)
@ -30,6 +30,7 @@ def test_cleanup_after_install_editable_from_hg():
assert not exists(build), "build/ dir still exists: %s" % build
assert exists(src), "expected src/ dir doesn't exist: %s" % src
def test_cleanup_after_install_from_local_directory():
"""
Test clean up after installing from a local directory.
@ -43,6 +44,7 @@ def test_cleanup_after_install_from_local_directory():
assert not exists(build), "unexpected build/ dir exists: %s" % build
assert not exists(src), "unexpected src/ dir exist: %s" % src
def test_cleanup_after_create_bundle():
"""
Test clean up after making a bundle. Make sure (build|src)-bundle/ dirs are removed but not src/.

View File

@ -20,7 +20,6 @@ complete -o default -F _pip_completion pip"""
assert bash_completion in result.stdout, 'bash completion is wrong'
def test_completion_for_zsh():
"""
Test getting completion for zsh shell
@ -31,7 +30,7 @@ function _pip_completion {
local words cword
read -Ac words
read -cn cword
reply=( $( COMP_WORDS="$words[*]" \\
reply=( $( COMP_WORDS="$words[*]" \\
COMP_CWORD=$(( cword-1 )) \\
PIP_AUTO_COMPLETE=1 $words[1] ) )
}
@ -41,7 +40,6 @@ compctl -K _pip_completion pip"""
assert zsh_completion in result.stdout, 'zsh completion is wrong'
def test_completion_for_unknown_shell():
"""
Test getting completion for an unknown shell

View File

@ -1,13 +1,13 @@
import tempfile
import textwrap
from test_pip import here, reset_env, run_pip, clear_environ, write_file
import os
def test_options_from_env_vars():
"""
Test if ConfigOptionParser reads env vars (e.g. not using PyPI here)
"""
environ = clear_environ(os.environ.copy())
environ['PIP_NO_INDEX'] = '1'
@ -16,10 +16,11 @@ def test_options_from_env_vars():
assert "Ignoring indexes:" in result.stdout, str(result)
assert "DistributionNotFound: No distributions at all found for INITools" in result.stdout
def test_command_line_options_override_env_vars():
"""
Test that command line options override environmental variables.
"""
environ = clear_environ(os.environ.copy())
environ['PIP_INDEX_URL'] = 'http://pypi.appspot.com/'
@ -31,10 +32,11 @@ def test_command_line_options_override_env_vars():
assert "http://pypi.appspot.com/INITools" not in result.stdout
assert "Getting page http://download.zope.org/ppix" in result.stdout
def test_command_line_append_flags():
"""
Test command line flags that append to defaults set by environmental variables.
"""
environ = clear_environ(os.environ.copy())
environ['PIP_FIND_LINKS'] = 'http://pypi.pinaxproject.com'
@ -46,11 +48,12 @@ def test_command_line_append_flags():
assert "Analyzing links from page http://pypi.pinaxproject.com" in result.stdout
assert "Analyzing links from page http://example.com" in result.stdout
def test_config_file_override_stack():
"""
Test config files (global, overriding a global config with a
local, overriding all with a command line flag).
"""
f, config_file = tempfile.mkstemp('-pip.cfg', 'test-')
environ = clear_environ(os.environ.copy())
@ -76,10 +79,11 @@ def test_config_file_override_stack():
assert "Getting page http://pypi.appspot.com/INITools" not in result.stdout
assert "Getting page http://pypi.python.org/simple/INITools" in result.stdout
def test_log_file_no_directory():
"""
Test opening a log file with no directory name.
"""
from pip.basecommand import open_logfile
fp = open_logfile('testpip.log')

View File

@ -1,23 +1,26 @@
from os import makedirs
from os.path import join
import textwrap
from test_pip import here, reset_env, run_pip, pyversion, write_file
from test_pip import here, reset_env, run_pip, pyversion, write_file
from path import Path
def test_download_if_requested():
"""
It should download (in the scratch path) and not install if requested.
"""
env = reset_env()
result = run_pip('install', 'INITools==0.1', '-d', '.', expect_error=True)
assert Path('scratch')/ 'INITools-0.1.tar.gz' in result.files_created
assert env.site_packages/ 'initools' not in result.files_created
def test_single_download_from_requirements_file():
"""
It should support download (in the scratch path) from PyPi from a requirements file
"""
env = reset_env()
write_file('test-req.txt', textwrap.dedent("""
INITools==0.1

View File

@ -5,6 +5,7 @@ from path import Path
index_url = 'file://' + urllib2.quote(str(Path(here).abspath/'in dex').replace('\\', '/'))
def test_install():
"""
Test installing from a local index.

View File

@ -1,11 +1,13 @@
import os, sys, re
import os
import sys
import re
import textwrap
from doctest import OutputChecker, ELLIPSIS
from test_pip import reset_env, run_pip, pyversion, write_file, get_env
from test_pip import reset_env, run_pip, pyversion, write_file, get_env
distribute_re = re.compile('^distribute==[0-9.]+\n', re.MULTILINE)
def _check_output(result, expected):
checker = OutputChecker()
actual = str(result)
@ -19,15 +21,17 @@ def _check_output(result, expected):
## thing to do in the end is probably to find out how to report
## the proper fully-cased package name in our error message.
if sys.platform == 'win32':
actual = actual.replace('initools','INITools')
actual = actual.replace('initools', 'INITools')
# This allows our existing tests to work when run in a context
# with distribute installed.
actual = distribute_re.sub('', actual)
def banner(msg): return '\n========== %s ==========\n'%msg
def banner(msg):
return '\n========== %s ==========\n' % msg
assert checker.check_output(expected, actual, ELLIPSIS), banner('EXPECTED')+expected+banner('ACTUAL')+actual+banner(6*'=')
def test_freeze():
"""
Some tests of freeze, first we have to install some stuff. Note that
@ -38,7 +42,7 @@ def test_freeze():
TODO: refactor this test into multiple tests? (and maybe different
test style instead of using doctest output checker)
"""
env = reset_env()
write_file('initools-req.txt', textwrap.dedent("""\
@ -96,15 +100,16 @@ def test_freeze():
<BLANKLINE>""")
_check_output(result, expected)
def test_freeze_git_clone():
"""
Test freezing a Git clone.
"""
env = reset_env()
result = env.run('git', 'clone', 'git://github.com/jezdez/django-pagination.git', 'django-pagination')
result = env.run('git', 'checkout', '1df6507872d73ee387eb375428eafbfc253dfcd8',
cwd= env.scratch_path/ 'django-pagination', expect_stderr=True)
cwd=env.scratch_path/'django-pagination', expect_stderr=True)
result = env.run('python', 'setup.py', 'develop',
cwd=env.scratch_path / 'django-pagination')
result = run_pip('freeze', expect_stderr=True)
@ -124,10 +129,11 @@ def test_freeze_git_clone():
...""")
_check_output(result, expected)
def test_freeze_mercurial_clone():
"""
Test freezing a Mercurial clone.
"""
reset_env()
env = get_env()
@ -151,10 +157,11 @@ def test_freeze_mercurial_clone():
...""")
_check_output(result, expected)
def test_freeze_bazaar_clone():
"""
Test freezing a Bazaar clone.
"""
reset_env()
env = get_env()
@ -178,10 +185,11 @@ def test_freeze_bazaar_clone():
...""")
_check_output(result, expected)
def test_freeze_with_local_option():
"""
Test that wsgiref (from global site-packages) is reported normally, but not with --local.
"""
reset_env()
result = run_pip('install', 'initools==0.2')

View File

@ -1,5 +1,11 @@
#!/usr/bin/env python
import os, sys, tempfile, shutil, glob, atexit, textwrap
import os
import sys
import tempfile
import shutil
import glob
import atexit
import textwrap
from path import *
from scripttest import TestFileEnvironment
@ -10,32 +16,35 @@ pyversion = sys.version[:3]
here = Path(__file__).abspath.folder
# the root of this pip source distribution
src = os.path.dirname(here)
src = os.path.dirname(here)
download_cache = os.path.join(tempfile.mkdtemp(), 'pip-test-cache')
def demand_dirs(path):
if not os.path.exists(path):
if not os.path.exists(path):
os.makedirs(path)
demand_dirs(download_cache)
# Tweak the path so we can find up-to-date pip sources
# (http://bitbucket.org/ianb/pip/issue/98)
sys.path = [src] + sys.path
def create_virtualenv(where, distribute=False):
save_argv = sys.argv
try:
import virtualenv
distribute_opt = distribute and ['--distribute'] or []
sys.argv = ['virtualenv', '--quiet'] + distribute_opt + ['--no-site-packages', '--unzip-setuptools', where]
virtualenv.main()
finally:
finally:
sys.argv = save_argv
return virtualenv.path_locations(where)
def relpath(root, other):
"""a poor man's os.path.relpath, since we may not have Python 2.6"""
prefix = root+Path.sep
@ -45,6 +54,7 @@ def relpath(root, other):
if 'PYTHONPATH' in os.environ:
del os.environ['PYTHONPATH']
try:
any
except NameError:
@ -54,16 +64,18 @@ except NameError:
return True
return False
def clear_environ(environ):
return dict(((k, v) for k, v in environ.iteritems()
if not k.lower().startswith('pip_')))
def install_setuptools(env):
easy_install = os.path.join(env.bin_path, 'easy_install')
version = 'setuptools==0.6c11'
if sys.platform != 'win32':
return env.run(easy_install, version)
tempdir = tempfile.mkdtemp()
try:
for f in glob.glob(easy_install+'*'):
@ -72,17 +84,19 @@ def install_setuptools(env):
finally:
shutil.rmtree(tempdir)
def reset_env(environ = None):
def reset_env(environ=None):
global env
env = TestPipEnvironment(environ)
return env
env = None
class TestFailure(AssertionError):
"""
An "assertion" failed during testing.
"""
@ -101,11 +115,12 @@ def _cleanup():
atexit.register(_cleanup)
class TestPipResult(object):
def __init__(self, impl, verbose=False):
self._impl = impl
if verbose:
print self.stdout
if self.stderr:
@ -114,7 +129,7 @@ class TestPipResult(object):
print '======================='
def __getattr__(self, attr):
return getattr(self._impl,attr)
return getattr(self._impl, attr)
if sys.platform == 'win32':
@property
@ -124,9 +139,9 @@ class TestPipResult(object):
@property
def stderr(self):
return self._impl.stderr.replace('\r\n', '\n')
def __str__(self):
return str(self._impl).replace('\r\n','\n')
return str(self._impl).replace('\r\n', '\n')
else:
# Python doesn't automatically forward __str__ through __getattr__
def __str__(self):
@ -140,49 +155,54 @@ class TestPipResult(object):
egg_link_path = e.site_packages / pkg_name + '.egg-link'
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)
raise TestFailure('unexpected egg link file created: '\
'%r\n%s' % (egg_link_path, self))
else:
if not egg_link_path in self.files_created:
raise TestFailure, 'expected egg link file missing: %r\n%s' % (egg_link_path, self)
raise TestFailure('expected egg link file missing: '\
'%r\n%s' % (egg_link_path, self))
egg_link_file = self.files_created[egg_link_path]
if not (# FIXME: I don't understand why there's a trailing . here
egg_link_file.bytes.endswith('.')
and egg_link_file.bytes[:-1].strip().endswith(pkg_dir)):
raise TestFailure, textwrap.dedent(u'''\
raise TestFailure(textwrap.dedent(u'''\
Incorrect egg_link file %r
Expected ending: %r
------- Actual contents -------
%s
-------------------------------''' % (
egg_link_file,
egg_link_file,
pkg_dir + u'\n.',
egg_link_file.bytes))
egg_link_file.bytes)))
pth_file = Path.string(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
''') % (
Path.string(pkg_dir),
(curdir in without_files and 'not ' or ''),
sorted(self.files_created.keys()))
Path.string(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 %f' % (pkg_dir,f)
raise TestFailure('Package directory %r missing '\
'expected content %f' % (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)
raise TestFailure('Package directory %r has '\
'unexpected content %f' % (pkg_dir, f))
class TestPipEnvironment(TestFileEnvironment):
"""A specialized TestFileEnvironment for testing pip"""
@ -190,7 +210,7 @@ class TestPipEnvironment(TestFileEnvironment):
#
# Attribute naming convention
# ---------------------------
#
#
# Instances of this class have many attributes representing paths
# in the filesystem. To keep things straight, absolute paths have
# a name of the form xxxx_path and relative paths have a name that
@ -204,7 +224,7 @@ class TestPipEnvironment(TestFileEnvironment):
#
# Named with a leading dot to reduce the chance of spurious
# results due to being mistaken for the virtualenv package.
venv = Path('.virtualenv')
venv = Path('.virtualenv')
# The root of a directory tree to be used arbitrarily by tests
scratch = Path('scratch')
@ -214,10 +234,10 @@ class TestPipEnvironment(TestFileEnvironment):
verbose = False
def __init__(self, environ=None):
self.root_path = Path(tempfile.mkdtemp('-piptest'))
# We will set up a virtual environment at root_path.
# We will set up a virtual environment at root_path.
self.scratch_path = self.root_path / self.scratch
self.venv_path = self.root_path / self.venv
@ -230,11 +250,10 @@ class TestPipEnvironment(TestFileEnvironment):
environ['PIP_NO_INPUT'] = '1'
environ['PIP_LOG_FILE'] = str(self.root_path/'pip-log.txt')
super(TestPipEnvironment,self).__init__(
self.root_path, ignore_hidden=False,
super(TestPipEnvironment, self).__init__(
self.root_path, ignore_hidden=False,
environ=environ, split_cmd=False, start_clear=False,
cwd=self.scratch_path, capture_temp=True, assert_no_temp=True
)
cwd=self.scratch_path, capture_temp=True, assert_no_temp=True)
demand_dirs(self.venv_path)
demand_dirs(self.scratch_path)
@ -246,16 +265,16 @@ class TestPipEnvironment(TestFileEnvironment):
assert self.venv_path == virtualenv_paths[0] # sanity check
for id,path in zip(('venv', 'lib', 'include', 'bin'), virtualenv_paths):
for id, path in zip(('venv', 'lib', 'include', 'bin'), virtualenv_paths):
setattr(self, id+'_path', Path(path))
setattr(self, id, relpath(self.root_path,path))
setattr(self, id, relpath(self.root_path, path))
assert self.venv == TestPipEnvironment.venv # sanity check
self.site_packages = self.lib/'site-packages'
# put the test-scratch virtualenv's bin dir first on the PATH
self.environ['PATH'] = Path.pathsep.join( (self.bin_path, self.environ['PATH']) )
self.environ['PATH'] = Path.pathsep.join((self.bin_path, self.environ['PATH']))
# test that test-scratch virtualenv creation produced sensible venv python
result = self.run('python', '-c', 'import sys; print sys.executable')
@ -263,7 +282,7 @@ class TestPipEnvironment(TestFileEnvironment):
if Path(pythonbin).noext != self.bin_path/'python':
raise RuntimeError(
"Oops! 'python' in our test environment runs %r"
"Oops! 'python' in our test environment runs %r"
" rather than expected %r" % (pythonbin, self.bin_path/'python'))
# make sure we have current setuptools to avoid svn incompatibilities
@ -273,8 +292,8 @@ class TestPipEnvironment(TestFileEnvironment):
# Uninstall whatever version of pip came with the virtualenv.
# Earlier versions of pip were incapable of
# self-uninstallation on Windows, so we use the one we're testing.
self.run('python', '-c',
'import sys;sys.path.insert(0, %r);import pip;sys.exit(pip.main());' % os.path.dirname(here),
self.run('python', '-c',
'import sys;sys.path.insert(0, %r);import pip;sys.exit(pip.main());' % os.path.dirname(here),
'uninstall', '-vvv', '-y', 'pip')
# Install this version instead
@ -284,21 +303,23 @@ class TestPipEnvironment(TestFileEnvironment):
if self.verbose:
print '>> running', args, kw
cwd = kw.pop('cwd', None)
run_from = kw.pop('run_from',None)
run_from = kw.pop('run_from', None)
assert not cwd or not run_from, "Don't use run_from; it's going away"
cwd = Path.string(cwd or run_from or self.cwd)
assert not isinstance(cwd,Path)
return TestPipResult( super(TestPipEnvironment,self).run(cwd=cwd,*args,**kw), verbose=self.verbose )
assert not isinstance(cwd, Path)
return TestPipResult(super(TestPipEnvironment, self).run(cwd=cwd, *args, **kw), verbose=self.verbose)
def __del__(self):
shutil.rmtree(self.root_path, ignore_errors=True)
def run_pip(*args, **kw):
return env.run('pip', *args, **kw)
def write_file(filename, text, dest=None):
"""Write a file in the dest (default=env.scratch_path)
"""
env = get_env()
if dest:
@ -309,14 +330,17 @@ def write_file(filename, text, dest=None):
f.write(text)
f.close()
def mkdir(dirname):
os.mkdir(os.path.join(get_env().scratch_path, dirname))
def get_env():
if env is None:
reset_env()
return env
# FIXME ScriptTest does something similar, but only within a single
# ProcResult; this generalizes it so states can be compared across
# multiple commands. Maybe should be rolled into ScriptTest?
@ -345,12 +369,13 @@ def diff_states(start, end, ignore=None):
"""
ignore = ignore or []
def prefix_match(path, prefix):
if path == prefix:
if path == prefix:
return True
prefix = prefix.rstrip(os.path.sep) + os.path.sep
return path.startswith(prefix)
start_keys = set([k for k in start.keys()
if not any([prefix_match(k, i) for i in ignore])])
end_keys = set([k for k in end.keys()
@ -363,10 +388,11 @@ def diff_states(start, end, ignore=None):
updated[k] = end[k]
return dict(deleted=deleted, created=created, updated=updated)
def assert_all_changes( start_state, end_state, expected_changes ):
def assert_all_changes(start_state, end_state, expected_changes):
"""
Fails if anything changed that isn't listed in the
expected_changes.
expected_changes.
start_state is either a dict mapping paths to
scripttest.[FoundFile|FoundDir] objects or a TestPipResult whose
@ -383,15 +409,16 @@ def assert_all_changes( start_state, end_state, expected_changes ):
if isinstance(end_state, TestPipResult):
end_files = end_state.files_after
diff = diff_states( start_files, end_files, ignore=expected_changes )
if diff.values() != [{},{},{}]:
diff = diff_states(start_files, end_files, ignore=expected_changes)
if diff.values() != [{}, {}, {}]:
import pprint
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
if __name__ == '__main__':
sys.stderr.write("Run pip's tests using nosetests. Requires virtualenv, ScriptTest, and nose.\n")
sys.exit(1)

View File

@ -4,7 +4,9 @@ Tests for the proxy support in pip.
TODO shouldn't need to hack sys.path in here.
"""
import os, sys
import os
import sys
sys.path.insert(0, os.path.dirname(os.path.dirname(__file__)))
import os
@ -13,22 +15,25 @@ import getpass
from pip.basecommand import get_proxy
from test_pip import here
def new_getpass(prompt, answer='passwd'):
print '%s%s' % (prompt, answer)
return answer
def test_correct_pip_version():
"""
Check we are importing pip from the right place.
"""
base = os.path.dirname(here)
assert pip.__file__.startswith(base), pip.__file__
def test_remove_proxy():
"""
Test removing proxy from environ.
"""
if 'HTTP_PROXY' in os.environ:
del os.environ['HTTP_PROXY']
@ -40,10 +45,11 @@ def test_remove_proxy():
assert get_proxy('server.com:80') == 'server.com:80'
assert get_proxy('user:passwd@server.com:3128') == 'user:passwd@server.com:3128'
def test_get_proxy():
"""
Test get_proxy returns correct proxy info.
"""
# monkeypatch getpass.getpass, to avoid asking for a password
old_getpass = getpass.getpass

View File

@ -3,10 +3,11 @@ import os
import textwrap
from test_pip import reset_env, run_pip, write_file, pyversion
def test_requirements_file():
"""
Test installing from a requirements file.
"""
env = reset_env()
write_file('initools-req.txt', textwrap.dedent("""\
@ -20,10 +21,11 @@ def test_requirements_file():
assert result.files_created[env.site_packages/'simplejson'].dir
assert result.files_created[env.site_packages/'simplejson-1.7.4-py%s.egg-info' % pyversion].dir
def test_multiple_requirements_files():
"""
Test installing from multiple nested requirements files.
"""
env = reset_env()
write_file('initools-req.txt', textwrap.dedent("""\

View File

@ -1,5 +1,6 @@
import os, sys
import os
import sys
sys.path.insert(0, os.path.dirname(os.path.dirname(__file__)))
from pip.commands.search import compare_versions, highest_version, transform_hits
@ -9,7 +10,7 @@ from test_pip import run_pip, reset_env
def test_version_compare():
"""
Test version comparison.
"""
assert compare_versions('1.0', '1.1') == -1
assert compare_versions('1.1', '1.0') == 1
@ -17,10 +18,11 @@ def test_version_compare():
assert highest_version(['1.0', '2.0', '0.1']) == '2.0'
assert highest_version(['1.0a1', '1.0']) == '1.0'
def test_pypi_xml_transformation():
"""
Test transformation of data structures (pypi xmlrpc to custom list).
"""
pypi_hits = [{'_pypi_ordering': 100, 'name': 'foo', 'summary': 'foo summary', 'version': '1.0'},
{'_pypi_ordering': 200, 'name': 'foo', 'summary': 'foo summary v2', 'version': '2.0'},
@ -29,10 +31,11 @@ def test_pypi_xml_transformation():
{'score': 50, 'versions': ['1.0'], 'name': 'bar', 'summary': 'bar summary'}]
assert expected == transform_hits(pypi_hits)
def test_search():
"""
End to end test of search command.
"""
reset_env()
output = run_pip('search', 'pip', expect_error=True)

View File

@ -1,15 +1,17 @@
import textwrap, sys
import textwrap
import sys
from os.path import join
from tempfile import mkdtemp
from test_pip import here, reset_env, run_pip, get_env, assert_all_changes, write_file
from path import Path
import pprint
def test_simple_uninstall():
"""
Test simple install and uninstall.
"""
env = reset_env()
result = run_pip('install', 'INITools==0.2', expect_error=True)
@ -17,14 +19,11 @@ def test_simple_uninstall():
result2 = run_pip('uninstall', 'INITools', '-y', expect_error=True)
assert_all_changes(result, result2, [env.venv/'build', 'cache'])
def test_uninstall_with_scripts():
"""
Uninstall an easy_installed package with scripts.
"""
"""
Uninstall an easy_installed package with scripts.
"""
env = reset_env()
result = env.run('easy_install', 'PyLogo')
@ -34,11 +33,12 @@ def test_uninstall_with_scripts():
result2 = run_pip('uninstall', 'pylogo', '-y', expect_error=True)
assert_all_changes(result, result2, [env.venv/'build', 'cache'])
def test_uninstall_namespace_package():
"""
Uninstall a distribution with a namespace package without clobbering
the namespace and everything in it.
"""
env = reset_env()
result = run_pip('install', 'pd.requires==0.0.3', expect_error=True)
@ -47,10 +47,11 @@ def test_uninstall_namespace_package():
assert join(env.site_packages, 'pd') not in result2.files_deleted, sorted(result2.files_deleted.keys())
assert join(env.site_packages, 'pd', 'find') in result2.files_deleted, sorted(result2.files_deleted.keys())
def test_uninstall_console_scripts():
"""
Test uninstalling a package with more files (console_script entry points, extra directories).
"""
env = reset_env()
result = run_pip('install', 'virtualenv', expect_error=True)
@ -58,10 +59,11 @@ def test_uninstall_console_scripts():
result2 = run_pip('uninstall', 'virtualenv', '-y', expect_error=True)
assert_all_changes(result, result2, [env.venv/'build', 'cache'])
def test_uninstall_easy_installed_console_scripts():
"""
Test uninstalling package with console_scripts that is easy_installed.
"""
env = reset_env()
result = env.run('easy_install', 'virtualenv')
@ -69,10 +71,11 @@ def test_uninstall_easy_installed_console_scripts():
result2 = run_pip('uninstall', 'virtualenv', '-y')
assert_all_changes(result, result2, [env.venv/'build', 'cache'])
def test_uninstall_editable_from_svn():
"""
Test uninstalling an editable installation from svn.
"""
env = reset_env()
result = run_pip('install', '-e', 'svn+http://svn.colorstudy.com/INITools/trunk#egg=initools-dev')
@ -81,11 +84,11 @@ def test_uninstall_editable_from_svn():
assert (env.venv/'src'/'initools' in result2.files_after), 'oh noes, pip deleted my sources!'
assert_all_changes(result, result2, [env.venv/'src', env.venv/'build'])
def test_uninstall_editable_with_source_outside_venv():
"""
Test uninstalling editable install from existing source outside the venv.
"""
tmpdir = join(mkdtemp(), 'virtualenv')
env = reset_env()
@ -94,11 +97,12 @@ def test_uninstall_editable_with_source_outside_venv():
assert (join(env.site_packages, 'virtualenv.egg-link') in result2.files_created), result2.files_created.keys()
result3 = run_pip('uninstall', '-y', 'virtualenv', expect_error=True)
assert_all_changes(result, result3, [env.venv/'build'])
def test_uninstall_from_reqs_file():
"""
Test uninstall from a requirements file.
"""
env = reset_env()
write_file('test-req.txt', textwrap.dedent("""\
@ -112,7 +116,7 @@ def test_uninstall_from_reqs_file():
-f http://www.example.com
-i http://www.example.com
--extra-index-url http://www.example.com
-e svn+http://svn.colorstudy.com/INITools/trunk#egg=initools-dev
# and something else to test out:
PyLogo<0.4

View File

@ -3,6 +3,7 @@ from os.path import join
import textwrap
from test_pip import here, reset_env, run_pip, get_env, assert_all_changes, write_file
def test_no_upgrade_unless_requested():
"""
No upgrade if not specifically requested.
@ -13,6 +14,7 @@ def test_no_upgrade_unless_requested():
result2 = run_pip('install', 'INITools', expect_error=True)
assert not result2.files_created, 'pip install INITools upgraded when it should not have'
def test_upgrade_to_specific_version():
"""
It does upgrade to specific version requested.
@ -23,6 +25,7 @@ def test_upgrade_to_specific_version():
result2 = run_pip('install', 'INITools==0.2', expect_error=True)
assert result2.files_created, 'pip install with specific version did not upgrade'
def test_upgrade_if_requested():
"""
And it does upgrade if requested.
@ -33,6 +36,7 @@ def test_upgrade_if_requested():
result2 = run_pip('install', '--upgrade', 'INITools', expect_error=True)
assert result2.files_created, 'pip install --upgrade did not upgrade'
def test_uninstall_before_upgrade():
"""
Automatic uninstall-before-upgrade.
@ -46,6 +50,7 @@ def test_uninstall_before_upgrade():
result3 = run_pip('uninstall', 'initools', '-y', expect_error=True)
assert_all_changes(result, result3, [env.venv/'build', 'cache'])
def test_upgrade_from_reqs_file():
"""
Upgrade from a requirements file.
@ -67,6 +72,7 @@ def test_upgrade_from_reqs_file():
result3 = run_pip('uninstall', '-r', env.scratch_path/ 'test-req.txt', '-y')
assert_all_changes(result, result3, [env.venv/'build', 'cache', env.scratch/'test-req.txt'])
def test_uninstall_rollback():
"""
Test uninstall-rollback (using test package with a setup.py
@ -79,6 +85,6 @@ def test_uninstall_rollback():
assert env.site_packages / 'broken.py' in result.files_created, result.files_created.keys()
result2 = run_pip('install', '-f', find_links, '--no-index', 'broken==0.2broken', expect_error=True)
assert result2.returncode == 1, str(result2)
env.run( 'python', '-c', "import broken; print broken.VERSION").stdout
env.run('python', '-c', "import broken; print broken.VERSION").stdout
'0.1\n'
assert_all_changes(result.files_after, result2, [env.venv/'build', 'pip-log.txt'])