Package: cloudpickle
Severity: normal
User: ubuntu-de...@lists.ubuntu.com
Usertags: origin-ubuntu lunar

Dear Maintainer,

This bug report was also filed in Ubuntu and can be found at
https://launchpad.net/bugs/1996655
The description, from Dan Bungert, follows:

Cloudpickle will FTBFS with an impressive array of unittest failures when
attempting to use python 3.11.

See attached for what I'm uploading for Ubuntu, which is backports of 2 commits
from upstream.

-Dan
diff -Nru cloudpickle-2.0.0/debian/patches/0cb1910.patch 
cloudpickle-2.0.0/debian/patches/0cb1910.patch
--- cloudpickle-2.0.0/debian/patches/0cb1910.patch      1969-12-31 
17:00:00.000000000 -0700
+++ cloudpickle-2.0.0/debian/patches/0cb1910.patch      2022-11-15 
16:40:33.000000000 -0700
@@ -0,0 +1,122 @@
+Description: Improve compatibility with "nogil" Python and 3.11
+Author:      Dan Bungert <daniel.bung...@canonical.com>
+Origin:      
https://github.com/cloudpipe/cloudpickle/pull/470/commits/0cb191032d4b7913e6a66e3f24788668efbd10dd
+Bug-Ubuntu:  https://bugs.launchpad.net/bugs/1996655
+Bug:         https://github.com/cloudpipe/cloudpickle/pull/470
+Last-Update: 2022-11-15
+
+Patch modified from original commit by `quilt refresh`.
+--- a/cloudpickle/cloudpickle.py
++++ b/cloudpickle/cloudpickle.py
+@@ -327,11 +327,10 @@
+     """
+     out_names = _extract_code_globals_cache.get(co)
+     if out_names is None:
+-        names = co.co_names
+         # We use a dict with None values instead of a set to get a
+         # deterministic order (assuming Python 3.6+) and avoid introducing
+         # non-deterministic pickle bytes as a results.
+-        out_names = {names[oparg]: None for _, oparg in _walk_global_ops(co)}
++        out_names = {name: None for name in _walk_global_ops(co)}
+ 
+         # Declaring a function inside another one using the "def ..."
+         # syntax generates a constant code object corresponding to the one
+@@ -517,13 +516,12 @@
+ 
+ def _walk_global_ops(code):
+     """
+-    Yield (opcode, argument number) tuples for all
+-    global-referencing instructions in *code*.
++    Yield referenced name for all global-referencing instructions in *code*.
+     """
+     for instr in dis.get_instructions(code):
+         op = instr.opcode
+         if op in GLOBAL_OPS:
+-            yield op, instr.arg
++            yield instr.argval
+ 
+ 
+ def _extract_class_dict(cls):
+@@ -793,6 +791,11 @@
+     return func
+ 
+ 
++def _make_function(code, globals, name, argdefs, closure):
++    globals["__builtins__"] = __builtins__
++    return types.FunctionType(code, globals, name, argdefs, closure)
++
++
+ def _make_empty_cell():
+     if False:
+         # trick the compiler into creating an empty cell in our lambda
+--- a/cloudpickle/cloudpickle_fast.py
++++ b/cloudpickle/cloudpickle_fast.py
+@@ -35,7 +35,7 @@
+     _is_parametrized_type_hint, PYPY, cell_set,
+     parametrized_type_hint_getinitargs, _create_parametrized_type_hint,
+     builtin_code_type,
+-    _make_dict_keys, _make_dict_values, _make_dict_items,
++    _make_dict_keys, _make_dict_values, _make_dict_items, _make_function,
+ )
+ 
+ 
+@@ -248,7 +248,7 @@
+     # of the specific type from types, for example:
+     # >>> from types import CodeType
+     # >>> help(CodeType)
+-    if hasattr(obj, "co_columntable"):  # pragma: no branch
++    if hasattr(obj, "co_exceptiontable"):  # pragma: no branch
+         # Python 3.11 and later: there are some new attributes
+         # related to the enhanced exceptions.
+         args = (
+@@ -256,9 +256,8 @@
+             obj.co_kwonlyargcount, obj.co_nlocals, obj.co_stacksize,
+             obj.co_flags, obj.co_code, obj.co_consts, obj.co_names,
+             obj.co_varnames, obj.co_filename, obj.co_name, obj.co_qualname,
+-            obj.co_firstlineno, obj.co_linetable, obj.co_endlinetable,
+-            obj.co_columntable, obj.co_exceptiontable, obj.co_freevars,
+-            obj.co_cellvars,
++            obj.co_firstlineno, obj.co_linetable, obj.co_exceptiontable,
++            obj.co_freevars, obj.co_cellvars,
+         )
+     elif hasattr(obj, "co_linetable"):  # pragma: no branch
+         # Python 3.10 and later: obj.co_lnotab is deprecated and constructor
+@@ -271,6 +270,18 @@
+             obj.co_firstlineno, obj.co_linetable, obj.co_freevars,
+             obj.co_cellvars
+         )
++    elif hasattr(obj, "co_nmeta"):  # pragma: no branch
++        # "nogil" Python: modified attributes from 3.9
++        args = (
++            obj.co_argcount, obj.co_posonlyargcount,
++            obj.co_kwonlyargcount, obj.co_nlocals, obj.co_framesize,
++            obj.co_ndefaultargs, obj.co_nmeta,
++            obj.co_flags, obj.co_code, obj.co_consts,
++            obj.co_varnames, obj.co_filename, obj.co_name,
++            obj.co_firstlineno, obj.co_lnotab, obj.co_exc_handlers,
++            obj.co_jump_table, obj.co_freevars, obj.co_cellvars,
++            obj.co_free2reg, obj.co_cell2reg
++        )
+     elif hasattr(obj, "co_posonlyargcount"):
+         # Backward compat for 3.9 and older
+         args = (
+@@ -560,7 +571,7 @@
+         """Reduce a function that is not pickleable via attribute lookup."""
+         newargs = self._function_getnewargs(func)
+         state = _function_getstate(func)
+-        return (types.FunctionType, newargs, state, None, None,
++        return (_make_function, newargs, state, None, None,
+                 _function_setstate)
+ 
+     def _function_reduce(self, obj):
+--- a/tests/cloudpickle_test.py
++++ b/tests/cloudpickle_test.py
+@@ -2139,7 +2139,7 @@
+ 
+     def test_recursion_during_pickling(self):
+         class A:
+-            def __getattr__(self, name):
++            def __getattribute__(self, name):
+                 return getattr(self, name)
+ 
+         a = A()
diff -Nru cloudpickle-2.0.0/debian/patches/47f0775.patch 
cloudpickle-2.0.0/debian/patches/47f0775.patch
--- cloudpickle-2.0.0/debian/patches/47f0775.patch      1969-12-31 
17:00:00.000000000 -0700
+++ cloudpickle-2.0.0/debian/patches/47f0775.patch      2022-11-15 
16:40:33.000000000 -0700
@@ -0,0 +1,75 @@
+Description: Fix compatibility with Python 3.11 #467
+Author:      Dan Bungert <daniel.bung...@canonical.com>
+Origin:      
https://github.com/cloudpipe/cloudpickle/pull/467/commits/47f07757d1aa7602a6b33cd4b85a67f3f367fe31
+Bug-Ubuntu:  https://bugs.launchpad.net/bugs/1996655
+Bug:         https://github.com/cloudpipe/cloudpickle/pull/467
+Last-Update: 2022-11-15
+
+Patch modified from commit to drop references to files that aren't in the
+source package, and a `quilt refresh`.
+--- a/cloudpickle/cloudpickle_fast.py
++++ b/cloudpickle/cloudpickle_fast.py
+@@ -244,7 +244,23 @@
+ 
+ def _code_reduce(obj):
+     """codeobject reducer"""
+-    if hasattr(obj, "co_linetable"):  # pragma: no branch
++    # If you are not sure about the order of arguments, take a look at help
++    # of the specific type from types, for example:
++    # >>> from types import CodeType
++    # >>> help(CodeType)
++    if hasattr(obj, "co_columntable"):  # pragma: no branch
++        # Python 3.11 and later: there are some new attributes
++        # related to the enhanced exceptions.
++        args = (
++            obj.co_argcount, obj.co_posonlyargcount,
++            obj.co_kwonlyargcount, obj.co_nlocals, obj.co_stacksize,
++            obj.co_flags, obj.co_code, obj.co_consts, obj.co_names,
++            obj.co_varnames, obj.co_filename, obj.co_name, obj.co_qualname,
++            obj.co_firstlineno, obj.co_linetable, obj.co_endlinetable,
++            obj.co_columntable, obj.co_exceptiontable, obj.co_freevars,
++            obj.co_cellvars,
++        )
++    elif hasattr(obj, "co_linetable"):  # pragma: no branch
+         # Python 3.10 and later: obj.co_lnotab is deprecated and constructor
+         # expects obj.co_linetable instead.
+         args = (
+--- a/tests/cloudpickle_test.py
++++ b/tests/cloudpickle_test.py
+@@ -2246,29 +2246,13 @@
+ 
+                 def check_annotations(obj, expected_type, expected_type_str):
+                     assert obj.__annotations__["attribute"] == expected_type
+-                    if sys.version_info >= (3, 11):
+-                        # In Python 3.11, type annotations are stored as 
strings.
+-                        # See PEP 563 for more details:
+-                        # https://www.python.org/dev/peps/pep-0563/
+-                        # Originaly scheduled for 3.10, then postponed.
+-                        # See this for more details:
+-                        # 
https://mail.python.org/archives/list/python-...@python.org/thread/CLVXXPQ2T2LQ5MP2Y53VVQFCXYWQJHKZ/
+-                        assert (
+-                            obj.method.__annotations__["arg"]
+-                            == expected_type_str
+-                        )
+-                        assert (
+-                            obj.method.__annotations__["return"]
+-                            == expected_type_str
+-                        )
+-                    else:
+-                        assert (
+-                            obj.method.__annotations__["arg"] == expected_type
+-                        )
+-                        assert (
+-                            obj.method.__annotations__["return"]
+-                            == expected_type
+-                        )
++                    assert (
++                        obj.method.__annotations__["arg"] == expected_type
++                    )
++                    assert (
++                        obj.method.__annotations__["return"]
++                        == expected_type
++                    )
+                     return "ok"
+ 
+                 obj = MyClass()
diff -Nru cloudpickle-2.0.0/debian/patches/series 
cloudpickle-2.0.0/debian/patches/series
--- cloudpickle-2.0.0/debian/patches/series     1969-12-31 17:00:00.000000000 
-0700
+++ cloudpickle-2.0.0/debian/patches/series     2022-11-15 16:40:33.000000000 
-0700
@@ -0,0 +1,3 @@
+# python 3.11 compat backports
+47f0775.patch
+0cb1910.patch

Reply via email to