@@ -110,37 +110,45 @@ impl_from_into_pytuple!(A, B, C, D, E, F, G);
110110pub type PyTupleRef = PyRef < PyTuple > ;
111111
112112impl Constructor for PyTuple {
113- type Args = OptionalArg < PyObjectRef > ;
113+ type Args = Vec < PyObjectRef > ;
114114
115115 fn slot_new ( cls : PyTypeRef , args : FuncArgs , vm : & VirtualMachine ) -> PyResult {
116- let iterable: Self :: Args = args. bind ( vm) ?;
116+ let iterable: OptionalArg < PyObjectRef > = args. bind ( vm) ?;
117+
118+ // Optimizations for exact tuple type
119+ if cls. is ( vm. ctx . types . tuple_type ) {
120+ // Return exact tuple as-is
121+ if let OptionalArg :: Present ( ref input) = iterable
122+ && let Ok ( tuple) = input. clone ( ) . downcast_exact :: < PyTuple > ( vm)
123+ {
124+ return Ok ( tuple. into_pyref ( ) . into ( ) ) ;
125+ }
126+
127+ // Return empty tuple singleton
128+ if iterable. is_missing ( ) {
129+ return Ok ( vm. ctx . empty_tuple . clone ( ) . into ( ) ) ;
130+ }
131+ }
132+
117133 let elements = if let OptionalArg :: Present ( iterable) = iterable {
118- let iterable = if cls. is ( vm. ctx . types . tuple_type ) {
119- match iterable. downcast_exact :: < Self > ( vm) {
120- Ok ( tuple) => return Ok ( tuple. into_pyref ( ) . into ( ) ) ,
121- Err ( iterable) => iterable,
122- }
123- } else {
124- iterable
125- } ;
126134 iterable. try_to_value ( vm) ?
127135 } else {
128136 vec ! [ ]
129137 } ;
130- // Return empty tuple only for exact tuple types if the iterable is empty.
138+
139+ // Return empty tuple singleton for exact tuple types (when iterable was empty)
131140 if elements. is_empty ( ) && cls. is ( vm. ctx . types . tuple_type ) {
132- Ok ( vm. ctx . empty_tuple . clone ( ) . into ( ) )
133- } else {
134- Self {
135- elements : elements. into_boxed_slice ( ) ,
136- }
137- . into_ref_with_type ( vm, cls)
138- . map ( Into :: into)
141+ return Ok ( vm. ctx . empty_tuple . clone ( ) . into ( ) ) ;
139142 }
143+
144+ let payload = Self :: py_new ( & cls, elements, vm) ?;
145+ payload. into_ref_with_type ( vm, cls) . map ( Into :: into)
140146 }
141147
142- fn py_new ( _cls : & Py < PyType > , _args : Self :: Args , _vm : & VirtualMachine ) -> PyResult < Self > {
143- unreachable ! ( "use slot_new" )
148+ fn py_new ( _cls : & Py < PyType > , elements : Self :: Args , _vm : & VirtualMachine ) -> PyResult < Self > {
149+ Ok ( Self {
150+ elements : elements. into_boxed_slice ( ) ,
151+ } )
144152 }
145153}
146154
0 commit comments