Skip to content

Fix output_transitions for Python 3.13+ (PEP 667)#57

Merged
xuan-w merged 3 commits into
CASCI-lab:masterfrom
xuan-w:fix/exec-eval-py313
Apr 27, 2026
Merged

Fix output_transitions for Python 3.13+ (PEP 667)#57
xuan-w merged 3 commits into
CASCI-lab:masterfrom
xuan-w:fix/exec-eval-py313

Conversation

@xuan-w

@xuan-w xuan-w commented Apr 9, 2026

Copy link
Copy Markdown
Contributor

Summary

python 3.13's change (PEP 667) breaks existing code to load models from logical expressions (not cnet LUT).

  • Fix output_transitions() in cana/utils.py to use an explicit namespace dict for exec()/eval(), resolving a bug where Python 3.13+ (PEP 667) snapshots locals making dynamically created variables invisible to eval()
  • Add unit tests for output_transitions, from_string_boolean parsing, and loading the LEUKEMIA logical-format model

Test plan

  • test_output_transitions — verifies truth table generation for basic logical expressions
  • test_from_string_boolean — verifies parsing of logical boolean rules
  • test_load_logical_LEUKEMIA — verifies loading a real biological model in logical format

🤖 Generated with Claude Code

xuan-w and others added 2 commits April 9, 2026 17:57
Python 3.13 changed locals() semantics (PEP 667): bare exec() inside a
function now writes to a snapshot of locals that eval() cannot see. This
broke loading of models that use the "logical" file format (e.g.
BREAST_CANCER, LEUKEMIA) because output_transitions() relied on exec()
to create variables that eval() would read.

Replace exec()/eval() with direct dict assignment and an explicit
namespace, which works on all Python versions. Also rename the loop
variable from `input` (shadowing the builtin) to `input_name`.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Cover the code path fixed in the previous commit:
- test_output_transitions: truth tables for AND, OR, OR+NOT gates
- test_from_string_boolean: parse a 3-node network from boolean rules
- test_load_logical_LEUKEMIA: load a real model in logical format

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Fixes Boolean-rule model loading on Python 3.13+ by updating output_transitions() to avoid relying on function locals mutated via exec() (affected by PEP 667), and adds regression/unit tests around logical rule parsing and dataset loading.

Changes:

  • Update cana.utils.output_transitions() to evaluate expressions using an explicit namespace dict (PEP 667-compatible).
  • Add unit tests for output_transitions() truth tables and BooleanNetwork.from_string_boolean() parsing.
  • Add a regression test that loads the logical-format LEUKEMIA model.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
cana/utils.py Reworks output_transitions() evaluation to be Python 3.13+ compatible by using an explicit namespace for eval().
tests/test_boolean_network.py Adds regression/unit tests covering truth table generation, boolean-rule parsing, and loading the logical-format LEUKEMIA dataset.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread cana/utils.py Outdated
Comment thread cana/utils.py Outdated

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread cana/utils.py

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread cana/utils.py Outdated
Comment thread cana/utils.py Outdated

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread cana/utils.py Outdated
Comment thread cana/utils.py Outdated
- Pass {"__builtins__": {}} to eval() to disable builtin functions
- Pre-compile eval_line with compile() to avoid re-parsing each iteration
- Update docstring to clarify trust assumption and current implementation

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@fxcosta-phd

Copy link
Copy Markdown
Contributor

@xuan-w can you briefly explain what is this fix?

The function output_transitions() seems to be important for STG related analysis, so I would like to make sure that we have some backwards compatibility implemented so that it won't break the existing codes just for the sake of updating.

@xuan-w

xuan-w commented Apr 15, 2026

Copy link
Copy Markdown
Contributor Author

To answer your questions

  1. this function is not used in STG, as far as I know.
  2. this function is used when we load models from Boolean expression files (not the LUT cnet files), currently Leukemia and Breast cancer model.
  3. About compatibility: this fix solved python 3.13 compatibility. We tested python 3.10, 3.11, 3.12 3.13, four major versions, via CI and local tests. Those are the python versions we declare compatible to. We didn't test older versions. I think it will not work in some ancient python versions like python 3.2. Let me know if there is a specific python version you want to be compatible with. Or we can add python version compatibility requirement.

@xuan-w

xuan-w commented Apr 27, 2026

Copy link
Copy Markdown
Contributor Author

We've examined the patch again for compatibility. The features used (eval() with globals/locals args, compile(), str.strip(), dict literals) have all been available since Python 2.0. Since CANA is already Python 3 only, there is no compatibility issue — this patch works on every Python version CANA supports.

Without the patch, Python 3.13+ (released Oct 2024) is broken due to PEP 667 changing how exec() interacts with function locals.

@xuan-w xuan-w merged commit cb2a538 into CASCI-lab:master Apr 27, 2026
8 checks passed
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.

3 participants