@@ -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