Python: fix AttributeError in TyTypesClient.shutdown - #8434
Merged
Conversation
`shutdown` sends a bounded "shutdown" request and then reaps the process. That request counts toward the consecutive-timeout breaker added in #8423, so when it is the third consecutive timeout, `_kill` sets `_process` to None before `shutdown` reaches `self._process.wait(...)`. The resulting AttributeError is not covered by the surrounding `except (subprocess.TimeoutExpired, OSError)`, so it escapes the `finally` block in `handle_parse_project` and fails the whole ParseProject request, discarding every file already parsed. Also drops the `__init__` copies of `_responses` and `_consecutive_timeouts` that `_start_process` immediately overwrites, and brings the comments and imports added in #8423 in line with the project's line length.
knutwannheden
force-pushed
the
python-ty-client-shutdown-breaker
branch
from
August 10, 2026 07:08
baed0eb to
8d6ed15
Compare
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.
Motivation
TyTypesClient.shutdownsends a bounded"shutdown"request and then reaps the process. That request counts toward the consecutive-timeout circuit breaker introduced in #8423, so when it happens to be the third consecutive timeout — the realistic case being a ty process that has already wedged at the end of a parse —_killsetsself._processtoNonebeforeshutdownreachesself._process.wait(timeout=5). The resultingAttributeError: 'NoneType' object has no attribute 'wait'is not covered by the surroundingexcept (subprocess.TimeoutExpired, OSError), so it propagates out of thefinallyblock inhandle_parse_projectand fails the entire ParseProject RPC — discarding every source file that had already been parsed successfully, instead of degrading gracefully to untyped LSTs.Two smaller items from the same change ride along:
__init__initialized_responsesand_consecutive_timeoutsonly for_start_processto overwrite both before any reader thread exists, and several comments needed a discipline pass.Summary
shutdownholds the process in a local before sending the request, so reaping is unaffected by the breaker detachingself._process. This also removes the now-redundantis not Noneguard in theexceptbranch._responses/_consecutive_timeoutsassignments from__init__._start_processis the load-bearing one: it must reset both on a restart so a stale queue or timeout count cannot leak across ty sessions.ty_client.pyand one in the test module were over the configured 120-columnline-length, and the_start_processcomment referred toselect(), which the file no longer uses. Two comments that restated adjacent code were dropped, and an unusedsysimport removed from the test module.Test plan
test_shutdown_when_its_own_request_trips_the_breakerfails onmainwith the exactAttributeErroratty_client.py:350and passes here. It drives a newWEDGED_SERVERfake that answersinitializeand then goes silent, leaving_consecutive_timeoutsat 2 so that theshutdownrequest itself trips the breaker.pytest tests/python/test_ty_client.py— 5 passed.pytest tests/python— 1603 passed, 10 skipped.ruff check --select E501,F401clean on both changed files.