cloudpipe / cloudpipe/cloudpickle

PyPy3.11: multiple test failures

Open
#557 3 comments 0 reactions 0 assignees View on GitHub
Dominant language
Python
Stars
1.9k
Forks
195
Avg merge
1d 10h
Merged PRs (30d)
1

Description

When testing with PyPy3.11 7.3.18, as of 8b821514e4eeee39ae4c775cbe7522b1e23df5a6:

```pytb
.pkg: _optional_hooks> python /usr/lib/python3.13/site-packages/pyproject_api/_backend.py True flit_core.buildapi
.pkg: get_requires_for_build_sdist> python /usr/lib/python3.13/site-packages/pyproject_api/_backend.py True flit_core.buildapi
.pkg: get_requires_for_build_wheel> python /usr/lib/python3.13/site-packages/pyproject_api/_backend.py True flit_core.buildapi
.pkg: prepare_metadata_for_build_wheel> python /usr/lib/python3.13/site-packages/pyproject_api/_backend.py True flit_core.buildapi
.pkg: build_sdist> python /usr/lib/python3.13/site-packages/pyproject_api/_backend.py True flit_core.buildapi
pypy311: install_package> python -I -m pip install --force-reinstall --no-deps /tmp/cloudpickle/.tox/.tmp/package/6/cloudpickle-3.2.0.dev0.tar.gz
pypy311: commands[0]> pytest -lv --maxfail=5
============================= test session starts ==============================
platform linux -- Python 3.11.11[pypy-7.3.18-final], pytest-8.3.4, pluggy-1.5.0 -- /tmp/cloudpickle/.tox/pypy311/bin/python
cachedir: .tox/pypy311/.pytest_cache
rootdir: /tmp/cloudpickle
configfile: tox.ini
plugins: cov-6.0.0
collecting ... collected 272 items

tests/cloudpickle_file_test.py::CloudPickleFileTests::test_closed_file PASSED
tests/cloudpickle_file_test.py::CloudPickleFileTests::test_empty_file PASSED
tests/cloudpickle_file_test.py::CloudPickleFileTests::test_pickling_special_file_handles PASSED
tests/cloudpickle_file_test.py::CloudPickleFileTests::test_plus_mode PASSED
tests/cloudpickle_file_test.py::CloudPickleFileTests::test_r_mode PASSED
tests/cloudpickle_file_test.py::CloudPickleFileTests::test_seek PASSED
tests/cloudpickle_file_test.py::CloudPickleFileTests::test_w_mode PASSED
tests/cloudpickle_test.py::test_extract_class_dict PASSED
tests/cloudpickle_test.py::CloudPickleTest::test_Ellipsis PASSED
tests/cloudpickle_test.py::CloudPickleTest::test_EllipsisType PASSED
tests/cloudpickle_test.py::CloudPickleTest::test_NamedTuple FAILED
tests/cloudpickle_test.py::CloudPickleTest::test_NoneType PASSED
tests/cloudpickle_test.py::CloudPickleTest::test_NotImplemented PASSED
tests/cloudpickle_test.py::CloudPickleTest::test_NotImplementedType PASSED
tests/cloudpickle_test.py::CloudPickleTest::test___reduce___returns_string PASSED
tests/cloudpickle_test.py::CloudPickleTest::test_abc PASSED
tests/cloudpickle_test.py::CloudPickleTest::test_abc_cache_not_pickled PASSED
tests/cloudpickle_test.py::CloudPickleTest::test_abstracts PASSED
tests/cloudpickle_test.py::CloudPickleTest::test_always_use_up_to_date_copyreg PASSED
tests/cloudpickle_test.py::CloudPickleTest::test_attrgetter PASSED
tests/cloudpickle_test.py::CloudPickleTest::test_bound_classmethod PASSED
tests/cloudpickle_test.py::CloudPickleTest::test_builtin_classicmethod PASSED
tests/cloudpickle_test.py::CloudPickleTest::test_builtin_classmethod PASSED
tests/cloudpickle_test.py::CloudPickleTest::test_builtin_classmethod_descriptor PASSED
tests/cloudpickle_test.py::CloudPickleTest::test_builtin_function PASSED
tests/cloudpickle_test.py::CloudPickleTest::test_builtin_slotmethod PASSED
tests/cloudpickle_test.py::CloudPickleTest::test_builtin_staticmethod SKIPPED
tests/cloudpickle_test.py::CloudPickleTest::test_builtin_type_constructor PASSED
tests/cloudpickle_test.py::CloudPickleTest::test_cell_manipulation PASSED
tests/cloudpickle_test.py::CloudPickleTest::test_class_annotations PASSED
tests/cloudpickle_test.py::CloudPickleTest::test_class_no_firstlineno_deletion_ PASSED
tests/cloudpickle_test.py::CloudPickleTest::test_classmethod PASSED
tests/cloudpickle_test.py::CloudPickleTest::test_closure_interacting_with_a_global_variable PASSED
tests/cloudpickle_test.py::CloudPickleTest::test_closure_none_is_preserved PASSED
tests/cloudpickle_test.py::CloudPickleTest::test_cloudpickle_extract_nested_globals PASSED
tests/cloudpickle_test.py::CloudPickleTest::test_correct_globals_import PASSED
tests/cloudpickle_test.py::CloudPickleTest::test_cycle_in_classdict_globals PASSED
tests/cloudpickle_test.py::CloudPickleTest::test_dataclass PASSED
tests/cloudpickle_test.py::CloudPickleTest::test_dataclass_fields_are_preserved PASSED
tests/cloudpickle_test.py::CloudPickleTest::test_deterministic_dynamic_class_attr_ordering_for_chained_pickling PASSED
tests/cloudpickle_test.py::CloudPickleTest::test_deterministic_pickle_bytes_for_function PASSED
tests/cloudpickle_test.py::CloudPickleTest::test_deterministic_str_interning_for_chained_dynamic_class_pickling PASSED
tests/cloudpickle_test.py::CloudPickleTest::test_dict_items PASSED
tests/cloudpickle_test.py::CloudPickleTest::test_dict_keys PASSED
tests/cloudpickle_test.py::CloudPickleTest::test_dict_values PASSED
tests/cloudpickle_test.py::CloudPickleTest::test_dynamic_class_determinist_subworker_tuple_memoization PASSED
tests/cloudpickle_test.py::CloudPickleTest::test_dynamic_class_deterministic_roundtrip XFAIL
tests/cloudpickle_test.py::CloudPickleTest::test_dynamic_func_deterministic_roundtrip PASSED
tests/cloudpickle_test.py::CloudPickleTest::test_dynamic_module PASSED
tests/cloudpickle_test.py::CloudPickleTest::test_dynamic_module_no_package PASSED
tests/cloudpickle_test.py::CloudPickleTest::test_dynamic_module_with_unpicklable_builtin PASSED
tests/cloudpickle_test.py::CloudPickleTest::test_dynamically_generated_class_that_uses_super PASSED
tests/cloudpickle_test.py::CloudPickleTest::test_empty_cell_preserved FAILED
tests/cloudpickle_test.py::CloudPickleTest::test_extended_arg FAILED
tests/cloudpickle_test.py::CloudPickleTest::test_final_or_classvar_misdetection PASSED
tests/cloudpickle_test.py::CloudPickleTest::test_func_globals PASSED
tests/cloudpickle_test.py::CloudPickleTest::test_function_annotations PASSED
tests/cloudpickle_test.py::CloudPickleTest::test_function_module_name PASSED
tests/cloudpickle_test.py::CloudPickleTest::test_function_qualname PASSED
tests/cloudpickle_test.py::CloudPickleTest::test_generator PASSED
tests/cloudpickle_test.py::CloudPickleTest::test_generic_subclass PASSED
tests/cloudpickle_test.py::CloudPickleTest::test_generic_type FAILED
tests/cloudpickle_test.py::CloudPickleTest::test_getset_descriptor PASSED
tests/cloudpickle_test.py::CloudPickleTest::test_import PASSED
tests/cloudpickle_test.py::CloudPickleTest::test_importing_multiprocessing_does_not_impact_whichmodule PASSED
tests/cloudpickle_test.py::CloudPickleTest::test_instance_with_slots PASSED
tests/cloudpickle_test.py::CloudPickleTest::test_instancemethods_without_self PASSED
tests/cloudpickle_test.py::CloudPickleTest::test_interactive_dynamic_type_and_remote_instances PASSED
tests/cloudpickle_test.py::CloudPickleTest::test_interactive_dynamic_type_and_stored_remote_instances FAILED

=================================== FAILURES ===================================
_______________________ CloudPickleTest.test_NamedTuple ________________________

self =

def test_NamedTuple(self):
class MyTuple(typing.NamedTuple):
a: int
b: int
c: int

t1 = MyTuple(1, 2, 3)
t2 = MyTuple(3, 2, 1)

> depickled_t1, depickled_MyTuple, depickled_t2 = pickle_depickle(
[t1, MyTuple, t2], protocol=self.protocol
)

MyTuple = .MyTuple'>
self =
t1 = MyTuple(a=1, b=2, c=3)
t2 = MyTuple(a=3, b=2, c=1)

tests/cloudpickle_test.py:1664:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
tests/cloudpickle_test.py:75: in pickle_depickle
return pickle.loads(cloudpickle.dumps(obj, protocol=protocol))
obj = [MyTuple(a=1, b=2, c=3), .MyTuple'>, MyTuple(a=3, b=2, c=1)]
protocol = 5
cloudpickle/cloudpickle.py:1537: in dumps
cp.dump(obj)
buffer_callback = None
cp =
file = <_io.BytesIO object at 0x00007f9ae09975c8>
obj = [MyTuple(a=1, b=2, c=3), .MyTuple'>, MyTuple(a=3, b=2, c=1)]
protocol = 5
cloudpickle/cloudpickle.py:1303: in dump
return super().dump(obj)
__class__ =
obj = [MyTuple(a=1, b=2, c=3), .MyTuple'>, MyTuple(a=3, b=2, c=1)]
self =
/usr/lib/pypy3.11/pickle.py:500: in dump
self.save(obj)
obj = [MyTuple(a=1, b=2, c=3), .MyTuple'>, MyTuple(a=3, b=2, c=1)]
self =
/usr/lib/pypy3.11/pickle.py:573: in save
f(self, obj) # Call unbound method with explicit self
f =
obj = [MyTuple(a=1, b=2, c=3), .MyTuple'>, MyTuple(a=3, b=2, c=1)]
pid = None
reduce = None
rv = NotImplemented
save_persistent_id = True
self =
t =
x = None
/usr/lib/pypy3.11/pickle.py:945: in save_list
self._batch_appends(obj)
obj = [MyTuple(a=1, b=2, c=3), .MyTuple'>, MyTuple(a=3, b=2, c=1)]
self =
/usr/lib/pypy3.11/pickle.py:969: in _batch_appends
save(x)
it =
items = [MyTuple(a=1, b=2, c=3), .MyTuple'>, MyTuple(a=3, b=2, c=1)]
n = 3
save = >
self =
tmp = [MyTuple(a=1, b=2, c=3), .MyTuple'>, MyTuple(a=3, b=2, c=1)]
write = >
x = MyTuple(a=1, b=2, c=3)
/usr/lib/pypy3.11/pickle.py:616: in save
self.save_reduce(obj=obj, *rv)
f = None
l = 5
obj = MyTuple(a=1, b=2, c=3)
pid = None
reduce =
rv = (, (.MyTuple'>, 1, 2, 3), None, None, None)
save_persistent_id = True
self =
t = .MyTuple'>
x = None
/usr/lib/pypy3.11/pickle.py:700: in save_reduce
save(cls)
args = (1, 2, 3)
cls = .MyTuple'>
dictitems = None
func =
func_name = '__newobj__'
listitems = None
obj = MyTuple(a=1, b=2, c=3)
save = >
self =
state = None
state_setter = None
write = >
/usr/lib/pypy3.11/pickle.py:573: in save
f(self, obj) # Call unbound method with explicit self
f =
obj = .MyTuple'>
pid = None
reduce = None
rv = NotImplemented
save_persistent_id = True
self =
t =
x = None
cloudpickle/cloudpickle.py:1454: in save_global
self._save_reduce_pickle5(*_dynamic_class_reduce(obj), obj=obj)
__class__ =
name = None
obj = .MyTuple'>
pack =
self =
cloudpickle/cloudpickle.py:1424: in _save_reduce_pickle5
save(state)
args = (, 'MyTuple', (,), {'__module__': 'tests.cloudpickle_test'}, '083a5eb1df0f44f5a421ba8b7ee90378', None)
dictitems = None
func =
listitems = None
obj = .MyTuple'>
save = >
self =
state = ({'__annotations__': {'a': , 'b': , 'c': }, '__doc__': 'MyTuple(a, b, c)', '__getnewargs__': , '__match_args__': ('a', 'b', 'c'), ...}, {})
state_setter =
write = >
/usr/lib/pypy3.11/pickle.py:573: in save
f(self, obj) # Call unbound method with explicit self
f =
obj = ({'__annotations__': {'a': , 'b': , 'c': }, '__doc__': 'MyTuple(a, b, c)', '__getnewargs__': , '__match_args__': ('a', 'b', 'c'), ...}, {})
pid = None
reduce = None
rv = NotImplemented
save_persistent_id = True
self =
t =
x = None
/usr/lib/pypy3.11/pickle.py:900: in save_tuple
save(element)
element = {'__annotations__': {'a': , 'b': , 'c': }, '__doc__': 'MyTuple(a, b, c)', '__getnewargs__': , '__match_args__': ('a', 'b', 'c'), ...}
memo = {-1589: (27, 'c'), -1573: (26, 'b'), -1557: (23, 'a'), 93954618292450: (128, '__name__'), ...}
n = 2
obj = ({'__annotations__': {'a': , 'b': , 'c': }, '__doc__': 'MyTuple(a, b, c)', '__getnewargs__': , '__match_args__': ('a', 'b', 'c'), ...}, {})
save = >
self =
/usr/lib/pypy3.11/pickle.py:573: in save
f(self, obj) # Call unbound method with explicit self
f =
obj = {'__annotations__': {'a': , 'b': , 'c': }, '__doc__': 'MyTuple(a, b, c)', '__getnewargs__': , '__match_args__': ('a', 'b', 'c'), ...}
pid = None
reduce = None
rv = NotImplemented
save_persistent_id = True
self =
t =
x = None
/usr/lib/pypy3.11/pickle.py:985: in save_dict
self._batch_setitems(obj.items())
obj = {'__annotations__': {'a': , 'b': , 'c': }, '__doc__': 'MyTuple(a, b, c)', '__getnewargs__': , '__match_args__': ('a', 'b', 'c'), ...}
self =
/usr/lib/pypy3.11/pickle.py:1011: in _batch_setitems
save(v)
it =
items = dict_items([('__annotations__', {'a': , 'b': , 'c': }), ('__doc__', 'MyTuple(a,... 0x00007f9ae09dc2a0>), ('b', ), ('c', )])
k = '_asdict'
n = 18
save = >
self =
tmp = [('__annotations__', {'a': , 'b': , 'c': }), ('__doc__', 'MyTuple(a, b, c)'), (...dule__', 'tests.cloudpickle_test'), ('__new__', )>), ...]
v =
write = >
/usr/lib/pypy3.11/pickle.py:573: in save
f(self, obj) # Call unbound method with explicit self
f =
obj =
pid = None
reduce = None
rv = NotImplemented
save_persistent_id = True
self =
t =
x = None
cloudpickle/cloudpickle.py:1472: in save_function
*self._dynamic_function_reduce(obj), obj=obj
__class__ =
name = None
obj =
self =
cloudpickle/cloudpickle.py:1251: in _dynamic_function_reduce
state = _function_getstate(func)
func =
newargs = (, {'__file__':...sr/lib/pypy3.11/collections']}, None, None, (, ))
self =
cloudpickle/cloudpickle.py:727: in _function_getstate
f_globals_ref = _extract_code_globals(func.__code__)
func =
slotstate = {'__annotations__': {}, '__closure__': (, ), '__defaults__': None, '__doc__': 'Return a new dict which maps field names to their values.', ...}
cloudpickle/cloudpickle.py:320: in _extract_code_globals
out_names = {name: None for name in _walk_global_ops(co)}
co =
out_names = None
cloudpickle/cloudpickle.py:320: in
out_names = {name: None for name in _walk_global_ops(co)}
.0 =
cloudpickle/cloudpickle.py:413: in _walk_global_ops
for instr in dis.get_instructions(code):
code =
instr = Instruction(opname='LOAD_DEREF', opcode=136, arg=0, argval='self', argrepr='self', offset=0, starts_line=499, is_jump_target=False, positions=Positions(lineno=499, end_lineno=499, col_offset=15, end_col_offset=20))
op = 136
/usr/lib/pypy3.11/dis.py:485: in _get_instructions_bytes
argval, argrepr = _get_name_info(arg, varname_from_oparg)
arg = 1
argrepr = ''
argval = 1
caches = 0
co_consts = ('Return a new dict which maps field names to their values.',)
co_positions =
code = b'\x88\x00\x88\x01|\x00j\x00|\x00\x83\x02\x83\x01S\x00'
deop = 136
exception_entries = ()
get_name =
is_jump_target = False
labels = set()
line_offset = 0
linestarts = {0: 499}
names = ('_fields',)
offset = 2
op = 136
positions = Positions(lineno=499, end_lineno=499, col_offset=21, end_col_offset=25)
show_caches = False
starts_line = None
varname_from_oparg = . at 0x00007f9ae097f560>
/usr/lib/pypy3.11/dis.py:395: in _get_name_info
argval = get_name(name_index, **extrainfo)
extrainfo = {}
get_name = . at 0x00007f9ae097f560>
name_index = 1
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

i = 1

> varname_from_oparg = lambda i: co.co_varnames[i]
E IndexError: tuple index out of range

co =
i = 1

/usr/lib/pypy3.11/dis.py:351: IndexError
__________________ CloudPickleTest.test_empty_cell_preserved ___________________

self =

def test_empty_cell_preserved(self):
def f():
if False: # pragma: no cover
cell = None

def g():
cell # NameError, unbound free variable

return g

g1 = f()
with pytest.raises(NameError):
g1()

> g2 = pickle_depickle(g1, protocol=self.protocol)

f = .f at 0x00007f9ae6d5ea20>
g1 = .f..g at 0x00007f9ae4563880>
self =

tests/cloudpickle_test.py:323:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
tests/cloudpickle_test.py:75: in pickle_depickle
return pickle.loads(cloudpickle.dumps(obj, protocol=protocol))
obj = .f..g at 0x00007f9ae4563880>
protocol = 5
cloudpickle/cloudpickle.py:1537: in dumps
cp.dump(obj)
buffer_callback = None
cp =
file = <_io.BytesIO object at 0x0000557399de7808>
obj = .f..g at 0x00007f9ae4563880>
protocol = 5
cloudpickle/cloudpickle.py:1303: in dump
return super().dump(obj)
__class__ =
obj = .f..g at 0x00007f9ae4563880>
self =
/usr/lib/pypy3.11/pickle.py:500: in dump
self.save(obj)
obj = .f..g at 0x00007f9ae4563880>
self =
/usr/lib/pypy3.11/pickle.py:573: in save
f(self, obj) # Call unbound method with explicit self
f =
obj = .f..g at 0x00007f9ae4563880>
pid = None
reduce = None
rv = NotImplemented
save_persistent_id = True
self =
t =
x = None
cloudpickle/cloudpickle.py:1472: in save_function
*self._dynamic_function_reduce(obj), obj=obj
__class__ =
name = None
obj = .f..g at 0x00007f9ae4563880>
self =
cloudpickle/cloudpickle.py:1251: in _dynamic_function_reduce
state = _function_getstate(func)
func = .f..g at 0x00007f9ae4563880>
newargs = (, {'__file__': '/tm...py', '__name__': 'tests.cloudpickle_test', '__package__': 'tests'}, None, None, (,))
self =
cloudpickle/cloudpickle.py:727: in _function_getstate
f_globals_ref = _extract_code_globals(func.__code__)
func = .f..g at 0x00007f9ae4563880>
slotstate = {'__annotations__': {}, '__closure__': (,), '__defaults__': None, '__doc__': None, ...}
cloudpickle/cloudpickle.py:320: in _extract_code_globals
out_names = {name: None for name in _walk_global_ops(co)}
co =
out_names = None
cloudpickle/cloudpickle.py:320: in
out_names = {name: None for name in _walk_global_ops(co)}
.0 =
cloudpickle/cloudpickle.py:413: in _walk_global_ops
for instr in dis.get_instructions(code):
code =
/usr/lib/pypy3.11/dis.py:485: in _get_instructions_bytes
argval, argrepr = _get_name_info(arg, varname_from_oparg)
arg = 0
argrepr = ''
argval = 0
co_consts = (None,)
co_positions =
code = b'\x88\x00\x01\x00d\x00S\x00'
deop = 136
exception_entries = ()
get_name =
is_jump_target = False
labels = set()
line_offset = 0
linestarts = {0: 315}
names = ()
offset = 0
op = 136
positions = Positions(lineno=315, end_lineno=315, col_offset=16, end_col_offset=20)
show_caches = False
starts_line = 315
varname_from_oparg = . at 0x00007f9ae45639c0>
/usr/lib/pypy3.11/dis.py:395: in _get_name_info
argval = get_name(name_index, **extrainfo)
extrainfo = {}
get_name = . at 0x00007f9ae45639c0>
name_index = 0
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

i = 0

> varname_from_oparg = lambda i: co.co_varnames[i]
E IndexError: tuple index out of range

co =
i = 0

/usr/lib/pypy3.11/dis.py:351: IndexError
______________________ CloudPickleTest.test_extended_arg _______________________

self =

@pytest.mark.skipif(
(3, 11, 0, "beta") <= sys.version_info < (3, 11, 0, "beta", 4),
reason="https://github.com/python/cpython/issues/92932",
)
def test_extended_arg(self):
# Functions with more than 65535 global vars prefix some global
# variable references with the EXTENDED_ARG opcode.
nvars = 65537 + 258
names = ["g%d" % i for i in range(1, nvars)]
r = random.Random(42)
d = {name: r.randrange(100) for name in names}
# def f(x):
# x = g1, g2, ...
# return zlib.crc32(bytes(bytearray(x)))
code = """
import zlib

def f():
x = {tup}
return zlib.crc32(bytes(bytearray(x)))
""".format(tup=", ".join(names))
exec(textwrap.dedent(code), d, d)
f = d["f"]
res = f()
data = cloudpickle.dumps([f, f], protocol=self.protocol)
d = f = None
f2, f3 = pickle.loads(data)
self.assertTrue(f2 is f3)
> self.assertEqual(f2(), res)

code = '\n import zlib\n\n def f():\n x = g1, g2, g3, g4, g5, g6, g7, g8, g9, g10, g11, g12, g13, g1..., g65788, g65789, g65790, g65791, g65792, g65793, g65794\n return zlib.crc32(bytes(bytearray(x)))\n '
d = None
data = b'\x80\x05\x95a\x00\x00\x00\x00\x00\x00\x00]\x94(\x8c\x17cloudpickle.cloudpickle\x94\x8c\x0e_make_function\x94\x93\x94...Tj\x8a\x80\x00\x00K.j\x8b\x80\x00\x00K\x1fj\x8c\x80\x00\x00KPj\x8d\x80\x00\x00K\x00uu\x86\x94\x86R0j\x1b\x01\x01\x00e.'
f = None
f2 =
f3 =
names = ['g1', 'g2', 'g3', 'g4', 'g5', 'g6', ...]
nvars = 65795
r =
res = 2957535583
self =

tests/cloudpickle_test.py:1078:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

> ???
E NameError: name 'g32900' is not defined

:5: NameError
______________________ CloudPickleTest.test_generic_type _______________________

self =

def test_generic_type(self):
T = typing.TypeVar("T")

class C(typing.Generic[T]):
pass

assert pickle_depickle(C, protocol=self.protocol) is C

# Identity is not part of the typing contract: only test for
# equality instead.
assert pickle_depickle(C[int], protocol=self.protocol) == C[int]

with subprocess_worker(protocol=self.protocol) as worker:

def check_generic(generic, origin, type_value):
assert generic.__origin__ is origin

assert len(origin.__orig_bases__) == 1
ob = origin.__orig_bases__[0]
assert ob.__origin__ is typing.Generic

assert len(generic.__args__) == 1
assert generic.__args__[0] is type_value
assert len(ob.__parameters__) == 1

return "ok"

assert check_generic(C[int], C, int) == "ok"
> assert worker.run(check_generic, C[int], C, int) == "ok"

C = .C'>
T = ~T
check_generic = .check_generic at 0x00007f9ae132f240>
self =
worker =

tests/cloudpickle_test.py:2603:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self =
func = .check_generic at 0x00007f9ae132f240>
args = (tests.cloudpickle_test.CloudPickleTest.test_generic_type..C[int], .C'>, )
kwargs = {}
input_payload = b'\x80\x05\x95\xb5\x14\x00\x00\x00\x00\x00\x00\x8c\x17cloudpickle.cloudpickle\x94\x8c\x0e_make_function\x94\x93\x94(h\...meters__\x94h\x96\x85\x94u}\x94\x86\x94\x86R0h\x83\x8c\x03int\x94\x93\x94\x86\x94R\x94h\x9eh\xaa\x87\x94}\x94\x87\x94.'
result_payload = b"\x80\x05\x95=\x00\x00\x00\x00\x00\x00\x00\x8c\x08builtins\x94\x8c\tNameError\x94\x93\x94\x8c\x1cname 'typing' is not defined\x94\x85\x94R\x94."
result = NameError("name 'typing' is not defined")

def run(self, func, *args, **kwargs):
"""Synchronous remote function call"""

input_payload = dumps((func, args, kwargs), protocol=self.protocol)
result_payload = self.pool.submit(
call_func, input_payload, self.protocol
).result()
result = loads(result_payload)

if isinstance(result, BaseException):
> raise result
E NameError: name 'typing' is not defined

args = (tests.cloudpickle_test.CloudPickleTest.test_generic_type..C[int], .C'>, )
func = .check_generic at 0x00007f9ae132f240>
input_payload = b'\x80\x05\x95\xb5\x14\x00\x00\x00\x00\x00\x00\x8c\x17cloudpickle.cloudpickle\x94\x8c\x0e_make_function\x94\x93\x94(h\...meters__\x94h\x96\x85\x94u}\x94\x86\x94\x86R0h\x83\x8c\x03int\x94\x93\x94\x86\x94R\x94h\x9eh\xaa\x87\x94}\x94\x87\x94.'
kwargs = {}
result = NameError("name 'typing' is not defined")
result_payload = b"\x80\x05\x95=\x00\x00\x00\x00\x00\x00\x00\x8c\x08builtins\x94\x8c\tNameError\x94\x93\x94\x8c\x1cname 'typing' is not defined\x94\x85\x94R\x94."
self =

tests/testutils.py:154: NameError
__ CloudPickleTest.test_interactive_dynamic_type_and_stored_remote_instances ___

source_code = 'if __name__ == "__main__":\n import cloudpickle, uuid\n from testutils import subprocess_worker\n\n ... class\n # method:\n assert w.run(lambda obj_id: lookup(obj_id).echo(43), id2) == 43\n\n '
timeout = 60

def assert_run_python_script(source_code, timeout=TIMEOUT):
"""Utility to help check pickleability of objects defined in __main__

The script provided in the source code should return 0 and not print
anything on stderr or stdout.
"""
fd, source_file = tempfile.mkstemp(suffix="_src_test_cloudpickle.py")
os.close(fd)
try:
with open(source_file, "wb") as f:
f.write(source_code.encode("utf-8"))
cmd = [sys.executable, "-W ignore", source_file]
cwd, env = _make_cwd_env()
kwargs = {
"cwd": cwd,
"stderr": STDOUT,
"env": env,
}
# If coverage is running, pass the config file to the subprocess
coverage_rc = os.environ.get("COVERAGE_PROCESS_START")
if coverage_rc:
kwargs["env"]["COVERAGE_PROCESS_START"] = coverage_rc
kwargs["timeout"] = timeout
try:
try:
> out = check_output(cmd, **kwargs)

cmd = ['/tmp/cloudpickle/.tox/pypy311/bin/python', '-W ignore', '/tmp/tmpby_84fww_src_test_cloudpickle.py']
coverage_rc = None
cwd = '/tmp/cloudpickle'
env = {'HOME': '/home/mgorny', 'LANG': 'pl_PL.UTF-8', 'PATH': '/tmp/cloudpickle/.tox/pypy311/bin:/home/mgorny/perl5/bin:/hom...m/19/bin:/usr/lib/llvm/9/bin:/etc/eselect/wine/bin:/home/mgorny/.local/bin', 'PIP_DISABLE_PIP_VERSION_CHECK': '1', ...}
f = <_io.BufferedWriter name='/tmp/tmpby_84fww_src_test_cloudpickle.py'>
fd = 14
kwargs = {'cwd': '/tmp/cloudpickle', 'env': {'HOME': '/home/mgorny', 'LANG': 'pl_PL.UTF-8', 'PATH': '/tmp/cloudpickle/.tox/pypy...etc/eselect/wine/bin:/home/mgorny/.local/bin', 'PIP_DISABLE_PIP_VERSION_CHECK': '1', ...}, 'stderr': -2, 'timeout': 60}
source_code = 'if __name__ == "__main__":\n import cloudpickle, uuid\n from testutils import subprocess_worker\n\n ... class\n # method:\n assert w.run(lambda obj_id: lookup(obj_id).echo(43), id2) == 43\n\n '
source_file = '/tmp/tmpby_84fww_src_test_cloudpickle.py'
timeout = 60

tests/testutils.py:204:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/usr/lib/pypy3.11/subprocess.py:466: in check_output
return run(*popenargs, stdout=PIPE, timeout=timeout, check=True,
kw = 'check'
kwargs = {'cwd': '/tmp/cloudpickle', 'env': {'HOME': '/home/mgorny', 'LANG': 'pl_PL.UTF-8', 'PATH': '/tmp/cloudpickle/.tox/pypy...ib/llvm/9/bin:/etc/eselect/wine/bin:/home/mgorny/.local/bin', 'PIP_DISABLE_PIP_VERSION_CHECK': '1', ...}, 'stderr': -2}
popenargs = (['/tmp/cloudpickle/.tox/pypy311/bin/python', '-W ignore', '/tmp/tmpby_84fww_src_test_cloudpickle.py'],)
timeout = 60
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

input = None, capture_output = False, timeout = 60, check = True
popenargs = (['/tmp/cloudpickle/.tox/pypy311/bin/python', '-W ignore', '/tmp/tmpby_84fww_src_test_cloudpickle.py'],)
kwargs = {'cwd': '/tmp/cloudpickle', 'env': {'HOME': '/home/mgorny', 'LANG': 'pl_PL.UTF-8', 'PATH': '/tmp/cloudpickle/.tox/pypy.../etc/eselect/wine/bin:/home/mgorny/.local/bin', 'PIP_DISABLE_PIP_VERSION_CHECK': '1', ...}, 'stderr': -2, 'stdout': -1}
process =
stdout = b'Traceback (most recent call last):\n File "/tmp/tmpby_84fww_src_test_cloudpickle.py", line 22, in \n id1...e "/tmp/cloudpickle/tests/testutils.py", line 154, in run\n raise result\nNameError: name \'uuid\' is not defined\n'
stderr = None, retcode = 1

def run(*popenargs,
input=None, capture_output=False, timeout=None, check=False, **kwargs):
"""Run command with arguments and return a CompletedProcess instance.

The returned instance will have attributes args, returncode, stdout and
stderr. By default, stdout and stderr are not captured, and those attributes
will be None. Pass stdout=PIPE and/or stderr=PIPE in order to capture them,
or pass capture_output=True to capture both.

If check is True and the exit code was non-zero, it raises a
CalledProcessError. The CalledProcessError object will have the return code
in the returncode attribute, and output & stderr attributes if those streams
were captured.

If timeout is given, and the process takes too long, a TimeoutExpired
exception will be raised.

There is an optional argument "input", allowing you to
pass bytes or a string to the subprocess's stdin. If you use this argument
you may not also use the Popen constructor's "stdin" argument, as
it will be used internally.

By default, all communication is in bytes, and therefore any "input" should
be bytes, and the stdout and stderr will be bytes. If in text mode, any
"input" should be a string, and stdout and stderr will be strings decoded
according to locale encoding, or by "encoding" if set. Text mode is
triggered by setting any of text, encoding, errors or universal_newlines.

The other arguments are the same as for the Popen constructor.
"""
if input is not None:
if kwargs.get('stdin') is not None:
raise ValueError('stdin and input arguments may not both be used.')
kwargs['stdin'] = PIPE

if capture_output:
if kwargs.get('stdout') is not None or kwargs.get('stderr') is not None:
raise ValueError('stdout and stderr arguments may not be used '
'with capture_output.')
kwargs['stdout'] = PIPE
kwargs['stderr'] = PIPE

with Popen(*popenargs, **kwargs) as process:
try:
stdout, stderr = process.communicate(input, timeout=timeout)
except TimeoutExpired as exc:
process.kill()
if _mswindows:
# Windows accumulates the output in a single blocking
# read() call run on child threads, with the timeout
# being done in a join() on those threads. communicate()
# _after_ kill() is required to collect that and add it
# to the exception.
exc.stdout, exc.stderr = process.communicate()
else:
# POSIX _communicate already populated the output so
# far into the TimeoutExpired exception.
process.wait()
raise
except: # Including KeyboardInterrupt, communicate handled that.
process.kill()
# We don't call process.wait() as .__exit__ does that for us.
raise
retcode = process.poll()
if check and retcode:
> raise CalledProcessError(retcode, process.args,
output=stdout, stderr=stderr)
E subprocess.CalledProcessError: Command '['/tmp/cloudpickle/.tox/pypy311/bin/python', '-W ignore', '/tmp/tmpby_84fww_src_test_cloudpickle.py']' returned non-zero exit status 1.

capture_output = False
check = True
input = None
kwargs = {'cwd': '/tmp/cloudpickle', 'env': {'HOME': '/home/mgorny', 'LANG': 'pl_PL.UTF-8', 'PATH': '/tmp/cloudpickle/.tox/pypy.../etc/eselect/wine/bin:/home/mgorny/.local/bin', 'PIP_DISABLE_PIP_VERSION_CHECK': '1', ...}, 'stderr': -2, 'stdout': -1}
popenargs = (['/tmp/cloudpickle/.tox/pypy311/bin/python', '-W ignore', '/tmp/tmpby_84fww_src_test_cloudpickle.py'],)
process =
retcode = 1
stderr = None
stdout = b'Traceback (most recent call last):\n File "/tmp/tmpby_84fww_src_test_cloudpickle.py", line 22, in \n id1...e "/tmp/cloudpickle/tests/testutils.py", line 154, in run\n raise result\nNameError: name \'uuid\' is not defined\n'
timeout = 60

/usr/lib/pypy3.11/subprocess.py:571: CalledProcessError

The above exception was the direct cause of the following exception:

self =

def test_interactive_dynamic_type_and_stored_remote_instances(self):
"""Simulate objects stored on workers to check isinstance semantics

Such instances stored in the memory of running worker processes are
similar to dask-distributed futures for instance.
"""
code = """if __name__ == "__main__":
import cloudpickle, uuid
from testutils import subprocess_worker

with subprocess_worker(protocol={protocol}) as w:

class A:
'''Original class definition'''
pass

def store(x):
storage = getattr(cloudpickle, "_test_storage", None)
if storage is None:
storage = cloudpickle._test_storage = dict()
obj_id = uuid.uuid4().hex
storage[obj_id] = x
return obj_id

def lookup(obj_id):
return cloudpickle._test_storage[obj_id]

id1 = w.run(store, A())

# The stored object on the worker is matched to a singleton class
# definition thanks to provenance tracking:
assert w.run(lambda obj_id: isinstance(lookup(obj_id), A), id1)

# Retrieving the object from the worker yields a local copy that
# is matched back the local class definition this instance
# originally stems from.
assert isinstance(w.run(lookup, id1), A)

# Changing the local class definition should be taken into account
# in all subsequent calls. In particular the old instances on the
# worker do not map back to the new class definition, neither on
# the worker itself, nor locally on the main program when the old
# instance is retrieved:

class A:
'''Updated class definition'''

assert not w.run(lambda obj_id: isinstance(lookup(obj_id), A), id1)
retrieved1 = w.run(lookup, id1)
assert not isinstance(retrieved1, A)
assert retrieved1.__class__ is not A
assert retrieved1.__class__.__doc__ == "Original class definition"

# New instances on the other hand are proper instances of the new
# class definition everywhere:

a = A()
id2 = w.run(store, a)
assert w.run(lambda obj_id: isinstance(lookup(obj_id), A), id2)
assert isinstance(w.run(lookup, id2), A)

# Monkeypatch the class defintion in the main process to a new
# class method:
A.echo = lambda cls, x: x

# Calling this method on an instance will automatically update
# the remote class definition on the worker to propagate the monkey
# patch dynamically.
assert w.run(a.echo, 42) == 42

# The stored instance can therefore also access the new class
# method:
assert w.run(lambda obj_id: lookup(obj_id).echo(43), id2) == 43

""".format(protocol=self.protocol)
> assert_run_python_script(code)

code = 'if __name__ == "__main__":\n import cloudpickle, uuid\n from testutils import subprocess_worker\n\n ... class\n # method:\n assert w.run(lambda obj_id: lookup(obj_id).echo(43), id2) == 43\n\n '
self =

tests/cloudpickle_test.py:2036:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

source_code = 'if __name__ == "__main__":\n import cloudpickle, uuid\n from testutils import subprocess_worker\n\n ... class\n # method:\n assert w.run(lambda obj_id: lookup(obj_id).echo(43), id2) == 43\n\n '
timeout = 60

def assert_run_python_script(source_code, timeout=TIMEOUT):
"""Utility to help check pickleability of objects defined in __main__

The script provided in the source code should return 0 and not print
anything on stderr or stdout.
"""
fd, source_file = tempfile.mkstemp(suffix="_src_test_cloudpickle.py")
os.close(fd)
try:
with open(source_file, "wb") as f:
f.write(source_code.encode("utf-8"))
cmd = [sys.executable, "-W ignore", source_file]
cwd, env = _make_cwd_env()
kwargs = {
"cwd": cwd,
"stderr": STDOUT,
"env": env,
}
# If coverage is running, pass the config file to the subprocess
coverage_rc = os.environ.get("COVERAGE_PROCESS_START")
if coverage_rc:
kwargs["env"]["COVERAGE_PROCESS_START"] = coverage_rc
kwargs["timeout"] = timeout
try:
try:
out = check_output(cmd, **kwargs)
except CalledProcessError as e:
> raise RuntimeError(
"script errored with output:\n%s" % e.output.decode("utf-8")
) from e
E RuntimeError: script errored with output:
E Traceback (most recent call last):
E File "/tmp/tmpby_84fww_src_test_cloudpickle.py", line 22, in
E id1 = w.run(store, A())
E ^^^^^^^^^^^^^^^^^
E File "/tmp/cloudpickle/tests/testutils.py", line 154, in run
E raise result
E NameError: name 'uuid' is not defined

cmd = ['/tmp/cloudpickle/.tox/pypy311/bin/python', '-W ignore', '/tmp/tmpby_84fww_src_test_cloudpickle.py']
coverage_rc = None
cwd = '/tmp/cloudpickle'
env = {'HOME': '/home/mgorny', 'LANG': 'pl_PL.UTF-8', 'PATH': '/tmp/cloudpickle/.tox/pypy311/bin:/home/mgorny/perl5/bin:/hom...m/19/bin:/usr/lib/llvm/9/bin:/etc/eselect/wine/bin:/home/mgorny/.local/bin', 'PIP_DISABLE_PIP_VERSION_CHECK': '1', ...}
f = <_io.BufferedWriter name='/tmp/tmpby_84fww_src_test_cloudpickle.py'>
fd = 14
kwargs = {'cwd': '/tmp/cloudpickle', 'env': {'HOME': '/home/mgorny', 'LANG': 'pl_PL.UTF-8', 'PATH': '/tmp/cloudpickle/.tox/pypy...etc/eselect/wine/bin:/home/mgorny/.local/bin', 'PIP_DISABLE_PIP_VERSION_CHECK': '1', ...}, 'stderr': -2, 'timeout': 60}
source_code = 'if __name__ == "__main__":\n import cloudpickle, uuid\n from testutils import subprocess_worker\n\n ... class\n # method:\n assert w.run(lambda obj_id: lookup(obj_id).echo(43), id2) == 43\n\n '
source_file = '/tmp/tmpby_84fww_src_test_cloudpickle.py'
timeout = 60

tests/testutils.py:206: RuntimeError
=========================== short test summary info ============================
FAILED tests/cloudpickle_test.py::CloudPickleTest::test_NamedTuple - IndexErr...
FAILED tests/cloudpickle_test.py::CloudPickleTest::test_empty_cell_preserved
FAILED tests/cloudpickle_test.py::CloudPickleTest::test_extended_arg - NameEr...
FAILED tests/cloudpickle_test.py::CloudPickleTest::test_generic_type - NameEr...
FAILED tests/cloudpickle_test.py::CloudPickleTest::test_interactive_dynamic_type_and_stored_remote_instances
!!!!!!!!!!!!!!!!!!!!!!!!!! stopping after 5 failures !!!!!!!!!!!!!!!!!!!!!!!!!!!
============== 5 failed, 62 passed, 1 skipped, 1 xfailed in 4.13s ==============
pypy311: exit 1 (4.52 seconds) /tmp/cloudpickle> pytest -lv --maxfail=5 pid=950736
.pkg: _exit> python /usr/lib/python3.13/site-packages/pyproject_api/_backend.py True flit_core.buildapi
pypy311: FAIL code 1 (6.78=setup[2.26]+cmd[4.52] seconds)
evaluation failed :( (6.85 seconds)
```

That said, when running the test suite locally on a Gentoo system, it's running many more tests and seeing many more failures — I'm guessing tox underspecifies test dependencies.

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.