diff --git a/build.sh b/build.sh index 19f95b7de..4a6800741 100755 --- a/build.sh +++ b/build.sh @@ -130,7 +130,7 @@ WORK_DIR=`mktemp -d` pushd $WORK_DIR git clone https://github.com/suquark/pickle5-backport pushd pickle5-backport - git checkout 43551fbb9add8ac2e8551b96fdaf2fe5a3b5997d + git checkout 8ffe41ceba9d5e2ce8a98190f6b3d2f3325e5a72 "$PYTHON_EXECUTABLE" setup.py bdist_wheel unzip -o dist/*.whl -d "$ROOT_DIR/python/ray/pickle5_files" popd diff --git a/python/ray/tests/test_basic.py b/python/ray/tests/test_basic.py index f477092f5..f800fc502 100644 --- a/python/ray/tests/test_basic.py +++ b/python/ray/tests/test_basic.py @@ -10,6 +10,7 @@ import sys import threading import time import pickle +import weakref import numpy as np import pytest @@ -453,6 +454,27 @@ def test_ray_recursive_objects(ray_start_regular): ray.put(obj) +def test_reducer_override_no_reference_cycle(ray_start_regular): + # bpo-39492: reducer_override used to induce a spurious reference cycle + # inside the Pickler object, that could prevent all serialized objects + # from being garbage-collected without explicity invoking gc.collect. + f = lambda: 4669201609102990671853203821578 + + wr = weakref.ref(f) + + bio = io.BytesIO() + from ray.cloudpickle import CloudPickler, loads + p = CloudPickler(bio, protocol=5) + p.dump(f) + new_f = loads(bio.getvalue()) + assert new_f() == 4669201609102990671853203821578 + + del p + del f + + assert wr() is None + + def test_passing_arguments_by_value_out_of_the_box(ray_start_regular): @ray.remote def f(x):