import sys
import unicodedata
import unittest
+import weakref
from test.support import (
+ gc_collect,
open_urlresource,
requires_resource,
script_helper,
self.assertEqual([x.start for x in result], breaks[i:-1], comment)
self.assertEqual([x.end for x in result], breaks[i+1:], comment)
+ def test_reference_loops(self):
+ # Test that reference loops involving GraphemeBreakIterator or
+ # Segment can be broken by the garbage collector.
+ class S(str):
+ pass
+
+ s = S('abc')
+ s.ref = unicodedata.iter_graphemes(s)
+ wr = weakref.ref(s)
+ del s
+ self.assertIsNotNone(wr())
+ gc_collect()
+ self.assertIsNone(wr())
+
+ s = S('abc')
+ s.ref = next(unicodedata.iter_graphemes(s))
+ wr = weakref.ref(s)
+ del s
+ self.assertIsNotNone(wr())
+ gc_collect()
+ self.assertIsNone(wr())
+
if __name__ == "__main__":
unittest.main()
return 0;
}
-static int
-Segment_clear(PyObject *self)
-{
- Py_CLEAR(((SegmentObject *)self)->string);
- return 0;
-}
-
static PyObject *
Segment_str(PyObject *self)
{
}
static PyMemberDef Segment_members[] = {
- {"start", Py_T_PYSSIZET, offsetof(SegmentObject, start), 0,
+ {"start", Py_T_PYSSIZET, offsetof(SegmentObject, start), Py_READONLY,
PyDoc_STR("grapheme start")},
- {"end", Py_T_PYSSIZET, offsetof(SegmentObject, end), 0,
+ {"end", Py_T_PYSSIZET, offsetof(SegmentObject, end), Py_READONLY,
PyDoc_STR("grapheme end")},
{NULL} /* Sentinel */
};
static PyType_Slot Segment_slots[] = {
{Py_tp_dealloc, Segment_dealloc},
{Py_tp_traverse, Segment_traverse},
- {Py_tp_clear, Segment_clear},
{Py_tp_str, Segment_str},
{Py_tp_repr, Segment_repr},
{Py_tp_members, Segment_members},
return 0;
}
-static int
-GBI_clear(PyObject *self)
-{
- Py_CLEAR(((GraphemeBreakIterator *)self)->iter.str);
- return 0;
-}
-
static PyObject *
GBI_iternext(PyObject *self)
{
{Py_tp_iter, PyObject_SelfIter},
{Py_tp_iternext, GBI_iternext},
{Py_tp_traverse, GBI_traverse},
- {Py_tp_clear, GBI_clear},
{0, 0},
};