@@ -35,14 +35,14 @@ fn try_new_from_iter<'py>(
3535 py : Python < ' py > ,
3636 mut elements : impl ExactSizeIterator < Item = PyResult < Bound < ' py , PyAny > > > ,
3737) -> PyResult < Bound < ' py , PyTuple > > {
38- #[ cfg( not( RustPython ) ) ]
39- unsafe {
40- // PyTuple_New checks for overflow but has a bad error message, so we check ourselves
41- let len: Py_ssize_t = elements
42- . len ( )
43- . try_into ( )
44- . expect ( "out of range integral type conversion attempted on `elements.len()`" ) ;
38+ // PyTuple_New checks for overflow but has a bad error message, so we check ourselves
39+ let len: Py_ssize_t = elements
40+ . len ( )
41+ . try_into ( )
42+ . expect ( "out of range integral type conversion attempted on `elements.len()`" ) ;
4543
44+ #[ cfg( not( RustPython ) ) ]
45+ let ( tup, counter) = unsafe {
4646 let ptr = ffi:: PyTuple_New ( len) ;
4747
4848 // - Panics if the ptr is null
@@ -59,20 +59,26 @@ fn try_new_from_iter<'py>(
5959 counter += 1 ;
6060 }
6161
62- assert ! ( elements. next( ) . is_none( ) , "Attempted to create PyTuple but `elements` was larger than reported by its `ExactSizeIterator` implementation." ) ;
63- assert_eq ! ( len, counter, "Attempted to create PyTuple but `elements` was smaller than reported by its `ExactSizeIterator` implementation." ) ;
64-
65- Ok ( tup)
66- }
62+ ( tup, counter)
63+ } ;
6764
6865 #[ cfg( RustPython ) ]
69- unsafe {
70- let elements = elements. collect :: < PyResult < Vec < _ > > > ( ) ?;
66+ let ( tup, counter) = unsafe {
67+ let elements = ( & mut elements)
68+ . take ( len as _ )
69+ . collect :: < PyResult < Vec < _ > > > ( ) ?;
7170 // SAFETY: list is layout compatible with *const *mut crate::PyObject
72- ffi:: PyTuple_FromArray ( elements. as_ptr ( ) . cast ( ) , elements. len ( ) as _ )
71+ let tup = ffi:: PyTuple_FromArray ( elements. as_ptr ( ) . cast ( ) , elements. len ( ) as _ )
7372 . assume_owned_or_err ( py)
74- . cast_into_unchecked ( )
75- }
73+ . cast_into_unchecked ( ) ?;
74+
75+ ( tup, elements. len ( ) as Py_ssize_t )
76+ } ;
77+
78+ assert ! ( elements. next( ) . is_none( ) , "Attempted to create PyTuple but `elements` was larger than reported by its `ExactSizeIterator` implementation." ) ;
79+ assert_eq ! ( len, counter, "Attempted to create PyTuple but `elements` was smaller than reported by its `ExactSizeIterator` implementation." ) ;
80+
81+ Ok ( tup)
7682}
7783
7884/// Represents a Python `tuple` object.
0 commit comments