mirror of
https://github.com/python/cpython.git
synced 2025-07-23 03:05:38 +00:00
[3.10] gh-94207: Fix struct module leak (GH-94239) (GH-94266)
* gh-94207: Fix struct module leak (GH-94239)
Make _struct.Struct a GC type
This fixes a memory leak in the _struct module, where as soon
as a Struct object is stored in the cache, there's a cycle from
the _struct module to the cache to Struct objects to the Struct
type back to the module. If _struct.Struct is not gc-tracked, that
cycle is never collected.
This PR makes _struct.Struct GC-tracked, and adds a regression test.
(cherry picked from commit 6b865349aa
)
Co-authored-by: Mark Dickinson <dickinsm@gmail.com>
This commit is contained in:
parent
14943829a8
commit
86e49a5026
3 changed files with 40 additions and 2 deletions
|
@ -1,12 +1,15 @@
|
|||
from collections import abc
|
||||
import array
|
||||
import gc
|
||||
import math
|
||||
import operator
|
||||
import unittest
|
||||
import struct
|
||||
import sys
|
||||
import weakref
|
||||
|
||||
from test import support
|
||||
from test.support import import_helper
|
||||
from test.support.script_helper import assert_python_ok
|
||||
|
||||
ISBIGENDIAN = sys.byteorder == "big"
|
||||
|
@ -671,6 +674,21 @@ class StructTest(unittest.TestCase):
|
|||
self.assertIn(b"Exception ignored in:", stderr)
|
||||
self.assertIn(b"C.__del__", stderr)
|
||||
|
||||
def test__struct_reference_cycle_cleaned_up(self):
|
||||
# Regression test for python/cpython#94207.
|
||||
|
||||
# When we create a new struct module, trigger use of its cache,
|
||||
# and then delete it ...
|
||||
_struct_module = import_helper.import_fresh_module("_struct")
|
||||
module_ref = weakref.ref(_struct_module)
|
||||
_struct_module.calcsize("b")
|
||||
del _struct_module
|
||||
|
||||
# Then the module should have been garbage collected.
|
||||
gc.collect()
|
||||
self.assertIsNone(
|
||||
module_ref(), "_struct module was not garbage collected")
|
||||
|
||||
def test_issue35714(self):
|
||||
# Embedded null characters should not be allowed in format strings.
|
||||
for s in '\0', '2\0i', b'\0':
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue