-
Notifications
You must be signed in to change notification settings - Fork 183
MTN deterministic co_filename for dynamic code pickling #560
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
ogrisel
merged 25 commits into
cloudpipe:master
from
tomMoral:MTN_deterministic_co_filenames
Nov 5, 2025
Merged
Changes from 23 commits
Commits
Show all changes
25 commits
Select commit
Hold shift + click to select a range
cfb5681
MTN deterministic co_filename for dynamic code pickling
tomMoral 0104e42
CI trigger
tomMoral 3630753
CI trigger
tomMoral df24e31
TST add test in ipykernel
tomMoral 738827e
CI trigger
tomMoral 2810106
CI trigger
tomMoral 58ac727
Apply suggestions from code review
tomMoral bb60081
skip workflow on forks (#559)
jeremiedbb 543ab59
MTN skip test with recursion limit on python3.14 due to segfault on O…
tomMoral 2aff8f2
MTN unskip 3.14
tomMoral 553025c
Merge branch 'master' into MTN_deterministic_co_filenames
tomMoral c435e14
Revert "MTN unskip 3.14"
tomMoral 7ffc74f
DBG add more logs
tomMoral ceb5247
Merge branch 'master' into MTN_deterministic_co_filenames
tomMoral cbc4a4c
DBG remove ipykernel tests
tomMoral ec76c5f
DBG skip ipykernel for win+py3.11-
tomMoral 8badf44
Merge branch 'master' into MTN_deterministic_co_filenames
ogrisel 5ea9b2c
Trigger CI
ogrisel 84f4239
Apply suggestion from @ogrisel
tomMoral db60564
TST run_in_notebook
tomMoral 1f28156
FIX import queue in run_in_notebook
tomMoral 17d6ffb
DOC add change log entry
tomMoral b96c3e9
FIX correct import
tomMoral 42caaae
CLN skip timeout tests on Pypy
tomMoral 66db929
Expand inline comment.
ogrisel File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,96 @@ | ||
| import sys | ||
| import time | ||
| import pytest | ||
| import textwrap | ||
| from queue import Empty | ||
|
|
||
| from .testutils import check_deterministic_pickle | ||
|
|
||
| if sys.platform == "win32": | ||
| if sys.version_info < (3, 11): | ||
| pytest.skip( | ||
| "ipykernel requires Python 3.11 or later", | ||
| allow_module_level=True | ||
| ) | ||
| ipykernel = pytest.importorskip("ipykernel") | ||
|
|
||
|
|
||
| def run_in_notebook(code, timeout=10): | ||
|
|
||
|
|
||
tomMoral marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| km = ipykernel.connect.jupyter_client.KernelManager() | ||
| km.start_kernel() | ||
| kc = km.client() | ||
| kc.start_channels() | ||
| status, output, err = "kernel_started", None, None | ||
| try: | ||
| assert km.is_alive() and kc.is_alive() | ||
| kc.wait_for_ready() | ||
| idx = kc.execute(code) | ||
| running = True | ||
| while running: | ||
| try: | ||
| res = kc.iopub_channel.get_msg(timeout=timeout) | ||
| except Empty: | ||
| status = "timeout" | ||
| break | ||
| if res['parent_header'].get('msg_id') != idx: | ||
| continue | ||
| content = res['content'] | ||
| if content.get("name", "state") == "stdout": | ||
| output = content['text'] | ||
| if "traceback" in content: | ||
| err = "\n".join(content['traceback']) | ||
| status = "error" | ||
| running = res['content'].get('execution_state', None) != "idle" | ||
| finally: | ||
| kc.shutdown() | ||
| kc.stop_channels() | ||
| km.shutdown_kernel(now=True, restart=False) | ||
| assert not km.is_alive() | ||
| if status not in ["error", "timeout"]: | ||
| status = "ok" if not running else "exec_error" | ||
| return status, output, err | ||
tomMoral marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
|
|
||
| @pytest.mark.parametrize("code, expected", [ | ||
| ("1 + 1", "ok"), | ||
| ("raise ValueError('This is a test error')", "error"), | ||
| ("import time; time.sleep(100)", "timeout") | ||
| ]) | ||
| def test_run_in_notebook(code, expected): | ||
| code = textwrap.dedent(code) | ||
|
|
||
| t_start = time.time() | ||
| status, output, err = run_in_notebook(code, timeout=1) | ||
| duration = time.time() - t_start | ||
| assert status == expected, ( | ||
| f"Unexpected status: {status}, output: {output}, err: {err}, duration: {duration}" | ||
| ) | ||
| assert duration < 10, "Timeout not enforced properly" | ||
| if expected == "error": | ||
| assert "This is a test error" in err | ||
|
|
||
|
|
||
| def test_deterministic_payload_for_dynamic_func_in_notebook(): | ||
| code = textwrap.dedent(""" | ||
| import cloudpickle | ||
| MY_PI = 3.1415 | ||
| def get_pi(): | ||
| return MY_PI | ||
| print(cloudpickle.dumps(get_pi)) | ||
| """) | ||
|
|
||
| status, output, err = run_in_notebook(code) | ||
| assert status == "ok" | ||
| payload = eval(output.strip(), {}) | ||
|
|
||
| status, output, err = run_in_notebook(code) | ||
| assert status == "ok" | ||
| payload2 = eval(output.strip(), {}) | ||
|
|
||
| check_deterministic_pickle(payload, payload2) | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.