Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions cloudpickle/cloudpickle.py
Original file line number Diff line number Diff line change
Expand Up @@ -591,6 +591,8 @@ def save_function_tuple(self, func):
state['annotations'] = func.__annotations__
if hasattr(func, '__qualname__'):
state['qualname'] = func.__qualname__
if hasattr(func, '__kwdefaults__'):
state['kwdefaults'] = func.__kwdefaults__
save(state)
write(pickle.TUPLE)
write(pickle.REDUCE) # applies _fill_function on the tuple
Expand Down Expand Up @@ -1075,6 +1077,8 @@ def _fill_function(*args):
func.__module__ = state['module']
if 'qualname' in state:
func.__qualname__ = state['qualname']
if 'kwdefaults' in state:
func.__kwdefaults__ = state['kwdefaults']

cells = func.__closure__
if cells is not None:
Expand Down
22 changes: 22 additions & 0 deletions tests/cloudpickle_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -1392,6 +1392,28 @@ def g():
cloned_func = pickle_depickle(func, protocol=self.protocol)
assert cloned_func() == "hello from a {}!".format(source)

@pytest.mark.skipif(sys.version_info[0] < 3,
reason="keyword only arguments were introduced in "
"python 3")
def test_interactively_defined_func_with_keyword_only_argument(self):
# fixes https://github.com/cloudpipe/cloudpickle/issues/263
# The source code of this test is bundled in a string and is ran from
# the __main__ module of a subprocess in order to avoid a SyntaxError
# in python2 when pytest imports this file, as the keyword-only syntax
# is python3-only.
code = """
from cloudpickle import loads, dumps

def f(a, *, b=1):
return a + b

depickled_f = loads(dumps(f, protocol={protocol}))

for func in (f, depickled_f):
assert func(2) == 3
assert func.__kwdefaults__ == {{'b': 1}}
""".format(protocol=self.protocol)
assert_run_python_script(textwrap.dedent(code))

class Protocol2CloudPickleTest(CloudPickleTest):

Expand Down