Skip to content

Commit 09f961a

Browse files
authored
Introspection: simplify code by leveraging that building type hint for containers now work (#5634)
* Introspection: simplify code by leveraging that building type hint for containers now work * Apply suggestion from @Tpt
1 parent d8e9a38 commit 09f961a

File tree

4 files changed

+18
-40
lines changed

4 files changed

+18
-40
lines changed

newsfragments/5634.changed.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Introspection: properly generate annotations for `Option<T>` in both input and output.

pyo3-macros-backend/src/introspection.rs

Lines changed: 8 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -339,34 +339,12 @@ fn argument_introspection_data<'a>(
339339
params.insert("annotation", IntrospectionNode::String(annotation.into()));
340340
} else if desc.from_py_with.is_none() {
341341
// If from_py_with is set we don't know anything on the input type
342-
if let Some(ty) = desc.option_wrapped_type {
343-
// Special case to properly generate a `T | None` annotation
344-
let mut ty = ty.clone();
345-
if let Some(class_type) = class_type {
346-
replace_self(&mut ty, class_type);
347-
}
348-
elide_lifetimes(&mut ty);
349-
params.insert(
350-
"annotation",
351-
IntrospectionNode::InputType {
352-
rust_type: ty,
353-
nullable: true,
354-
},
355-
);
356-
} else {
357-
let mut ty = desc.ty.clone();
358-
if let Some(class_type) = class_type {
359-
replace_self(&mut ty, class_type);
360-
}
361-
elide_lifetimes(&mut ty);
362-
params.insert(
363-
"annotation",
364-
IntrospectionNode::InputType {
365-
rust_type: ty,
366-
nullable: false,
367-
},
368-
);
342+
let mut ty = desc.ty.clone();
343+
if let Some(class_type) = class_type {
344+
replace_self(&mut ty, class_type);
369345
}
346+
elide_lifetimes(&mut ty);
347+
params.insert("annotation", IntrospectionNode::InputType(ty));
370348
}
371349
IntrospectionNode::Map(params).into()
372350
}
@@ -375,7 +353,7 @@ enum IntrospectionNode<'a> {
375353
String(Cow<'a, str>),
376354
Bool(bool),
377355
IntrospectionId(Option<Cow<'a, Type>>),
378-
InputType { rust_type: Type, nullable: bool },
356+
InputType(Type),
379357
OutputType { rust_type: Type, is_final: bool },
380358
ConstantType(PythonIdentifier),
381359
Map(HashMap<&'static str, IntrospectionNode<'a>>),
@@ -411,11 +389,8 @@ impl IntrospectionNode<'_> {
411389
});
412390
content.push_str("\"");
413391
}
414-
Self::InputType {
415-
rust_type,
416-
nullable,
417-
} => {
418-
let mut annotation = quote! {
392+
Self::InputType(rust_type) => {
393+
let annotation = quote! {
419394
<#rust_type as #pyo3_crate_path::impl_::extract_argument::PyFunctionArgument<
420395
{
421396
#[allow(unused_imports, reason = "`Probe` trait used on negative case only")]
@@ -424,9 +399,6 @@ impl IntrospectionNode<'_> {
424399
}
425400
>>::INPUT_TYPE
426401
};
427-
if nullable {
428-
annotation = quote! { #pyo3_crate_path::inspect::TypeHint::union(&[#annotation, #pyo3_crate_path::inspect::TypeHint::builtin("None")]) };
429-
}
430402
content.push_tokens(serialize_type_hint(annotation, pyo3_crate_path));
431403
}
432404
Self::OutputType {

src/conversions/std/option.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#[cfg(feature = "experimental-inspect")]
2+
use crate::inspect::TypeHint;
13
use crate::{
24
conversion::IntoPyObject, types::any::PyAnyMethods, BoundObject, FromPyObject, PyAny, Python,
35
};
@@ -10,6 +12,8 @@ where
1012
type Target = PyAny;
1113
type Output = Bound<'py, Self::Target>;
1214
type Error = T::Error;
15+
#[cfg(feature = "experimental-inspect")]
16+
const OUTPUT_TYPE: TypeHint = TypeHint::union(&[T::OUTPUT_TYPE, TypeHint::builtin("None")]);
1317

1418
fn into_pyobject(self, py: Python<'py>) -> Result<Self::Output, Self::Error> {
1519
self.map_or_else(
@@ -30,6 +34,8 @@ where
3034
type Target = PyAny;
3135
type Output = Bound<'py, Self::Target>;
3236
type Error = <&'a T as IntoPyObject<'py>>::Error;
37+
#[cfg(feature = "experimental-inspect")]
38+
const OUTPUT_TYPE: TypeHint = <Option<&T>>::OUTPUT_TYPE;
3339

3440
#[inline]
3541
fn into_pyobject(self, py: Python<'py>) -> Result<Self::Output, Self::Error> {
@@ -42,6 +48,8 @@ where
4248
T: FromPyObject<'a, 'py>,
4349
{
4450
type Error = T::Error;
51+
#[cfg(feature = "experimental-inspect")]
52+
const INPUT_TYPE: TypeHint = TypeHint::union(&[T::INPUT_TYPE, TypeHint::builtin("None")]);
4553

4654
fn extract(obj: Borrowed<'a, 'py, PyAny>) -> Result<Self, Self::Error> {
4755
if obj.is_none() {

src/impl_/extract_argument.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -108,10 +108,7 @@ where
108108
type Error = T::Error;
109109

110110
#[cfg(feature = "experimental-inspect")]
111-
const INPUT_TYPE: TypeHint = TypeHint::union(&[
112-
TypeHint::module_attr("typing", "Any"),
113-
TypeHint::builtin("None"),
114-
]);
111+
const INPUT_TYPE: TypeHint = TypeHint::union(&[T::INPUT_TYPE, TypeHint::builtin("None")]);
115112

116113
#[inline]
117114
fn extract(

0 commit comments

Comments
 (0)