Use pyupgrade to convert simple string formatting to use f-string
syntax. pyupgrade is intentionally timid and will not create an f-string
if it would make the expression longer or if the substitution parameters
are anything but simple names or dotted names.
Using typing.Text is unnecessary since dropping Python 2 support.
In Python 3, typing.Text is a simple alias of str. It exists as a
backward compatibility shim for Python 2.
This is done by catching InstallationError from the underlying
distribution preparation logic. There are three cases to catch:
1. Candidates from indexes. These are simply ignored since we can
potentially satisfy the requirement with other candidates.
2. Candidates from URLs with a dist name (PEP 508 or #egg=). A new
UnsatisfiableRequirement class is introduced to represent this; it is
like an ExplicitRequirement without an underlying candidate. As the
name suggests, an instance of this can never be satisfied, and will
cause eventual backtracking.
3. Candidates from URLs without a dist name. This is only possible for
top-level user requirements, and no recourse is possible for them. So
we error out eagerly.
The InstallationError raised during distribution preparation is cached
in the factory, like successfully prepared candidates, since we don't
want to repeatedly try to build a candidate if we already know it'd
fail. Plus pip's preparation logic also does not allow packages to be
built multiple times anyway.
HashError.order is now annotated as an int to allow
HashErrors.errors.sort(key=lambda e: e.order). Alternatively we can
define a function which assert e is not None but I prefer the more
concise version, since we never raise HashError directly anyway.