Python 3.11.0

-----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCAAdFiEEz9yiRbEEPPKl+Xhl/+h0BBaL2EcFAmNWzOwACgkQ/+h0BBaL
 2EcepxAAmZLGMrL4D7Zxzo6N2ezkuiuoQH4JvxIUaB7cjU5h0GSUFlmcJQCHhCwk
 AvToQrmH/7uuuEZKST1fomtUE83wudfHhX2t+CMBdbLG1hIwhTfLNMTqFhONturF
 XlkVUcva1i9XrYZPLl1pIcBf1Sjm6pPW5QZ4BP1ZHJ5C2pHEzaBRFX/q0lU5aF9O
 z5nBBpnga2gShUTqM1VkXucU4lKXsi4blbn/Z8giganMXY1SXIsEOoCaDZYN1Hh/
 xQiOpSrjy/uSz4vGSNuPwp9J2lRlw8n4RBd/P7om01CrJMAKotH+62OqwhlQ8ydB
 ywp0kygtPtMdSK7F1WKMWkYX4CXfLpYwN0+x3Z3iYFBFiuzOFrUCQYgqqfEPNq+o
 bQxxnhAvYcOVINUub6oL23hgFZIoM6l54L66qujQVFM0usCY2f23Ikqd0Z7K8+6e
 uDRAvGiCHkbbfhdnfXzc/Wgj4zLaPnNs8S2s8ojK32NPV8gyWVBumcsRvlocfl6K
 hoA5wqeAXsOv+pFjkGtk90Yg+8R9n+n47//o6uYW/vvZtksm2wPm3hnuCA0WqPzN
 IM7SJE5VrtSRqQpXT9j4G3zyHDNT/Qhrh+cyBM5kgoPSdbU0ugZN8P7GWVtsFhmK
 rrHRns85gNZJ6qTN1pU22MybYCPIsg5Dt6+jZ8hJWIzOOy9apIk=
 =Ryd2
 -----END PGP SIGNATURE-----
gpgsig -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCAAdFiEEz9yiRbEEPPKl+Xhl/+h0BBaL2EcFAmNW55YACgkQ/+h0BBaL
 2EfCLg//bMWtb/X3D+IM+9BIrpEscj/vw22zH9j8PIRd8iWfW80TNEIBh4uPEc0j
 SDTkA5bqN6CB7xqIxDlWQcJpGiImVZ2LzOw8HHye1QCfVZk741CF78UhEnb+hTbO
 gr7nIznytv+VdMSDRHTSgpnkRNQ9FjFEHLu7YQTMof5i/YmTxWZcsru6dTLlEutg
 F3+PfxbKwPgJkfare91X62XSQwyTL6k0mvl5+Sdq2WEQdgMqv4I8V9dHbnk9K3VI
 B+K2xsfIyWHrLDwQa3LBZj4YOKTwnwqlr1sEqO47NfasWaMYa1vBsktLVtPVQ3xS
 Hz0lLhJXJLzf5hmf2r4Tw1S5spn5ijsZ7CwK2Zl+1+dbJMpRoK4VeSSYy/OfEpwy
 8Hx1YitMyORF3HkGWa+pPYPNaIOw4S/EQQPYd5osg3NnknYjkkKZZaliq7EZra7c
 GANPJamXhHREQyhux9KeiYZer3SU3CSXopyxm8ClcBZJAiAOjhAdeOk+Q4Ta9T6+
 gRWBOrelroyFTWHsOd8V7gSz3XJNuAzlNZ/+1Oj/7Em+5DGLFcxJrZGLxn+hruZ5
 GPK9IQXbURAuxqVrqCzw2tzf/NzJr0fs4QDYEVI95pfLjzk1tuJ5WR6zFNC0COK2
 qw8TTvXglsvHqVMnK8u73GVSTv1UGYqbQH9uAeEikAQYr3TTdZo=
 =dsZm
 -----END PGP SIGNATURE-----

Merge tag 'v3.11.0' into 3.11

Python 3.11.0
This commit is contained in:
Pablo Galindo 2022-10-24 20:29:24 +01:00
commit 69b6b56d85
7 changed files with 518 additions and 131 deletions

View file

@ -326,5 +326,69 @@ def f():
gc.enable()
@support.cpython_only
def test_sneaky_frame_object(self):
def trace(frame, event, arg):
"""
Don't actually do anything, just force a frame object to be created.
"""
def callback(phase, info):
"""
Yo dawg, I heard you like frames, so I'm allocating a frame while
you're allocating a frame, so you can have a frame while you have a
frame!
"""
nonlocal sneaky_frame_object
sneaky_frame_object = sys._getframe().f_back
# We're done here:
gc.callbacks.remove(callback)
def f():
while True:
yield
old_threshold = gc.get_threshold()
old_callbacks = gc.callbacks[:]
old_enabled = gc.isenabled()
old_trace = sys.gettrace()
try:
# Stop the GC for a second while we set things up:
gc.disable()
# Create a paused generator:
g = f()
next(g)
# Move all objects to the oldest generation, and tell the GC to run
# on the *very next* allocation:
gc.collect()
gc.set_threshold(1, 0, 0)
# Okay, so here's the nightmare scenario:
# - We're tracing the resumption of a generator, which creates a new
# frame object.
# - The allocation of this frame object triggers a collection
# *before* the frame object is actually created.
# - During the collection, we request the exact same frame object.
# This test does it with a GC callback, but in real code it would
# likely be a trace function, weakref callback, or finalizer.
# - The collection finishes, and the original frame object is
# created. We now have two frame objects fighting over ownership
# of the same interpreter frame!
sys.settrace(trace)
gc.callbacks.append(callback)
sneaky_frame_object = None
gc.enable()
next(g)
# g.gi_frame should be the the frame object from the callback (the
# one that was *requested* second, but *created* first):
self.assertIs(g.gi_frame, sneaky_frame_object)
finally:
gc.set_threshold(*old_threshold)
gc.callbacks[:] = old_callbacks
sys.settrace(old_trace)
if old_enabled:
gc.enable()
if __name__ == "__main__":
unittest.main()