Skip to content

Introspection: use SupportsIndex and SupportsFloat for int and float input - #6396

Open
jorenham wants to merge 1 commit into
PyO3:mainfrom
jorenham:introspection/SupportsIndex
Open

Introspection: use SupportsIndex and SupportsFloat for int and float input#6396
jorenham wants to merge 1 commit into
PyO3:mainfrom
jorenham:introspection/SupportsIndex

Conversation

@jorenham

@jorenham jorenham commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

This widens the generated input annotations for int to typing.SupportsIndex and for float to typing.SupportsFloat | typing.SupportsIndex. This way, numpy scalars like np.int_ are no longer falsely rejected by type-checkers, even though it's supported at runtime.

@MatthieuDartiailh

MatthieuDartiailh commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

Out of curiosity why use SupportsIndex instead of SupportsInt since this is for generic int support and not for int as index support.

@jorenham

jorenham commented Sep 8, 2026

Copy link
Copy Markdown
Contributor Author

Ou of curiosity why use SupportsIndex instead of SupportsInt since this for generic int support and not for int as index support.

Because if you pass an object with only __int__ and no __index__, it'll result in a TypeError. Or at least, that's the case in pyo3_pytests.

@MatthieuDartiailh

Copy link
Copy Markdown
Contributor

Ok so I guess pyo3 relies on index rather than int for conversion. I am a bit surprised but an annotation change is not the right place to change this behavior.

@jonasdedden

jonasdedden commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

(caution: not a PyO3 maintainer) I think this PR is correct and also does correctly reflect what PyO3 is doing internally for integer conversions, as it's using this macro AFAIS.

I think the reason why reliance on __index__ and not __int__ was chosen is some Python data model distinction:

  • __index__: lossless “can be interpreted as integer” (used for indexing, C-int conversion). float, str, Decimal("1.1") do not provide it.
  • __int__: explicit, possibly lossy int(x) conversion.

EDIT: Just to show this:

>>> 1.2.__int__()
1

It makes sense I guess that PyO3 chose not to accept classes purely implementing __int__ (but not __index__) for integer inputs.

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.

3 participants