From 9ef61deffb85aeb56d22da01f1aefb72ffc304cb Mon Sep 17 00:00:00 2001 From: Brett Date: Thu, 19 Sep 2024 08:32:07 -0400 Subject: [PATCH 1/2] make 3.13 testing part of our regular CI --- .github/workflows/ci.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8ad9e8297..f54064da8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -42,6 +42,9 @@ jobs: # Any env name which does not start with `pyXY` will use this Python version. default_python: '3.10' envs: | + - linux: coverage + name: Python 3.13 coverage + python-version: 3.13-dev - linux: coverage name: Python 3.12 coverage python-version: 3.12 From aa40657e50d74e91ec122ae750295efa42748de0 Mon Sep 17 00:00:00 2001 From: Brett Date: Thu, 19 Sep 2024 08:32:18 -0400 Subject: [PATCH 2/2] add gc.collect after del in tests --- asdf/_tests/_block/test_callback.py | 3 +++ asdf/_tests/_block/test_key.py | 5 +++++ asdf/_tests/_block/test_manager.py | 3 +++ asdf/_tests/_block/test_store.py | 5 +++++ asdf/_tests/test_block_converter.py | 2 ++ asdf/_tests/test_lazy_nodes.py | 9 +++++++-- 6 files changed, 25 insertions(+), 2 deletions(-) diff --git a/asdf/_tests/_block/test_callback.py b/asdf/_tests/_block/test_callback.py index d173ded44..79bb79d77 100644 --- a/asdf/_tests/_block/test_callback.py +++ b/asdf/_tests/_block/test_callback.py @@ -1,3 +1,5 @@ +import gc + import pytest from asdf._block.callback import DataCallback @@ -35,6 +37,7 @@ def __init__(self, value): blks = ReadBlocks([Data("a"), Data("b")]) cb = DataCallback(0, blks) del blks + gc.collect(2) with pytest.raises(OSError, match="Attempt to read block data from missing block"): cb() diff --git a/asdf/_tests/_block/test_key.py b/asdf/_tests/_block/test_key.py index 204a761c4..f99384af6 100644 --- a/asdf/_tests/_block/test_key.py +++ b/asdf/_tests/_block/test_key.py @@ -1,4 +1,5 @@ import copy +import gc from asdf._block.key import Key @@ -41,6 +42,7 @@ def test_is_valid(): bk = Key(f) assert bk._is_valid() del f + gc.collect(2) assert not bk._is_valid() @@ -48,6 +50,7 @@ def test_same_class(): f = Foo() bk = Key(f) del f + gc.collect(2) f2 = Foo() assert not bk._is_valid() assert not bk._matches_object(f2) @@ -92,6 +95,7 @@ def test_deleted_object_not_equal(): k1 = Key(f, key_value) k2 = Key(f, key_value) del f + gc.collect(2) assert k1 != k2 @@ -113,4 +117,5 @@ def test_copy_deleted_object_not_equal(): k1 = Key(f) k2 = copy.copy(k1) del f + gc.collect(2) assert k1 != k2 diff --git a/asdf/_tests/_block/test_manager.py b/asdf/_tests/_block/test_manager.py index 6c43d086f..d175b195d 100644 --- a/asdf/_tests/_block/test_manager.py +++ b/asdf/_tests/_block/test_manager.py @@ -1,3 +1,5 @@ +import gc + import numpy as np import pytest @@ -14,6 +16,7 @@ def test_set_streamed_block_via_options(): with pytest.raises(ValueError, match=r"Can not add second streaming block"): options.set_options(arr2, Options("streamed")) del arr1 + gc.collect(2) options.set_options(arr2, Options("streamed")) diff --git a/asdf/_tests/_block/test_store.py b/asdf/_tests/_block/test_store.py index dd48b4013..fb6c38b27 100644 --- a/asdf/_tests/_block/test_store.py +++ b/asdf/_tests/_block/test_store.py @@ -1,3 +1,4 @@ +import gc from unittest.mock import patch import pytest @@ -108,6 +109,7 @@ def test_get_memory_reused(): s.assign_object(f, v) fid = id(f) del f + gc.collect(2) f2 = Foo() def mock_id(obj): @@ -126,6 +128,7 @@ def test_set_memory_reused(): s.assign_object(f, v) fid = id(f) del f + gc.collect(2) f2 = Foo() def mock_id(obj): @@ -146,6 +149,7 @@ def test_cleanup(): s.assign_object(s, 42) s.assign_object(k, 26) del f + gc.collect(2) s._cleanup() assert s.lookup_by_object(k, None) is None @@ -172,3 +176,4 @@ def test_keys_for_value(): returned_objects.add(obj) assert objs == returned_objects del returned_objects, objs + gc.collect(2) diff --git a/asdf/_tests/test_block_converter.py b/asdf/_tests/test_block_converter.py index 71e9bc1fb..28289ce9f 100644 --- a/asdf/_tests/test_block_converter.py +++ b/asdf/_tests/test_block_converter.py @@ -1,4 +1,5 @@ import contextlib +import gc import numpy as np from numpy.testing import assert_array_equal @@ -290,6 +291,7 @@ def test_shared_block_obj_removal(tmp_path): with asdf.open(fn, mode="rw") as af: af["b"] = None del b + gc.collect(2) af.update() with asdf.open(fn) as af: np.testing.assert_array_equal(af["a"].data, arr1) diff --git a/asdf/_tests/test_lazy_nodes.py b/asdf/_tests/test_lazy_nodes.py index 3490c1a1d..fa8a9fd60 100644 --- a/asdf/_tests/test_lazy_nodes.py +++ b/asdf/_tests/test_lazy_nodes.py @@ -181,6 +181,7 @@ def test_access_after_del(tmp_path): d = af["a"] del af + gc.collect(2) with pytest.raises(asdf.exceptions.AsdfLazyReferenceError, match="Failed to resolve"): d["b"] @@ -215,10 +216,14 @@ def test_lazy_tree_option(tmp_path): def test_resolve_af_ref(): with pytest.raises(asdf.exceptions.AsdfLazyReferenceError, match="Failed to resolve"): _resolve_af_ref(None) + af = asdf.AsdfFile() af_ref = weakref.ref(af) assert _resolve_af_ref(af_ref) is af + del af + gc.collect(2) + with pytest.raises(asdf.exceptions.AsdfLazyReferenceError, match="Failed to resolve"): _resolve_af_ref(af_ref) @@ -285,7 +290,7 @@ def test_cache_frees_deleted_object(cache_test_tree_path): # now delete all references to the list (including the one in the tree) del l0, af.tree["a"] # trigger garbage collection - gc.collect() + gc.collect(2) # check that the weakref fails to resolve (so the list was freed) assert lref() is None # and we can no longer access 'a' @@ -303,7 +308,7 @@ def test_cache_non_weakref(): obj = complex(1, 1) cache_item = asdf.lazy_nodes._TaggedObjectCacheItem(tagged_node, obj) del obj - gc.collect() + gc.collect(2) assert cache_item.custom_object == complex(1, 1)