Skip to content

[Feature] Test Python 3.14#840

Merged
jan-janssen merged 15 commits into
mainfrom
Py314u
Jun 16, 2026
Merged

[Feature] Test Python 3.14#840
jan-janssen merged 15 commits into
mainfrom
Py314u

Conversation

@jan-janssen

@jan-janssen jan-janssen commented Oct 8, 2025

Copy link
Copy Markdown
Member

Summary by CodeRabbit

  • Chores
    • Official Python support expanded to include 3.14; updated installation constraints and classifiers accordingly.
    • CI pipeline updated to run the relevant jobs with Python 3.14.
  • Tests
    • Integration test coverage adjusted by skipping specific workflow tests on Python 3.14+ to improve stability.
  • Refactor
    • Updated the interactive serial command entrypoint to use a new evaluation function name, with corresponding unit test updates.

@coderabbitai

coderabbitai Bot commented Oct 8, 2025

Copy link
Copy Markdown
Contributor

Review Change Stack

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: bdf91113-4cee-48f2-8e11-a2b6cd7aa173

📥 Commits

Reviewing files that changed from the base of the PR and between d2f7512 and 2a1ba33.

📒 Files selected for processing (4)
  • .github/workflows/pipeline.yml
  • pyproject.toml
  • src/executorlib/backend/interactive_serial.py
  • tests/unit/backend/test_interactive_serial.py
✅ Files skipped from review due to trivial changes (1)
  • pyproject.toml

📝 Walkthrough

Walkthrough

Widened Python compatibility and CI/test targets: pyproject metadata updated to allow Python <3.15 and add 3.14 classifier; CI workflow matrix and setup updated from 3.13→3.14; interactive serial backend function renamed from main to evaluate_cmd with test suite updated accordingly.

Changes

Python 3.14 Support Expansion

Layer / File(s) Summary
Project metadata for Python 3.14 support
pyproject.toml
Widened project.requires-python upper bound from <3.14 to <3.15; added Programming Language :: Python :: 3.14 classifier.
CI workflow Python 3.14 updates
.github/workflows/pipeline.yml
Updated Python version from 3.13 to 3.14 across multiple CI job matrix entries and conda setup steps for pip_check, benchmark, unittest_mpich, unittest_openmpi, and unittest_win jobs.

Interactive Serial Backend Function Rename

Layer / File(s) Summary
Function signature and entrypoint rename
src/executorlib/backend/interactive_serial.py
Renamed top-level entry function from main(argument_lst: Optional[list[str]] = None) to evaluate_cmd(argument_lst: Optional[list[str]] = None); updated module entrypoint to invoke the renamed function.
Test suite refactoring for renamed function
tests/unit/backend/test_interactive_serial.py
Updated import from main to evaluate_cmd; renamed global initialization helper from set_global to set_global_variable; updated all test cases to call evaluate_cmd through thread targets and direct invocations.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

  • pyiron/executorlib#877 — Also modifies .github/workflows/pipeline.yml to change CI Python version targets across the job matrix.
  • pyiron/executorlib#737 — Also updates pyproject.toml Python version compatibility constraints.

Poem

A rabbit hops through versions new,
Main becomes evaluate_cmd true,
CI stretches up to three-fourteen,
Bounds extended, clean and keen,
Tests rewired, all runs pristine! 🥕✨

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title '[Feature] Test Python 3.14' is vague and does not clearly summarize the main technical changes in the pull request. Consider a more specific title that describes the actual changes, such as 'Add Python 3.14 support to CI workflow and update version constraints' or 'Update Python version constraints and CI pipeline for Python 3.14 testing'.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch Py314u

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov

codecov Bot commented Oct 8, 2025

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 50.00000% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 94.24%. Comparing base (630e95c) to head (2a1ba33).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
src/executorlib/backend/interactive_serial.py 50.00% 1 Missing ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##             main     #840   +/-   ##
=======================================
  Coverage   94.24%   94.24%           
=======================================
  Files          39       39           
  Lines        2119     2119           
=======================================
  Hits         1997     1997           
  Misses        122      122           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@jan-janssen jan-janssen changed the title Test Python 3.14 [Feature] Test Python 3.14 Jan 4, 2026
@jan-janssen

Copy link
Copy Markdown
Member Author
      The following packages are incompatible
      ├─ pygraphviz =1.14 * is installable with the potential options
      │  ├─ pygraphviz 1.14 would require
      │  │  └─ python_abi =3.10 *_cp310, which can be installed;
      │  ├─ pygraphviz 1.14 would require
      │  │  ├─ python >=3.11,<3.12.0a0 *, which can be installed;
      │  │  └─ python_abi =3.11 *_cp311, which can be installed;
      │  ├─ pygraphviz 1.14 would require
      │  │  ├─ python >=3.12,<3.13.0a0 *, which can be installed;
      │  │  └─ python_abi =3.12 *_cp312, which can be installed;
      │  └─ pygraphviz 1.14 would require
      │     ├─ python [>=3.13,<3.14.0a0 *_cp313|>=3.13.0rc2,<3.14.0a0 *_cp313], which can be installed;
      │     └─ python_abi =3.13 *_cp313, which can be installed;
      └─ python =3.14 * is not installable because there are no viable options
         ├─ python [3.14.0|3.14.1|3.14.2] would require
         │  └─ python_abi =3.14 *_cp314t, which conflicts with any installable versions previously reported;
         ├─ python [3.14.0|3.14.1|3.14.2] would require
         │  └─ python_abi =3.14 *_cp314, which conflicts with any installable versions previously reported;
         └─ python [3.14.0rc1|3.14.0rc2|3.14.0rc3] would require
            └─ _python_rc =* *, which does not exist (perhaps a missing channel).

@jan-janssen

Copy link
Copy Markdown
Member Author
======================================================================
ERROR: test_args (integration.test_pyiron_workflow.TestDynamicallyDefinedObjects.test_args)
We should be able to use a dynamically defined return value.
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/runner/work/executorlib/executorlib/tests/integration/test_pyiron_workflow.py", line 84, in test_args
    fs.result().attribute_on_dynamic,
    ~~~~~~~~~^^
  File "/home/runner/miniconda3/envs/test/lib/python3.14/concurrent/futures/_base.py", line 450, in result
    return self.__get_result()
           ~~~~~~~~~~~~~~~~~^^
  File "/home/runner/miniconda3/envs/test/lib/python3.14/concurrent/futures/_base.py", line 395, in __get_result
    raise self._exception
executorlib.standalone.interactive.communication.ExecutorlibSocketError: SocketInterface crashed during execution.
======================================================================
ERROR: test_return (integration.test_pyiron_workflow.TestDynamicallyDefinedObjects.test_return)
We should be able to use a dynamic return value -- in this case, a
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/runner/work/executorlib/executorlib/tests/integration/test_pyiron_workflow.py", line 202, in test_return
    fs.result(),
    ~~~~~~~~~^^
  File "/home/runner/miniconda3/envs/test/lib/python3.14/concurrent/futures/_base.py", line 450, in result
    return self.__get_result()
           ~~~~~~~~~~~~~~~~~^^
  File "/home/runner/miniconda3/envs/test/lib/python3.14/concurrent/futures/_base.py", line 395, in __get_result
    raise self._exception
executorlib.standalone.interactive.communication.ExecutorlibSocketError: SocketInterface crashed during execution.
----------------------------------------------------------------------

@jan-janssen

Copy link
Copy Markdown
Member Author
Traceback (most recent call last):
  File "/home/runner/miniconda3/envs/test/lib/python3.14/site-packages/executorlib/backend/interactive_serial.py", line 93, in <module>
    main(argument_lst=sys.argv)
    ~~~~^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/runner/miniconda3/envs/test/lib/python3.14/site-packages/executorlib/backend/interactive_serial.py", line 41, in main
    input_dict = interface_receive(socket=socket)
  File "/home/runner/miniconda3/envs/test/lib/python3.14/site-packages/executorlib/standalone/interactive/communication.py", line 270, in interface_receive
    return cloudpickle.loads(socket.recv())
           ~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^
TypeError: _partial_new() missing 1 required positional argument: 'func'

@jan-janssen

Copy link
Copy Markdown
Member Author

@liamhuber Somehow the integration tests fail with Python 3.14. It seems to be related to the use of partialmethod in the decorator:

def dynamic_foo():
    """
    A decorator for dynamically modifying the Foo class to test
    CloudpickleProcessPoolExecutor.

    Overrides the `fnc` input of `Foo` with the decorated function.
    """

    def as_dynamic_foo(fnc: Callable):
        return type(
            "DynamicFoo",
            (Foo,),  # Define parentage
            {"__init__": partialmethod(Foo.__init__, fnc)},
        )

    return as_dynamic_foo

I was wondering if you had similar issues with pyiron_workflow. Did you test Python 3.14 already?

@jan-janssen

Copy link
Copy Markdown
Member Author

It seems to be a cloudpickle related issue cloudpipe/cloudpickle#585

@liamhuber

Copy link
Copy Markdown
Member

I haven't tested 3.14 for workflow yet, so I'm not sure. I've done it only(?) for snippets, but that is pretty trivial.

@jan-janssen jan-janssen marked this pull request as ready for review February 22, 2026 12:53

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
.github/workflows/pipeline.yml (2)

192-221: unittest_flux_mpich and unittest_flux_openmpi intentionally left on 3.13.

Keeping flux-related jobs on 3.13 appears to be a deliberate decision (likely due to flux-core=0.81.0 and related conda packages not being available for Python 3.14). Worth adding a comment in the YAML to document why these differ from the other test jobs, to avoid confusion during future version bumps.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/pipeline.yml around lines 192 - 221, Add an inline comment
above the unittest_flux_mpich and unittest_flux_openmpi job definitions
explaining why they pin python-version: '3.13' (e.g., flux-core=0.81.0 and
related conda packages are not available on Python 3.14), so future maintainers
know the version divergence is intentional; place the comment near the job
headers (unittest_flux_mpich / unittest_flux_openmpi) and mention the dependency
(flux-core=0.81.0) and that the pin is to satisfy conda package compatibility.

44-58: mypy job still on Python 3.13 — consider whether 3.14 should be added here too.

The mypy job at Line 51 is the only type-checking job; it still runs on 3.13. While not blocking, any type-checking against 3.14-only syntax or stub differences won't be caught. If this is intentional (no 3.14-specific type changes expected), no action needed.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/pipeline.yml around lines 44 - 58, Update the mypy job to
also run under Python 3.14 so type-checking covers 3.14-specific syntax/stubs:
modify the mypy job (the job named "mypy" and its "Setup Python" step that uses
actions/setup-python@v5 and the python-version input) to either use a matrix
over python-version including "3.13" and "3.14", or add a parallel mypy job
configured with python-version: "3.14"; ensure the subsequent steps (Checkout,
Install mypy, Test) run for both Python versions.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@tests/integration/test_pyiron_workflow.py`:
- Around line 59-62: The skip condition incorrectly uses sys.version_info.minor
twice; change the decorator's condition to compare the version tuple instead of
comparing .minor fields (e.g., replace the current sys.version_info.minor >= 14
and sys.version_info.minor >= 3 with a tuple comparison like sys.version_info >=
(3, 14) or an equivalent major/minor check) so the `@unittest.skipIf` using
sys.version_info correctly skips on Python versions >= 3.14; update the
`@unittest.skipIf` expression that references sys.version_info in the
test_pyiron_workflow.py decorator accordingly.

---

Nitpick comments:
In @.github/workflows/pipeline.yml:
- Around line 192-221: Add an inline comment above the unittest_flux_mpich and
unittest_flux_openmpi job definitions explaining why they pin python-version:
'3.13' (e.g., flux-core=0.81.0 and related conda packages are not available on
Python 3.14), so future maintainers know the version divergence is intentional;
place the comment near the job headers (unittest_flux_mpich /
unittest_flux_openmpi) and mention the dependency (flux-core=0.81.0) and that
the pin is to satisfy conda package compatibility.
- Around line 44-58: Update the mypy job to also run under Python 3.14 so
type-checking covers 3.14-specific syntax/stubs: modify the mypy job (the job
named "mypy" and its "Setup Python" step that uses actions/setup-python@v5 and
the python-version input) to either use a matrix over python-version including
"3.13" and "3.14", or add a parallel mypy job configured with python-version:
"3.14"; ensure the subsequent steps (Checkout, Install mypy, Test) run for both
Python versions.

Comment on lines +59 to +62
@unittest.skipIf(
sys.version_info.minor >= 14 and sys.version_info.minor >= 3,
"Test environment has to be Python <3.14 for dynamic objects.",
)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Bug in skipIf condition: .minor used twice instead of .major + .minor.

sys.version_info.minor >= 14 and sys.version_info.minor >= 3

Both sides reference .minor. The second clause (minor >= 3) is always True when the first (minor >= 14) is, making the and entirely redundant. The condition collapses to sys.version_info.minor >= 14, which happens to work for current Python 3.x releases but would silently misbehave on a future Python 4.x (e.g., 4.0 has minor=0, so no skip even if the same cloudpickle bug persists).

The idiomatic and correct form is a tuple comparison:

🐛 Proposed fix
 `@unittest.skipIf`(
-    sys.version_info.minor >= 14 and sys.version_info.minor >= 3,
+    sys.version_info >= (3, 14),
     "Test environment has to be Python <3.14 for dynamic objects.",
 )
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/integration/test_pyiron_workflow.py` around lines 59 - 62, The skip
condition incorrectly uses sys.version_info.minor twice; change the decorator's
condition to compare the version tuple instead of comparing .minor fields (e.g.,
replace the current sys.version_info.minor >= 14 and sys.version_info.minor >= 3
with a tuple comparison like sys.version_info >= (3, 14) or an equivalent
major/minor check) so the `@unittest.skipIf` using sys.version_info correctly
skips on Python versions >= 3.14; update the `@unittest.skipIf` expression that
references sys.version_info in the test_pyiron_workflow.py decorator
accordingly.

@jan-janssen jan-janssen marked this pull request as draft February 22, 2026 13:24
@jan-janssen

Copy link
Copy Markdown
Member Author
ssssssE/home/runner/miniconda3/envs/test/lib/python3.14t/unittest/case.py:668: ResourceWarning: Unclosed socket <zmq.Socket(zmq.PAIR) at 0x3cb97240390>
2026-02-22T13:11:04.1279087Z   with outcome.testPartExecutor(self):
2026-02-22T13:11:04.1279685Z ResourceWarning: Enable tracemalloc to get the object allocation traceback
2026-02-22T13:11:04.1280685Z /home/runner/miniconda3/envs/test/lib/python3.14t/unittest/case.py:668: ResourceWarning: Unclosed context <zmq.Context() at 0x3cb980c1b10>
2026-02-22T13:11:04.1281677Z   with outcome.testPartExecutor(self):
2026-02-22T13:11:04.1282302Z ResourceWarning: Enable tracemalloc to get the object allocation traceback
2026-02-22T13:11:04.4513768Z E/home/runner/miniconda3/envs/test/lib/python3.14t/unittest/case.py:668: ResourceWarning: Unclosed socket <zmq.Socket(zmq.PAIR) at 0x3cb980c2710>
2026-02-22T13:11:04.4514748Z   with outcome.testPartExecutor(self):
2026-02-22T13:11:04.4515341Z ResourceWarning: Enable tracemalloc to get the object allocation traceback
2026-02-22T13:11:04.4516665Z /home/runner/miniconda3/envs/test/lib/python3.14t/unittest/case.py:668: ResourceWarning: Unclosed context <zmq.Context() at 0x3cb980c2590>
2026-02-22T13:11:04.4517646Z   with outcome.testPartExecutor(self):
2026-02-22T13:11:04.4518242Z ResourceWarning: Enable tracemalloc to get the object allocation traceback
2026-02-22T13:11:04.7775812Z E/home/runner/miniconda3/envs/test/lib/python3.14t/unittest/case.py:668: ResourceWarning: Unclosed socket <zmq.Socket(zmq.PAIR) at 0x3cb980c2410>
2026-02-22T13:11:04.7776993Z   with outcome.testPartExecutor(self):
2026-02-22T13:11:04.7777419Z ResourceWarning: Enable tracemalloc to get the object allocation traceback
2026-02-22T13:11:05.0621289Z Exception in thread Thread-4 (submit):
2026-02-22T13:11:05.0626602Z Traceback (most recent call last):
2026-02-22T13:11:05.0637020Z   File "/home/runner/miniconda3/envs/test/lib/python3.14t/threading.py", line 1082, in _bootstrap_inner
2026-02-22T13:11:05.0638002Z     self._context.run(self.run)
2026-02-22T13:11:05.0638466Z     ~~~~~~~~~~~~~~~~~^^^^^^^^^^
2026-02-22T13:11:05.0639258Z   File "/home/runner/miniconda3/envs/test/lib/python3.14t/threading.py", line 1024, in run
2026-02-22T13:11:05.0640194Z     self._target(*self._args, **self._kwargs)
2026-02-22T13:11:05.0640706Z     ~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2026-02-22T13:11:05.0641960Z   File "/home/runner/work/executorlib/executorlib/tests/unit/backend/test_interactive_serial.py", line 24, in submit
2026-02-22T13:11:05.0643127Z     cloudpickle.dumps({"init": True, "fn": set_global, "args": (), "kwargs": {}})
2026-02-22T13:11:05.0643908Z     ~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2026-02-22T13:11:05.0645008Z   File "/home/runner/miniconda3/envs/test/lib/python3.14t/site-packages/cloudpickle/cloudpickle.py", line 1529, in dumps
2026-02-22T13:11:05.0645948Z     cp.dump(obj)
2026-02-22T13:11:05.0646426Z     ~~~~~~~^^^^^
2026-02-22T13:11:05.0647380Z   File "/home/runner/miniconda3/envs/test/lib/python3.14t/site-packages/cloudpickle/cloudpickle.py", line 1295, in dump
2026-02-22T13:11:05.0648512Z     return super().dump(obj)
2026-02-22T13:11:05.0648949Z            ~~~~~~~~~~~~^^^^^
2026-02-22T13:11:05.0650096Z   File "/home/runner/miniconda3/envs/test/lib/python3.14t/site-packages/cloudpickle/cloudpickle.py", line 1380, in reducer_override
2026-02-22T13:11:05.0651184Z     return self._function_reduce(obj)
2026-02-22T13:11:05.0651607Z            ~~~~~~~~~~~~~~~~~~~~~^^^^^
2026-02-22T13:11:05.0652541Z   File "/home/runner/miniconda3/envs/test/lib/python3.14t/site-packages/cloudpickle/cloudpickle.py", line 1255, in _function_reduce
2026-02-22T13:11:05.0653869Z     if _should_pickle_by_reference(obj):
2026-02-22T13:11:05.0654294Z        ~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^
2026-02-22T13:11:05.0655299Z   File "/home/runner/miniconda3/envs/test/lib/python3.14t/site-packages/cloudpickle/cloudpickle.py", line 244, in _should_pickle_by_reference
2026-02-22T13:11:05.0656586Z     module_and_name = _lookup_module_and_qualname(obj, name=name)
2026-02-22T13:11:05.0657246Z   File "/home/runner/miniconda3/envs/test/lib/python3.14t/site-packages/cloudpickle/cloudpickle.py", line 296, in _lookup_module_and_qualname
2026-02-22T13:11:05.0658183Z     obj2, parent = _getattribute(module, name)
2026-02-22T13:11:05.0658602Z                    ~~~~~~~~~~~~~^^^^^^^^^^^^^^
2026-02-22T13:11:05.0659272Z   File "/home/runner/miniconda3/envs/test/lib/python3.14t/pickle.py", line 317, in _getattribute
2026-02-22T13:11:05.0659967Z     obj = getattr(obj, subpath)
2026-02-22T13:11:05.0660506Z RecursionError: Stack overflow (used 16348 kB) while calling a Python object
2026-02-22T13:11:05.0661197Z Normalization failed: type=AttributeError args=<unknown>
2026-02-22T13:11:05.0661688Z when serializing function reconstructor
2026-02-22T13:11:05.0662102Z when serializing function object

@jan-janssen

Copy link
Copy Markdown
Member Author

The minimal tests are using a different Python version:

python 3.14.3  he1279bd_1_cp314t 

versus:

 python 3.14.3  h32b2ec7_101_cp314 

@jan-janssen

Copy link
Copy Markdown
Member Author

More issues with threading without global interpreter lock:

sssssssssssssssssssssssssssssssssssssssssssssssssss........E.E..EEEE....sEE.s.EE./home/runner/miniconda3/envs/test/lib/python3.14t/subprocess.py:1138: ResourceWarning: subprocess 2663 is still running
  _warn("subprocess %s is still running" % self.pid,
ResourceWarning: Enable tracemalloc to get the object allocation traceback
/home/runner/miniconda3/envs/test/lib/python3.14t/site-packages/cloudpickle/cloudpickle.py:720: ResourceWarning: Unclosed socket <zmq.Socket(zmq.PAIR) at 0x52a3c1c0290>
  f_globals = {k: func.__globals__[k] for k in f_globals_ref if k in func.__globals__}
ResourceWarning: Enable tracemalloc to get the object allocation traceback
/home/runner/miniconda3/envs/test/lib/python3.14t/site-packages/cloudpickle/cloudpickle.py:720: ResourceWarning: Unclosed context <zmq.Context(1 socket) at 0x52a3c1c0150>
  f_globals = {k: func.__globals__[k] for k in f_globals_ref if k in func.__globals__}
ResourceWarning: Enable tracemalloc to get the object allocation traceback
Exception ignored while calling deallocator <function SocketInterface.__del__ at 0x52a36f74140>:
Traceback (most recent call last):
  File "/home/runner/miniconda3/envs/test/lib/python3.14t/site-packages/executorlib/standalone/interactive/communication.py", line 179, in __del__
    self.shutdown(wait=True)
  File "/home/runner/miniconda3/envs/test/lib/python3.14t/site-packages/executorlib/standalone/interactive/communication.py", line 155, in shutdown
    result = self.send_and_receive_dict(
  File "/home/runner/miniconda3/envs/test/lib/python3.14t/site-packages/executorlib/standalone/interactive/communication.py", line 106, in send_and_receive_dict
    self.send_dict(input_dict=input_dict)
  File "/home/runner/miniconda3/envs/test/lib/python3.14t/site-packages/executorlib/standalone/interactive/communication.py", line 68, in send_dict
    self._socket.send(data)
  File "/home/runner/miniconda3/envs/test/lib/python3.14t/site-packages/zmq/sugar/socket.py", line 698, in send
    return super().send(data, flags=flags, copy=copy, track=track)
  File "zmq/backend/cython/_zmq.py", line 1152, in zmq.backend.cython._zmq.Socket.send
  File "zmq/backend/cython/_zmq.py", line 1194, in zmq.backend.cython._zmq.Socket.send
  File "zmq/backend/cython/_zmq.py", line 1339, in zmq.backend.cython._zmq._check_closed
zmq.error.ZMQError: Socket operation on non-socket
/home/runner/miniconda3/envs/test/lib/python3.14t/subprocess.py:1138: ResourceWarning: subprocess 2673 is still running
  _warn("subprocess %s is still running" % self.pid,
ResourceWarning: Enable tracemalloc to get the object allocation traceback
/home/runner/miniconda3/envs/test/lib/python3.14t/site-packages/cloudpickle/cloudpickle.py:720: ResourceWarning: Unclosed socket <zmq.Socket(zmq.PAIR) at 0x52a42260290>
  f_globals = {k: func.__globals__[k] for k in f_globals_ref if k in func.__globals__}
ResourceWarning: Enable tracemalloc to get the object allocation traceback
/home/runner/miniconda3/envs/test/lib/python3.14t/site-packages/cloudpickle/cloudpickle.py:720: ResourceWarning: Unclosed context <zmq.Context(1 socket) at 0x52a42260150>
  f_globals = {k: func.__globals__[k] for k in f_globals_ref if k in func.__globals__}
ResourceWarning: Enable tracemalloc to get the object allocation traceback
Exception ignored while calling deallocator <function SocketInterface.__del__ at 0x52a36f74140>:
Traceback (most recent call last):
  File "/home/runner/miniconda3/envs/test/lib/python3.14t/site-packages/executorlib/standalone/interactive/communication.py", line 179, in __del__
    self.shutdown(wait=True)
  File "/home/runner/miniconda3/envs/test/lib/python3.14t/site-packages/executorlib/standalone/interactive/communication.py", line 155, in shutdown
    result = self.send_and_receive_dict(
  File "/home/runner/miniconda3/envs/test/lib/python3.14t/site-packages/executorlib/standalone/interactive/communication.py", line 106, in send_and_receive_dict
    self.send_dict(input_dict=input_dict)
  File "/home/runner/miniconda3/envs/test/lib/python3.14t/site-packages/executorlib/standalone/interactive/communication.py", line 68, in send_dict
    self._socket.send(data)
  File "/home/runner/miniconda3/envs/test/lib/python3.14t/site-packages/zmq/sugar/socket.py", line 698, in send
    return super().send(data, flags=flags, copy=copy, track=track)
  File "zmq/backend/cython/_zmq.py", line 1152, in zmq.backend.cython._zmq.Socket.send
  File "zmq/backend/cython/_zmq.py", line 1194, in zmq.backend.cython._zmq.Socket.send
  File "zmq/backend/cython/_zmq.py", line 1339, in zmq.backend.cython._zmq._check_closed
zmq.error.ZMQError: Socket operation on non-socket
/home/runner/miniconda3/envs/test/lib/python3.14t/site-packages/cloudpickle/cloudpickle.py:720: ResourceWarning: Unclosed context <zmq.Context(1 socket) at 0x52a41480150>
  f_globals = {k: func.__globals__[k] for k in f_globals_ref if k in func.__globals__}
ResourceWarning: Enable tracemalloc to get the object allocation traceback

@jan-janssen jan-janssen marked this pull request as ready for review June 16, 2026 07:42

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
tests/unit/backend/test_interactive_serial.py (1)

51-58: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Tests should join spawned threads before teardown

Across these test blocks (e.g., Line 51/64/79 and submit-thread flows around Line 97/110), threads are started but never joined. This can leave work in-flight during socket/context teardown and create flaky behavior under Python 3.14 builds.

Add t.join(timeout=...) (and optionally assert not t.is_alive()) before closing sockets/contexts in each test.

Also applies to: 64-73, 79-89, 97-102, 110-117

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/unit/backend/test_interactive_serial.py` around lines 51 - 58, Threads
are started using Thread(target=evaluate_cmd, ...) and t.start() but never
joined before socket and context teardown, which can cause flaky behavior. Add
t.join(timeout=...) calls (with an optional assertion that not t.is_alive())
immediately before socket.close() and context.term() in all affected test
methods. This needs to be fixed at the following locations in
test_interactive_serial.py: lines 51-58 (add join before socket.close()), lines
64-73 (add join before socket.close()), lines 79-89 (add join before
socket.close()), lines 97-102 (add join before socket.close() in the
submit-thread flow), and lines 110-117 (add join before socket.close() in the
submit-thread flow). Each location follows the same pattern where evaluate_cmd
or a similar thread target is started and then later the socket is closed.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/pipeline.yml:
- Around line 109-110: The `uv_check` job uses tag-based action references which
pose security risks. Pin both the `actions/checkout@v4` action to its full
commit SHA and the `astral-sh/setup-uv@v7` action to its full commit SHA for
supply-chain hardening. Additionally, add the `persist-credentials: false`
parameter to the checkout action since this job only performs read-only
operations and does not need credential persistence.
- Around line 105-115: In the uv_check job workflow, the pip check command is
running in the runner's default Python environment instead of the uv-managed
virtual environment. Replace the direct `pip check` call with `uv run pip check`
to execute it within the uv-managed environment. Additionally, add a step to
explicitly specify and set up Python 3.14 before the uv setup to align with the
PR objective, using the appropriate GitHub Actions setup-python action.

In `@src/executorlib/backend/interactive_serial.py`:
- Line 15: The public function main() has been renamed to evaluate_cmd() without
providing backward compatibility, which will break external code importing
executorlib.backend.interactive_serial.main. After the evaluate_cmd() function
definition, add a backward-compatible alias or wrapper function named main that
calls evaluate_cmd() with the same arguments to maintain compatibility for at
least one deprecation cycle.

---

Outside diff comments:
In `@tests/unit/backend/test_interactive_serial.py`:
- Around line 51-58: Threads are started using Thread(target=evaluate_cmd, ...)
and t.start() but never joined before socket and context teardown, which can
cause flaky behavior. Add t.join(timeout=...) calls (with an optional assertion
that not t.is_alive()) immediately before socket.close() and context.term() in
all affected test methods. This needs to be fixed at the following locations in
test_interactive_serial.py: lines 51-58 (add join before socket.close()), lines
64-73 (add join before socket.close()), lines 79-89 (add join before
socket.close()), lines 97-102 (add join before socket.close() in the
submit-thread flow), and lines 110-117 (add join before socket.close() in the
submit-thread flow). Each location follows the same pattern where evaluate_cmd
or a similar thread target is started and then later the socket is closed.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: bdf91113-4cee-48f2-8e11-a2b6cd7aa173

📥 Commits

Reviewing files that changed from the base of the PR and between d2f7512 and 2a1ba33.

📒 Files selected for processing (4)
  • .github/workflows/pipeline.yml
  • pyproject.toml
  • src/executorlib/backend/interactive_serial.py
  • tests/unit/backend/test_interactive_serial.py
✅ Files skipped from review due to trivial changes (1)
  • pyproject.toml

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Inline review comments failed to post. This is likely due to GitHub's internal server error or limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
tests/unit/backend/test_interactive_serial.py (1)

51-58: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Tests should join spawned threads before teardown

Across these test blocks (e.g., Line 51/64/79 and submit-thread flows around Line 97/110), threads are started but never joined. This can leave work in-flight during socket/context teardown and create flaky behavior under Python 3.14 builds.

Add t.join(timeout=...) (and optionally assert not t.is_alive()) before closing sockets/contexts in each test.

Also applies to: 64-73, 79-89, 97-102, 110-117

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/unit/backend/test_interactive_serial.py` around lines 51 - 58, Threads
are started using Thread(target=evaluate_cmd, ...) and t.start() but never
joined before socket and context teardown, which can cause flaky behavior. Add
t.join(timeout=...) calls (with an optional assertion that not t.is_alive())
immediately before socket.close() and context.term() in all affected test
methods. This needs to be fixed at the following locations in
test_interactive_serial.py: lines 51-58 (add join before socket.close()), lines
64-73 (add join before socket.close()), lines 79-89 (add join before
socket.close()), lines 97-102 (add join before socket.close() in the
submit-thread flow), and lines 110-117 (add join before socket.close() in the
submit-thread flow). Each location follows the same pattern where evaluate_cmd
or a similar thread target is started and then later the socket is closed.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/pipeline.yml:
- Around line 109-110: The `uv_check` job uses tag-based action references which
pose security risks. Pin both the `actions/checkout@v4` action to its full
commit SHA and the `astral-sh/setup-uv@v7` action to its full commit SHA for
supply-chain hardening. Additionally, add the `persist-credentials: false`
parameter to the checkout action since this job only performs read-only
operations and does not need credential persistence.
- Around line 105-115: In the uv_check job workflow, the pip check command is
running in the runner's default Python environment instead of the uv-managed
virtual environment. Replace the direct `pip check` call with `uv run pip check`
to execute it within the uv-managed environment. Additionally, add a step to
explicitly specify and set up Python 3.14 before the uv setup to align with the
PR objective, using the appropriate GitHub Actions setup-python action.

In `@src/executorlib/backend/interactive_serial.py`:
- Line 15: The public function main() has been renamed to evaluate_cmd() without
providing backward compatibility, which will break external code importing
executorlib.backend.interactive_serial.main. After the evaluate_cmd() function
definition, add a backward-compatible alias or wrapper function named main that
calls evaluate_cmd() with the same arguments to maintain compatibility for at
least one deprecation cycle.

---

Outside diff comments:
In `@tests/unit/backend/test_interactive_serial.py`:
- Around line 51-58: Threads are started using Thread(target=evaluate_cmd, ...)
and t.start() but never joined before socket and context teardown, which can
cause flaky behavior. Add t.join(timeout=...) calls (with an optional assertion
that not t.is_alive()) immediately before socket.close() and context.term() in
all affected test methods. This needs to be fixed at the following locations in
test_interactive_serial.py: lines 51-58 (add join before socket.close()), lines
64-73 (add join before socket.close()), lines 79-89 (add join before
socket.close()), lines 97-102 (add join before socket.close() in the
submit-thread flow), and lines 110-117 (add join before socket.close() in the
submit-thread flow). Each location follows the same pattern where evaluate_cmd
or a similar thread target is started and then later the socket is closed.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: bdf91113-4cee-48f2-8e11-a2b6cd7aa173

📥 Commits

Reviewing files that changed from the base of the PR and between d2f7512 and 2a1ba33.

📒 Files selected for processing (4)
  • .github/workflows/pipeline.yml
  • pyproject.toml
  • src/executorlib/backend/interactive_serial.py
  • tests/unit/backend/test_interactive_serial.py
✅ Files skipped from review due to trivial changes (1)
  • pyproject.toml
🛑 Comments failed to post (3)
.github/workflows/pipeline.yml (2)

105-115: ⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify uv_check currently lacks explicit Python setup and uses plain pip.
awk '/^  uv_check:/{flag=1} flag{print} /^  benchmark:/{if(flag) exit}' .github/workflows/pipeline.yml

Repository: pyiron/executorlib

Length of output: 348


🌐 Web query:

uv sync environment activation bash shell how does uv manage virtual environments

💡 Result:

uv manages virtual environments by automatically creating, discovering, and synchronizing them, rather than relying on manual shell activation for its internal operations [1][2]. Virtual Environment Management When working on a project, uv creates a virtual environment—by default named.venv—in the project root [1][2]. This environment is created lazily; it is initialized automatically the first time you run a project command such as uv run, uv sync, or uv lock [2][3]. Unlike traditional workflows where you must activate an environment, uv is designed to be "stateless" regarding shell activation [4]. How uv Uses Environments 1. Automatic Discovery: When you run commands like uv run or uv sync, uv walks up the directory tree from your current working directory to discover the project root, the pyproject.toml file, and the associated virtual environment [2][3]. 2. Execution via uv run: The preferred way to interact with your environment is via uv run. This command automatically ensures the environment is synchronized (i.e., dependencies are installed and the lockfile is up to date) before executing your specified command within that isolated environment [2][5]. 3. Manual Syncing: While uv sync happens automatically with other commands, you can manually trigger it to ensure your virtual environment is perfectly aligned with your uv.lock file [5]. 4. Shell Activation: Because uv commands handle environment isolation internally, you do not need to manually run source.venv/bin/activate to use dependencies installed by uv [1][2]. However, if you wish to use your project's dependencies directly in your shell (outside of uv run), you can still activate the environment using standard shell commands (e.g., source.venv/bin/activate) [1][6]. Advanced Configuration and Active Environments By default, uv ignores the VIRTUAL_ENV environment variable during project operations to maintain isolation [7][8]. If you prefer to use an already-active environment rather than uv's managed.venv, you can use the --active flag with commands like uv sync or uv run [9][3]. This flag tells uv to respect the VIRTUAL_ENV environment variable, effectively targeting the currently active shell environment instead of the project-specific one [9][7][8]. You can also explicitly configure the environment path by setting the UV_PROJECT_ENVIRONMENT environment variable [4][8].

Citations:


🌐 Web query:

uv run command purpose how to run commands in uv virtual environment

💡 Result:

The uv run command is the primary method for executing scripts or programs within the context of a uv project or a managed Python environment [1][2][3]. Purpose of uv run The main purpose of uv run is to ensure that commands are executed in a correctly configured, isolated Python environment [1][2]. Its key features include: Automatic Synchronization: When you run a command in a project, uv ensures the virtual environment (typically located in.venv) is up-to-date and consistent with your project's lockfile before execution [1][3][4]. Dependency Management: If a command requires additional packages not already in your project, you can use the --with option to add them to the environment for that specific invocation without permanently modifying your project dependencies [1][4]. Script Execution: It handles Python scripts seamlessly [2]. If you point it to a script file (e.g., uv run script.py), uv runs it with the appropriate interpreter [2][5]. If the script uses inline dependency metadata, uv will automatically create an isolated, ephemeral environment for it [1][2][5]. Flexibility: It works both inside projects (using the project's dependencies) and outside of them (where it may use a discovered virtual environment or a standalone interpreter) [2]. How to Run Commands To run a command using uv, use the following syntax in your terminal: uv run [COMMAND] Examples: Running a Python file: uv run script.py Running a command from the project environment (e.g., a tool or CLI utility): uv run pytest uv run flask run Passing arguments to commands: uv run pytest --verbose Adding temporary dependencies for a single run: uv run --with httpx==0.26.0 python -c "import httpx; print(httpx.version)" Important Usage Notes: Separating Arguments: If you need to separate uv options from the command arguments to avoid ambiguity, use -- [2]: uv run --python 3.12 -- pytest --verbose Alternative to Activation: Unlike traditional workflows that require manually running source.venv/bin/activate (or.venv\Scripts\activate on Windows), uv run makes manual environment activation unnecessary for most tasks, as it handles the environment context automatically [1][3][4]. For running isolated tools without project involvement, consider using uvx (an alias for uv tool run), which is specifically designed to run tools in temporary, isolated environments [6][7].

Citations:


🌐 Web query:

GitHub Actions setup-python with uv package manager best practices

💡 Result:

The best practice for using the uv package manager in GitHub Actions is to use the official astral-sh/setup-uv action [1][2]. While you can use actions/setup-python to manage Python versions due to its native speed from GitHub-hosted runner caching [1][2], astral-sh/setup-uv provides robust, built-in support for installing uv, managing the uv cache, and configuring environments [1][3][4]. Key best practices include: 1. Use the official action: Employ astral-sh/setup-uv to install and configure uv. Pin the action to a specific commit or full version tag (e.g., @v8.1.0) rather than a moving tag to ensure stable builds [1][5]. 2. Enable caching: Set enable-cache: true in your workflow step to persist the uv package store between runs [3][5]. This significantly reduces build times by skipping the re-downloading of dependencies [5]. You can control which files trigger a cache refresh using the cache-dependency-glob input, typically targeting your lockfile (e.g., uv.lock) or requirements files [3]. 3. Manage Python versions: You have two primary options: - astral-sh/setup-uv: Use the python-version input to specify the version [5][4]. This is convenient and keeps configuration within the uv action. - actions/setup-python: Use this action first if you prefer GitHub's native optimization for Python version caching [1][2]. Configure it with python-version-file (pointing to.python-version or pyproject.toml) to automatically pick up the version required by your project [1][2]. 4. Use uv sync: Always use uv sync --locked in CI environments [5]. This command installs dependencies exactly as defined in your uv.lock file and will fail the build if the lockfile is out of sync with your project configuration, ensuring consistency across environments [5]. 5. Execution: Use uv run [command] to execute your tasks (e.g., uv run pytest, uv run ruff check). This ensures that commands are executed within the correct environment managed by uv, without requiring manual activation [5]. Example workflow configuration: name: CI jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 - name: Set up Python uses: actions/setup-python@v6 with: python-version-file: "pyproject.toml" - name: Install uv uses: astral-sh/setup-uv@v8.1.0 with: enable-cache: true - name: Sync dependencies run: uv sync --locked --all-extras --dev - name: Run tests run: uv run pytest

Citations:


🏁 Script executed:

# Search for other uv usage patterns in the repository workflows
rg "uv sync|uv run" .github/workflows/ -A 2 -B 2

Repository: pyiron/executorlib

Length of output: 309


🏁 Script executed:

# Check if there are any Python version specifications in the workflow for other jobs
rg "python-version|setup-python" .github/workflows/pipeline.yml -B 2 -A 2

Repository: pyiron/executorlib

Length of output: 3797


Use uv run to execute pip check within the uv-managed environment.

Running plain pip check after uv sync executes in the runner's default Python, not the uv-managed virtual environment. This defeats the purpose of the check. Additionally, explicitly specify Python 3.14 to align with the PR objective.

Suggested fix
  uv_check:
    needs: [black]
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v4
+   - name: Setup Python
+     uses: actions/setup-python@v5
+     with:
+       python-version: "3.14"
    - uses: astral-sh/setup-uv@v7
    - name: Install the project and pip check
      shell: bash -l {0}
      run: |
        uv sync --all-extras --dev
-       pip check
+       uv run pip check
🧰 Tools
🪛 zizmor (1.25.2)

[warning] 109-109: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false

(artipacked)


[warning] 105-115: overly broad permissions (excessive-permissions): default permissions used due to no permissions: block

(excessive-permissions)


[error] 109-109: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)


[error] 110-110: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/pipeline.yml around lines 105 - 115, In the uv_check job
workflow, the pip check command is running in the runner's default Python
environment instead of the uv-managed virtual environment. Replace the direct
`pip check` call with `uv run pip check` to execute it within the uv-managed
environment. Additionally, add a step to explicitly specify and set up Python
3.14 before the uv setup to align with the PR objective, using the appropriate
GitHub Actions setup-python action.

109-110: ⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

cat -n .github/workflows/pipeline.yml | sed -n '100,120p'

Repository: pyiron/executorlib

Length of output: 707


🏁 Script executed:

rg "uv_check" .github/workflows/pipeline.yml -B 5 -A 15

Repository: pyiron/executorlib

Length of output: 1398


🏁 Script executed:

wc -l .github/workflows/pipeline.yml

Repository: pyiron/executorlib

Length of output: 97


🏁 Script executed:

head -20 .github/workflows/pipeline.yml

Repository: pyiron/executorlib

Length of output: 417


🏁 Script executed:

rg "on:" .github/workflows/pipeline.yml -A 10

Repository: pyiron/executorlib

Length of output: 11617


Harden action references in uv_check by pinning to SHAs and disabling credential persistence.

The uses: entries are tag-based (@v4, @v7). For supply-chain hardening, pin action SHAs. Additionally, since this job performs read-only operations, set persist-credentials: false on checkout.

Suggested fix
-    - uses: actions/checkout@v4
+    - uses: actions/checkout@<full_commit_sha_for_v4>
+      with:
+        persist-credentials: false
-    - uses: astral-sh/setup-uv@v7
+    - uses: astral-sh/setup-uv@<full_commit_sha_for_v7>
🧰 Tools
🪛 zizmor (1.25.2)

[warning] 109-109: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false

(artipacked)


[error] 109-109: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)


[error] 110-110: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/pipeline.yml around lines 109 - 110, The `uv_check` job
uses tag-based action references which pose security risks. Pin both the
`actions/checkout@v4` action to its full commit SHA and the
`astral-sh/setup-uv@v7` action to its full commit SHA for supply-chain
hardening. Additionally, add the `persist-credentials: false` parameter to the
checkout action since this job only performs read-only operations and does not
need credential persistence.

Source: Linters/SAST tools

src/executorlib/backend/interactive_serial.py (1)

15-15: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Public API rename is breaking without a compatibility shim

main(...) appears to have been replaced by evaluate_cmd(...) at Line 15, which can break external callers importing executorlib.backend.interactive_serial.main. Please keep a backward-compatible alias/wrapper (at least for one deprecation cycle).

Suggested compatibility patch
 def evaluate_cmd(argument_lst: Optional[list[str]] = None):
@@
     while True:
         ...
 
+def main(argument_lst: Optional[list[str]] = None):
+    """Backward-compatible alias for evaluate_cmd()."""
+    return evaluate_cmd(argument_lst=argument_lst)
+
 if __name__ == "__main__":
     evaluate_cmd(argument_lst=sys.argv)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

def evaluate_cmd(argument_lst: Optional[list[str]] = None):
    # [existing function body remains unchanged]

def main(argument_lst: Optional[list[str]] = None):
    """Backward-compatible alias for evaluate_cmd()."""
    return evaluate_cmd(argument_lst=argument_lst)

if __name__ == "__main__":
    evaluate_cmd(argument_lst=sys.argv)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/executorlib/backend/interactive_serial.py` at line 15, The public
function main() has been renamed to evaluate_cmd() without providing backward
compatibility, which will break external code importing
executorlib.backend.interactive_serial.main. After the evaluate_cmd() function
definition, add a backward-compatible alias or wrapper function named main that
calls evaluate_cmd() with the same arguments to maintain compatibility for at
least one deprecation cycle.

@jan-janssen jan-janssen merged commit 640e440 into main Jun 16, 2026
37 of 38 checks passed
@jan-janssen jan-janssen deleted the Py314u branch June 16, 2026 08:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants