-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Make pyproject.toml the single definition for lint tool versions and settings #9067
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
Changes from all commits
5bf09d4
2aa2d14
5a51a44
733c6ce
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -18,17 +18,57 @@ | |
|
|
||
| from __future__ import annotations | ||
|
|
||
| import re | ||
| import sys | ||
| from collections.abc import Collection | ||
|
|
||
| BUILD_SYSTEM_KEY = "build-system" | ||
| PROJ_KEY = "project" | ||
| OPTS_KEY = "optional-dependencies" | ||
| DEP_KEY = "dependencies" | ||
| NAME_KEY = "name" | ||
| REQ_KEY = "requires" | ||
| TOML_FILE = "pyproject.toml" | ||
|
|
||
|
|
||
| def _expand_self_extras(dependencies: list[str], name: str, opts: dict) -> list[str]: | ||
| """ | ||
| Replace self-referential requirements such as ``monai[lint]`` with the contents of that group. | ||
|
|
||
| pip resolves such a requirement against the package index, so leaving one in a generated | ||
| requirements file installs the published release instead of the checkout being worked on. | ||
|
|
||
| Args: | ||
| dependencies: requirement strings, some of which may be self-references. | ||
| name: this project's name, the only one treated as a self-reference. | ||
| opts: the "optional-dependencies" table the groups are read from. | ||
|
|
||
| Returns: | ||
| List of requirements with every self-reference replaced by the group it names. | ||
|
|
||
| Raises: | ||
| KeyError: If a self-reference names a group absent from `opts`. | ||
| """ | ||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
| pattern = re.compile(rf"^{re.escape(name)}\s*\[([^\]]+)\]$", re.IGNORECASE) | ||
| expanded: list[str] = [] | ||
| pending = list(dependencies) | ||
| seen: set[str] = set() | ||
|
|
||
| while pending: | ||
| req = pending.pop(0) | ||
| match = pattern.match(req.strip()) | ||
| if match is None: | ||
| expanded.append(req) | ||
| continue | ||
| for group in (g.strip() for g in match.group(1).split(",")): | ||
| if group in seen: # a group already expanded, or a cycle | ||
| continue | ||
| seen.add(group) | ||
| pending.extend(opts[group]) | ||
|
Comment on lines
+63
to
+67
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
# Inspect current expansion logic and test coverage for extra-name spelling variants.
sed -n '34,69p' monai/config/print_dependencies.py
rg -n -C 3 'test\[.*(Lint|lint|_|-|\.).*?\]|optional-dependencies' tests/config/test_print_dependencies.pyRepository: Project-MONAI/MONAI Length of output: 2199 🌐 Web query:
💡 Result: According to the official PyPA specifications—specifically PEP 685 and the core metadata documentation—Python package extra names are normalized and compared using the same rules applied to distribution project names [1][2][3]. To normalize an extra name, the name must be lowercased, and all consecutive sequences of the characters '.', '', or '-' must be replaced with a single '-' character [4][5]. In Python, this normalization can be implemented using the following regex substitution: import re def normalize(name): return re.sub(r"[-.]+", "-", name).lower Key aspects of this process include: 1. Comparison: When comparing extra names for equality or during dependency resolution, tools must normalize both names using the rule above [1][3]. This ensures that variations such as friendly.bard, friendly_bard, and Friendly-Bard are all treated as equivalent [4][5]. 2. Metadata Requirements: For core metadata version 2.3 and later, projects are required to write out extra names in their normalized form [1][2]. Furthermore, tools generating metadata must raise an error if multiple extra names are provided that would normalize to the same name [1][6]. 3. Format: Valid extra names are constrained to consist of ASCII letters, numbers, and the characters '.', '_', or '-'. They must start and end with a letter or number [4][5]. PEP 685 (introduced in core metadata 2.3) further restricted extra names to guarantee they are unambiguous, mandating a format that matches the regex ^[a-z0-9]+(-[a-z0-9]+)*$ [2]. For older metadata versions, tools are encouraged to follow these normalization rules to ensure consistency, though they may encounter non-compliant legacy metadata [2][7]. Citations:
🏁 Script executed: #!/bin/bash
set -euo pipefail
sed -n '1,130p' monai/config/print_dependencies.py
printf '\n--- relevant tests ---\n'
sed -n '1,180p' tests/config/test_print_dependencies.py
printf '\n--- declared optional-dependency keys ---\n'
python3 - <<'PY'
import ast
from pathlib import Path
for path in Path(".").rglob("pyproject.toml"):
text = path.read_text()
print(path)
for line in text.splitlines():
if line.startswith(("lint =", "testing =", "all =", "cyclic =")):
print(line)
PYRepository: Project-MONAI/MONAI Length of output: 7628 🏁 Script executed: #!/bin/bash
set -euo pipefail
python3 - <<'PY'
import re
name = "monai"
opts = {"lint": ["ruff", "black"]}
pattern = re.compile(rf"^{re.escape(name)}\s*\[([^\]]+)\]$", re.IGNORECASE)
for requirement in ("monai[lint]", "monai[Lint]", "monai[lint-extra]", "monai[lint_extra]", "monai[lint.extra]"):
match = pattern.match(requirement.strip())
if match is None:
result = "not a self-reference"
else:
group = match.group(1).strip()
try:
result = opts[group]
except KeyError:
result = "KeyError"
print(f"{requirement}: {result}")
PYRepository: Project-MONAI/MONAI Length of output: 294 Normalize extra names before lookup.
🤖 Prompt for AI AgentsSource: Path instructions |
||
|
|
||
| return expanded | ||
|
|
||
|
|
||
| def parse_dependencies(filename: str | None = None, sections: Collection[str] | None = None) -> list[str]: | ||
| """ | ||
| Parse the toml file given by `filename` and return the dependency sections selected by `sections`. | ||
|
|
@@ -68,6 +108,8 @@ def parse_dependencies(filename: str | None = None, sections: Collection[str] | | |
| for s in sections: | ||
| dependencies += opts[s] | ||
|
|
||
| dependencies = _expand_self_extras(dependencies, proj[NAME_KEY], opts) | ||
|
|
||
| return sorted(set(dependencies)) | ||
|
|
||
|
|
||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.