Skip to content

Commit a063c2b

Browse files
committed
Introspection: Set INPUT_TYPE and OUTPUT_TYPE on Vec<_> and &[]
Properly specialize for u8
1 parent c840dd7 commit a063c2b

File tree

6 files changed

+49
-1
lines changed

6 files changed

+49
-1
lines changed

src/conversion.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,11 @@ use crate::inspect::types::TypeInfo;
77
use crate::inspect::TypeHint;
88
use crate::pyclass::boolean_struct::False;
99
use crate::pyclass::{PyClassGuardError, PyClassGuardMutError};
10+
#[cfg(feature = "experimental-inspect")]
11+
use crate::type_object::PyTypeInfo;
1012
use crate::types::PyTuple;
13+
#[cfg(feature = "experimental-inspect")]
14+
use crate::types::{PyList, PySequence};
1115
use crate::{
1216
Borrowed, Bound, BoundObject, Py, PyAny, PyClass, PyClassGuard, PyErr, PyRef, PyRefMut, Python,
1317
};
@@ -109,6 +113,12 @@ pub trait IntoPyObject<'py>: Sized {
109113
let list = crate::types::list::try_new_from_iter(py, &mut iter);
110114
list.map(Bound::into_any)
111115
}
116+
117+
/// The output type of [`owned_sequence_into_pyobject`] and [`borrowed_sequence_into_pyobject`]
118+
#[cfg(feature = "experimental-inspect")]
119+
#[doc(hidden)]
120+
const SEQUENCE_OUTPUT_TYPE: TypeHint =
121+
TypeHint::subscript(&PyList::TYPE_HINT, &[Self::OUTPUT_TYPE]);
112122
}
113123

114124
pub(crate) mod private {
@@ -436,6 +446,12 @@ pub trait FromPyObject<'a, 'py>: Sized {
436446
Option::<NeverASequence<Self>>::None
437447
}
438448

449+
/// The union of Sequence[Self::INPUT_TYPE] and the input sequence extraction function [`sequence_extractor`] if it's defined
450+
#[cfg(feature = "experimental-inspect")]
451+
#[doc(hidden)]
452+
const SEQUENCE_INPUT_TYPE: TypeHint =
453+
TypeHint::subscript(&PySequence::TYPE_HINT, &[Self::INPUT_TYPE]);
454+
439455
/// Helper used to make a specialized path in extracting `DateTime<Tz>` where `Tz` is
440456
/// `chrono::Local`, which will accept "naive" datetime objects as being in the local timezone.
441457
#[cfg(feature = "chrono-local")]

src/conversions/smallvec.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ use crate::conversion::{FromPyObjectOwned, IntoPyObject};
1919
use crate::exceptions::PyTypeError;
2020
#[cfg(feature = "experimental-inspect")]
2121
use crate::inspect::types::TypeInfo;
22+
#[cfg(feature = "experimental-inspect")]
23+
use crate::inspect::TypeHint;
2224
use crate::types::any::PyAnyMethods;
2325
use crate::types::{PySequence, PyString};
2426
use crate::{
@@ -35,6 +37,9 @@ where
3537
type Output = Bound<'py, Self::Target>;
3638
type Error = PyErr;
3739

40+
#[cfg(feature = "experimental-inspect")]
41+
const OUTPUT_TYPE: TypeHint = A::SEQUENCE_OUTPUT_TYPE;
42+
3843
/// Turns [`SmallVec<u8>`] into [`PyBytes`], all other `T`s will be turned into a [`PyList`]
3944
///
4045
/// [`PyBytes`]: crate::types::PyBytes

src/conversions/std/array.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ where
1414
type Output = Bound<'py, Self::Target>;
1515
type Error = PyErr;
1616

17+
#[cfg(feature = "experimental-inspect")]
18+
const OUTPUT_TYPE: TypeHint = T::SEQUENCE_OUTPUT_TYPE;
19+
1720
/// Turns [`[u8; N]`](std::array) into [`PyBytes`], all other `T`s will be turned into a [`PyList`]
1821
///
1922
/// [`PyBytes`]: crate::types::PyBytes
@@ -47,6 +50,9 @@ where
4750
{
4851
type Error = PyErr;
4952

53+
#[cfg(feature = "experimental-inspect")]
54+
const INPUT_TYPE: TypeHint = T::SEQUENCE_INPUT_TYPE;
55+
5056
fn extract(obj: Borrowed<'_, 'py, PyAny>) -> PyResult<Self> {
5157
if let Some(extractor) = T::sequence_extractor(obj, crate::conversion::private::Token) {
5258
return extractor.to_array();

src/conversions/std/num.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ use crate::inspect::TypeHint;
88
use crate::py_result_ext::PyResultExt;
99
#[cfg(feature = "experimental-inspect")]
1010
use crate::type_object::PyTypeInfo;
11+
#[cfg(feature = "experimental-inspect")]
12+
use crate::types::PySequence;
1113
use crate::types::{PyByteArray, PyByteArrayMethods, PyBytes, PyInt};
1214
use crate::{exceptions, ffi, Borrowed, Bound, FromPyObject, PyAny, PyErr, PyResult, Python};
1315
use std::convert::Infallible;
@@ -283,6 +285,9 @@ impl<'py> IntoPyObject<'py> for &'_ u8 {
283285
{
284286
Ok(PyBytes::new(py, iter.as_ref()).into_any())
285287
}
288+
289+
#[cfg(feature = "experimental-inspect")]
290+
const SEQUENCE_OUTPUT_TYPE: TypeHint = PyBytes::TYPE_HINT;
286291
}
287292

288293
impl<'py> FromPyObject<'_, 'py> for u8 {
@@ -314,6 +319,13 @@ impl<'py> FromPyObject<'_, 'py> for u8 {
314319
None
315320
}
316321
}
322+
323+
#[cfg(feature = "experimental-inspect")]
324+
const SEQUENCE_INPUT_TYPE: TypeHint = TypeHint::union(&[
325+
TypeHint::subscript(&PySequence::TYPE_HINT, &[Self::INPUT_TYPE]),
326+
PyBytes::TYPE_HINT,
327+
PyByteArray::TYPE_HINT,
328+
]);
317329
}
318330

319331
pub(crate) enum BytesSequenceExtractor<'a, 'py> {

src/conversions/std/slice.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ where
2020
type Output = Bound<'py, Self::Target>;
2121
type Error = PyErr;
2222

23+
#[cfg(feature = "experimental-inspect")]
24+
const OUTPUT_TYPE: TypeHint = <&T>::SEQUENCE_OUTPUT_TYPE;
25+
2326
/// Turns [`&[u8]`](std::slice) into [`PyBytes`], all other `T`s will be turned into a [`PyList`]
2427
///
2528
/// [`PyBytes`]: crate::types::PyBytes
@@ -90,7 +93,7 @@ where
9093
type Error = PyErr;
9194

9295
#[cfg(feature = "experimental-inspect")]
93-
const OUTPUT_TYPE: TypeHint = <&[T]>::OUTPUT_TYPE;
96+
const OUTPUT_TYPE: TypeHint = <&T>::SEQUENCE_OUTPUT_TYPE;
9497

9598
/// Turns `Cow<[u8]>` into [`PyBytes`], all other `T`s will be turned into a [`PyList`]
9699
///

src/conversions/std/vec.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ where
1919
type Output = Bound<'py, Self::Target>;
2020
type Error = PyErr;
2121

22+
#[cfg(feature = "experimental-inspect")]
23+
const OUTPUT_TYPE: TypeHint = T::SEQUENCE_OUTPUT_TYPE;
24+
2225
/// Turns [`Vec<u8>`] into [`PyBytes`], all other `T`s will be turned into a [`PyList`]
2326
///
2427
/// [`PyBytes`]: crate::types::PyBytes
@@ -65,6 +68,9 @@ where
6568
{
6669
type Error = PyErr;
6770

71+
#[cfg(feature = "experimental-inspect")]
72+
const INPUT_TYPE: TypeHint = T::SEQUENCE_INPUT_TYPE;
73+
6874
fn extract(obj: Borrowed<'_, 'py, PyAny>) -> PyResult<Self> {
6975
if let Some(extractor) = T::sequence_extractor(obj, crate::conversion::private::Token) {
7076
return Ok(extractor.to_vec());

0 commit comments

Comments
 (0)