@@ -156,6 +156,22 @@ _PyTuple_MaybeUntrack(PyObject *op)
156156    _PyObject_GC_UNTRACK (op );
157157}
158158
159+ static  bool 
160+ tuple_need_tracking (PyTupleObject  * t )
161+ {
162+     Py_ssize_t  i  =  0 , n  =  Py_SIZE (t );
163+     for  (; i  <  n ; i ++ ) {
164+         PyObject  * elt  =  PyTuple_GET_ITEM (t , i );
165+         /* Tuple with NULL elements aren't 
166+            fully constructed, we should track them. */ 
167+         if  (!elt  || 
168+             _PyObject_GC_MAY_BE_TRACKED (elt )) {
169+             return  true;
170+         }
171+     }
172+     return  false;
173+ }
174+ 
159175PyObject  * 
160176PyTuple_Pack (Py_ssize_t  n , ...)
161177{
@@ -169,25 +185,21 @@ PyTuple_Pack(Py_ssize_t n, ...)
169185    }
170186
171187    va_start (vargs , n );
172-     PyTupleObject  * result  =  tuple_alloc (n );
173-     if  (result  ==  NULL ) {
188+     PyTupleObject  * tuple  =  tuple_alloc (n );
189+     if  (tuple  ==  NULL ) {
174190        va_end (vargs );
175191        return  NULL ;
176192    }
177-     items  =  result -> ob_item ;
178-     bool  track  =  false;
193+     items  =  tuple -> ob_item ;
179194    for  (i  =  0 ; i  <  n ; i ++ ) {
180195        o  =  va_arg (vargs , PyObject  * );
181196        items [i ] =  Py_NewRef (o );
182-         if  (!track  &&  _PyObject_GC_MAY_BE_TRACKED (items [i ])) {
183-             track  =  true;
184-         }
185197    }
186198    va_end (vargs );
187-     if  (track ) {
188-         _PyObject_GC_TRACK (result );
199+     if  (tuple_need_tracking ( tuple ) ) {
200+         _PyObject_GC_TRACK (tuple );
189201    }
190-     return  (PyObject  * )result ;
202+     return  (PyObject  * )tuple ;
191203}
192204
193205
@@ -382,16 +394,12 @@ PyTuple_FromArray(PyObject *const *src, Py_ssize_t n)
382394    if  (tuple  ==  NULL ) {
383395        return  NULL ;
384396    }
385-     bool  track  =  false;
386397    PyObject  * * dst  =  tuple -> ob_item ;
387398    for  (Py_ssize_t  i  =  0 ; i  <  n ; i ++ ) {
388399        PyObject  * item  =  src [i ];
389400        dst [i ] =  Py_NewRef (item );
390-         if  (!track  &&  _PyObject_GC_MAY_BE_TRACKED (dst [i ])) {
391-             track  =  true;
392-         }
393401    }
394-     if  (track ) {
402+     if  (tuple_need_tracking ( tuple ) ) {
395403        _PyObject_GC_TRACK (tuple );
396404    }
397405    return  (PyObject  * )tuple ;
@@ -407,15 +415,11 @@ _PyTuple_FromStackRefStealOnSuccess(const _PyStackRef *src, Py_ssize_t n)
407415    if  (tuple  ==  NULL ) {
408416        return  NULL ;
409417    }
410-     bool  track  =  false;
411418    PyObject  * * dst  =  tuple -> ob_item ;
412419    for  (Py_ssize_t  i  =  0 ; i  <  n ; i ++ ) {
413420        dst [i ] =  PyStackRef_AsPyObjectSteal (src [i ]);
414-         if  (!track  &&  _PyObject_GC_MAY_BE_TRACKED (dst [i ])) {
415-             track  =  true;
416-         }
417421    }
418-     if  (track ) {
422+     if  (tuple_need_tracking ( tuple ) ) {
419423        _PyObject_GC_TRACK (tuple );
420424    }
421425    return  (PyObject  * )tuple ;
@@ -434,16 +438,12 @@ _PyTuple_FromArraySteal(PyObject *const *src, Py_ssize_t n)
434438        }
435439        return  NULL ;
436440    }
437-     bool  track  =  false;
438441    PyObject  * * dst  =  tuple -> ob_item ;
439442    for  (Py_ssize_t  i  =  0 ; i  <  n ; i ++ ) {
440443        PyObject  * item  =  src [i ];
441444        dst [i ] =  item ;
442-         if  (!track  &&  _PyObject_GC_MAY_BE_TRACKED (item )) {
443-             track  =  true;
444-         }
445445    }
446-     if  (track ) {
446+     if  (tuple_need_tracking ( tuple ) ) {
447447        _PyObject_GC_TRACK (tuple );
448448    }
449449    return  (PyObject  * )tuple ;
@@ -572,7 +572,7 @@ tuple_repeat(PyObject *self, Py_ssize_t n)
572572    if  (_PyObject_GC_IS_TRACKED (a )) {
573573        _PyObject_GC_TRACK (np );
574574    }
575-     return  (PyObject  * )  np ;
575+     return  (PyObject  * )np ;
576576}
577577
578578/*[clinic input] 
0 commit comments