mirror of
https://github.com/RustPython/RustPython.git
synced 2026-06-02 19:39:49 +09:00
* gc: add CollectResult, stats fields, get_referrers, and fix count reset - Add CollectResult struct with collected/uncollectable/candidates/duration - Add candidates and duration fields to GcStats and gc.get_stats() - Pass CollectResult to gc.callbacks info dict - Reset generation counts for all collected generations (0..=N) - Return 0 for third value in gc.get_threshold() (3.13+) - Implement gc.get_referrers() by scanning all tracked objects - Add DEBUG_COLLECTABLE output for collectable objects - Update test_gc.py to expect candidates/duration in stats * Update test_gc from v3.14.3 * Update test_gc.py from CPython v3.15.0a5 Taken from v3.15 (not v3.14.3) because get_stats() candidates/duration fields were added in 3.13+ and the corresponding test assertions only exist in 3.15. * Fix gc_state build on wasm32: skip Instant timing * Add candidates/duration to gc callback info, mark v3.15 test failures * Fix gc.get_referrers to exclude executing frames, fix Future cancelled exc leak - get_referrers: skip frame objects on the execution stack, since they are not GC-tracked in CPython (_PyInterpreterFrame) - _asyncio Future/Task make_cancelled_error_impl: clear the stored cancelled exception after returning it, matching the Python _make_cancelled_error behavior * Fix gc.get_threshold to return actual gen2 threshold value * Fix inconsistent GC count reset in early-return paths Use the same reset_end formula in unreachable-empty early returns as in the main collection path and collecting-empty path. * Accept keyword arguments in socket.__init__ Use a FromArgs struct instead of a positional-only tuple so that family, type, proto, and fileno can be passed as keyword arguments. * Disable comp_inlined in symbol table to match compiler The compiler does not yet implement PEP 709 inlined comprehensions (is_inlined_comprehension_context always returns false), but the symbol table was marking comprehensions as inlined. This mismatch could cause comprehension-local symbols to be merged into the parent scope while the compiler still looks them up in a separate scope. --------- Co-authored-by: CPython Developers <>
49 lines
1.5 KiB
Python
Vendored
49 lines
1.5 KiB
Python
Vendored
# Run by test_gc.
|
|
from test import support
|
|
import _testinternalcapi
|
|
import gc
|
|
import unittest
|
|
|
|
class IncrementalGCTests(unittest.TestCase):
|
|
|
|
# Use small increments to emulate longer running process in a shorter time
|
|
@support.gc_threshold(200, 10)
|
|
def test_incremental_gc_handles_fast_cycle_creation(self):
|
|
|
|
class LinkedList:
|
|
|
|
#Use slots to reduce number of implicit objects
|
|
__slots__ = "next", "prev", "surprise"
|
|
|
|
def __init__(self, next=None, prev=None):
|
|
self.next = next
|
|
if next is not None:
|
|
next.prev = self
|
|
self.prev = prev
|
|
if prev is not None:
|
|
prev.next = self
|
|
|
|
def make_ll(depth):
|
|
head = LinkedList()
|
|
for i in range(depth):
|
|
head = LinkedList(head, head.prev)
|
|
return head
|
|
|
|
head = make_ll(1000)
|
|
|
|
assert(gc.isenabled())
|
|
olds = []
|
|
initial_heap_size = _testinternalcapi.get_tracked_heap_size()
|
|
for i in range(20_000):
|
|
newhead = make_ll(20)
|
|
newhead.surprise = head
|
|
olds.append(newhead)
|
|
if len(olds) == 20:
|
|
new_objects = _testinternalcapi.get_tracked_heap_size() - initial_heap_size
|
|
self.assertLess(new_objects, 27_000, f"Heap growing. Reached limit after {i} iterations")
|
|
del olds[:]
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|