17db96d56Sopenharmony_ci
27db96d56Sopenharmony_ci# The cycle GC collector can be executed when any GC-tracked object is
37db96d56Sopenharmony_ci# allocated, e.g. during a call to PyList_New(), PyDict_New(), ...
47db96d56Sopenharmony_ci# Moreover, it can invoke arbitrary Python code via a weakref callback.
57db96d56Sopenharmony_ci# This means that there are many places in the source where an arbitrary
67db96d56Sopenharmony_ci# mutation could unexpectedly occur.
77db96d56Sopenharmony_ci
87db96d56Sopenharmony_ci# The example below shows list_slice() not expecting the call to
97db96d56Sopenharmony_ci# PyList_New to mutate the input list.  (Of course there are many
107db96d56Sopenharmony_ci# more examples like this one.)
117db96d56Sopenharmony_ci
127db96d56Sopenharmony_ci
137db96d56Sopenharmony_ciimport weakref
147db96d56Sopenharmony_ci
157db96d56Sopenharmony_ciclass A(object):
167db96d56Sopenharmony_ci    pass
177db96d56Sopenharmony_ci
187db96d56Sopenharmony_cidef callback(x):
197db96d56Sopenharmony_ci    del lst[:]
207db96d56Sopenharmony_ci
217db96d56Sopenharmony_ci
227db96d56Sopenharmony_cikeepalive = []
237db96d56Sopenharmony_ci
247db96d56Sopenharmony_cifor i in range(100):
257db96d56Sopenharmony_ci    lst = [str(i)]
267db96d56Sopenharmony_ci    a = A()
277db96d56Sopenharmony_ci    a.cycle = a
287db96d56Sopenharmony_ci    keepalive.append(weakref.ref(a, callback))
297db96d56Sopenharmony_ci    del a
307db96d56Sopenharmony_ci    while lst:
317db96d56Sopenharmony_ci        keepalive.append(lst[:])
32