Skip to content

[feat]: allowing all fields to be set as default for FromPyObject #5163

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
WSH032 opened this issue May 22, 2025 · 0 comments
Open

[feat]: allowing all fields to be set as default for FromPyObject #5163

WSH032 opened this issue May 22, 2025 · 0 comments

Comments

@WSH032
Copy link

WSH032 commented May 22, 2025

In #4829 (comment), FromPyObject was intentionally designed to disallow all fields being set with #[pyo3(default)]. I wonder if this is because:

ref: #4829 (comment)

the surprising behavior that a variant Foo { #[pyo3(default)] value: usize } becomes a catch-all just like the Foo {} variant.

However, for me, this behavior makes sense, as I use it to extract class Foo(TypedDict, total=False) for typed kwargs.

// 💥 cannot derive FromPyObject for structs and variants with only default values
#[derive(FromPyObject)]
#[pyo3(from_item_all)]
pub struct Foo {
    #[pyo3(default)]
    id: Option<i32>,
}

#[pyfunction]
#[pyo3(signature = (**kwargs))]
fn foo(kwargs: Option<&Bound<'_, PyDict>>) -> PyResult<()> {
    let foo: Option<Foo> = kwargs.map(|kwargs| kwargs.extract::<Foo>()).transpose()?;
    Ok(())
}
from typing_extensions import NotRequired, TypedDict, Unpack


class Foo(TypedDict, total=False):
    id: NotRequired[int]


def foo(**kwargs: Unpack[Foo]) -> None: ...

foo()  # ok
foo(id=1)  # ok
foo(id=1, foo=2)  # Err: no `foo` parameter
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant