Fix: repair the eval-set route NameError, and select ruff F821 so undefined names cannot return to src/ - #200
Open
AmaadMartin wants to merge 3 commits into
Open
Conversation
added 3 commits
August 9, 2026 14:04
…ameError
The route POST /dev/apps/{app_name}/eval_sets/{eval_set_id} built its request
body from UserEvalSet, a name that never existed in this repository. Every
request to the route died with NameError before it reached the create path.
The field's own declared type is EvalSet, already imported in dev_server.py.
The regression test for this defect was marked xfail(strict=True). Strict xfail
reports an unexpected pass as a failure, so the marker is removed and the test
now guards the repaired route.
Each name was used in an annotation but never imported, so the annotation was a static-typing lie. ADK resolves tool annotations at runtime with get_type_hints(), which makes an unimportable name a real hazard. api_server.py types two constructor parameters, so its imports go under TYPE_CHECKING, matching cli/utils/evals.py. The environment_simulation modules take plain module-level imports, matching every sibling in that package. Self comes from typing_extensions because requires-python is >=3.10.
F821 was never selected, so nothing in the repository ran it. The pre-commit ruff hook is scoped files: ^src/ and is the only ruff invocation, so this enforces the rule on src/ without touching the tests/ backlog.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Please ensure you have read the contribution guide before creating a pull request.
Link to Issue or Description of Change
N/A
Problem: Ruff
lint.selectdoes not containF821, so nothing in the repository ever checks for undefined names. Enabling the rule reports 8 findings insrc/. One of them is a real defect:dev_server.pybuilds its request body fromUserEvalSet, a name that has never existed here, so the deprecated routePOST /dev/apps/{app_name}/eval_sets/{eval_set_id}raisesNameErroron every request. The other 7 are annotations that reference a name the module never imports, which breaks any consumer that resolves hints at runtime.Solution: I triaged all 8 findings individually and fixed each at its root.
UserEvalSetbecomesEvalSet, the field's own declared type, already imported indev_server.py. The other 7 get the import they were missing. ThenF821goes intolint.selectso the class of defect cannot come back. I added no# noqa.The
Selffindings were not breaking anything at runtime.environment_simulation_config.pyhasfrom __future__ import annotations, and pydantic does not resolve the return annotation of anaftermodel validator. They are a typing defect, not a behaviour change.Import placement follows the existing precedent in each file.
api_server.pyonly needs the two eval-manager names for constructor annotations, so they go underTYPE_CHECKING, matchingcli/utils/evals.py. Theenvironment_simulationmodules take plain module-level imports, matching all five siblings in that package.Selfcomes fromtyping_extensionsbecauserequires-pythonis>=3.10andtyping.Selfis 3.11+;typing-extensions>=4.5,<5is already a core dependency, so this adds none.Scope.
tests/has 53F821findings and is deliberately out of scope; it is queued separately. The pre-commitruffhook is scopedfiles: ^src/and is the only ruff invocation in the repository, so enabling the rule cannot turn CI red on that backlog. I did not add atests/**per-file-ignore, because that would relabel real undefined names as permanently allowed.Collision check. I listed all 199 open pull requests on the fork and diffed every one that touches
pyproject.toml,api_server.py,dev_server.py, orenvironment_simulation/. No PR does this change. #17 (fix/cli-mypy-strict) contains the same one-lineUserEvalSet->EvalSetfix inside a 32-file mypy pass, but it isCONFLICTINGagainstmainand it leaves thexfail(strict=True)marker in place, so it would turn the suite red. I branched frommainrather than stacking on a conflicting branch, to keep this diff at 7 files.Testing Plan
Please describe the tests that you ran to verify your changes. This is required for all PRs that are not small documentation or typo fixes.
Unit Tests:
[x] I have added or updated unit tests for my change.
[x] All unit tests pass locally.
The repository already had the regression test for the one behavioural defect, at
tests/unittests/cli/test_fast_api.py. It was marked@pytest.mark.xfail(strict=True, reason="legacy create-eval-set route references an undefined name"). Strict xfail reports an unexpected pass as a failure, so I removed the marker. I changed no assertion in the body. It still assertsresponse.status_code == 200and thatmock_eval_sets_manager.get_eval_set("test_app", "legacy_eval_set")is notNone, and its fixture is a realInMemoryEvalSetsManager, not a mock.I wrote no new test for the 7 annotation findings. They change no runtime behaviour, and the
lint.selectchange is their regression guard.Mutation proof. I ran each guard against the unfixed code and confirmed it fails.
EvalSetback toUserEvalSetindev_server.py:BaseTool,Self) and ran the lint gate:Both were restored, and the full run is green again.
Manual End-to-End (E2E) Tests:
Please provide instructions on how to manually test your changes, including any necessary setup or configuration.
Two of the new imports are runtime imports, so I checked each touched module in a cold interpreter for a circular import. All succeed:
Gates run locally on the pushed commit, with
ruff==0.15.17, the pin inpyproject.tomland.pre-commit-config.yaml:The remaining
1 xfailedis a different, pre-existing xfail that this change does not touch.mypy. I ran the same A/B the CI gate runs (
mypy . | grep "error:" | sed 's/:\([0-9]\+\):/::/g' | sort, thencomm) againstmain:name-definederrors matching theF821findings, plus 3no-any-returnerrors indev_server.pythat disappear becauseself.eval_sets_manageris no longer inferred asAny.Total repository errors drop from 1600 to 1589.
CI. Unit Tests pass on Python 3.10, 3.11, 3.12, 3.13 and 3.14. Mypy Check passes on 3.10, 3.11, 3.12 and 3.13. A2A v0.3 Tests pass on all five versions.
Pre-commit Linterfails, for a reason unrelated to this change. Theupdate-constraintshook regenerates the fiveconstraints-*.txtfiles, finds a newer snapshot date, and exits 1. I reproduced it onmainwith an empty working tree:The same job fails the same way on #199, #198 and #197, which touch neither
pyproject.tomlnor the constraints files. #163, #56, #54 and #49 are already open against this hook. I did not fix it here.Checklist
[x] I have read the CONTRIBUTING.md document.
[x] I have performed a self-review of my own code.
[x] I have commented my code, particularly in hard-to-understand areas.
[x] I have added tests that prove my fix is effective or that my feature works.
[x] New and existing unit tests pass locally with my changes.