Skip to content

fix: include complex in std::complex input annotation - #6113

Merged
rwgk merged 3 commits into
pybind:masterfrom
henryiii:fix/complex-input-annotation
Jul 27, 2026
Merged

fix: include complex in std::complex input annotation#6113
rwgk merged 3 commits into
pybind:masterfrom
henryiii:fix/complex-input-annotation

Conversation

@henryiii

@henryiii henryiii commented Jul 25, 2026

Copy link
Copy Markdown
Collaborator

See #6112.

🤖 AI text below 🤖

Description

Fixes #6102

The std::complex<T> caster declared its input annotation as
typing.SupportsComplex | typing.SupportsFloat | typing.SupportsIndex, which
omits the builtin complex. In typeshed, complex only gets __complex__ on
Python 3.11+, so on Python 3.10 a strict type checker rejects passing a plain
complex literal, although the caster accepts it. The input annotation now starts
with complex |, and the signature test was updated.

Suggested changelog entry:

  • Include the builtin complex type in the input annotation of the
    std::complex<T> type caster.

https://claude.ai/code/session_013JABmnjt9oAh29p1pytAB3

The input annotation for `std::complex<T>` omitted the builtin `complex`
type, which typeshed only makes a `typing.SupportsComplex` on Python 3.11+.

Assisted-by: ClaudeCode:claude-opus-5
Claude-Session: https://claude.ai/code/session_013JABmnjt9oAh29p1pytAB3
@henryiii
henryiii marked this pull request as ready for review July 26, 2026 03:01

@rwgk rwgk left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I added a comment (commit 87f6c85) and merged latest master.

@rwgk

rwgk commented Jul 27, 2026

Copy link
Copy Markdown
Collaborator

Why the explicit complex is not version-gated

I asked Codex to look specifically at whether the new complex | member should be guarded with something like #if PY_VERSION_HEX < 0x030B0000, since it is only needed as a separate union member when type checking for Python 3.10 and older.

The recommendation was to keep it unconditional and add an explanatory comment.

The strongest precedent is typeshed itself: its complex.__new__ annotation unconditionally uses complex | SupportsComplex | SupportsFloat | SupportsIndex, while complex.__complex__ is present only under sys.version_info >= (3, 11).

There are also two practical reasons not to use an #ifdef:

  • The annotation describes values accepted by the caster, and the caster accepts a builtin complex on every supported Python version. The explicit member is therefore accurate everywhere, even when it is redundant for a type checker targeting Python 3.11+.
  • PY_VERSION_HEX describes the Python headers used to compile the extension, which is not necessarily the version targeted by a generated or distributed stub. Version-gating the annotation could therefore reintroduce the Python 3.10 typing problem when stubs are generated once and used across multiple supported Python versions.

Keeping one stable annotation also avoids needlessly version-dependent docstrings and tests. The latest commit therefore documents the intentional redundancy next to the caster:

// `complex` does not satisfy `typing.SupportsComplex` in typeshed for Python <= 3.10.
// Keep it explicit so generated stubs targeting those versions accept complex values.

@rwgk
rwgk merged commit f95b7a5 into pybind:master Jul 27, 2026
78 checks passed
@rwgk
rwgk deleted the fix/complex-input-annotation branch July 27, 2026 04:25
@github-actions github-actions Bot added the needs changelog Possibly needs a changelog entry label Jul 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs changelog Possibly needs a changelog entry

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG]: type_caster<std::complex<T>>'s parameter annotation omits builtin complex for Python 3.10

2 participants