Skip to content

Commit 6c60eaf

Browse files
committed
Merge remote-tracking branch 'upstream/master' into refactor-builtin_method_pickling
2 parents 106700a + 74d69d7 commit 6c60eaf

File tree

6 files changed

+116
-38
lines changed

6 files changed

+116
-38
lines changed

.travis.yml

+31-13
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ matrix:
1212
- os: linux
1313
dist: trusty
1414
python: "pypy3"
15+
- os: linux
16+
if: commit_message =~ /(\[ci python-nightly\])/
17+
env: PYTHON_NIGHTLY=1
1518
- os: linux
1619
python: 3.7
1720
- os: linux
@@ -69,38 +72,53 @@ before_install:
6972
export PATH="$PYTHON_ROOT:$PYTHON_ROOT/Scripts:$PATH";
7073
python -m pip install --upgrade pip;
7174
fi
75+
- if [[ "$PYTHON_NIGHTLY" == 1 ]]; then
76+
export VENV_DIR="$HOME/python38";
77+
pushd ..;
78+
git clone https://github.com/python/cpython.git;
79+
pushd cpython;
80+
./configure;
81+
make;
82+
./python -m venv "$VENV_DIR";
83+
popd;
84+
popd;
85+
export PYTHON_EXE="$VENV_DIR/bin/python";
86+
else
87+
export PYTHON_EXE="python";
88+
fi
89+
7290
install:
73-
- pip install .
74-
- pip install --upgrade -r dev-requirements.txt
75-
- pip install tornado
76-
- if [[ $TRAVIS_PYTHON_VERSION != 'pypy'* ]]; then
77-
pip install numpy scipy;
91+
- $PYTHON_EXE -m pip install .
92+
- $PYTHON_EXE -m pip install --upgrade -r dev-requirements.txt
93+
- $PYTHON_EXE -m pip install tornado
94+
- if [[ $TRAVIS_PYTHON_VERSION != 'pypy'* && "$PYTHON_NIGHTLY" != 1 ]]; then
95+
$PYTHON_EXE -m pip install numpy scipy;
7896
fi
7997
- if [[ $PROJECT != "" ]]; then
80-
pip install $TEST_REQUIREMENTS;
98+
$PYTHON_EXE -m pip install $TEST_REQUIREMENTS;
8199
pushd ..;
82100
git clone $PROJECT_URL;
83101
if [[ $PROJECT == "joblib" ]]; then
84102
pushd joblib/joblib/externals;
85103
source vendor_cloudpickle.sh ../../../cloudpickle;
86104
popd;
87105
fi;
88-
pip install ./$PROJECT;
106+
$PYTHON_EXE -m pip install ./$PROJECT;
89107
popd;
90108
fi
91-
- pip list
109+
- $PYTHON_EXE -m pip list
92110
before_script:
93111
# stop the build if there are Python syntax errors or undefined names
94-
- flake8 . --count --select=E901,E999,F821,F822,F823 --show-source --statistics
112+
- $PYTHON_EXE -m flake8 . --count --verbose --select=E901,E999,F821,F822,F823 --show-source --statistics
95113
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
96-
- flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
97-
- python ci/install_coverage_subprocess_pth.py
114+
- $PYTHON_EXE -m flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
115+
- $PYTHON_EXE ci/install_coverage_subprocess_pth.py
98116
script:
99-
- COVERAGE_PROCESS_START="$TRAVIS_BUILD_DIR/.coveragerc" PYTHONPATH='.:tests' pytest -r s
117+
- COVERAGE_PROCESS_START="$TRAVIS_BUILD_DIR/.coveragerc" PYTHONPATH='.:tests' $PYTHON_EXE -m pytest -r s
100118
- |
101119
if [[ $PROJECT != "" ]]; then
102120
pushd ../$PROJECT
103-
pytest -vl
121+
$PYTHON_EXE -m pytest -vl
104122
TEST_RETURN_CODE=$?
105123
popd
106124
if [[ "$TEST_RETURN_CODE" != "0" ]]; then

CHANGES.md

+3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
1.1.0
22
=====
33

4+
- Support the pickling of interactively-defined functions with positional-only
5+
arguments. ([issue #266](https://github.com/cloudpipe/cloudpickle/pull/266))
6+
47
- Track the provenance of dynamic classes and enums so as to preseve the
58
usual `isinstance` relationship between pickled objects and their
69
original class defintions.

cloudpickle/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22

33
from cloudpickle.cloudpickle import *
44

5-
__version__ = '1.0.0'
5+
__version__ = '1.1.1'

cloudpickle/cloudpickle.py

+54-24
Original file line numberDiff line numberDiff line change
@@ -178,24 +178,43 @@ def inner(value):
178178
(),
179179
)
180180
else:
181-
return types.CodeType(
182-
co.co_argcount,
183-
co.co_kwonlyargcount,
184-
co.co_nlocals,
185-
co.co_stacksize,
186-
co.co_flags,
187-
co.co_code,
188-
co.co_consts,
189-
co.co_names,
190-
co.co_varnames,
191-
co.co_filename,
192-
co.co_name,
193-
co.co_firstlineno,
194-
co.co_lnotab,
195-
co.co_cellvars, # this is the trickery
196-
(),
197-
)
198-
181+
if hasattr(types.CodeType, "co_posonlyargcount"): # pragma: no branch
182+
return types.CodeType(
183+
co.co_argcount,
184+
co.co_posonlyargcount, # Python3.8 with PEP570
185+
co.co_kwonlyargcount,
186+
co.co_nlocals,
187+
co.co_stacksize,
188+
co.co_flags,
189+
co.co_code,
190+
co.co_consts,
191+
co.co_names,
192+
co.co_varnames,
193+
co.co_filename,
194+
co.co_name,
195+
co.co_firstlineno,
196+
co.co_lnotab,
197+
co.co_cellvars, # this is the trickery
198+
(),
199+
)
200+
else:
201+
return types.CodeType(
202+
co.co_argcount,
203+
co.co_kwonlyargcount,
204+
co.co_nlocals,
205+
co.co_stacksize,
206+
co.co_flags,
207+
co.co_code,
208+
co.co_consts,
209+
co.co_names,
210+
co.co_varnames,
211+
co.co_filename,
212+
co.co_name,
213+
co.co_firstlineno,
214+
co.co_lnotab,
215+
co.co_cellvars, # this is the trickery
216+
(),
217+
)
199218

200219
_cell_set_template_code = _make_cell_set_template_code()
201220

@@ -355,12 +374,23 @@ def save_codeobject(self, obj):
355374
Save a code object
356375
"""
357376
if PY3: # pragma: no branch
358-
args = (
359-
obj.co_argcount, obj.co_kwonlyargcount, obj.co_nlocals, obj.co_stacksize,
360-
obj.co_flags, obj.co_code, obj.co_consts, obj.co_names, obj.co_varnames,
361-
obj.co_filename, obj.co_name, obj.co_firstlineno, obj.co_lnotab, obj.co_freevars,
362-
obj.co_cellvars
363-
)
377+
if hasattr(obj, "co_posonlyargcount"): # pragma: no branch
378+
args = (
379+
obj.co_argcount, obj.co_posonlyargcount,
380+
obj.co_kwonlyargcount, obj.co_nlocals, obj.co_stacksize,
381+
obj.co_flags, obj.co_code, obj.co_consts, obj.co_names,
382+
obj.co_varnames, obj.co_filename, obj.co_name,
383+
obj.co_firstlineno, obj.co_lnotab, obj.co_freevars,
384+
obj.co_cellvars
385+
)
386+
else:
387+
args = (
388+
obj.co_argcount, obj.co_kwonlyargcount, obj.co_nlocals,
389+
obj.co_stacksize, obj.co_flags, obj.co_code, obj.co_consts,
390+
obj.co_names, obj.co_varnames, obj.co_filename,
391+
obj.co_name, obj.co_firstlineno, obj.co_lnotab,
392+
obj.co_freevars, obj.co_cellvars
393+
)
364394
else:
365395
args = (
366396
obj.co_argcount, obj.co_nlocals, obj.co_stacksize, obj.co_flags, obj.co_code,

setup.py

+1
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ def find_version():
3131
license='BSD 3-Clause License',
3232
packages=['cloudpickle'],
3333
long_description=open('README.md').read(),
34+
long_description_content_type="text/markdown",
3435
classifiers=[
3536
'Development Status :: 4 - Beta',
3637
'Intended Audience :: Developers',

tests/cloudpickle_test.py

+26
Original file line numberDiff line numberDiff line change
@@ -1768,6 +1768,32 @@ def f(a, *, b=1):
17681768
""".format(protocol=self.protocol)
17691769
assert_run_python_script(textwrap.dedent(code))
17701770

1771+
@pytest.mark.skipif(not hasattr(types.CodeType, "co_posonlyargcount"),
1772+
reason="Requires positional-only argument syntax")
1773+
def test_interactively_defined_func_with_positional_only_argument(self):
1774+
# Fixes https://github.com/cloudpipe/cloudpickle/issues/266
1775+
# The source code of this test is bundled in a string and is ran from
1776+
# the __main__ module of a subprocess in order to avoid a SyntaxError
1777+
# in versions of python that do not support positional-only argument
1778+
# syntax.
1779+
code = """
1780+
import pytest
1781+
from cloudpickle import loads, dumps
1782+
1783+
def f(a, /, b=1):
1784+
return a + b
1785+
1786+
depickled_f = loads(dumps(f, protocol={protocol}))
1787+
1788+
for func in (f, depickled_f):
1789+
assert func(2) == 3
1790+
assert func.__code__.co_posonlyargcount == 1
1791+
with pytest.raises(TypeError):
1792+
func(a=2)
1793+
1794+
""".format(protocol=self.protocol)
1795+
assert_run_python_script(textwrap.dedent(code))
1796+
17711797
class Protocol2CloudPickleTest(CloudPickleTest):
17721798

17731799
protocol = 2

0 commit comments

Comments
 (0)