Skip to content

Fix property access for function types - #21885

Open
daleselaji-dev wants to merge 3 commits into
python:masterfrom
daleselaji-dev:fix/property-function-type-narrowing-21879
Open

Fix property access for function types#21885
daleselaji-dev wants to merge 3 commits into
python:masterfrom
daleselaji-dev:fix/property-function-type-narrowing-21879

Conversation

@daleselaji-dev

@daleselaji-dev daleselaji-dev commented Aug 24, 2026

Copy link
Copy Markdown

Problem

Mypy treats a property returning types.FunctionType as a bound method when the value is accessed from an instance. A valid isinstance(..., FunctionType) assertion is therefore reported as an impossible intersection with MethodType when --warn-unreachable is enabled.

Root Cause

Member analysis can apply descriptor access a second time after a property getter has already produced its value. The original fix skipped that duplicate pass for read-only properties, but the first review repair also exposed an existing dataclass-transform descriptor case whose synthetic read-only field still needs descriptor access.

Solution

Skip the duplicate descriptor pass for ordinary read-only property results while preserving descriptor evaluation for fields recorded in the dataclass-transform metadata. This keeps the reported FunctionType property narrowing correct without regressing generic descriptor-backed dataclass fields.

Changes

  • Avoid the second descriptor binding for ordinary read-only property results in analyze_var.
  • Preserve descriptor access for synthetic dataclass fields by checking the field metadata.
  • Keep the original focused FunctionType/MethodType regression and descriptor fixture.
  • Fix the related CI regression on check-dataclass-transform.test.

Testing

  • Reproduction before fix: current main revealed wrapped.__func__ as types.MethodType and emitted two [unreachable] errors.
  • Property regression plus dataclass regression: pytest -n0 mypy/test/testcheck.py -k 'testPropertyReturningFunctionType or testDataclassTransformGenericDescriptor' — 3 passed.
  • Full check-classes.test: 610 passed, 1 existing xfailed.
  • Self typecheck: python -m mypy --config-file mypy_self_check.ini -p mypy — 196 source files, no issues.
  • Ruff: not verified; the local environment has no Ruff module.
  • git diff --check: passed.
  • CI repair evidence: run 32691141642 failed consistently on the pre-existing check-dataclass-transform.test expectation after the original diff; the new same-scope head is 3f4c859 and the local regression is green.

Compatibility/Risk

Only static member-type analysis is changed. Ordinary read-only properties retain value semantics, settable properties retain their descriptor behavior, and synthetic dataclass-transform descriptor fields retain instance access through __get__. Runtime Python behavior is unchanged.

Notes for Reviewer

The added metadata check is intentionally narrow: it identifies a dataclass field by the existing info.metadata["dataclass"]["attributes"] record instead of broadening descriptor handling for every property. This contribution was AI-assisted.

Linked Issue

Fixes #21879

@daleselaji-dev
daleselaji-dev marked this pull request as ready for review August 24, 2026 03:17
@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

Copy link
Copy Markdown
Contributor

Diff from mypy_primer, showing the effect of this PR on open source code:

colour (https://github.com/colour-science/colour)
- colour/continuous/signal.py:1207: error: Argument 1 to "as_float_array" has incompatible type "ndarray[tuple[int], dtype[Any]] | ExtensionArray"; expected "Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | complex | bytes | str | _NestedSequence[complex | bytes | str]"  [arg-type]
+ colour/continuous/signal.py:1207: error: Argument 1 to "as_float_array" has incompatible type "ndarray[tuple[int], dtype[Any]] | ExtensionArray | Categorical[object]"; expected "Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | complex | bytes | str | _NestedSequence[complex | bytes | str]"  [arg-type]

freqtrade (https://github.com/freqtrade/freqtrade)
+ freqtrade/freqai/freqai_interface.py:950: error: Argument 1 to "to_datetime" has incompatible type "Any | object"; expected "float | str | datetime | datetime64[Any] | date"  [arg-type]

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.

Property annotated as FunctionType triggers false unreachable error on isinstance check

1 participant