mirror of https://github.com/pypa/pip
Move InstallRequirement.from_line to constructors module
This commit is contained in:
parent
69b494aa29
commit
a5a07fe61c
|
@ -22,9 +22,10 @@ from pip._internal.exceptions import (
|
||||||
)
|
)
|
||||||
from pip._internal.index import PackageFinder
|
from pip._internal.index import PackageFinder
|
||||||
from pip._internal.locations import running_under_virtualenv
|
from pip._internal.locations import running_under_virtualenv
|
||||||
from pip._internal.req.constructors import install_req_from_editable
|
from pip._internal.req.constructors import (
|
||||||
|
install_req_from_editable, install_req_from_line,
|
||||||
|
)
|
||||||
from pip._internal.req.req_file import parse_requirements
|
from pip._internal.req.req_file import parse_requirements
|
||||||
from pip._internal.req.req_install import InstallRequirement
|
|
||||||
from pip._internal.utils.logging import setup_logging
|
from pip._internal.utils.logging import setup_logging
|
||||||
from pip._internal.utils.misc import get_prog, normalize_path
|
from pip._internal.utils.misc import get_prog, normalize_path
|
||||||
from pip._internal.utils.outdated import pip_version_check
|
from pip._internal.utils.outdated import pip_version_check
|
||||||
|
@ -209,7 +210,7 @@ class RequirementCommand(Command):
|
||||||
requirement_set.add_requirement(req_to_add)
|
requirement_set.add_requirement(req_to_add)
|
||||||
|
|
||||||
for req in args:
|
for req in args:
|
||||||
req_to_add = InstallRequirement.from_line(
|
req_to_add = install_req_from_line(
|
||||||
req, None, isolated=options.isolated_mode,
|
req, None, isolated=options.isolated_mode,
|
||||||
wheel_cache=wheel_cache
|
wheel_cache=wheel_cache
|
||||||
)
|
)
|
||||||
|
|
|
@ -4,7 +4,8 @@ from pip._vendor.packaging.utils import canonicalize_name
|
||||||
|
|
||||||
from pip._internal.cli.base_command import Command
|
from pip._internal.cli.base_command import Command
|
||||||
from pip._internal.exceptions import InstallationError
|
from pip._internal.exceptions import InstallationError
|
||||||
from pip._internal.req import InstallRequirement, parse_requirements
|
from pip._internal.req import parse_requirements
|
||||||
|
from pip._internal.req.constructors import install_req_from_line
|
||||||
from pip._internal.utils.misc import protect_pip_from_modification_on_windows
|
from pip._internal.utils.misc import protect_pip_from_modification_on_windows
|
||||||
|
|
||||||
|
|
||||||
|
@ -47,7 +48,7 @@ class UninstallCommand(Command):
|
||||||
with self._build_session(options) as session:
|
with self._build_session(options) as session:
|
||||||
reqs_to_uninstall = {}
|
reqs_to_uninstall = {}
|
||||||
for name in args:
|
for name in args:
|
||||||
req = InstallRequirement.from_line(
|
req = install_req_from_line(
|
||||||
name, isolated=options.isolated_mode,
|
name, isolated=options.isolated_mode,
|
||||||
)
|
)
|
||||||
if req.name:
|
if req.name:
|
||||||
|
|
|
@ -10,8 +10,9 @@ from pip._vendor.packaging.utils import canonicalize_name
|
||||||
from pip._vendor.pkg_resources import RequirementParseError
|
from pip._vendor.pkg_resources import RequirementParseError
|
||||||
|
|
||||||
from pip._internal.exceptions import InstallationError
|
from pip._internal.exceptions import InstallationError
|
||||||
from pip._internal.req import InstallRequirement
|
from pip._internal.req.constructors import (
|
||||||
from pip._internal.req.constructors import install_req_from_editable
|
install_req_from_editable, install_req_from_line,
|
||||||
|
)
|
||||||
from pip._internal.req.req_file import COMMENT_RE
|
from pip._internal.req.req_file import COMMENT_RE
|
||||||
from pip._internal.utils.deprecation import deprecated
|
from pip._internal.utils.deprecation import deprecated
|
||||||
from pip._internal.utils.misc import (
|
from pip._internal.utils.misc import (
|
||||||
|
@ -106,7 +107,7 @@ def freeze(
|
||||||
wheel_cache=wheel_cache,
|
wheel_cache=wheel_cache,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
line_req = InstallRequirement.from_line(
|
line_req = install_req_from_line(
|
||||||
COMMENT_RE.sub('', line).strip(),
|
COMMENT_RE.sub('', line).strip(),
|
||||||
isolated=isolated,
|
isolated=isolated,
|
||||||
wheel_cache=wheel_cache,
|
wheel_cache=wheel_cache,
|
||||||
|
|
|
@ -8,18 +8,45 @@ These are meant to be used elsewhere within pip to create instances of
|
||||||
InstallRequirement.
|
InstallRequirement.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import logging
|
||||||
import os
|
import os
|
||||||
|
import re
|
||||||
|
import traceback
|
||||||
|
|
||||||
|
from pip._vendor.packaging.markers import Marker
|
||||||
from pip._vendor.packaging.requirements import InvalidRequirement, Requirement
|
from pip._vendor.packaging.requirements import InvalidRequirement, Requirement
|
||||||
|
from pip._vendor.packaging.specifiers import Specifier
|
||||||
|
from pip._vendor.pkg_resources import RequirementParseError, parse_requirements
|
||||||
|
|
||||||
# XXX: Temporarily importing _strip_extras
|
from pip._internal.download import (
|
||||||
from pip._internal.download import path_to_url, url_to_path
|
is_archive_file, is_url, path_to_url, url_to_path,
|
||||||
|
)
|
||||||
from pip._internal.exceptions import InstallationError
|
from pip._internal.exceptions import InstallationError
|
||||||
from pip._internal.models.link import Link
|
from pip._internal.models.link import Link
|
||||||
from pip._internal.req.req_install import InstallRequirement, _strip_extras
|
from pip._internal.req.req_install import InstallRequirement
|
||||||
|
from pip._internal.utils.misc import is_installable_dir
|
||||||
from pip._internal.vcs import vcs
|
from pip._internal.vcs import vcs
|
||||||
|
from pip._internal.wheel import Wheel
|
||||||
|
|
||||||
__all__ = ["install_req_from_editable", "parse_editable"]
|
__all__ = [
|
||||||
|
"install_req_from_editable", "install_req_from_line",
|
||||||
|
"parse_editable"
|
||||||
|
]
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
operators = Specifier._operators.keys()
|
||||||
|
|
||||||
|
|
||||||
|
def _strip_extras(path):
|
||||||
|
m = re.match(r'^(.+)(\[[^\]]+\])$', path)
|
||||||
|
extras = None
|
||||||
|
if m:
|
||||||
|
path_no_extras = m.group(1)
|
||||||
|
extras = m.group(2)
|
||||||
|
else:
|
||||||
|
path_no_extras = path
|
||||||
|
|
||||||
|
return path_no_extras, extras
|
||||||
|
|
||||||
|
|
||||||
def parse_editable(editable_req):
|
def parse_editable(editable_req):
|
||||||
|
@ -87,6 +114,36 @@ def parse_editable(editable_req):
|
||||||
return package_name, url, None
|
return package_name, url, None
|
||||||
|
|
||||||
|
|
||||||
|
def deduce_helpful_msg(req):
|
||||||
|
"""Returns helpful msg in case requirements file does not exist,
|
||||||
|
or cannot be parsed.
|
||||||
|
|
||||||
|
:params req: Requirements file path
|
||||||
|
"""
|
||||||
|
msg = ""
|
||||||
|
if os.path.exists(req):
|
||||||
|
msg = " It does exist."
|
||||||
|
# Try to parse and check if it is a requirements file.
|
||||||
|
try:
|
||||||
|
with open(req, 'r') as fp:
|
||||||
|
# parse first line only
|
||||||
|
next(parse_requirements(fp.read()))
|
||||||
|
msg += " The argument you provided " + \
|
||||||
|
"(%s) appears to be a" % (req) + \
|
||||||
|
" requirements file. If that is the" + \
|
||||||
|
" case, use the '-r' flag to install" + \
|
||||||
|
" the packages specified within it."
|
||||||
|
except RequirementParseError:
|
||||||
|
logger.debug("Cannot parse '%s' as requirements \
|
||||||
|
file" % (req), exc_info=1)
|
||||||
|
else:
|
||||||
|
msg += " File '%s' does not exist." % (req)
|
||||||
|
return msg
|
||||||
|
|
||||||
|
|
||||||
|
# ---- The actual constructors follow ----
|
||||||
|
|
||||||
|
|
||||||
def install_req_from_editable(
|
def install_req_from_editable(
|
||||||
editable_req, comes_from=None, isolated=False, options=None,
|
editable_req, comes_from=None, isolated=False, options=None,
|
||||||
wheel_cache=None, constraint=False
|
wheel_cache=None, constraint=False
|
||||||
|
@ -114,3 +171,102 @@ def install_req_from_editable(
|
||||||
wheel_cache=wheel_cache,
|
wheel_cache=wheel_cache,
|
||||||
extras=extras_override or (),
|
extras=extras_override or (),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def install_req_from_line(
|
||||||
|
name, comes_from=None, isolated=False, options=None, wheel_cache=None,
|
||||||
|
constraint=False
|
||||||
|
):
|
||||||
|
"""Creates an InstallRequirement from a name, which might be a
|
||||||
|
requirement, directory containing 'setup.py', filename, or URL.
|
||||||
|
"""
|
||||||
|
if is_url(name):
|
||||||
|
marker_sep = '; '
|
||||||
|
else:
|
||||||
|
marker_sep = ';'
|
||||||
|
if marker_sep in name:
|
||||||
|
name, markers = name.split(marker_sep, 1)
|
||||||
|
markers = markers.strip()
|
||||||
|
if not markers:
|
||||||
|
markers = None
|
||||||
|
else:
|
||||||
|
markers = Marker(markers)
|
||||||
|
else:
|
||||||
|
markers = None
|
||||||
|
name = name.strip()
|
||||||
|
req = None
|
||||||
|
path = os.path.normpath(os.path.abspath(name))
|
||||||
|
link = None
|
||||||
|
extras = None
|
||||||
|
|
||||||
|
if is_url(name):
|
||||||
|
link = Link(name)
|
||||||
|
else:
|
||||||
|
p, extras = _strip_extras(path)
|
||||||
|
looks_like_dir = os.path.isdir(p) and (
|
||||||
|
os.path.sep in name or
|
||||||
|
(os.path.altsep is not None and os.path.altsep in name) or
|
||||||
|
name.startswith('.')
|
||||||
|
)
|
||||||
|
if looks_like_dir:
|
||||||
|
if not is_installable_dir(p):
|
||||||
|
raise InstallationError(
|
||||||
|
"Directory %r is not installable. Neither 'setup.py' "
|
||||||
|
"nor 'pyproject.toml' found." % name
|
||||||
|
)
|
||||||
|
link = Link(path_to_url(p))
|
||||||
|
elif is_archive_file(p):
|
||||||
|
if not os.path.isfile(p):
|
||||||
|
logger.warning(
|
||||||
|
'Requirement %r looks like a filename, but the '
|
||||||
|
'file does not exist',
|
||||||
|
name
|
||||||
|
)
|
||||||
|
link = Link(path_to_url(p))
|
||||||
|
|
||||||
|
# it's a local file, dir, or url
|
||||||
|
if link:
|
||||||
|
# Handle relative file URLs
|
||||||
|
if link.scheme == 'file' and re.search(r'\.\./', link.url):
|
||||||
|
link = Link(
|
||||||
|
path_to_url(os.path.normpath(os.path.abspath(link.path))))
|
||||||
|
# wheel file
|
||||||
|
if link.is_wheel:
|
||||||
|
wheel = Wheel(link.filename) # can raise InvalidWheelFilename
|
||||||
|
req = "%s==%s" % (wheel.name, wheel.version)
|
||||||
|
else:
|
||||||
|
# set the req to the egg fragment. when it's not there, this
|
||||||
|
# will become an 'unnamed' requirement
|
||||||
|
req = link.egg_fragment
|
||||||
|
|
||||||
|
# a requirement specifier
|
||||||
|
else:
|
||||||
|
req = name
|
||||||
|
|
||||||
|
if extras:
|
||||||
|
extras = Requirement("placeholder" + extras.lower()).extras
|
||||||
|
else:
|
||||||
|
extras = ()
|
||||||
|
if req is not None:
|
||||||
|
try:
|
||||||
|
req = Requirement(req)
|
||||||
|
except InvalidRequirement:
|
||||||
|
if os.path.sep in req:
|
||||||
|
add_msg = "It looks like a path."
|
||||||
|
add_msg += deduce_helpful_msg(req)
|
||||||
|
elif '=' in req and not any(op in req for op in operators):
|
||||||
|
add_msg = "= is not a valid operator. Did you mean == ?"
|
||||||
|
else:
|
||||||
|
add_msg = traceback.format_exc()
|
||||||
|
raise InstallationError(
|
||||||
|
"Invalid requirement: '%s'\n%s" % (req, add_msg)
|
||||||
|
)
|
||||||
|
|
||||||
|
return InstallRequirement(
|
||||||
|
req, comes_from, link=link, markers=markers,
|
||||||
|
isolated=isolated,
|
||||||
|
options=options if options else {},
|
||||||
|
wheel_cache=wheel_cache,
|
||||||
|
constraint=constraint,
|
||||||
|
extras=extras,
|
||||||
|
)
|
||||||
|
|
|
@ -16,8 +16,9 @@ from pip._vendor.six.moves.urllib import parse as urllib_parse
|
||||||
from pip._internal.cli import cmdoptions
|
from pip._internal.cli import cmdoptions
|
||||||
from pip._internal.download import get_file_content
|
from pip._internal.download import get_file_content
|
||||||
from pip._internal.exceptions import RequirementsFileParseError
|
from pip._internal.exceptions import RequirementsFileParseError
|
||||||
from pip._internal.req.constructors import install_req_from_editable
|
from pip._internal.req.constructors import (
|
||||||
from pip._internal.req.req_install import InstallRequirement
|
install_req_from_editable, install_req_from_line,
|
||||||
|
)
|
||||||
|
|
||||||
__all__ = ['parse_requirements']
|
__all__ = ['parse_requirements']
|
||||||
|
|
||||||
|
@ -152,7 +153,7 @@ def process_line(line, filename, line_number, finder=None, comes_from=None,
|
||||||
for dest in SUPPORTED_OPTIONS_REQ_DEST:
|
for dest in SUPPORTED_OPTIONS_REQ_DEST:
|
||||||
if dest in opts.__dict__ and opts.__dict__[dest]:
|
if dest in opts.__dict__ and opts.__dict__[dest]:
|
||||||
req_options[dest] = opts.__dict__[dest]
|
req_options[dest] = opts.__dict__[dest]
|
||||||
yield InstallRequirement.from_line(
|
yield install_req_from_line(
|
||||||
args_str, line_comes_from, constraint=constraint,
|
args_str, line_comes_from, constraint=constraint,
|
||||||
isolated=isolated, options=req_options, wheel_cache=wheel_cache
|
isolated=isolated, options=req_options, wheel_cache=wheel_cache
|
||||||
)
|
)
|
||||||
|
|
|
@ -2,27 +2,21 @@ from __future__ import absolute_import
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import re
|
|
||||||
import shutil
|
import shutil
|
||||||
import sys
|
import sys
|
||||||
import sysconfig
|
import sysconfig
|
||||||
import traceback
|
|
||||||
import zipfile
|
import zipfile
|
||||||
from distutils.util import change_root
|
from distutils.util import change_root
|
||||||
|
|
||||||
from pip._vendor import pkg_resources, six
|
from pip._vendor import pkg_resources, six
|
||||||
from pip._vendor.packaging import specifiers
|
|
||||||
from pip._vendor.packaging.markers import Marker
|
|
||||||
from pip._vendor.packaging.requirements import InvalidRequirement, Requirement
|
from pip._vendor.packaging.requirements import InvalidRequirement, Requirement
|
||||||
from pip._vendor.packaging.utils import canonicalize_name
|
from pip._vendor.packaging.utils import canonicalize_name
|
||||||
from pip._vendor.packaging.version import Version
|
from pip._vendor.packaging.version import Version
|
||||||
from pip._vendor.packaging.version import parse as parse_version
|
from pip._vendor.packaging.version import parse as parse_version
|
||||||
from pip._vendor.pep517.wrappers import Pep517HookCaller
|
from pip._vendor.pep517.wrappers import Pep517HookCaller
|
||||||
from pip._vendor.pkg_resources import RequirementParseError, parse_requirements
|
|
||||||
|
|
||||||
from pip._internal import wheel
|
from pip._internal import wheel
|
||||||
from pip._internal.build_env import NoOpBuildEnvironment
|
from pip._internal.build_env import NoOpBuildEnvironment
|
||||||
from pip._internal.download import is_archive_file, is_url, path_to_url
|
|
||||||
from pip._internal.exceptions import InstallationError
|
from pip._internal.exceptions import InstallationError
|
||||||
from pip._internal.locations import (
|
from pip._internal.locations import (
|
||||||
PIP_DELETE_MARKER_FILENAME, running_under_virtualenv,
|
PIP_DELETE_MARKER_FILENAME, running_under_virtualenv,
|
||||||
|
@ -37,31 +31,17 @@ from pip._internal.utils.logging import indent_log
|
||||||
from pip._internal.utils.misc import (
|
from pip._internal.utils.misc import (
|
||||||
_make_build_dir, ask_path_exists, backup_dir, call_subprocess,
|
_make_build_dir, ask_path_exists, backup_dir, call_subprocess,
|
||||||
display_path, dist_in_site_packages, dist_in_usersite, ensure_dir,
|
display_path, dist_in_site_packages, dist_in_usersite, ensure_dir,
|
||||||
get_installed_version, is_installable_dir, rmtree,
|
get_installed_version, rmtree,
|
||||||
)
|
)
|
||||||
from pip._internal.utils.packaging import get_metadata
|
from pip._internal.utils.packaging import get_metadata
|
||||||
from pip._internal.utils.setuptools_build import SETUPTOOLS_SHIM
|
from pip._internal.utils.setuptools_build import SETUPTOOLS_SHIM
|
||||||
from pip._internal.utils.temp_dir import TempDirectory
|
from pip._internal.utils.temp_dir import TempDirectory
|
||||||
from pip._internal.utils.ui import open_spinner
|
from pip._internal.utils.ui import open_spinner
|
||||||
from pip._internal.vcs import vcs
|
from pip._internal.vcs import vcs
|
||||||
from pip._internal.wheel import Wheel, move_wheel_files
|
from pip._internal.wheel import move_wheel_files
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
operators = specifiers.Specifier._operators.keys()
|
|
||||||
|
|
||||||
|
|
||||||
def _strip_extras(path):
|
|
||||||
m = re.match(r'^(.+)(\[[^\]]+\])$', path)
|
|
||||||
extras = None
|
|
||||||
if m:
|
|
||||||
path_no_extras = m.group(1)
|
|
||||||
extras = m.group(2)
|
|
||||||
else:
|
|
||||||
path_no_extras = path
|
|
||||||
|
|
||||||
return path_no_extras, extras
|
|
||||||
|
|
||||||
|
|
||||||
class InstallRequirement(object):
|
class InstallRequirement(object):
|
||||||
"""
|
"""
|
||||||
|
@ -168,102 +148,6 @@ class InstallRequirement(object):
|
||||||
|
|
||||||
return cls(req, comes_from, isolated=isolated, wheel_cache=wheel_cache)
|
return cls(req, comes_from, isolated=isolated, wheel_cache=wheel_cache)
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def from_line(
|
|
||||||
cls, name, comes_from=None, isolated=False, options=None,
|
|
||||||
wheel_cache=None, constraint=False):
|
|
||||||
"""Creates an InstallRequirement from a name, which might be a
|
|
||||||
requirement, directory containing 'setup.py', filename, or URL.
|
|
||||||
"""
|
|
||||||
if is_url(name):
|
|
||||||
marker_sep = '; '
|
|
||||||
else:
|
|
||||||
marker_sep = ';'
|
|
||||||
if marker_sep in name:
|
|
||||||
name, markers = name.split(marker_sep, 1)
|
|
||||||
markers = markers.strip()
|
|
||||||
if not markers:
|
|
||||||
markers = None
|
|
||||||
else:
|
|
||||||
markers = Marker(markers)
|
|
||||||
else:
|
|
||||||
markers = None
|
|
||||||
name = name.strip()
|
|
||||||
req = None
|
|
||||||
path = os.path.normpath(os.path.abspath(name))
|
|
||||||
link = None
|
|
||||||
extras = None
|
|
||||||
|
|
||||||
if is_url(name):
|
|
||||||
link = Link(name)
|
|
||||||
else:
|
|
||||||
p, extras = _strip_extras(path)
|
|
||||||
looks_like_dir = os.path.isdir(p) and (
|
|
||||||
os.path.sep in name or
|
|
||||||
(os.path.altsep is not None and os.path.altsep in name) or
|
|
||||||
name.startswith('.')
|
|
||||||
)
|
|
||||||
if looks_like_dir:
|
|
||||||
if not is_installable_dir(p):
|
|
||||||
raise InstallationError(
|
|
||||||
"Directory %r is not installable. Neither 'setup.py' "
|
|
||||||
"nor 'pyproject.toml' found." % name
|
|
||||||
)
|
|
||||||
link = Link(path_to_url(p))
|
|
||||||
elif is_archive_file(p):
|
|
||||||
if not os.path.isfile(p):
|
|
||||||
logger.warning(
|
|
||||||
'Requirement %r looks like a filename, but the '
|
|
||||||
'file does not exist',
|
|
||||||
name
|
|
||||||
)
|
|
||||||
link = Link(path_to_url(p))
|
|
||||||
|
|
||||||
# it's a local file, dir, or url
|
|
||||||
if link:
|
|
||||||
# Handle relative file URLs
|
|
||||||
if link.scheme == 'file' and re.search(r'\.\./', link.url):
|
|
||||||
link = Link(
|
|
||||||
path_to_url(os.path.normpath(os.path.abspath(link.path))))
|
|
||||||
# wheel file
|
|
||||||
if link.is_wheel:
|
|
||||||
wheel = Wheel(link.filename) # can raise InvalidWheelFilename
|
|
||||||
req = "%s==%s" % (wheel.name, wheel.version)
|
|
||||||
else:
|
|
||||||
# set the req to the egg fragment. when it's not there, this
|
|
||||||
# will become an 'unnamed' requirement
|
|
||||||
req = link.egg_fragment
|
|
||||||
|
|
||||||
# a requirement specifier
|
|
||||||
else:
|
|
||||||
req = name
|
|
||||||
|
|
||||||
if extras:
|
|
||||||
extras = Requirement("placeholder" + extras.lower()).extras
|
|
||||||
else:
|
|
||||||
extras = ()
|
|
||||||
if req is not None:
|
|
||||||
try:
|
|
||||||
req = Requirement(req)
|
|
||||||
except InvalidRequirement:
|
|
||||||
if os.path.sep in req:
|
|
||||||
add_msg = "It looks like a path."
|
|
||||||
add_msg += deduce_helpful_msg(req)
|
|
||||||
elif '=' in req and not any(op in req for op in operators):
|
|
||||||
add_msg = "= is not a valid operator. Did you mean == ?"
|
|
||||||
else:
|
|
||||||
add_msg = traceback.format_exc()
|
|
||||||
raise InstallationError(
|
|
||||||
"Invalid requirement: '%s'\n%s" % (req, add_msg))
|
|
||||||
return cls(
|
|
||||||
req, comes_from, link=link, markers=markers,
|
|
||||||
isolated=isolated,
|
|
||||||
options=options if options else {},
|
|
||||||
wheel_cache=wheel_cache,
|
|
||||||
constraint=constraint,
|
|
||||||
extras=extras,
|
|
||||||
)
|
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
if self.req:
|
if self.req:
|
||||||
s = str(self.req)
|
s = str(self.req)
|
||||||
|
@ -998,30 +882,3 @@ class InstallRequirement(object):
|
||||||
py_ver_str, self.name)]
|
py_ver_str, self.name)]
|
||||||
|
|
||||||
return install_args
|
return install_args
|
||||||
|
|
||||||
|
|
||||||
def deduce_helpful_msg(req):
|
|
||||||
"""Returns helpful msg in case requirements file does not exist,
|
|
||||||
or cannot be parsed.
|
|
||||||
|
|
||||||
:params req: Requirements file path
|
|
||||||
"""
|
|
||||||
msg = ""
|
|
||||||
if os.path.exists(req):
|
|
||||||
msg = " It does exist."
|
|
||||||
# Try to parse and check if it is a requirements file.
|
|
||||||
try:
|
|
||||||
with open(req, 'r') as fp:
|
|
||||||
# parse first line only
|
|
||||||
next(parse_requirements(fp.read()))
|
|
||||||
msg += " The argument you provided " + \
|
|
||||||
"(%s) appears to be a" % (req) + \
|
|
||||||
" requirements file. If that is the" + \
|
|
||||||
" case, use the '-r' flag to install" + \
|
|
||||||
" the packages specified within it."
|
|
||||||
except RequirementParseError:
|
|
||||||
logger.debug("Cannot parse '%s' as requirements \
|
|
||||||
file" % (req), exc_info=1)
|
|
||||||
else:
|
|
||||||
msg += " File '%s' does not exist." % (req)
|
|
||||||
return msg
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ from tempfile import mkdtemp
|
||||||
import pretend
|
import pretend
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from pip._internal.req import InstallRequirement
|
from pip._internal.req.constructors import install_req_from_line
|
||||||
from pip._internal.utils.misc import rmtree
|
from pip._internal.utils.misc import rmtree
|
||||||
from tests.lib import assert_all_changes, create_test_package_with_setup
|
from tests.lib import assert_all_changes, create_test_package_with_setup
|
||||||
from tests.lib.local_repos import local_checkout, local_repo
|
from tests.lib.local_repos import local_checkout, local_repo
|
||||||
|
@ -439,7 +439,7 @@ def test_uninstall_non_local_distutils(caplog, monkeypatch, tmpdir):
|
||||||
get_dist = pretend.call_recorder(lambda x: dist)
|
get_dist = pretend.call_recorder(lambda x: dist)
|
||||||
monkeypatch.setattr("pip._vendor.pkg_resources.get_distribution", get_dist)
|
monkeypatch.setattr("pip._vendor.pkg_resources.get_distribution", get_dist)
|
||||||
|
|
||||||
req = InstallRequirement.from_line("thing")
|
req = install_req_from_line("thing")
|
||||||
req.uninstall()
|
req.uninstall()
|
||||||
|
|
||||||
assert os.path.exists(einfo)
|
assert os.path.exists(einfo)
|
||||||
|
|
|
@ -14,13 +14,13 @@ from pip._internal.exceptions import (
|
||||||
from pip._internal.index import (
|
from pip._internal.index import (
|
||||||
FormatControl, InstallationCandidate, Link, PackageFinder, fmt_ctl_formats,
|
FormatControl, InstallationCandidate, Link, PackageFinder, fmt_ctl_formats,
|
||||||
)
|
)
|
||||||
from pip._internal.req import InstallRequirement
|
from pip._internal.req.constructors import install_req_from_line
|
||||||
|
|
||||||
|
|
||||||
def test_no_mpkg(data):
|
def test_no_mpkg(data):
|
||||||
"""Finder skips zipfiles with "macosx10" in the name."""
|
"""Finder skips zipfiles with "macosx10" in the name."""
|
||||||
finder = PackageFinder([data.find_links], [], session=PipSession())
|
finder = PackageFinder([data.find_links], [], session=PipSession())
|
||||||
req = InstallRequirement.from_line("pkgwithmpkg")
|
req = install_req_from_line("pkgwithmpkg")
|
||||||
found = finder.find_requirement(req, False)
|
found = finder.find_requirement(req, False)
|
||||||
|
|
||||||
assert found.url.endswith("pkgwithmpkg-1.0.tar.gz"), found
|
assert found.url.endswith("pkgwithmpkg-1.0.tar.gz"), found
|
||||||
|
@ -29,7 +29,7 @@ def test_no_mpkg(data):
|
||||||
def test_no_partial_name_match(data):
|
def test_no_partial_name_match(data):
|
||||||
"""Finder requires the full project name to match, not just beginning."""
|
"""Finder requires the full project name to match, not just beginning."""
|
||||||
finder = PackageFinder([data.find_links], [], session=PipSession())
|
finder = PackageFinder([data.find_links], [], session=PipSession())
|
||||||
req = InstallRequirement.from_line("gmpy")
|
req = install_req_from_line("gmpy")
|
||||||
found = finder.find_requirement(req, False)
|
found = finder.find_requirement(req, False)
|
||||||
|
|
||||||
assert found.url.endswith("gmpy-1.15.tar.gz"), found
|
assert found.url.endswith("gmpy-1.15.tar.gz"), found
|
||||||
|
@ -40,7 +40,7 @@ def test_tilde():
|
||||||
session = PipSession()
|
session = PipSession()
|
||||||
with patch('pip._internal.index.os.path.exists', return_value=True):
|
with patch('pip._internal.index.os.path.exists', return_value=True):
|
||||||
finder = PackageFinder(['~/python-pkgs'], [], session=session)
|
finder = PackageFinder(['~/python-pkgs'], [], session=session)
|
||||||
req = InstallRequirement.from_line("gmpy")
|
req = install_req_from_line("gmpy")
|
||||||
with pytest.raises(DistributionNotFound):
|
with pytest.raises(DistributionNotFound):
|
||||||
finder.find_requirement(req, False)
|
finder.find_requirement(req, False)
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@ def test_duplicates_sort_ok(data):
|
||||||
[],
|
[],
|
||||||
session=PipSession(),
|
session=PipSession(),
|
||||||
)
|
)
|
||||||
req = InstallRequirement.from_line("duplicate")
|
req = install_req_from_line("duplicate")
|
||||||
found = finder.find_requirement(req, False)
|
found = finder.find_requirement(req, False)
|
||||||
|
|
||||||
assert found.url.endswith("duplicate-1.0.tar.gz"), found
|
assert found.url.endswith("duplicate-1.0.tar.gz"), found
|
||||||
|
@ -61,7 +61,7 @@ def test_duplicates_sort_ok(data):
|
||||||
|
|
||||||
def test_finder_detects_latest_find_links(data):
|
def test_finder_detects_latest_find_links(data):
|
||||||
"""Test PackageFinder detects latest using find-links"""
|
"""Test PackageFinder detects latest using find-links"""
|
||||||
req = InstallRequirement.from_line('simple', None)
|
req = install_req_from_line('simple', None)
|
||||||
finder = PackageFinder([data.find_links], [], session=PipSession())
|
finder = PackageFinder([data.find_links], [], session=PipSession())
|
||||||
link = finder.find_requirement(req, False)
|
link = finder.find_requirement(req, False)
|
||||||
assert link.url.endswith("simple-3.0.tar.gz")
|
assert link.url.endswith("simple-3.0.tar.gz")
|
||||||
|
@ -69,7 +69,7 @@ def test_finder_detects_latest_find_links(data):
|
||||||
|
|
||||||
def test_incorrect_case_file_index(data):
|
def test_incorrect_case_file_index(data):
|
||||||
"""Test PackageFinder detects latest using wrong case"""
|
"""Test PackageFinder detects latest using wrong case"""
|
||||||
req = InstallRequirement.from_line('dinner', None)
|
req = install_req_from_line('dinner', None)
|
||||||
finder = PackageFinder([], [data.find_links3], session=PipSession())
|
finder = PackageFinder([], [data.find_links3], session=PipSession())
|
||||||
link = finder.find_requirement(req, False)
|
link = finder.find_requirement(req, False)
|
||||||
assert link.url.endswith("Dinner-2.0.tar.gz")
|
assert link.url.endswith("Dinner-2.0.tar.gz")
|
||||||
|
@ -78,7 +78,7 @@ def test_incorrect_case_file_index(data):
|
||||||
@pytest.mark.network
|
@pytest.mark.network
|
||||||
def test_finder_detects_latest_already_satisfied_find_links(data):
|
def test_finder_detects_latest_already_satisfied_find_links(data):
|
||||||
"""Test PackageFinder detects latest already satisfied using find-links"""
|
"""Test PackageFinder detects latest already satisfied using find-links"""
|
||||||
req = InstallRequirement.from_line('simple', None)
|
req = install_req_from_line('simple', None)
|
||||||
# the latest simple in local pkgs is 3.0
|
# the latest simple in local pkgs is 3.0
|
||||||
latest_version = "3.0"
|
latest_version = "3.0"
|
||||||
satisfied_by = Mock(
|
satisfied_by = Mock(
|
||||||
|
@ -96,7 +96,7 @@ def test_finder_detects_latest_already_satisfied_find_links(data):
|
||||||
@pytest.mark.network
|
@pytest.mark.network
|
||||||
def test_finder_detects_latest_already_satisfied_pypi_links():
|
def test_finder_detects_latest_already_satisfied_pypi_links():
|
||||||
"""Test PackageFinder detects latest already satisfied using pypi links"""
|
"""Test PackageFinder detects latest already satisfied using pypi links"""
|
||||||
req = InstallRequirement.from_line('initools', None)
|
req = install_req_from_line('initools', None)
|
||||||
# the latest initools on pypi is 0.3.1
|
# the latest initools on pypi is 0.3.1
|
||||||
latest_version = "0.3.1"
|
latest_version = "0.3.1"
|
||||||
satisfied_by = Mock(
|
satisfied_by = Mock(
|
||||||
|
@ -123,7 +123,7 @@ class TestWheel:
|
||||||
"""
|
"""
|
||||||
caplog.set_level(logging.DEBUG)
|
caplog.set_level(logging.DEBUG)
|
||||||
|
|
||||||
req = InstallRequirement.from_line("invalid")
|
req = install_req_from_line("invalid")
|
||||||
# data.find_links contains "invalid.whl", which is an invalid wheel
|
# data.find_links contains "invalid.whl", which is an invalid wheel
|
||||||
finder = PackageFinder(
|
finder = PackageFinder(
|
||||||
[data.find_links],
|
[data.find_links],
|
||||||
|
@ -148,7 +148,7 @@ class TestWheel:
|
||||||
lambda **kw: [("py1", "none", "any")],
|
lambda **kw: [("py1", "none", "any")],
|
||||||
)
|
)
|
||||||
|
|
||||||
req = InstallRequirement.from_line("simple.dist")
|
req = install_req_from_line("simple.dist")
|
||||||
finder = PackageFinder(
|
finder = PackageFinder(
|
||||||
[data.find_links],
|
[data.find_links],
|
||||||
[],
|
[],
|
||||||
|
@ -169,7 +169,7 @@ class TestWheel:
|
||||||
lambda **kw: [('py2', 'none', 'any')],
|
lambda **kw: [('py2', 'none', 'any')],
|
||||||
)
|
)
|
||||||
|
|
||||||
req = InstallRequirement.from_line("simple.dist")
|
req = install_req_from_line("simple.dist")
|
||||||
finder = PackageFinder(
|
finder = PackageFinder(
|
||||||
[data.find_links],
|
[data.find_links],
|
||||||
[],
|
[],
|
||||||
|
@ -185,7 +185,7 @@ class TestWheel:
|
||||||
Test wheels have priority over sdists.
|
Test wheels have priority over sdists.
|
||||||
`test_link_sorting` also covers this at lower level
|
`test_link_sorting` also covers this at lower level
|
||||||
"""
|
"""
|
||||||
req = InstallRequirement.from_line("priority")
|
req = install_req_from_line("priority")
|
||||||
finder = PackageFinder(
|
finder = PackageFinder(
|
||||||
[data.find_links],
|
[data.find_links],
|
||||||
[],
|
[],
|
||||||
|
@ -199,7 +199,7 @@ class TestWheel:
|
||||||
Test existing install has priority over wheels.
|
Test existing install has priority over wheels.
|
||||||
`test_link_sorting` also covers this at a lower level
|
`test_link_sorting` also covers this at a lower level
|
||||||
"""
|
"""
|
||||||
req = InstallRequirement.from_line('priority', None)
|
req = install_req_from_line('priority', None)
|
||||||
latest_version = "1.0"
|
latest_version = "1.0"
|
||||||
satisfied_by = Mock(
|
satisfied_by = Mock(
|
||||||
location="/path",
|
location="/path",
|
||||||
|
@ -284,7 +284,7 @@ class TestWheel:
|
||||||
|
|
||||||
def test_finder_priority_file_over_page(data):
|
def test_finder_priority_file_over_page(data):
|
||||||
"""Test PackageFinder prefers file links over equivalent page links"""
|
"""Test PackageFinder prefers file links over equivalent page links"""
|
||||||
req = InstallRequirement.from_line('gmpy==1.15', None)
|
req = install_req_from_line('gmpy==1.15', None)
|
||||||
finder = PackageFinder(
|
finder = PackageFinder(
|
||||||
[data.find_links],
|
[data.find_links],
|
||||||
["http://pypi.org/simple/"],
|
["http://pypi.org/simple/"],
|
||||||
|
@ -304,7 +304,7 @@ def test_finder_deplink():
|
||||||
"""
|
"""
|
||||||
Test PackageFinder with dependency links only
|
Test PackageFinder with dependency links only
|
||||||
"""
|
"""
|
||||||
req = InstallRequirement.from_line('gmpy==1.15', None)
|
req = install_req_from_line('gmpy==1.15', None)
|
||||||
finder = PackageFinder(
|
finder = PackageFinder(
|
||||||
[],
|
[],
|
||||||
[],
|
[],
|
||||||
|
@ -323,7 +323,7 @@ def test_finder_priority_page_over_deplink():
|
||||||
"""
|
"""
|
||||||
Test PackageFinder prefers page links over equivalent dependency links
|
Test PackageFinder prefers page links over equivalent dependency links
|
||||||
"""
|
"""
|
||||||
req = InstallRequirement.from_line('pip==1.5.6', None)
|
req = install_req_from_line('pip==1.5.6', None)
|
||||||
finder = PackageFinder(
|
finder = PackageFinder(
|
||||||
[],
|
[],
|
||||||
["https://pypi.org/simple/"],
|
["https://pypi.org/simple/"],
|
||||||
|
@ -346,7 +346,7 @@ def test_finder_priority_page_over_deplink():
|
||||||
|
|
||||||
def test_finder_priority_nonegg_over_eggfragments():
|
def test_finder_priority_nonegg_over_eggfragments():
|
||||||
"""Test PackageFinder prefers non-egg links over "#egg=" links"""
|
"""Test PackageFinder prefers non-egg links over "#egg=" links"""
|
||||||
req = InstallRequirement.from_line('bar==1.0', None)
|
req = install_req_from_line('bar==1.0', None)
|
||||||
links = ['http://foo/bar.py#egg=bar-1.0', 'http://foo/bar-1.0.tar.gz']
|
links = ['http://foo/bar.py#egg=bar-1.0', 'http://foo/bar-1.0.tar.gz']
|
||||||
|
|
||||||
finder = PackageFinder(links, [], session=PipSession())
|
finder = PackageFinder(links, [], session=PipSession())
|
||||||
|
@ -377,7 +377,7 @@ def test_finder_only_installs_stable_releases(data):
|
||||||
Test PackageFinder only accepts stable versioned releases by default.
|
Test PackageFinder only accepts stable versioned releases by default.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
req = InstallRequirement.from_line("bar", None)
|
req = install_req_from_line("bar", None)
|
||||||
|
|
||||||
# using a local index (that has pre & dev releases)
|
# using a local index (that has pre & dev releases)
|
||||||
finder = PackageFinder([], [data.index_url("pre")], session=PipSession())
|
finder = PackageFinder([], [data.index_url("pre")], session=PipSession())
|
||||||
|
@ -431,7 +431,7 @@ def test_finder_installs_pre_releases(data):
|
||||||
Test PackageFinder finds pre-releases if asked to.
|
Test PackageFinder finds pre-releases if asked to.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
req = InstallRequirement.from_line("bar", None)
|
req = install_req_from_line("bar", None)
|
||||||
|
|
||||||
# using a local index (that has pre & dev releases)
|
# using a local index (that has pre & dev releases)
|
||||||
finder = PackageFinder(
|
finder = PackageFinder(
|
||||||
|
@ -471,7 +471,7 @@ def test_finder_installs_dev_releases(data):
|
||||||
Test PackageFinder finds dev releases if asked to.
|
Test PackageFinder finds dev releases if asked to.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
req = InstallRequirement.from_line("bar", None)
|
req = install_req_from_line("bar", None)
|
||||||
|
|
||||||
# using a local index (that has dev releases)
|
# using a local index (that has dev releases)
|
||||||
finder = PackageFinder(
|
finder = PackageFinder(
|
||||||
|
@ -487,7 +487,7 @@ def test_finder_installs_pre_releases_with_version_spec():
|
||||||
"""
|
"""
|
||||||
Test PackageFinder only accepts stable versioned releases by default.
|
Test PackageFinder only accepts stable versioned releases by default.
|
||||||
"""
|
"""
|
||||||
req = InstallRequirement.from_line("bar>=0.0.dev0", None)
|
req = install_req_from_line("bar>=0.0.dev0", None)
|
||||||
links = ["https://foo/bar-1.0.tar.gz", "https://foo/bar-2.0b1.tar.gz"]
|
links = ["https://foo/bar-1.0.tar.gz", "https://foo/bar-2.0b1.tar.gz"]
|
||||||
|
|
||||||
finder = PackageFinder(links, [], session=PipSession())
|
finder = PackageFinder(links, [], session=PipSession())
|
||||||
|
@ -555,7 +555,7 @@ def test_get_index_urls_locations():
|
||||||
finder = PackageFinder(
|
finder = PackageFinder(
|
||||||
[], ['file://index1/', 'file://index2'], session=PipSession())
|
[], ['file://index1/', 'file://index2'], session=PipSession())
|
||||||
locations = finder._get_index_urls_locations(
|
locations = finder._get_index_urls_locations(
|
||||||
InstallRequirement.from_line('Complex_Name').name)
|
install_req_from_line('Complex_Name').name)
|
||||||
assert locations == ['file://index1/complex-name/',
|
assert locations == ['file://index1/complex-name/',
|
||||||
'file://index2/complex-name/']
|
'file://index2/complex-name/']
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@ from pip._internal.index import PackageFinder
|
||||||
from pip._internal.operations.prepare import RequirementPreparer
|
from pip._internal.operations.prepare import RequirementPreparer
|
||||||
from pip._internal.req import InstallRequirement, RequirementSet
|
from pip._internal.req import InstallRequirement, RequirementSet
|
||||||
from pip._internal.req.constructors import (
|
from pip._internal.req.constructors import (
|
||||||
install_req_from_editable, parse_editable,
|
install_req_from_editable, install_req_from_line, parse_editable,
|
||||||
)
|
)
|
||||||
from pip._internal.req.req_file import process_line
|
from pip._internal.req.req_file import process_line
|
||||||
from pip._internal.req.req_tracker import RequirementTracker
|
from pip._internal.req.req_tracker import RequirementTracker
|
||||||
|
@ -68,7 +68,7 @@ class TestRequirementSet(object):
|
||||||
os.makedirs(build_dir)
|
os.makedirs(build_dir)
|
||||||
open(os.path.join(build_dir, "setup.py"), 'w')
|
open(os.path.join(build_dir, "setup.py"), 'w')
|
||||||
reqset = RequirementSet()
|
reqset = RequirementSet()
|
||||||
req = InstallRequirement.from_line('simple')
|
req = install_req_from_line('simple')
|
||||||
req.is_direct = True
|
req.is_direct = True
|
||||||
reqset.add_requirement(req)
|
reqset.add_requirement(req)
|
||||||
finder = PackageFinder([data.find_links], [], session=PipSession())
|
finder = PackageFinder([data.find_links], [], session=PipSession())
|
||||||
|
@ -341,12 +341,12 @@ class TestInstallRequirement(object):
|
||||||
"""InstallRequirement should strip the fragment, but not the query."""
|
"""InstallRequirement should strip the fragment, but not the query."""
|
||||||
url = 'http://foo.com/?p=bar.git;a=snapshot;h=v0.1;sf=tgz'
|
url = 'http://foo.com/?p=bar.git;a=snapshot;h=v0.1;sf=tgz'
|
||||||
fragment = '#egg=bar'
|
fragment = '#egg=bar'
|
||||||
req = InstallRequirement.from_line(url + fragment)
|
req = install_req_from_line(url + fragment)
|
||||||
assert req.link.url == url + fragment, req.link
|
assert req.link.url == url + fragment, req.link
|
||||||
|
|
||||||
def test_unsupported_wheel_link_requirement_raises(self):
|
def test_unsupported_wheel_link_requirement_raises(self):
|
||||||
reqset = RequirementSet()
|
reqset = RequirementSet()
|
||||||
req = InstallRequirement.from_line(
|
req = install_req_from_line(
|
||||||
'https://whatever.com/peppercorn-0.4-py2.py3-bogus-any.whl',
|
'https://whatever.com/peppercorn-0.4-py2.py3-bogus-any.whl',
|
||||||
)
|
)
|
||||||
assert req.link is not None
|
assert req.link is not None
|
||||||
|
@ -358,7 +358,7 @@ class TestInstallRequirement(object):
|
||||||
|
|
||||||
def test_unsupported_wheel_local_file_requirement_raises(self, data):
|
def test_unsupported_wheel_local_file_requirement_raises(self, data):
|
||||||
reqset = RequirementSet()
|
reqset = RequirementSet()
|
||||||
req = InstallRequirement.from_line(
|
req = install_req_from_line(
|
||||||
data.packages.join('simple.dist-0.1-py1-none-invalid.whl'),
|
data.packages.join('simple.dist-0.1-py1-none-invalid.whl'),
|
||||||
)
|
)
|
||||||
assert req.link is not None
|
assert req.link is not None
|
||||||
|
@ -369,32 +369,32 @@ class TestInstallRequirement(object):
|
||||||
reqset.add_requirement(req)
|
reqset.add_requirement(req)
|
||||||
|
|
||||||
def test_installed_version_not_installed(self):
|
def test_installed_version_not_installed(self):
|
||||||
req = InstallRequirement.from_line('simple-0.1-py2.py3-none-any.whl')
|
req = install_req_from_line('simple-0.1-py2.py3-none-any.whl')
|
||||||
assert req.installed_version is None
|
assert req.installed_version is None
|
||||||
|
|
||||||
def test_str(self):
|
def test_str(self):
|
||||||
req = InstallRequirement.from_line('simple==0.1')
|
req = install_req_from_line('simple==0.1')
|
||||||
assert str(req) == 'simple==0.1'
|
assert str(req) == 'simple==0.1'
|
||||||
|
|
||||||
def test_repr(self):
|
def test_repr(self):
|
||||||
req = InstallRequirement.from_line('simple==0.1')
|
req = install_req_from_line('simple==0.1')
|
||||||
assert repr(req) == (
|
assert repr(req) == (
|
||||||
'<InstallRequirement object: simple==0.1 editable=False>'
|
'<InstallRequirement object: simple==0.1 editable=False>'
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_invalid_wheel_requirement_raises(self):
|
def test_invalid_wheel_requirement_raises(self):
|
||||||
with pytest.raises(InvalidWheelFilename):
|
with pytest.raises(InvalidWheelFilename):
|
||||||
InstallRequirement.from_line('invalid.whl')
|
install_req_from_line('invalid.whl')
|
||||||
|
|
||||||
def test_wheel_requirement_sets_req_attribute(self):
|
def test_wheel_requirement_sets_req_attribute(self):
|
||||||
req = InstallRequirement.from_line('simple-0.1-py2.py3-none-any.whl')
|
req = install_req_from_line('simple-0.1-py2.py3-none-any.whl')
|
||||||
assert isinstance(req.req, Requirement)
|
assert isinstance(req.req, Requirement)
|
||||||
assert str(req.req) == 'simple==0.1'
|
assert str(req.req) == 'simple==0.1'
|
||||||
|
|
||||||
def test_url_preserved_line_req(self):
|
def test_url_preserved_line_req(self):
|
||||||
"""Confirm the url is preserved in a non-editable requirement"""
|
"""Confirm the url is preserved in a non-editable requirement"""
|
||||||
url = 'git+http://foo.com@ref#egg=foo'
|
url = 'git+http://foo.com@ref#egg=foo'
|
||||||
req = InstallRequirement.from_line(url)
|
req = install_req_from_line(url)
|
||||||
assert req.link.url == url
|
assert req.link.url == url
|
||||||
|
|
||||||
def test_url_preserved_editable_req(self):
|
def test_url_preserved_editable_req(self):
|
||||||
|
@ -409,7 +409,7 @@ class TestInstallRequirement(object):
|
||||||
'/path/to/foo.egg-info/'.replace('/', os.path.sep),
|
'/path/to/foo.egg-info/'.replace('/', os.path.sep),
|
||||||
))
|
))
|
||||||
def test_get_dist(self, path):
|
def test_get_dist(self, path):
|
||||||
req = InstallRequirement.from_line('foo')
|
req = install_req_from_line('foo')
|
||||||
req._egg_info_path = path
|
req._egg_info_path = path
|
||||||
dist = req.get_dist()
|
dist = req.get_dist()
|
||||||
assert isinstance(dist, pkg_resources.Distribution)
|
assert isinstance(dist, pkg_resources.Distribution)
|
||||||
|
@ -425,14 +425,14 @@ class TestInstallRequirement(object):
|
||||||
# without spaces
|
# without spaces
|
||||||
'mock3;python_version >= "3"',
|
'mock3;python_version >= "3"',
|
||||||
):
|
):
|
||||||
req = InstallRequirement.from_line(line)
|
req = install_req_from_line(line)
|
||||||
assert req.req.name == 'mock3'
|
assert req.req.name == 'mock3'
|
||||||
assert str(req.req.specifier) == ''
|
assert str(req.req.specifier) == ''
|
||||||
assert str(req.markers) == 'python_version >= "3"'
|
assert str(req.markers) == 'python_version >= "3"'
|
||||||
|
|
||||||
def test_markers_semicolon(self):
|
def test_markers_semicolon(self):
|
||||||
# check that the markers can contain a semicolon
|
# check that the markers can contain a semicolon
|
||||||
req = InstallRequirement.from_line('semicolon; os_name == "a; b"')
|
req = install_req_from_line('semicolon; os_name == "a; b"')
|
||||||
assert req.req.name == 'semicolon'
|
assert req.req.name == 'semicolon'
|
||||||
assert str(req.req.specifier) == ''
|
assert str(req.req.specifier) == ''
|
||||||
assert str(req.markers) == 'os_name == "a; b"'
|
assert str(req.markers) == 'os_name == "a; b"'
|
||||||
|
@ -441,14 +441,14 @@ class TestInstallRequirement(object):
|
||||||
# test "URL; markers" syntax
|
# test "URL; markers" syntax
|
||||||
url = 'http://foo.com/?p=bar.git;a=snapshot;h=v0.1;sf=tgz'
|
url = 'http://foo.com/?p=bar.git;a=snapshot;h=v0.1;sf=tgz'
|
||||||
line = '%s; python_version >= "3"' % url
|
line = '%s; python_version >= "3"' % url
|
||||||
req = InstallRequirement.from_line(line)
|
req = install_req_from_line(line)
|
||||||
assert req.link.url == url, req.url
|
assert req.link.url == url, req.url
|
||||||
assert str(req.markers) == 'python_version >= "3"'
|
assert str(req.markers) == 'python_version >= "3"'
|
||||||
|
|
||||||
# without space, markers are part of the URL
|
# without space, markers are part of the URL
|
||||||
url = 'http://foo.com/?p=bar.git;a=snapshot;h=v0.1;sf=tgz'
|
url = 'http://foo.com/?p=bar.git;a=snapshot;h=v0.1;sf=tgz'
|
||||||
line = '%s;python_version >= "3"' % url
|
line = '%s;python_version >= "3"' % url
|
||||||
req = InstallRequirement.from_line(line)
|
req = install_req_from_line(line)
|
||||||
assert req.link.url == line, req.url
|
assert req.link.url == line, req.url
|
||||||
assert req.markers is None
|
assert req.markers is None
|
||||||
|
|
||||||
|
@ -459,7 +459,7 @@ class TestInstallRequirement(object):
|
||||||
'sys_platform == %r' % sys.platform,
|
'sys_platform == %r' % sys.platform,
|
||||||
):
|
):
|
||||||
line = 'name; ' + markers
|
line = 'name; ' + markers
|
||||||
req = InstallRequirement.from_line(line)
|
req = install_req_from_line(line)
|
||||||
assert str(req.markers) == str(Marker(markers))
|
assert str(req.markers) == str(Marker(markers))
|
||||||
assert req.match_markers()
|
assert req.match_markers()
|
||||||
|
|
||||||
|
@ -469,7 +469,7 @@ class TestInstallRequirement(object):
|
||||||
'sys_platform != %r' % sys.platform,
|
'sys_platform != %r' % sys.platform,
|
||||||
):
|
):
|
||||||
line = 'name; ' + markers
|
line = 'name; ' + markers
|
||||||
req = InstallRequirement.from_line(line)
|
req = install_req_from_line(line)
|
||||||
assert str(req.markers) == str(Marker(markers))
|
assert str(req.markers) == str(Marker(markers))
|
||||||
assert not req.match_markers()
|
assert not req.match_markers()
|
||||||
|
|
||||||
|
@ -480,7 +480,7 @@ class TestInstallRequirement(object):
|
||||||
'sys_platform == %r' % sys.platform,
|
'sys_platform == %r' % sys.platform,
|
||||||
):
|
):
|
||||||
line = 'name; ' + markers
|
line = 'name; ' + markers
|
||||||
req = InstallRequirement.from_line(line, comes_from='')
|
req = install_req_from_line(line, comes_from='')
|
||||||
assert str(req.markers) == str(Marker(markers))
|
assert str(req.markers) == str(Marker(markers))
|
||||||
assert req.match_markers()
|
assert req.match_markers()
|
||||||
|
|
||||||
|
@ -490,7 +490,7 @@ class TestInstallRequirement(object):
|
||||||
'sys_platform != %r' % sys.platform,
|
'sys_platform != %r' % sys.platform,
|
||||||
):
|
):
|
||||||
line = 'name; ' + markers
|
line = 'name; ' + markers
|
||||||
req = InstallRequirement.from_line(line, comes_from='')
|
req = install_req_from_line(line, comes_from='')
|
||||||
assert str(req.markers) == str(Marker(markers))
|
assert str(req.markers) == str(Marker(markers))
|
||||||
assert not req.match_markers()
|
assert not req.match_markers()
|
||||||
|
|
||||||
|
@ -498,7 +498,7 @@ class TestInstallRequirement(object):
|
||||||
line = 'SomeProject[ex1,ex2]'
|
line = 'SomeProject[ex1,ex2]'
|
||||||
filename = 'filename'
|
filename = 'filename'
|
||||||
comes_from = '-r %s (line %s)' % (filename, 1)
|
comes_from = '-r %s (line %s)' % (filename, 1)
|
||||||
req = InstallRequirement.from_line(line, comes_from=comes_from)
|
req = install_req_from_line(line, comes_from=comes_from)
|
||||||
assert len(req.extras) == 2
|
assert len(req.extras) == 2
|
||||||
assert req.extras == {'ex1', 'ex2'}
|
assert req.extras == {'ex1', 'ex2'}
|
||||||
|
|
||||||
|
@ -506,7 +506,7 @@ class TestInstallRequirement(object):
|
||||||
line = 'git+https://url#egg=SomeProject[ex1,ex2]'
|
line = 'git+https://url#egg=SomeProject[ex1,ex2]'
|
||||||
filename = 'filename'
|
filename = 'filename'
|
||||||
comes_from = '-r %s (line %s)' % (filename, 1)
|
comes_from = '-r %s (line %s)' % (filename, 1)
|
||||||
req = InstallRequirement.from_line(line, comes_from=comes_from)
|
req = install_req_from_line(line, comes_from=comes_from)
|
||||||
assert len(req.extras) == 2
|
assert len(req.extras) == 2
|
||||||
assert req.extras == {'ex1', 'ex2'}
|
assert req.extras == {'ex1', 'ex2'}
|
||||||
|
|
||||||
|
@ -528,7 +528,7 @@ class TestInstallRequirement(object):
|
||||||
|
|
||||||
def test_unexisting_path(self):
|
def test_unexisting_path(self):
|
||||||
with pytest.raises(InstallationError) as e:
|
with pytest.raises(InstallationError) as e:
|
||||||
InstallRequirement.from_line(
|
install_req_from_line(
|
||||||
os.path.join('this', 'path', 'does', 'not', 'exist'))
|
os.path.join('this', 'path', 'does', 'not', 'exist'))
|
||||||
err_msg = e.value.args[0]
|
err_msg = e.value.args[0]
|
||||||
assert "Invalid requirement" in err_msg
|
assert "Invalid requirement" in err_msg
|
||||||
|
@ -536,14 +536,14 @@ class TestInstallRequirement(object):
|
||||||
|
|
||||||
def test_single_equal_sign(self):
|
def test_single_equal_sign(self):
|
||||||
with pytest.raises(InstallationError) as e:
|
with pytest.raises(InstallationError) as e:
|
||||||
InstallRequirement.from_line('toto=42')
|
install_req_from_line('toto=42')
|
||||||
err_msg = e.value.args[0]
|
err_msg = e.value.args[0]
|
||||||
assert "Invalid requirement" in err_msg
|
assert "Invalid requirement" in err_msg
|
||||||
assert "= is not a valid operator. Did you mean == ?" in err_msg
|
assert "= is not a valid operator. Did you mean == ?" in err_msg
|
||||||
|
|
||||||
def test_traceback(self):
|
def test_traceback(self):
|
||||||
with pytest.raises(InstallationError) as e:
|
with pytest.raises(InstallationError) as e:
|
||||||
InstallRequirement.from_line('toto 42')
|
install_req_from_line('toto 42')
|
||||||
err_msg = e.value.args[0]
|
err_msg = e.value.args[0]
|
||||||
assert "Invalid requirement" in err_msg
|
assert "Invalid requirement" in err_msg
|
||||||
assert "\nTraceback " in err_msg
|
assert "\nTraceback " in err_msg
|
||||||
|
@ -553,7 +553,7 @@ class TestInstallRequirement(object):
|
||||||
with open(req_file_path, 'w') as req_file:
|
with open(req_file_path, 'w') as req_file:
|
||||||
req_file.write('pip\nsetuptools')
|
req_file.write('pip\nsetuptools')
|
||||||
with pytest.raises(InstallationError) as e:
|
with pytest.raises(InstallationError) as e:
|
||||||
InstallRequirement.from_line(req_file_path)
|
install_req_from_line(req_file_path)
|
||||||
err_msg = e.value.args[0]
|
err_msg = e.value.args[0]
|
||||||
assert "Invalid requirement" in err_msg
|
assert "Invalid requirement" in err_msg
|
||||||
assert "It looks like a path. It does exist." in err_msg
|
assert "It looks like a path. It does exist." in err_msg
|
||||||
|
@ -610,10 +610,10 @@ def test_parse_editable_local_extras(
|
||||||
|
|
||||||
def test_exclusive_environment_markers():
|
def test_exclusive_environment_markers():
|
||||||
"""Make sure RequirementSet accepts several excluding env markers"""
|
"""Make sure RequirementSet accepts several excluding env markers"""
|
||||||
eq26 = InstallRequirement.from_line(
|
eq26 = install_req_from_line(
|
||||||
"Django>=1.6.10,<1.7 ; python_version == '2.6'")
|
"Django>=1.6.10,<1.7 ; python_version == '2.6'")
|
||||||
eq26.is_direct = True
|
eq26.is_direct = True
|
||||||
ne26 = InstallRequirement.from_line(
|
ne26 = install_req_from_line(
|
||||||
"Django>=1.6.10,<1.8 ; python_version != '2.6'")
|
"Django>=1.6.10,<1.8 ; python_version != '2.6'")
|
||||||
ne26.is_direct = True
|
ne26.is_direct = True
|
||||||
|
|
||||||
|
|
|
@ -12,12 +12,13 @@ from pip._internal.exceptions import (
|
||||||
InstallationError, RequirementsFileParseError,
|
InstallationError, RequirementsFileParseError,
|
||||||
)
|
)
|
||||||
from pip._internal.index import PackageFinder
|
from pip._internal.index import PackageFinder
|
||||||
from pip._internal.req.constructors import install_req_from_editable
|
from pip._internal.req.constructors import (
|
||||||
|
install_req_from_editable, install_req_from_line,
|
||||||
|
)
|
||||||
from pip._internal.req.req_file import (
|
from pip._internal.req.req_file import (
|
||||||
break_args_options, ignore_comments, join_lines, parse_requirements,
|
break_args_options, ignore_comments, join_lines, parse_requirements,
|
||||||
preprocess, process_line, skip_regex,
|
preprocess, process_line, skip_regex,
|
||||||
)
|
)
|
||||||
from pip._internal.req.req_install import InstallRequirement
|
|
||||||
from tests.lib import requirements_file
|
from tests.lib import requirements_file
|
||||||
|
|
||||||
|
|
||||||
|
@ -193,14 +194,14 @@ class TestProcessLine(object):
|
||||||
line = 'SomeProject'
|
line = 'SomeProject'
|
||||||
filename = 'filename'
|
filename = 'filename'
|
||||||
comes_from = '-r %s (line %s)' % (filename, 1)
|
comes_from = '-r %s (line %s)' % (filename, 1)
|
||||||
req = InstallRequirement.from_line(line, comes_from=comes_from)
|
req = install_req_from_line(line, comes_from=comes_from)
|
||||||
assert repr(list(process_line(line, filename, 1))[0]) == repr(req)
|
assert repr(list(process_line(line, filename, 1))[0]) == repr(req)
|
||||||
|
|
||||||
def test_yield_line_constraint(self):
|
def test_yield_line_constraint(self):
|
||||||
line = 'SomeProject'
|
line = 'SomeProject'
|
||||||
filename = 'filename'
|
filename = 'filename'
|
||||||
comes_from = '-c %s (line %s)' % (filename, 1)
|
comes_from = '-c %s (line %s)' % (filename, 1)
|
||||||
req = InstallRequirement.from_line(
|
req = install_req_from_line(
|
||||||
line, comes_from=comes_from, constraint=True)
|
line, comes_from=comes_from, constraint=True)
|
||||||
found_req = list(process_line(line, filename, 1, constraint=True))[0]
|
found_req = list(process_line(line, filename, 1, constraint=True))[0]
|
||||||
assert repr(found_req) == repr(req)
|
assert repr(found_req) == repr(req)
|
||||||
|
@ -210,7 +211,7 @@ class TestProcessLine(object):
|
||||||
line = 'SomeProject >= 2'
|
line = 'SomeProject >= 2'
|
||||||
filename = 'filename'
|
filename = 'filename'
|
||||||
comes_from = '-r %s (line %s)' % (filename, 1)
|
comes_from = '-r %s (line %s)' % (filename, 1)
|
||||||
req = InstallRequirement.from_line(line, comes_from=comes_from)
|
req = install_req_from_line(line, comes_from=comes_from)
|
||||||
assert repr(list(process_line(line, filename, 1))[0]) == repr(req)
|
assert repr(list(process_line(line, filename, 1))[0]) == repr(req)
|
||||||
assert str(req.req.specifier) == '>=2'
|
assert str(req.req.specifier) == '>=2'
|
||||||
|
|
||||||
|
@ -235,7 +236,7 @@ class TestProcessLine(object):
|
||||||
|
|
||||||
def test_nested_requirements_file(self, monkeypatch):
|
def test_nested_requirements_file(self, monkeypatch):
|
||||||
line = '-r another_file'
|
line = '-r another_file'
|
||||||
req = InstallRequirement.from_line('SomeProject')
|
req = install_req_from_line('SomeProject')
|
||||||
import pip._internal.req.req_file
|
import pip._internal.req.req_file
|
||||||
|
|
||||||
def stub_parse_requirements(req_url, finder, comes_from, options,
|
def stub_parse_requirements(req_url, finder, comes_from, options,
|
||||||
|
@ -248,7 +249,7 @@ class TestProcessLine(object):
|
||||||
|
|
||||||
def test_nested_constraints_file(self, monkeypatch):
|
def test_nested_constraints_file(self, monkeypatch):
|
||||||
line = '-c another_file'
|
line = '-c another_file'
|
||||||
req = InstallRequirement.from_line('SomeProject')
|
req = install_req_from_line('SomeProject')
|
||||||
import pip._internal.req.req_file
|
import pip._internal.req.req_file
|
||||||
|
|
||||||
def stub_parse_requirements(req_url, finder, comes_from, options,
|
def stub_parse_requirements(req_url, finder, comes_from, options,
|
||||||
|
|
|
@ -3,6 +3,7 @@ import tempfile
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
|
from pip._internal.req.constructors import install_req_from_line
|
||||||
from pip._internal.req.req_install import InstallRequirement
|
from pip._internal.req.req_install import InstallRequirement
|
||||||
|
|
||||||
|
|
||||||
|
@ -36,7 +37,7 @@ class TestInstallRequirementBuildDirectory(object):
|
||||||
with open(setup_py_path, 'w') as f:
|
with open(setup_py_path, 'w') as f:
|
||||||
f.write('')
|
f.write('')
|
||||||
|
|
||||||
requirement = InstallRequirement.from_line(
|
requirement = install_req_from_line(
|
||||||
str(install_dir).replace(os.sep, os.altsep or os.sep)
|
str(install_dir).replace(os.sep, os.altsep or os.sep)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue