| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 944c7d8 commit 6b86534
3 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,10 +1,12 @@ | |||
| 1 | 1 | from collections import abc | |
| 2 | 2 | import array | |
| 3 | + import gc | ||
| 3 | 4 | import math | |
| 4 | 5 | import operator | |
| 5 | 6 | import unittest | |
| 6 | 7 | import struct | |
| 7 | 8 | import sys | |
| 9 | + import weakref | ||
| 8 | 10 | ||
| 9 | 11 | from test import support | |
| 10 | 12 | from test.support import import_helper | |
@@ -672,6 +674,21 @@ def __del__(self): | |||
| 672 | 674 | self.assertIn(b"Exception ignored in:", stderr) | |
| 673 | 675 | self.assertIn(b"C.__del__", stderr) | |
| 674 | 676 | ||
| 677 | + def test__struct_reference_cycle_cleaned_up(self): | ||
| 678 | + # Regression test for python/cpython#94207. | ||
| 679 | + | ||
| 680 | + # When we create a new struct module, trigger use of its cache, | ||
| 681 | + # and then delete it ... | ||
| 682 | + _struct_module = import_helper.import_fresh_module("_struct") | ||
| 683 | + module_ref = weakref.ref(_struct_module) | ||
| 684 | + _struct_module.calcsize("b") | ||
| 685 | + del _struct_module | ||
| 686 | + | ||
| 687 | + # Then the module should have been garbage collected. | ||
| 688 | + gc.collect() | ||
| 689 | + self.assertIsNone( | ||
| 690 | + module_ref(), "_struct module was not garbage collected") | ||
| 691 | + | ||
| 675 | 692 | def test_issue35714(self): | |
| 676 | 693 | # Embedded null characters should not be allowed in format strings. | |
| 677 | 694 | for s in '\0', '2\0i', b'\0': | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,2 @@ | |||
| 1 | + Made :class:`_struct.Struct` GC-tracked in order to fix a reference leak in | ||
| 2 | + the :mod:`_struct` module. | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1496,10 +1496,26 @@ Struct___init___impl(PyStructObject *self, PyObject *format) | |||
| 1496 | 1496 | return ret; | |
| 1497 | 1497 | } | |
| 1498 | 1498 | ||
| 1499 | + static int | ||
| 1500 | + s_clear(PyStructObject *s) | ||
| 1501 | + { | ||
| 1502 | + Py_CLEAR(s->s_format); | ||
| 1503 | + return 0; | ||
| 1504 | + } | ||
| 1505 | + | ||
| 1506 | + static int | ||
| 1507 | + s_traverse(PyStructObject *s, visitproc visit, void *arg) | ||
| 1508 | + { | ||
| 1509 | + Py_VISIT(Py_TYPE(s)); | ||
| 1510 | + Py_VISIT(s->s_format); | ||
| 1511 | + return 0; | ||
| 1512 | + } | ||
| 1513 | + | ||
| 1499 | 1514 | static void | |
| 1500 | 1515 | s_dealloc(PyStructObject *s) | |
| 1501 | 1516 | { | |
| 1502 | 1517 | PyTypeObject *tp = Py_TYPE(s); | |
| 1518 | + PyObject_GC_UnTrack(s); | ||
| 1503 | 1519 | if (s->weakreflist != NULL) | |
| 1504 | 1520 | PyObject_ClearWeakRefs((PyObject *)s); | |
| 1505 | 1521 | if (s->s_codes != NULL) { | |
@@ -2078,21 +2094,23 @@ static PyType_Slot PyStructType_slots[] = { | |||
| 2078 | 2094 | {Py_tp_getattro, PyObject_GenericGetAttr}, | |
| 2079 | 2095 | {Py_tp_setattro, PyObject_GenericSetAttr}, | |
| 2080 | 2096 | {Py_tp_doc, (void*)s__doc__}, | |
| 2097 | + {Py_tp_traverse, s_traverse}, | ||
| 2098 | + {Py_tp_clear, s_clear}, | ||
| 2081 | 2099 | {Py_tp_methods, s_methods}, | |
| 2082 | 2100 | {Py_tp_members, s_members}, | |
| 2083 | 2101 | {Py_tp_getset, s_getsetlist}, | |
| 2084 | 2102 | {Py_tp_init, Struct___init__}, | |
| 2085 | 2103 | {Py_tp_alloc, PyType_GenericAlloc}, | |
| 2086 | 2104 | {Py_tp_new, s_new}, | |
| 2087 | - {Py_tp_free, PyObject_Del}, | ||
| 2105 | + {Py_tp_free, PyObject_GC_Del}, | ||
| 2088 | 2106 | {0, 0}, | |
| 2089 | 2107 | }; | |
| 2090 | 2108 | ||
| 2091 | 2109 | static PyType_Spec PyStructType_spec = { | |
| 2092 | 2110 | "_struct.Struct", | |
| 2093 | 2111 | sizeof(PyStructObject), | |
| 2094 | 2112 | 0, | |
| 2095 | - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, | ||
| 2113 | + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, | ||
| 2096 | 2114 | PyStructType_slots | |
| 2097 | 2115 | }; | |
| 2098 | 2116 | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments