The new functionality serves a use case which was not previously possible with pip configuration files, namely the situation where you have a base Python installation and want to influence the pip configuration for all derivative virtual environments *without* changing the config for all other environments on a machine (global), or for all other environment run by the same user (user). Concretely, this could be used for a centrally managed network mounted filesystem based Python installation, from which multiple users can build virtual environments and inside which a specific pip configuration is needed (e.g. an index URL).
See #11276
SearchScope was extended with an extra parameter to be able to pass-on the
value of no_index as we do with the other parameters. This allows us to respect
its value regardless of the order in which options are evaluated.
This applies to the new importlib.metadata backend. The legacy
pkg_resources backend already does this (albeit accidentally).
A package inside a wheel is not guaranteed to "work" when directly
imported, so we should not treat it as an installed distribution.
egg-info distributions may not have the Requires-Dist and Provides-Extra
fields in their metadata. For consistency and to provide an
unsurprising metadata property, we emulate it by reading requires.txt.
The pip-specific Path implementation has been removed, and all its
usages replaced by pathlib.Path. The tmpdir and tmpdir_factory fixtures
are also removed, and all usages are replaced by tmp_path and
tmp_path_factory, which use pathlib.Path.
The pip() function now also accepts pathlib.Path so we don't need to put
str() everywhere. Path arguments are coerced with os.fspath() into str.
This was the only call-site for this method and, realistically, it is
highly coupled with the legacy resolver's dependency resolution
strategy/approach; so it makes sense for this code to live as part of
the resolver, rather than the container object the various resolvers.
- Move the lookup within `selfcheck/*.json` files into a method on
`SelfCheckState`.
- Factor out `PackageFinder` interaction into a separate function.
- Rename variables to more clearly reflect what they're for.
Co-Authored-By: Pradyun Gedam <pradyunsg@gmail.com>
These were intended to help users transition when the default behaviour
changed to no longer perform out-of-tree builds. The transition is now
considered complete.
A new enum class is implemented for the link evaluator to use instead
of a simple boolean to better distinguish between various evaluation
errors. This allows the caller to better distinguish error sources with
a structured check instead of fragile error string comparison.
This reworks the HTML parsing logic, to gracefully use `html5lib` on
non-compliant HTML 5 documents. This warning softens the failure mode
for users who are using commercial package index solutions that do not
follow the requisite standards and serve malformed HTML documents.
The earlier variant _returned_ an iterable object from a generator. This
did not properly handle the fallback, resulting in the html5lib code
path not being executed.
The html5lib library isn't strictly required as the same functionality
can be achieved through the stdlib html.parser module.
The html5lib is one of the largest uses of the six library. By dropping
this unnecessary dependency, the pip project is closer to dropping the
six library.
Additionally, html5lib maintenance has slowed down and the project has
rejected pull requests to drop Python 2 support.
For now, the html5lib code remains, but is gated behind a command
line option: `--use-deprecated=html5lib`. After a sufficient amount of
time has passed without any reported bugs, the vendored library and this
flag can be removed completely.
Modernise the shim, to account for the Python 3.2+ support matrix.
This also presents clearer error messages on failures, the included
comment helps inform users about why this shim exists and the traceback
now explicitly mentions `<pip-setuptools-shim>` to make it clearer to
users that this shim exists.
This makes it possible to present output with rich markup, within the
constraints of our logging infrastructure.
Further, diagnostic errors can now by presented using rich, using their
own special "[present-diagnostic]" marker string, since those need to be
handled differently from regular log messages and passed directly
through to rich's console object, after an indentation wrapper.
Borrow error presentation logic from sphinx-theme-builder, and
exhaustively test both the unicode and non-unicode presentation.
Utilise rich for colours and presentation logic handling, with tests to
ensure that colour degradation happens cleanly, and that the content is
stylized exactly as expected.
Catch diagnostic errors eagerly, and present them using rich. While this
won't include the pretty presentation in user logs, those files will
contain the entire traceback upto that line.
Fixes https://github.com/pypa/pip/issues/10557 where the resolver spends too much time calculating the weights.
Also, do not let `get_installation_order` calculate these weights at all when there is nothing left to install.
Co-authored-by: Tzu-ping Chung <uranusjr@gmail.com>
Note that the functional test does not actually detect the behavioral
change of throwing unhandled `BadZipFile` → throwing unhandled
`InvalidWheel`, whereas the unit test does.
This introduces an exception and presentation model, for providing
better errors messages. The motivating idea is that the better error
messages contain clear wording and provide additional context to users
to better understand what is happening.
The `DiagnosticPipError` class introduces a structured framework in our
exception model, for code authors to write their error messages. The
usage explicitly requires passing "context" and a "hint" (which accept
None values). This should nudge code authors to explicitly think about
what additional information can/should be presented to the user, and
to provide relevant hints to them whenever possible. It also makes it
straightforward to identify cases where we don't do this, which may
serve as clear areas for improvement in the future.
The initial implementation is intentionally basic and doesn't do much;
however we should be able to introduce better usage of terminal colors
and other features (eg: hyperlinks!) to further improve the presentation
of these errors. It does improve the presentation style by a bit, even
though there are significant presentation-related improvements to be
made.
Additionally, having a structured framework means that these would be
improvements in presentation of *all* the errors that are within this
framework -- increasing the benefits of investing in the presentation
of these errors.
When there is a pyproject.toml, metadata preparation must be
done in the isolated build environment for legacy editable installs too
(fixes a regression).
Also detect earlier if an editable install must go through the
legacy install path, to be sure to run it in an environment
with the correct build requirements.
This brings us in line with pre-platformdirs behaviours on these,
following the details of the configuration paths, as documented in pip's
own documentation.
Examining the pytest.raises excinfo object should be done outside the
with statement block. Previously, the raised exception prevented the
assert from being executed.
Per the docs:
https://docs.pytest.org/en/latest/how-to/assert.html#assertions-about-expected-exceptions
The exception is the "value" attribute, not "info".
mypy also caught this mistake:
tests/unit/test_network_utils.py:23: error:
"ExceptionInfo[NetworkConnectionError]" has no attribute "info" [attr-defined]
assert str(exc.info) == (