build(deps): bump typeguard from 2.13.3 to 4.6.0 - #23
Conversation
Bumps [typeguard](https://github.com/agronholm/typeguard) from 2.13.3 to 4.6.0. - [Release notes](https://github.com/agronholm/typeguard/releases) - [Commits](agronholm/typeguard@2.13.3...4.6.0) --- updated-dependencies: - dependency-name: typeguard dependency-version: 4.6.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com>
nishantmodak
left a comment
There was a problem hiding this comment.
Reviewed a195845b8c708b44eb5876d1911ec06f074a9908: both changed dependency files, Python support/setup and CI contracts, typeguard usage across the package, subprocess/health-check paths and representative CLI, parsing and metric consumers. One P1 blocks approval: the major upgrade rejects actual subprocess results and breaks DCGM diagnostics. The inline thread includes three executed, copyable base-versus-head regression cases.
Validation: the declared dev/runtime dependency install succeeded on Python 3.12.9; 134 focused existing tests pass. The broader local suite, excluding two modules that fail collection on an unchanged macOS timezone assumption, reports 726 passed / 64 failed / 1 skipped on head versus 766 passed / 24 failed / 1 skipped on base. Forty additional failing test cases need migration; some concern test-double protocol signatures, so I am not claiming forty distinct production bugs. A separate 15-case exploratory harness passes 12 cases on both heads (including 100 seeded parser examples); its three device/job attribution failures are identical on base and are not reported as introduced defects.
GitHub's Python 3.10/3.11/3.12 jobs are failed; the other ten checks are successful. Their job steps/log cause was not available, so this review relies on local evidence rather than attributing remote failures. Limits: the local install resolved the declared dependency groups rather than installing the entire hashed dev lockfile; base used that same environment with only typeguard changed. The complete suite is not green; no Linux runtime, GPU hardware, live exporter, infrastructure service or container was exercised. These limits do not affect the reproduced subprocess contract regression. No source changes were pushed.
| "typing_extensions", | ||
| "click==8.0.4", | ||
| "typeguard==2.13.3", | ||
| "typeguard==4.6.0", |
There was a problem hiding this comment.
[P1] Migrate subprocess result contracts before enabling typeguard 4
This upgrade instruments annotated local assignments and validates protocol attributes. The real DCGMImpl returns shell_command() results whose CompletedProcess.args is a string and stderr is None (shell=True, stderr=STDOUT), but ShellCommandOut requires List[str] and str. At check_dcgmi.py:461, a normal command result now raises TypeCheckError; the exception recovery result then fails the same protocol's stderr check. The timeout path fails as well.
I reproduced this through the actual CLI, DCGMImpl, shell wrapper and output contexts with only the subprocess boundary replaced. A passing GPU diagnostic, a failing diagnostic, and a timeout all end with WARNING - check did not exit normally and TypeCheckError, instead of their expected OK/CRITICAL/WARN result and diagnostic message. This breaks the health-check path even for valid command output and can turn a critical result into an unexplained warning.
Update the subprocess protocol and recovery values to reflect the real producer contract, and audit the newly enforced annotated assignments and protocol consumers before taking the major upgrade. Keep this dependency at its compatible version until those migrations and the affected tests pass. Do not solve this only by changing test fakes: the production CompletedProcess shape triggers the failure.
Executed regression at a195845b8c708b44eb5876d1911ec06f074a9908: save the following as l9gpu/tests/test_typeguard_subprocess_review.py. With Python 3.12 and the PR's declared dependencies installed (python -m pip install -e '.[dev,k8s]'), run:
python -m pytest -q l9gpu/tests/test_typeguard_subprocess_review.pyimport json
import subprocess
from unittest.mock import patch
import pytest
from click.testing import CliRunner
from l9gpu.health_checks.checks.check_dcgmi import DCGMImpl, check_dcgmi
@pytest.mark.parametrize("status,code,message", [
("Pass", 0, "All checks passed"),
("Fail", 2, "software failed"),
("timeout", 1, "Error command timeout because of timeout setting"),
])
def test_real_subprocess_contract(tmp_path, status, code, message):
def fake_run(cmd, **kwargs):
# Same CompletedProcess shape as the production shell=True /
# stderr=STDOUT / text-mode subprocess.run invocation.
assert kwargs["shell"] is True
assert kwargs["stderr"] is subprocess.STDOUT
if status == "timeout":
raise subprocess.TimeoutExpired(cmd, kwargs["timeout"])
body = {"DCGM Diagnostic": {"test_categories": [
{"tests": [{"name": "software", "test_summary": {"status": status}}]}
]}}
return subprocess.CompletedProcess(cmd, 0, json.dumps(body), None)
obj = DCGMImpl("synthetic", "nagios", "INFO", str(tmp_path), "localhost")
with patch("l9gpu.health_checks.subprocess.subprocess.run", side_effect=fake_run):
result = CliRunner().invoke(check_dcgmi, [
"diag", "synthetic", "nagios", "--log-folder", str(tmp_path),
"--sink", "do_nothing", "--verbose-out",
], obj=obj)
assert result.exit_code == code, (result.output, repr(result.exception))
assert message in result.output, (result.output, repr(result.exception))Executed on Python 3.12.9: all three cases fail on this head. The identical test passes all three at base 215314527174c7e59743f21fde067be26db5fff1 with typeguard 2.13.3 and otherwise identical resolved dependencies. The failure assertions show TypeCheckError on the ShellCommandOut attributes. No GPU, subprocess command, service, or external telemetry endpoint is used by this test.
Bumps typeguard from 2.13.3 to 4.6.0.
Release notes
Sourced from typeguard's releases.
... (truncated)
Commits
9f289c7Added release datef7784d6Removed leftover compatibility code for Python 3.9 and earlierf971baaAdded support for the sentinel typeabf8f43Added the typeguard-packages-ignore option7e5102eFixed a typoa319de1Do not erase a meaningful empty tuple[()] subscript in the transformer (#565)dd7fa67Fixed Literal check depending on argument order for bools (#566)a42dc4dRecognize wildcard-imported Literal annotations (#549)f1007efFixed false positive checking a class against type[Protocol] with instance at...32e7c85Fixed annotated assignment expressions being treated as unpacking targets (#563)You can trigger a rebase of this PR by commenting
@dependabot rebase.Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR:
@dependabot rebasewill rebase this PR@dependabot recreatewill recreate this PR, overwriting any edits that have been made to it@dependabot show <dependency name> ignore conditionswill show all of the ignore conditions of the specified dependency@dependabot ignore this major versionwill close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)@dependabot ignore this minor versionwill close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)@dependabot ignore this dependencywill close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)