Repository navigation
Fix @control(...) overload inferring type[Never] in mypy - #7087
Merged
FeodorFitsner merged 3 commits intoNov 14, 2026
Merged
Conversation
Fixes flet-dev#7085. The overload for @control(...) accepted type[T] as dart_widget_name, so a call with a string left T unbound and mypy inferred the returned decorator as Callable[[type[Never]], type[Never]]. The bare @control case is already covered by the first overload.
ndonkoHenri
approved these changes
Nov 13, 2026
ndonkoHenri
left a comment
Contributor
There was a problem hiding this comment.
Thanks! Please add a changelog entry.
FeodorFitsner
approved these changes
Nov 14, 2026
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.
Description
Fixes #7085.
The second overload of
control(used for@control(...)with arguments) typeddart_widget_nameasOptional[Union[type[T], str]]. When a string is passed,Tonly appears in the return type and stays unbound, so mypy solves it asNeverand reports:This PR narrows that parameter to
Optional[str]. The bare@controlcase (a class passed directly) is already handled by the first overload, so nothing changes at runtime and the implementation signature stays the same.Test code
mypy before:
type[Never]errors onMyControlandIso.mypy after:
Success: no issues found, and all three are revealed as their own class.pyright: no errors before or after (it already resolved these correctly).
Also added
test_control_args_overload_accepts_only_str_nametotest_base_control.py(checks the overload viatyping.get_overloads, skipped on Python 3.10); it fails without the fix and passes with it.Type of change
Checklist
website/sidebars.ymlfor breaking changes, removals, and deprecations, if applicable.Additional details
uv run --group test pytest packages/flet/tests: 507 passed, 8 skipped.ruff checkandruff format --checkare clean on the changed files.This touches the same file as #7084 but different lines, so they don't conflict except for both appending a test at the end of
test_base_control.py; I'll rebase whichever lands second.Changelog suggestion, under Bug fixes:
Summary by Sourcery
Correct the
@control(...)overload so mypy preserves the decorated class type instead of inferringtype[Never]. крепBug Fixes:
@control(...)usage by restricting the overload’s widget name parameter to strings.Tests:
controloverload accepts only an optional string widget name.