mirror of https://github.com/pypa/pip
Merge branch 'master' into new_resolver_extras
This commit is contained in:
commit
fea9766fa2
|
@ -49,19 +49,19 @@ pip's tests are written using the :pypi:`pytest` test framework, :pypi:`mock`
|
|||
and :pypi:`pretend`. :pypi:`tox` is used to automate the setup and execution of
|
||||
pip's tests.
|
||||
|
||||
To run tests locally, run:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ tox -e py36
|
||||
|
||||
Generally, it can take a long time to run pip's test suite. To run tests in parallel,
|
||||
which is faster, run:
|
||||
It is preferable to run the tests in parallel for better experience during development,
|
||||
since the tests can take a long time to finish when run sequentially.
|
||||
|
||||
To run tests:
|
||||
.. code-block:: console
|
||||
|
||||
$ tox -e py36 -- -n auto
|
||||
|
||||
To run tests without parallelization, run:
|
||||
.. code-block:: console
|
||||
|
||||
$ tox -e py36
|
||||
|
||||
The example above runs tests against Python 3.6. You can also use other
|
||||
versions like ``py27`` and ``pypy3``.
|
||||
|
||||
|
@ -123,8 +123,22 @@ To build it locally, run:
|
|||
|
||||
The built documentation can be found in the ``docs/build`` folder.
|
||||
|
||||
What Next?
|
||||
==========
|
||||
|
||||
The following pages may be helpful for new contributors on where to look next
|
||||
in order to start contributing.
|
||||
|
||||
* Some `good first issues`_ on GitHub for new contributors
|
||||
* A deep dive into `pip's architecture`_
|
||||
* A guide on `triaging issues`_ for issue tracker
|
||||
|
||||
|
||||
.. _`open an issue`: https://github.com/pypa/pip/issues/new?title=Trouble+with+pip+development+environment
|
||||
.. _`install Python`: https://realpython.com/installing-python/
|
||||
.. _`PEP 484 type-comments`: https://www.python.org/dev/peps/pep-0484/#suggested-syntax-for-python-2-7-and-straddling-code
|
||||
.. _`rich CLI`: https://docs.pytest.org/en/latest/usage.html#specifying-tests-selecting-tests
|
||||
.. _`GitHub`: https://github.com/pypa/pip
|
||||
.. _`good first issues`: https://github.com/pypa/pip/labels/good%20first%20issue
|
||||
.. _`pip's architecture`: https://pip.pypa.io/en/latest/development/architecture/
|
||||
.. _`triaging issues`: https://pip.pypa.io/en/latest/development/issue-triage/
|
||||
|
|
|
@ -506,7 +506,7 @@ Finding Packages
|
|||
pip searches for packages on `PyPI`_ using the
|
||||
`HTTP simple interface <https://pypi.org/simple/>`_,
|
||||
which is documented `here <https://setuptools.readthedocs.io/en/latest/easy_install.html#package-index-api>`_
|
||||
and `there <https://www.python.org/dev/peps/pep-0301/>`_.
|
||||
and `there <https://www.python.org/dev/peps/pep-0503/>`_.
|
||||
|
||||
pip offers a number of package index options for modifying how packages are
|
||||
found.
|
||||
|
|
|
@ -20,11 +20,13 @@ class PipProvider(AbstractProvider):
|
|||
self,
|
||||
finder, # type: PackageFinder
|
||||
preparer, # type: RequirementPreparer
|
||||
ignore_dependencies, # type: bool
|
||||
make_install_req # type: InstallRequirementProvider
|
||||
):
|
||||
# type: (...) -> None
|
||||
self._finder = finder
|
||||
self._preparer = preparer
|
||||
self._ignore_dependencies = ignore_dependencies
|
||||
self._make_install_req = make_install_req
|
||||
|
||||
def make_requirement(self, ireq):
|
||||
|
@ -64,6 +66,8 @@ class PipProvider(AbstractProvider):
|
|||
|
||||
def get_dependencies(self, candidate):
|
||||
# type: (Candidate) -> Sequence[Requirement]
|
||||
if self._ignore_dependencies:
|
||||
return []
|
||||
return [
|
||||
make_requirement(
|
||||
r,
|
||||
|
|
|
@ -103,7 +103,6 @@ class SpecifierRequirement(Requirement):
|
|||
|
||||
def is_satisfied_by(self, candidate):
|
||||
# type: (Candidate) -> bool
|
||||
|
||||
assert candidate.name == self.name, \
|
||||
"Internal issue: Candidate is not for this requirement " \
|
||||
" {} vs {}".format(candidate.name, self.name)
|
||||
|
|
|
@ -37,15 +37,17 @@ class Resolver(BaseResolver):
|
|||
super(Resolver, self).__init__()
|
||||
self.finder = finder
|
||||
self.preparer = preparer
|
||||
self.ignore_dependencies = ignore_dependencies
|
||||
self.make_install_req = make_install_req
|
||||
self._result = None # type: Optional[Result]
|
||||
|
||||
def resolve(self, root_reqs, check_supported_wheels):
|
||||
# type: (List[InstallRequirement], bool) -> RequirementSet
|
||||
provider = PipProvider(
|
||||
self.finder,
|
||||
self.preparer,
|
||||
self.make_install_req,
|
||||
finder=self.finder,
|
||||
preparer=self.preparer,
|
||||
ignore_dependencies=self.ignore_dependencies,
|
||||
make_install_req=self.make_install_req,
|
||||
)
|
||||
reporter = BaseReporter()
|
||||
resolver = RLResolver(provider, reporter)
|
||||
|
|
|
@ -25,7 +25,12 @@ def user_cache_dir(appname):
|
|||
|
||||
def user_config_dir(appname, roaming=True):
|
||||
# type: (str, bool) -> str
|
||||
return _appdirs.user_config_dir(appname, appauthor=False, roaming=roaming)
|
||||
path = _appdirs.user_config_dir(appname, appauthor=False, roaming=roaming)
|
||||
if _appdirs.system == "darwin" and not os.path.isdir(path):
|
||||
path = os.path.expanduser('~/.config/')
|
||||
if appname:
|
||||
path = os.path.join(path, appname)
|
||||
return path
|
||||
|
||||
|
||||
# for the discussion regarding site_config_dir locations
|
||||
|
|
|
@ -92,10 +92,6 @@ def user_data_dir(appname=None, appauthor=None, version=None, roaming=False):
|
|||
path = os.path.expanduser('~/Library/Application Support/')
|
||||
if appname:
|
||||
path = os.path.join(path, appname)
|
||||
if not os.path.isdir(path):
|
||||
path = os.path.expanduser('~/.config/')
|
||||
if appname:
|
||||
path = os.path.join(path, appname)
|
||||
else:
|
||||
path = os.getenv('XDG_DATA_HOME', os.path.expanduser("~/.local/share"))
|
||||
if appname:
|
||||
|
|
|
@ -9,7 +9,15 @@ def assert_installed(script, **kwargs):
|
|||
(val['name'], val['version'])
|
||||
for val in json.loads(ret.stdout)
|
||||
)
|
||||
assert set(kwargs.items()) <= installed
|
||||
assert all(item in installed for item in kwargs.items()), \
|
||||
"{!r} not all in {!r}".format(kwargs, installed)
|
||||
|
||||
|
||||
def assert_not_installed(script, *args):
|
||||
ret = script.pip("list", "--format=json")
|
||||
installed = set(val["name"] for val in json.loads(ret.stdout))
|
||||
assert all(a not in installed for a in args), \
|
||||
"{!r} contained in {!r}".format(args, installed)
|
||||
|
||||
|
||||
def test_new_resolver_can_install(script):
|
||||
|
@ -83,6 +91,28 @@ def test_new_resolver_installs_dependencies(script):
|
|||
assert_installed(script, base="0.1.0", dep="0.1.0")
|
||||
|
||||
|
||||
def test_new_resolver_ignore_dependencies(script):
|
||||
create_basic_wheel_for_package(
|
||||
script,
|
||||
"base",
|
||||
"0.1.0",
|
||||
depends=["dep"],
|
||||
)
|
||||
create_basic_wheel_for_package(
|
||||
script,
|
||||
"dep",
|
||||
"0.1.0",
|
||||
)
|
||||
script.pip(
|
||||
"install", "--unstable-feature=resolver",
|
||||
"--no-cache-dir", "--no-index", "--no-deps",
|
||||
"--find-links", script.scratch_path,
|
||||
"base"
|
||||
)
|
||||
assert_installed(script, base="0.1.0")
|
||||
assert_not_installed(script, "dep")
|
||||
|
||||
|
||||
def test_new_resolver_installs_extras(script):
|
||||
create_basic_wheel_for_package(
|
||||
script,
|
||||
|
|
|
@ -55,4 +55,9 @@ def provider(finder, preparer):
|
|||
wheel_cache=None,
|
||||
use_pep517=None,
|
||||
)
|
||||
yield PipProvider(finder, preparer, make_install_req)
|
||||
yield PipProvider(
|
||||
finder=finder,
|
||||
preparer=preparer,
|
||||
ignore_dependencies=False,
|
||||
make_install_req=make_install_req,
|
||||
)
|
||||
|
|
|
@ -22,18 +22,7 @@ index ae67001a..3a52b758 100644
|
|||
Unix: ~/.local/share/<AppName> # or in $XDG_DATA_HOME, if defined
|
||||
Win XP (not roaming): C:\Documents and Settings\<username>\Application Data\<AppAuthor>\<AppName>
|
||||
Win XP (roaming): C:\Documents and Settings\<username>\Local Settings\Application Data\<AppAuthor>\<AppName>
|
||||
@@ -88,6 +92,10 @@ def user_data_dir(appname=None, appauthor=None, version=None, roaming=False):
|
||||
path = os.path.expanduser('~/Library/Application Support/')
|
||||
if appname:
|
||||
path = os.path.join(path, appname)
|
||||
+ if not os.path.isdir(path):
|
||||
+ path = os.path.expanduser('~/.config/')
|
||||
+ if appname:
|
||||
+ path = os.path.join(path, appname)
|
||||
else:
|
||||
path = os.getenv('XDG_DATA_HOME', os.path.expanduser("~/.local/share"))
|
||||
if appname:
|
||||
@@ -150,7 +158,7 @@ def site_data_dir(appname=None, appauthor=None, version=None, multipath=False):
|
||||
@@ -150,7 +154,7 @@ def site_data_dir(appname=None, appauthor=None, version=None, multipath=False):
|
||||
if appname:
|
||||
if version:
|
||||
appname = os.path.join(appname, version)
|
||||
|
@ -42,7 +31,7 @@ index ae67001a..3a52b758 100644
|
|||
|
||||
if multipath:
|
||||
path = os.pathsep.join(pathlist)
|
||||
@@ -203,6 +211,8 @@ def user_config_dir(appname=None, appauthor=None, version=None, roaming=False):
|
||||
@@ -203,6 +203,8 @@ def user_config_dir(appname=None, appauthor=None, version=None, roaming=False):
|
||||
return path
|
||||
|
||||
|
||||
|
@ -51,7 +40,7 @@ index ae67001a..3a52b758 100644
|
|||
def site_config_dir(appname=None, appauthor=None, version=None, multipath=False):
|
||||
r"""Return full path to the user-shared data dir for this application.
|
||||
|
||||
@@ -238,14 +248,15 @@ def site_config_dir(appname=None, appauthor=None, version=None, multipath=False)
|
||||
@@ -238,14 +244,15 @@ def site_config_dir(appname=None, appauthor=None, version=None, multipath=False)
|
||||
if appname and version:
|
||||
path = os.path.join(path, version)
|
||||
else:
|
||||
|
@ -71,7 +60,7 @@ index ae67001a..3a52b758 100644
|
|||
|
||||
if multipath:
|
||||
path = os.pathsep.join(pathlist)
|
||||
@@ -291,6 +304,10 @@ def user_cache_dir(appname=None, appauthor=None, version=None, opinion=True):
|
||||
@@ -291,6 +300,10 @@ def user_cache_dir(appname=None, appauthor=None, version=None, opinion=True):
|
||||
if appauthor is None:
|
||||
appauthor = appname
|
||||
path = os.path.normpath(_get_win_folder("CSIDL_LOCAL_APPDATA"))
|
||||
|
@ -82,7 +71,7 @@ index ae67001a..3a52b758 100644
|
|||
if appname:
|
||||
if appauthor is not False:
|
||||
path = os.path.join(path, appauthor, appname)
|
||||
@@ -557,18 +574,32 @@ def _get_win_folder_with_jna(csidl_name):
|
||||
@@ -557,18 +570,32 @@ def _get_win_folder_with_jna(csidl_name):
|
||||
|
||||
if system == "win32":
|
||||
try:
|
||||
|
|
Loading…
Reference in New Issue