Skip to content

Commit a7381d8

Browse files
Python: stabilize dependency maintenance final checks (microsoft#6662)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent d108d4b commit a7381d8

2 files changed

Lines changed: 21 additions & 31 deletions

File tree

‎.github/workflows/python-dependency-maintenance.yml‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ jobs:
4949
working-directory: ./python
5050

5151
- name: Refresh lockfile after dev pin updates
52-
run: uv lock --upgrade
52+
run: uv lock
5353
working-directory: ./python
5454

5555
- name: Save dev dependency changes
@@ -285,7 +285,7 @@ jobs:
285285
286286
- name: Refresh lockfile after dependency range updates
287287
if: steps.validate_bounds_test.outcome == 'success' && steps.validate_ranges.outcome == 'success'
288-
run: uv lock --upgrade
288+
run: uv lock
289289
working-directory: ./python
290290

291291
- name: Install final dependency set

‎python/scripts/dependencies/_dependency_bounds_upper_impl.py‎

Lines changed: 19 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
import threading
1818
from dataclasses import dataclass
1919
from datetime import datetime, timezone
20-
from functools import lru_cache
2120
from pathlib import Path
2221
from urllib import error as urllib_error
2322
from urllib import request as urllib_request
@@ -39,6 +38,7 @@
3938
CHECK_TASK_PRIORITY = ("check", "typing", "pyright", "mypy", "lint")
4039
AZURE_MONITOR_OPENTELEMETRY = "azure-monitor-opentelemetry"
4140
OPENTELEMETRY_SDK = "opentelemetry-sdk"
41+
VALIDATION_TOOL_DEV_PINS = frozenset({"mypy", "pyrefly", "pyright", "ruff", "ty", "zuban"})
4242
REQ_PATTERN = r"^\s*([A-Za-z0-9_.-]+(?:\[[^\]]+\])?)\s*(.*?)\s*$"
4343
SECTION_HEADER_PATTERN = re.compile(r"^\s*\[([^\]]+)\]\s*$")
4444
INLINE_ARRAY_ASSIGNMENT_PATTERN = re.compile(
@@ -252,25 +252,6 @@ def _exact_pin_version(requirement: Requirement) -> Version | None:
252252
return None
253253

254254

255-
@lru_cache(maxsize=8)
256-
def _load_workspace_package_versions(workspace_root: str) -> dict[str, Version]:
257-
workspace_path = Path(workspace_root)
258-
versions: dict[str, Version] = {}
259-
for package_pyproject in sorted((workspace_path / "packages").glob("*/pyproject.toml")):
260-
with package_pyproject.open("rb") as f:
261-
package_data = tomli.load(f)
262-
project_section = package_data.get("project", {}) or {}
263-
package_name = str(project_section.get("name", "")).strip().lower()
264-
package_version = project_section.get("version")
265-
if not package_name or not package_version:
266-
continue
267-
try:
268-
versions[package_name] = Version(str(package_version))
269-
except InvalidVersion:
270-
continue
271-
return versions
272-
273-
274255
def _collect_dev_pin_replacements(
275256
pyproject_file: Path,
276257
*,
@@ -287,8 +268,6 @@ def _collect_dev_pin_replacements(
287268
optional_dependencies.keys(),
288269
dependency_groups.keys(),
289270
)
290-
workspace_versions = _load_workspace_package_versions(str(pyproject_file.parent.parent.parent.resolve()))
291-
292271
dev_requirements: list[str] = []
293272
dev_requirements.extend(
294273
requirement for requirement in (optional_dependencies.get("dev", []) or []) if isinstance(requirement, str)
@@ -322,16 +301,27 @@ def _collect_dev_pin_replacements(
322301
continue
323302
dependency_name = parsed_requirement.name.lower()
324303
if dependency_name.startswith("agent-framework"):
325-
latest_version = workspace_versions.get(dependency_name)
326-
else:
327-
# Dev-tool refreshes should follow the selected version source (PyPI by default)
328-
# instead of being pinned by the current lockfile. VersionCatalog already falls
329-
# back to lock data when PyPI cannot be reached or --version-source=lock is used.
330-
latest_version = _select_latest_dev_version(catalog.get(dependency_name))
304+
logger.info(
305+
"Skipping %s in %s because internal package pins are maintained by package versioning.",
306+
dependency_name,
307+
pyproject_file,
308+
)
309+
continue
310+
# Dev-tool refreshes should follow the selected version source (PyPI by default)
311+
# instead of being pinned by the current lockfile. VersionCatalog already falls
312+
# back to lock data when PyPI cannot be reached or --version-source=lock is used.
313+
latest_version = _select_latest_dev_version(catalog.get(dependency_name))
331314
if latest_version is None:
332315
continue
333316
current_exact_version = _exact_pin_version(parsed_requirement)
334-
if current_exact_version is None and not dependency_name.startswith("agent-framework"):
317+
if current_exact_version is not None and dependency_name in VALIDATION_TOOL_DEV_PINS:
318+
logger.info(
319+
"Skipping %s in %s because validation tool upgrades should be handled separately.",
320+
dependency_name,
321+
pyproject_file,
322+
)
323+
continue
324+
if current_exact_version is None:
335325
locked_version = _select_latest_dev_version(catalog.get_lock(dependency_name))
336326
if locked_version is not None:
337327
latest_version = locked_version

0 commit comments

Comments
 (0)