diff --git a/docs/html/development/getting-started.rst b/docs/html/development/getting-started.rst
index 6fa4f9edc..75097157b 100644
--- a/docs/html/development/getting-started.rst
+++ b/docs/html/development/getting-started.rst
@@ -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/
diff --git a/docs/html/reference/pip_install.rst b/docs/html/reference/pip_install.rst
index c81e43ba4..bd61151d7 100644
--- a/docs/html/reference/pip_install.rst
+++ b/docs/html/reference/pip_install.rst
@@ -506,7 +506,7 @@ Finding Packages
pip searches for packages on `PyPI`_ using the
`HTTP simple interface `_,
which is documented `here `_
-and `there `_.
+and `there `_.
pip offers a number of package index options for modifying how packages are
found.
diff --git a/news/2808D551-576D-4239-BBB4-F5B9DB5E36A2.trivial b/news/2808D551-576D-4239-BBB4-F5B9DB5E36A2.trivial
new file mode 100644
index 000000000..e69de29bb
diff --git a/news/533EA005-0471-4D5D-A81B-B6904A844EEE.trivial b/news/533EA005-0471-4D5D-A81B-B6904A844EEE.trivial
new file mode 100644
index 000000000..e69de29bb
diff --git a/src/pip/_internal/resolution/resolvelib/provider.py b/src/pip/_internal/resolution/resolvelib/provider.py
index 7ce924f65..21a9b07ac 100644
--- a/src/pip/_internal/resolution/resolvelib/provider.py
+++ b/src/pip/_internal/resolution/resolvelib/provider.py
@@ -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,
diff --git a/src/pip/_internal/resolution/resolvelib/requirements.py b/src/pip/_internal/resolution/resolvelib/requirements.py
index e9ba61008..5e4688821 100644
--- a/src/pip/_internal/resolution/resolvelib/requirements.py
+++ b/src/pip/_internal/resolution/resolvelib/requirements.py
@@ -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)
diff --git a/src/pip/_internal/resolution/resolvelib/resolver.py b/src/pip/_internal/resolution/resolvelib/resolver.py
index 4a38096a0..b0aa501ba 100644
--- a/src/pip/_internal/resolution/resolvelib/resolver.py
+++ b/src/pip/_internal/resolution/resolvelib/resolver.py
@@ -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)
diff --git a/src/pip/_internal/utils/appdirs.py b/src/pip/_internal/utils/appdirs.py
index f80e4af45..3989ed31c 100644
--- a/src/pip/_internal/utils/appdirs.py
+++ b/src/pip/_internal/utils/appdirs.py
@@ -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
diff --git a/src/pip/_vendor/appdirs.py b/src/pip/_vendor/appdirs.py
index cf37f9820..8bd9c9ca0 100644
--- a/src/pip/_vendor/appdirs.py
+++ b/src/pip/_vendor/appdirs.py
@@ -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:
diff --git a/tests/functional/test_new_resolver.py b/tests/functional/test_new_resolver.py
index 3c3b290ba..c3a132e91 100644
--- a/tests/functional/test_new_resolver.py
+++ b/tests/functional/test_new_resolver.py
@@ -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,
diff --git a/tests/unit/resolution_resolvelib/conftest.py b/tests/unit/resolution_resolvelib/conftest.py
index 6ddc6422a..f4b979d15 100644
--- a/tests/unit/resolution_resolvelib/conftest.py
+++ b/tests/unit/resolution_resolvelib/conftest.py
@@ -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,
+ )
diff --git a/tools/automation/vendoring/patches/appdirs.patch b/tools/automation/vendoring/patches/appdirs.patch
index fd3c200ac..69afd3e86 100644
--- a/tools/automation/vendoring/patches/appdirs.patch
+++ b/tools/automation/vendoring/patches/appdirs.patch
@@ -22,18 +22,7 @@ index ae67001a..3a52b758 100644
Unix: ~/.local/share/ # or in $XDG_DATA_HOME, if defined
Win XP (not roaming): C:\Documents and Settings\\Application Data\\
Win XP (roaming): C:\Documents and Settings\\Local Settings\Application Data\\
-@@ -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: