Skip to content

Add stub generation support for overloads.#5957

Open
tychedelia wants to merge 8 commits intoPyO3:mainfrom
tychedelia:overloads
Open

Add stub generation support for overloads.#5957
tychedelia wants to merge 8 commits intoPyO3:mainfrom
tychedelia:overloads

Conversation

@tychedelia
Copy link
Copy Markdown

Partially addresses #5137.

We need support for overloads in stub generation in our project. I mostly copied the argument parsing code and tried to extract that as shared helpers for the overload support. I'm not totally sure about the error path, this may be a bit brittle, but I added some baseline tests to ensure it works.

@Tpt
Copy link
Copy Markdown
Contributor

Tpt commented Apr 7, 2026

Thank you very much for working on this large topic. I have not reviewed the MR in details yet but I have a few questions.

About the #[pyo3(...)] attribute syntax I would tend to think that something like the following would be clearer and more aligned with signature:

#[pyo3(overloads = [
    (foo: "int") -> "int",
    (foo: "float") -> "float"
])]
fn my_function() {
}

this enforces that only a single attribute set overloads making sure there is only a single source of truth for overloads, preventing footguns that two different macros inserting conflicting overloads. But I don't feel strongly on that and @davidhewitt might disagree.

It would be great to provide more careful validations like checking if overloads are consistent with the default signature (same default value...). But I am fine to have that in follow-ups to avoid a too large MR.

On the emitted stubs, the python typing doc state: All variants of overloaded functions and methods must have an @overload decorator. Do not include the implementation’s final non-@overload-decorated definition.. I would tend to think we should follow that.

Thank you aggain!

@tychedelia
Copy link
Copy Markdown
Author

I would tend to think that something like the following would be clearer and more aligned with signature:

Okay, I think that makes sense. I wasn't totally sure about the whether to go for single attr or multiple, but looking at your example I think I prefer this as well.

On the emitted stubs, the python typing doc state: "All variants of overloaded functions and methods must have an @overload decorator. Do not include the implementation’s final non-@overload-decorated definition.". I would tend to think we should follow that.

Yeah, mypy actually just caught this, I've fixed it up.

@tychedelia
Copy link
Copy Markdown
Author

Okay I'm waffling back and forth on the syntax, but happy to support whatever the project wants I'm agnostic.

Copy link
Copy Markdown
Contributor

@Tpt Tpt left a comment

Choose a reason for hiding this comment

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

Okay I'm waffling back and forth on the syntax, but happy to support whatever the project wants I'm agnostic.

I think I prefer:

#[pyo3(overloads = [
    (foo: "int") -> "int",
    (foo: "float") -> "float"
])]

but I do not feel strongly so glad to change my mind on this topic. This is also something we can tweak in follow ups.

#[serde(default)]
doc: Option<String>,
#[serde(default)]
overloads: Vec<ChunkOverload>,
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.

open design question: do we want to have overloads field in the introspection JSON with the olverloads or be closer to the final Python stubs and just have multiple Function chunks with the @overload decorator (and not chunk for the base function)?

I feel that it's underlying a deeper question on if the introspection data must be a more "semantic" AST or more "syntactic" one closer to the Python stubs.

);
}
if !overloads.is_empty() {
let overload_nodes: Vec<AttributedIntrospectionNode<'_>> = overloads
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.

hyper-nit: I am not sure the explicit type is useful here:

Suggested change
let overload_nodes: Vec<AttributedIntrospectionNode<'_>> = overloads
let overload_nodes = overloads

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.

2 participants