Skip to content

Declare dataclasses.field as a field specifier for @control and @value - #7084

Merged
FeodorFitsner merged 3 commits into
flet-dev:mainfrom
joaoaracheski:fix-dataclass-transform-field-specifiers
Nov 14, 2026
Merged

FeodorFitsner merged 3 commits into
flet-dev:mainfrom
joaoaracheski:fix-dataclass-transform-field-specifiers

Conversation

@joaoaracheski

@joaoaracheski joaoaracheski commented Nov 13, 2026 •

Copy link
Copy Markdown
Contributor

Description

Fixes #6377.

@control and @value use @dataclass_transform() without field_specifiers. Per the typing spec, type checkers then don't treat dataclasses.field() as a field specifier, so its arguments are ignored: a field declared with field(init=False) is still accepted as an __init__ argument. At runtime both decorators wrap dataclasses.dataclass, so field() already works there; this only aligns the static view with the runtime.

This PR adds field_specifiers=(dataclasses.field,) to both decorators.

skip_field() is intentionally not listed. It calls field(default=None, ...) internally, but checkers only see a default when the call passes default= explicitly, so listing it would turn fields declared with skip_field() into required parameters.

Test code

from dataclasses import field

import flet as ft
from flet.controls.base_control import control
from flet.controls.value_types import value


@control("MyControl")
class MyControl(ft.Control):
    internal: int = field(init=False, default=0)


@value
class MyValue:
    internal: int = field(init=False, default=0)


MyControl(internal=1)  # should be reported: `internal` is init=False
MyValue(internal=1)  # should be reported: `internal` is init=False

mypy before: no error on the last two lines.
mypy after:

error: Unexpected keyword argument "internal" for "MyControl"  [call-arg]
error: Unexpected keyword argument "internal" for "MyValue"  [call-arg]

Also added test_dataclass_transforms_declare_field_specifiers to test_base_control.py; it fails without the fix and passes with it.

Type of change

  • Bug fix (non-breaking change which fixes an issue)

Checklist

  • I signed the CLA.
  • I have performed a self-review of my own code.
  • My code follows the style guidelines of this project.
  • I have commented my code, particularly in hard-to-understand areas.
  • My changes generate no new warnings.
  • New and existing tests pass locally with my changes.
  • I have made corresponding documentation changes, if applicable.
  • I have added changelog entries for user-facing changes, if applicable.
  • I have updated release guide pages and website/sidebars.yml for breaking changes, removals, and deprecations, if applicable.

Additional details

uv run --group test pytest packages/flet/tests: 507 passed, 8 skipped. ruff check and ruff format --check are clean on the changed files.

I didn't add a changelog entry because there's no section for the next release yet. Happy to add it where you prefer, e.g. under Bug fixes:

  • Fix type checkers ignoring dataclasses.field() arguments such as init=False in classes decorated with @control and @value (#6377) by @joaoaracheski.

Side note, unrelated to this PR: with @control("MyControl") mypy also reports Argument 1 has incompatible type "type[MyControl]"; expected "type[Never]" on the class line. I can open a separate issue for it if useful.

Summary by Sourcery

Align the static dataclass behavior of @control and @value with their runtime behavior by declaring dataclasses.field as a supported field specifier.

Bug Fixes:

  • Ensure type checkers honor dataclasses.field() options such as init=False for classes decorated with @control and @value.],
  • enhancements=[],
  • build=[],
  • ci=[],
  • deployment=[],
  • docs=[],
  • tests=[

Tests:

  • Add coverage verifying both decorators declare dataclasses.field as a dataclass field specifier.

Fixes flet-dev#6377. Without field_specifiers, type checkers ignore dataclasses.field() arguments such as init=False on classes built with @control and @value.
Copilot AI balanced review requested due to automatic review settings November 13, 2026 18:53
@CLAassistant

CLAassistant commented Nov 13, 2026 •

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has insufficient remaining quota. Try requesting a review at a lower effort level.

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've reviewed your changes and they look great!


Sourcery is free for open source - if you like our reviews please consider sharing them ✨

@ndonkoHenri ndonkoHenri left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your contribution! Looks good to me.

Please add a changelog entry as you suggested.

@FeodorFitsner
FeodorFitsner merged commit f718129 into flet-dev:main Nov 14, 2026
16 of 85 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug: dataclass_transform() uses should include field_specifiers argument

5 participants