Skip to content

Commit

Permalink
Merge branch 'main' into release/23.3.2
Browse files Browse the repository at this point in the history
  • Loading branch information
sbidoul committed Dec 17, 2023
2 parents 0e2bd74 + 417ca92 commit 0668050
Show file tree
Hide file tree
Showing 80 changed files with 275 additions and 389 deletions.
19 changes: 10 additions & 9 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,25 +22,26 @@ repos:
- id: black

- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.0.292
rev: v0.1.4
hooks:
- id: ruff
args: [--fix, --exit-non-zero-on-fix]

- repo: https://github.com/pre-commit/mirrors-mypy
rev: v0.961
rev: v1.6.1
hooks:
- id: mypy
exclude: tests/data
args: ["--pretty", "--show-error-codes"]
additional_dependencies: [
'keyring==23.0.1',
'nox==2021.6.12',
'keyring==24.2.0',
'nox==2023.4.22',
'pytest',
'types-docutils==0.18.3',
'types-setuptools==57.4.14',
'types-freezegun==1.1.9',
'types-six==1.16.15',
'types-pyyaml==6.0.12.2',
'types-docutils==0.20.0.3',
'types-setuptools==68.2.0.0',
'types-freezegun==1.1.10',
'types-six==1.16.21.9',
'types-pyyaml==6.0.12.12',
]

- repo: https://github.com/pre-commit/pygrep-hooks
Expand Down
4 changes: 2 additions & 2 deletions docs/html/cli/pip_install.rst
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ When looking at the items to be installed, pip checks what type of item
each is, in the following order:

1. Project or archive URL.
2. Local directory (which must contain a ``setup.py``, or pip will report
an error).
2. Local directory (which must contain a ``pyproject.toml`` or ``setup.py``,
otherwise pip will report an error).
3. Local file (a sdist or wheel format archive, following the naming
conventions for those formats).
4. A requirement, as specified in :pep:`440`.
Expand Down
19 changes: 12 additions & 7 deletions docs/html/topics/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,24 @@ and how they are related to pip's various command line options.

## Configuration Files

Configuration files can change the default values for command line option.
They are written using a standard INI style configuration files.
Configuration files can change the default values for command line options.
The files are written using standard INI format.

pip has 3 "levels" of configuration files:

- `global`: system-wide configuration file, shared across users.
- `user`: per-user configuration file.
- `site`: per-environment configuration file; i.e. per-virtualenv.

Additionally, environment variables can be specified which will override any of the above.

### Location

pip's configuration files are located in fairly standard locations. This
location is different on different operating systems, and has some additional
complexity for backwards compatibility reasons.
complexity for backwards compatibility reasons. Note that if user config files
exist in both the legacy and current locations, values in the current file
will override values in the legacy file.

```{tab} Unix
Expand Down Expand Up @@ -88,9 +92,10 @@ Site
### `PIP_CONFIG_FILE`

Additionally, the environment variable `PIP_CONFIG_FILE` can be used to specify
a configuration file that's loaded first, and whose values are overridden by
the values set in the aforementioned files. Setting this to {any}`os.devnull`
disables the loading of _all_ configuration files.
a configuration file that's loaded last, and whose values override the values
set in the aforementioned files. Setting this to {any}`os.devnull`
disables the loading of _all_ configuration files. Note that if a file exists
at the location that this is set to, the user config file will not be loaded.

(config-precedence)=

Expand All @@ -99,10 +104,10 @@ disables the loading of _all_ configuration files.
When multiple configuration files are found, pip combines them in the following
order:

- `PIP_CONFIG_FILE`, if given.
- Global
- User
- Site
- `PIP_CONFIG_FILE`, if given.

Each file read overrides any values read from previous files, so if the
global timeout is specified in both the global file and the per-user file
Expand Down
11 changes: 3 additions & 8 deletions docs/pip_sphinxext.py
Original file line number Diff line number Diff line change
Expand Up @@ -194,22 +194,17 @@ def process_options(self) -> None:
opt = option()
opt_name = opt._long_opts[0]
if opt._short_opts:
short_opt_name = "{}, ".format(opt._short_opts[0])
short_opt_name = f"{opt._short_opts[0]}, "
else:
short_opt_name = ""

if option in cmdoptions.general_group["options"]:
prefix = ""
else:
prefix = "{}_".format(self.determine_opt_prefix(opt_name))
prefix = f"{self.determine_opt_prefix(opt_name)}_"

self.view_list.append(
"* :ref:`{short}{long}<{prefix}{opt_name}>`".format(
short=short_opt_name,
long=opt_name,
prefix=prefix,
opt_name=opt_name,
),
f"* :ref:`{short_opt_name}{opt_name}<{prefix}{opt_name}>`",
"\n",
)

Expand Down
1 change: 1 addition & 0 deletions news/11815.doc.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix explanation of how PIP_CONFIG_FILE works
1 change: 1 addition & 0 deletions news/12372.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix a bug in extras handling for link requirements
1 change: 1 addition & 0 deletions news/12389.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Update mypy to 1.6.1 and fix/ignore types
1 change: 1 addition & 0 deletions news/12390.trivial.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Update ruff versions and config for dev
1 change: 1 addition & 0 deletions news/12393.trivial.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Enforce and update code to use f-strings via Ruff rule UP032
1 change: 1 addition & 0 deletions news/12417.doc.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix outdated pip install argument description in documentation.
1 change: 1 addition & 0 deletions news/370392cf-52cd-402c-b402-06d2ff398f89.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix mercurial revision "parse error": use ``--rev={ref}`` instead of ``-r={ref}``
3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,8 @@ ignore = [
"B020",
"B904", # Ruff enables opinionated warnings by default
"B905", # Ruff enables opinionated warnings by default
"G202",
]
target-version = "py37"
line-length = 88
select = [
"ASYNC",
Expand All @@ -102,6 +102,7 @@ select = [
"PLR0",
"W",
"RUF100",
"UP032",
]

[tool.ruff.isort]
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ def get_version(rel_path: str) -> str:
entry_points={
"console_scripts": [
"pip=pip._internal.cli.main:main",
"pip{}=pip._internal.cli.main:main".format(sys.version_info[0]),
f"pip{sys.version_info[0]}=pip._internal.cli.main:main",
"pip{}.{}=pip._internal.cli.main:main".format(*sys.version_info[:2]),
],
},
Expand Down
9 changes: 3 additions & 6 deletions src/pip/_internal/cli/cmdoptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -582,10 +582,7 @@ def _handle_python_version(
"""
version_info, error_msg = _convert_python_version(value)
if error_msg is not None:
msg = "invalid --python-version value: {!r}: {}".format(
value,
error_msg,
)
msg = f"invalid --python-version value: {value!r}: {error_msg}"
raise_option_error(parser, option=option, msg=msg)

parser.values.python_version = version_info
Expand Down Expand Up @@ -921,9 +918,9 @@ def _handle_merge_hash(
algo, digest = value.split(":", 1)
except ValueError:
parser.error(
"Arguments to {} must be a hash name "
f"Arguments to {opt_str} must be a hash name "
"followed by a value, like --hash=sha256:"
"abcde...".format(opt_str)
"abcde..."
)
if algo not in STRONG_HASHES:
parser.error(
Expand Down
8 changes: 4 additions & 4 deletions src/pip/_internal/cli/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -229,9 +229,9 @@ def _update_defaults(self, defaults: Dict[str, Any]) -> Dict[str, Any]:
val = strtobool(val)
except ValueError:
self.error(
"{} is not a valid value for {} option, "
f"{val} is not a valid value for {key} option, "
"please specify a boolean value like yes/no, "
"true/false or 1/0 instead.".format(val, key)
"true/false or 1/0 instead."
)
elif option.action == "count":
with suppress(ValueError):
Expand All @@ -240,10 +240,10 @@ def _update_defaults(self, defaults: Dict[str, Any]) -> Dict[str, Any]:
val = int(val)
if not isinstance(val, int) or val < 0:
self.error(
"{} is not a valid value for {} option, "
f"{val} is not a valid value for {key} option, "
"please instead specify either a non-negative integer "
"or a boolean value like yes/no or false/true "
"which is equivalent to 1/0.".format(val, key)
"which is equivalent to 1/0."
)
elif option.action == "append":
val = val.split()
Expand Down
2 changes: 1 addition & 1 deletion src/pip/_internal/commands/cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ def remove_cache_items(self, options: Values, args: List[Any]) -> None:
files += self._find_http_files(options)
else:
# Add the pattern to the log message
no_matching_msg += ' for pattern "{}"'.format(args[0])
no_matching_msg += f' for pattern "{args[0]}"'

if not files:
logger.warning(no_matching_msg)
Expand Down
10 changes: 4 additions & 6 deletions src/pip/_internal/commands/configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -242,17 +242,15 @@ def open_in_editor(self, options: Values, args: List[str]) -> None:
e.filename = editor
raise
except subprocess.CalledProcessError as e:
raise PipError(
"Editor Subprocess exited with exit code {}".format(e.returncode)
)
raise PipError(f"Editor Subprocess exited with exit code {e.returncode}")

def _get_n_args(self, args: List[str], example: str, n: int) -> Any:
"""Helper to make sure the command got the right number of arguments"""
if len(args) != n:
msg = (
"Got unexpected number of arguments, expected {}. "
'(example: "{} config {}")'
).format(n, get_prog(), example)
f"Got unexpected number of arguments, expected {n}. "
f'(example: "{get_prog()} config {example}")'
)
raise PipError(msg)

if n == 1:
Expand Down
8 changes: 3 additions & 5 deletions src/pip/_internal/commands/debug.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ def show_actual_vendor_versions(vendor_txt_versions: Dict[str, str]) -> None:
elif parse_version(actual_version) != parse_version(expected_version):
extra_message = (
" (CONFLICT: vendor.txt suggests version should"
" be {})".format(expected_version)
f" be {expected_version})"
)
logger.info("%s==%s%s", module_name, actual_version, extra_message)

Expand All @@ -120,7 +120,7 @@ def show_tags(options: Values) -> None:
if formatted_target:
suffix = f" (target: {formatted_target})"

msg = "Compatible tags: {}{}".format(len(tags), suffix)
msg = f"Compatible tags: {len(tags)}{suffix}"
logger.info(msg)

if options.verbose < 1 and len(tags) > tag_limit:
Expand All @@ -134,9 +134,7 @@ def show_tags(options: Values) -> None:
logger.info(str(tag))

if tags_limited:
msg = (
"...\n[First {tag_limit} tags shown. Pass --verbose to show all.]"
).format(tag_limit=tag_limit)
msg = f"...\n[First {tag_limit} tags shown. Pass --verbose to show all.]"
logger.info(msg)


Expand Down
4 changes: 2 additions & 2 deletions src/pip/_internal/commands/index.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,12 +128,12 @@ def get_available_package_versions(self, options: Values, args: List[Any]) -> No

if not versions:
raise DistributionNotFound(
"No matching distribution found for {}".format(query)
f"No matching distribution found for {query}"
)

formatted_versions = [str(ver) for ver in sorted(versions, reverse=True)]
latest = formatted_versions[0]

write_output("{} ({})".format(query, latest))
write_output(f"{query} ({latest})")
write_output("Available versions: {}".format(", ".join(formatted_versions)))
print_dist_installation_info(query, latest)
6 changes: 1 addition & 5 deletions src/pip/_internal/commands/install.py
Original file line number Diff line number Diff line change
Expand Up @@ -607,12 +607,8 @@ def _warn_about_conflicts(
version = package_set[project_name][0]
for dependency in missing[project_name]:
message = (
"{name} {version} requires {requirement}, "
f"{project_name} {version} requires {dependency[1]}, "
"which is not installed."
).format(
name=project_name,
version=version,
requirement=dependency[1],
)
parts.append(message)

Expand Down
30 changes: 16 additions & 14 deletions src/pip/_internal/configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@ def _disassemble_key(name: str) -> List[str]:
if "." not in name:
error_message = (
"Key does not contain dot separated section and key. "
"Perhaps you wanted to use 'global.{}' instead?"
).format(name)
f"Perhaps you wanted to use 'global.{name}' instead?"
)
raise ConfigurationError(error_message)
return name.split(".", 1)

Expand Down Expand Up @@ -327,33 +327,35 @@ def get_environ_vars(self) -> Iterable[Tuple[str, str]]:
def iter_config_files(self) -> Iterable[Tuple[Kind, List[str]]]:
"""Yields variant and configuration files associated with it.
This should be treated like items of a dictionary.
This should be treated like items of a dictionary. The order
here doesn't affect what gets overridden. That is controlled
by OVERRIDE_ORDER. However this does control the order they are
displayed to the user. It's probably most ergononmic to display
things in the same order as OVERRIDE_ORDER
"""
# SMELL: Move the conditions out of this function

# environment variables have the lowest priority
config_file = os.environ.get("PIP_CONFIG_FILE", None)
if config_file is not None:
yield kinds.ENV, [config_file]
else:
yield kinds.ENV, []

env_config_file = os.environ.get("PIP_CONFIG_FILE", None)
config_files = get_configuration_files()

# at the base we have any global configuration
yield kinds.GLOBAL, config_files[kinds.GLOBAL]

# per-user configuration next
# per-user config is not loaded when env_config_file exists
should_load_user_config = not self.isolated and not (
config_file and os.path.exists(config_file)
env_config_file and os.path.exists(env_config_file)
)
if should_load_user_config:
# The legacy config file is overridden by the new config file
yield kinds.USER, config_files[kinds.USER]

# finally virtualenv configuration first trumping others
# virtualenv config
yield kinds.SITE, config_files[kinds.SITE]

if env_config_file is not None:
yield kinds.ENV, [env_config_file]
else:
yield kinds.ENV, []

def get_values_in_config(self, variant: Kind) -> Dict[str, Any]:
"""Get values present in a config file"""
return self._config[variant]
Expand Down
13 changes: 4 additions & 9 deletions src/pip/_internal/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -247,10 +247,7 @@ def __init__(
def __str__(self) -> str:
# Use `dist` in the error message because its stringification
# includes more information, like the version and location.
return "None {} metadata found for distribution: {}".format(
self.metadata_name,
self.dist,
)
return f"None {self.metadata_name} metadata found for distribution: {self.dist}"


class UserInstallationInvalid(InstallationError):
Expand Down Expand Up @@ -594,7 +591,7 @@ def __init__(self, allowed: Dict[str, List[str]], gots: Dict[str, "_Hash"]) -> N
self.gots = gots

def body(self) -> str:
return " {}:\n{}".format(self._requirement_name(), self._hash_comparison())
return f" {self._requirement_name()}:\n{self._hash_comparison()}"

def _hash_comparison(self) -> str:
"""
Expand All @@ -616,11 +613,9 @@ def hash_then_or(hash_name: str) -> "chain[str]":
lines: List[str] = []
for hash_name, expecteds in self.allowed.items():
prefix = hash_then_or(hash_name)
lines.extend(
(" Expected {} {}".format(next(prefix), e)) for e in expecteds
)
lines.extend((f" Expected {next(prefix)} {e}") for e in expecteds)
lines.append(
" Got {}\n".format(self.gots[hash_name].hexdigest())
f" Got {self.gots[hash_name].hexdigest()}\n"
)
return "\n".join(lines)

Expand Down
Loading

0 comments on commit 0668050

Please sign in to comment.