Changes by Jules#104
Merged
Merged
Conversation
…recated actions - Run black on 9 files failing formatting check - Fix _resolve_block_adder to raise BNGModelError instead of ValueError - Fix test assertion expectations to match actual exception types - Fix simulator tests to properly skip when BNG2.pl unavailable - Update deprecated actions/checkout@v2/v3 to v4 - Update deprecated docker actions from v2 to v3/v5/v6
…ssertions, mock exception types, and SBML skip
Extracted duplicate logic for grouping equivalent molecules from different rules in `contextAnalyzer.py` into a new `groupEquivalentItems` helper function. This satisfies the long-standing "TODO: i have to find the way to group together equivalent molecules from different rules and find the metarule" and improves code readability. Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
…g slicing. * Fix contactMap.py to only process the first cluster using slicing. Co-authored-by: akutuva21 <44119804+akutuva21@users.noreply.github.com> * Fix contactMap.py to only process the first cluster using slicing. Co-authored-by: akutuva21 <44119804+akutuva21@users.noreply.github.com> * Fix contactMap.py to only process the first cluster using slicing. Co-authored-by: akutuva21 <44119804+akutuva21@users.noreply.github.com> --------- Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
* Fix string copying bug in analyzeSBML by performing token-based prefix matching
The original logic was iterating character-by-character over
`tmpRuleList[1][0]` and checking if the character itself (`in sym`)
was present in the list of symbols (`sym`). However, `sym` can contain
multi-character strings (e.g. '~P', '~U'), meaning the first character
('~') alone evaluates to False, causing the loop to fail to copy the
symbols properly.
The fix sorts the symbols by length in descending order to handle
overlapping prefixes correctly and then uses `.startswith` from the
current index to greedily match the longest possible valid string
token in `sym`.
Co-authored-by: akutuva21 <44119804+akutuva21@users.noreply.github.com>
* Fix string copying bug in analyzeSBML by performing token-based prefix matching
The original logic was iterating character-by-character over
`tmpRuleList[1][0]` and checking if the character itself (`in sym`)
was present in the list of symbols (`sym`). However, `sym` can contain
multi-character strings (e.g. '~P', '~U'), meaning the first character
('~') alone evaluates to False, causing the loop to fail to copy the
symbols properly.
The fix sorts the symbols by length in descending order to handle
overlapping prefixes correctly and then uses `.startswith` from the
current index to greedily match the longest possible valid string
token in `sym`.
Co-authored-by: akutuva21 <44119804+akutuva21@users.noreply.github.com>
* Fix string copying bug in analyzeSBML by performing token-based prefix matching
The original logic was iterating character-by-character over
`tmpRuleList[1][0]` and checking if the character itself (`in sym`)
was present in the list of symbols (`sym`). However, `sym` can contain
multi-character strings (e.g. '~P', '~U'), meaning the first character
('~') alone evaluates to False, causing the loop to fail to copy the
symbols properly.
The fix sorts the symbols by length in descending order to handle
overlapping prefixes correctly and then uses `.startswith` from the
current index to greedily match the longest possible valid string
token in `sym`.
Co-authored-by: akutuva21 <44119804+akutuva21@users.noreply.github.com>
* fix(atomizer): apply greedy matching fix to analyzeSBML string copy
Co-authored-by: akutuva21 <44119804+akutuva21@users.noreply.github.com>
---------
Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
Implemented the verbosity check in `bionetgen/modelapi/bngparser.py` that was mentioned in a TODO comment. If `self.verbose` is set to true, it will now print "Parsing XML" before calling `xml_file.read()`. Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
* fix(parser): handle 0 as a valid dictionary key in BNGL action arguments
Modified `curly_arg_token` in `ActionList.define_parser` to allow `0` as a bare dictionary key using `pp.Literal("0")`. This resolves the TODO for handling the 0 case and ensures action strings like `simulate({print_functions=>{0=>1}})` are properly parsed instead of failing with a syntax error.
Co-authored-by: akutuva21 <44119804+akutuva21@users.noreply.github.com>
* fix: adjust curly_arg_token formatting to pass black lint check
Co-authored-by: akutuva21 <44119804+akutuva21@users.noreply.github.com>
---------
Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
…tion in analyzeSBML * perf: optimize levenshtein distance calculations using memoization The `levenshtein` method in `analyzeSBML.py` is repeatedly called during string processing and matching. Adding the `@pmemoize` decorator caches its results for duplicate inputs, significantly speeding up nested string comparisons across the atomizer module. The method was safely converted to a `@staticmethod` to ensure compatibility with `pmemoize`'s underlying `marshal` logic, which cannot serialize `self`. Co-authored-by: akutuva21 <44119804+akutuva21@users.noreply.github.com> * perf: optimize levenshtein distance calculations using memoization The `levenshtein` method in `analyzeSBML.py` is repeatedly called during string processing and matching. Adding the `@pmemoize` decorator caches its results for duplicate inputs, significantly speeding up nested string comparisons across the atomizer module. The method was safely converted to a `@staticmethod` to ensure compatibility with `pmemoize`'s underlying `marshal` logic, which cannot serialize `self`. Co-authored-by: akutuva21 <44119804+akutuva21@users.noreply.github.com> --------- Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
* 🧪 Add error test for shutil.rmtree in CSimulator Co-authored-by: akutuva21 <44119804+akutuva21@users.noreply.github.com> * Fix syntax error and compile errors in test_csimulator.py - Fixed Python 3.8/3.9 syntax error by unwrapping parenthesized context managers. - Fixed `distutils.errors.CompileError` by correctly mocking `bionetgen.simulator.csimulator._new_ccompiler` instead of `ccompiler` directly, returning `compile_shared_lib` compatibility with tests. - Reverted unintentional use of `Exception` instead of `ValueError` in test expectations. Co-authored-by: akutuva21 <44119804+akutuva21@users.noreply.github.com> --------- Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
* fix: migrate BNGL function creation logic to bngModel class This commit adds a new `add_bngl_function` method to the `bngModel` class which encapsulates the repetitive logic of instantiating a Function object, parsing its definition from a BNGL string, assigning its properties, and adding it to the model. It then updates the `sbml2bngl.py` converter to use this new method instead of executing the logic inline, satisfying the previous "TODO: Add to bngModel functions" task. Co-authored-by: akutuva21 <44119804+akutuva21@users.noreply.github.com> * fix: migrate BNGL function creation logic to bngModel class This commit adds a new `add_bngl_function` method to the `bngModel` class which encapsulates the repetitive logic of instantiating a Function object, parsing its definition from a BNGL string, assigning its properties, and adding it to the model. It then updates the `sbml2bngl.py` converter to use this new method instead of executing the logic inline, satisfying the previous "TODO: Add to bngModel functions" task. Ran black to fix formatting issues caught by CI. Co-authored-by: akutuva21 <44119804+akutuva21@users.noreply.github.com> * fix: migrate BNGL function creation logic to bngModel class This commit adds a new `add_bngl_function` method to the `bngModel` class which encapsulates the repetitive logic of instantiating a Function object, parsing its definition from a BNGL string, assigning its properties, and adding it to the model. It then updates the `sbml2bngl.py` converter to use this new method instead of executing the logic inline, satisfying the previous "TODO: Add to bngModel functions" task. Includes proper black formatting. Co-authored-by: akutuva21 <44119804+akutuva21@users.noreply.github.com> * fix: migrate BNGL function creation logic to bngModel class This commit adds a new `add_bngl_function` method to the `bngModel` class which encapsulates the repetitive logic of instantiating a Function object, parsing its definition from a BNGL string, assigning its properties, and adding it to the model. It then updates the `sbml2bngl.py` converter to use this new method instead of executing the logic inline, satisfying the previous "TODO: Add to bngModel functions" task. Includes proper black formatting. Co-authored-by: akutuva21 <44119804+akutuva21@users.noreply.github.com> * fix: migrate BNGL function creation logic to bngModel class This commit adds a new `add_bngl_function` method to the `bngModel` class which encapsulates the repetitive logic of instantiating a Function object, parsing its definition from a BNGL string, assigning its properties, and adding it to the model. It then updates the `sbml2bngl.py` converter to use this new method instead of executing the logic inline, satisfying the previous "TODO: Add to bngModel functions" task. Includes proper black formatting. Co-authored-by: akutuva21 <44119804+akutuva21@users.noreply.github.com> * fix: migrate BNGL function creation logic to bngModel class This commit adds a new `add_bngl_function` method to the `bngModel` class which encapsulates the repetitive logic of instantiating a Function object, parsing its definition from a BNGL string, assigning its properties, and adding it to the model. It then updates the `sbml2bngl.py` converter to use this new method instead of executing the logic inline, satisfying the previous "TODO: Add to bngModel functions" task. Includes proper black formatting. Co-authored-by: akutuva21 <44119804+akutuva21@users.noreply.github.com> --------- Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
* Remove hardcoded BioGRID API key - Removed the hardcoded API key (`f74b8d6f4c394fcc9d97b11c8c83d7f3`) from `bionetgen/atomizer/utils/pathwaycommons.py`. - Updated `queryBioGridByName` to retrieve the key from the `BIOGRID_API_KEY` environment variable. - Added a graceful fallback: if the key is not set, a warning is logged (`WARNING:ATO006`), and the function returns `False`. - Updated tests in `tests/test_pathwaycommons.py` to mock `os.environ` so they continue passing. Co-authored-by: akutuva21 <44119804+akutuva21@users.noreply.github.com> * Remove hardcoded BioGRID API key - Removed the hardcoded API key (`f74b8d6f4c394fcc9d97b11c8c83d7f3`) from `bionetgen/atomizer/utils/pathwaycommons.py`. - Updated `queryBioGridByName` to retrieve the key from the `BIOGRID_API_KEY` environment variable. - Added a graceful fallback: if the key is not set, a warning is logged (`WARNING:ATO006`), and the function returns `False`. - Updated tests in `tests/test_pathwaycommons.py` to mock `os.environ` so they continue passing. Co-authored-by: akutuva21 <44119804+akutuva21@users.noreply.github.com> * 🔒 fix(pathwaycommons): Remove hardcoded API key Refactor `queryBioGridByName` in `bionetgen/atomizer/utils/pathwaycommons.py` to retrieve the BioGRID API key via the `BIOGRID_API_KEY` environment variable instead of using a hardcoded string. A fallback was added to return `False` gracefully if the key is not set, logging a warning. This addresses the security vulnerability of hardcoded secrets in the code. Tests in `tests/test_pathwaycommons.py` were also updated to mock the environment variable to ensure existing tests pass. Co-authored-by: akutuva21 <44119804+akutuva21@users.noreply.github.com> * 🔒 fix(pathwaycommons): Remove hardcoded API key Refactor `queryBioGridByName` in `bionetgen/atomizer/utils/pathwaycommons.py` to retrieve the BioGRID API key via the `BIOGRID_API_KEY` environment variable instead of using a hardcoded string. A fallback was added to return `False` gracefully if the key is not set, logging a warning. This addresses the security vulnerability of hardcoded secrets in the code. Tests in `tests/test_pathwaycommons.py` were also updated to mock the environment variable to ensure existing tests pass. Co-authored-by: akutuva21 <44119804+akutuva21@users.noreply.github.com> --------- Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
…ix CI test failures
Previously the BNGsim backend hook rejected PLA actions and routed them to the BNG2.pl subprocess, where the bundled run_network binary fails on the '-p pla' method. Now PLA is treated like ode/ssa/psa: the Perl hook intercepts it and delegates to the backend helper, which passes it through to BNGsim when available. The method alias map, routing checks, and test patch hook are all updated accordingly.
Replaced the assert statement with proper BNGModelError raising and logger calls, maintaining consistency with all other block adders in bionetgen/modelapi/model.py. Co-authored-by: akutuva21 <44119804+akutuva21@users.noreply.github.com>
- Modified `add_protocol_block` in `bionetgen/modelapi/model.py` to replace the bare `assert` statement with an `if not isinstance` check. - Now properly uses `self.logger.error()` with the location passed as `loc`, and raises a `BNGModelError` in case of failure. - This brings `add_protocol_block` in line with the consistent exception and logging pattern applied to all other model blocks in the codebase. Co-authored-by: akutuva21 <44119804+akutuva21@users.noreply.github.com>
…emoving redundant detectOntology call Remove the `detectOntology.analyzeNamingConventions` call inside `SBMLAnalyzer.processNamingConventions2` in `bionetgen/atomizer/atomizer/analyzeSBML.py`. This call was identified as the single biggest execution bottleneck. This redundant work can be safely removed because an equivalent call is already correctly made at a higher scope level (`processNamingConventions`) resolving naming conventions without this inline nested duplication. Tests verify that the removal causes no functional regressions. Co-authored-by: akutuva21 <44119804+akutuva21@users.noreply.github.com>
Replaced O(N) list membership checks (e.g., `in ["pow"]`) with O(1) set membership checks (e.g., `in {"pow"}`) in `bionetgen/atomizer/writer/bnglWriter.py` to improve performance. Checked other occurrences in the file and applied the optimization to them as well (`["root", "pow"]`, `["sqr", "sqrt"]`, `["and", "or"]`, and a large keyword list in `any()`). All tests pass.
Co-authored-by: akutuva21 <44119804+akutuva21@users.noreply.github.com>
This commit addresses a missing testing coverage for the error paths in the `generate_notebook` function inside `bionetgen/core/main.py`. Specifically, `AttributeError` and `KeyError` exception paths related to checking custom stdout/stderr configurations are now verified. Two new tests are added to `tests/test_notebook_cmd.py`: - `test_bionetgen_notebook_attribute_error` sets missing config strings. - `test_bionetgen_notebook_key_error` dynamically deletes config keys. Both tests verify that `subprocess.PIPE` and `subprocess.STDOUT` fallbacks are used in the resulting Popen call. Co-authored-by: akutuva21 <44119804+akutuva21@users.noreply.github.com>
…_bngpath Co-authored-by: akutuva21 <44119804+akutuva21@users.noreply.github.com>
Co-authored-by: akutuva21 <44119804+akutuva21@users.noreply.github.com>
Co-authored-by: akutuva21 <44119804+akutuva21@users.noreply.github.com>
Co-authored-by: akutuva21 <44119804+akutuva21@users.noreply.github.com>
Co-authored-by: akutuva21 <44119804+akutuva21@users.noreply.github.com>
Addressed the TODO in bionetgen/modelapi/model.py by replacing the log warning with raising a BNGModelError when a loaded model contains no active blocks. Also updated the tests in test_bionetgen.py to appropriately skip action loading tests when BNG2.pl is missing (which causes empty blocks and correctly triggers the new error) rather than failing. Co-authored-by: akutuva21 <44119804+akutuva21@users.noreply.github.com>
Replaced a manual loop iterating over kwargs keys with direct dictionary instantiation (`self.odict = dict(kwargs)`) to improve performance and code readability. Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
…iguration (#539) The doubleModifications mapping in moleculeCreation.py was previously hardcoded and contained a typo. This commit extracts the mapping into the respective namingConventions.json configuration files and modifies moleculeCreation.py and detectOntology.py to retrieve and use it dynamically from the configuration object instead. Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
Instead of doing a simple split by `_` when extracting actionable units, we now compare against `strippedMolecules` and split by smallest actionable units utilizing `self.greedyModificationMatching()`. If `greedyModificationMatching()` fails to find a valid match, we fall back to splitting the string by `_`. Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
) Removed the `.keys()` call in `bionetgen/core/tools/gdiff.py`'s `_get_node_text` method. Iterating directly over the dictionary is faster and more idiomatic as it avoids creating a temporary view object in Python 3. Measured improvement (via 1,000,000 simulated iterations): ~11.29% speedup for node text retrieval. Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
Iterating directly over a dictionary avoids allocating a view object for `.keys()` and slightly improves CPU and memory efficiency. Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
* test: add coverage for ModelObj comment setter Co-authored-by: akutuva21 <44119804+akutuva21@users.noreply.github.com> * style: format test_structs.py with black Co-authored-by: akutuva21 <44119804+akutuva21@users.noreply.github.com> --------- Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
* Add unit tests for Species gen_string method Co-authored-by: akutuva21 <44119804+akutuva21@users.noreply.github.com> * Fix formatting in test_structs.py Co-authored-by: akutuva21 <44119804+akutuva21@users.noreply.github.com> * Fix formatting in tests/test_structs.py Co-authored-by: akutuva21 <44119804+akutuva21@users.noreply.github.com> --------- Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
…xes (#529) Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
Added test_rule_gen_string to tests/test_structs.py to cover bidirectional rules, unidirectional rules, rules with multiple reactants/products, and rules with RuleMod modifiers. Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
…_symbols (#531) Added comprehensive test cases for the `_replace_indexed_symbols` function, specifically covering its parameter indexing logic (including the internal `repl_param` method). This ensures `param[...]`, `params[...]`, and `p[...]` constructs are correctly substituted with explicit parameter names or appropriate index fallbacks when out of bounds. Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
Added a new unit test test_modelobj_comment to tests/test_structs.py to verify the getter and setter functionality of the comment property in bionetgen.modelapi.structs.ModelObj. The test covers setting strings with hash marks, leading whitespaces, strings without hashes, and non-string values. Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
Resolves an issue where BNGModelError printed the empty self object representation instead of the model path when there are no active blocks. Updates `bionetgen/modelapi/model.py` and `bionetgen/network/network.py` to correctly pass the file path context. Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
* 🧪 Add test for EnergyPattern.gen_string Co-authored-by: akutuva21 <44119804+akutuva21@users.noreply.github.com> * 🧪 Add test for EnergyPattern.gen_string Co-authored-by: akutuva21 <44119804+akutuva21@users.noreply.github.com> --------- Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
* Add tests for Rule.set_rate_constants Co-authored-by: akutuva21 <44119804+akutuva21@users.noreply.github.com> * Fix tests/test_structs.py formatting to pass CI Co-authored-by: akutuva21 <44119804+akutuva21@users.noreply.github.com> --------- Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
* Add test for repl_param in sympy_odes.py Co-authored-by: akutuva21 <44119804+akutuva21@users.noreply.github.com> * Add test for repl_param in sympy_odes.py Co-authored-by: akutuva21 <44119804+akutuva21@users.noreply.github.com> * Fix test to pass using proper regex patterns Co-authored-by: akutuva21 <44119804+akutuva21@users.noreply.github.com> --------- Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
* Add unit tests for Observable.gen_string method Co-authored-by: akutuva21 <44119804+akutuva21@users.noreply.github.com> * Fix PEP8 violation by moving Observable import to top of test_structs.py Co-authored-by: akutuva21 <44119804+akutuva21@users.noreply.github.com> * Fix PEP8 violation by moving Observable import to top of test_structs.py Co-authored-by: akutuva21 <44119804+akutuva21@users.noreply.github.com> --------- Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
Contributor
|
@akutuva21 : I think previous merges have created some conflicts. Can you please resolve? |
Resolved conflicts in: - bionetgen/core/utils/utils.py: kept upstream's e-notation and trailing comma support for list args (fixes #110) - bionetgen/modelapi/bngparser.py: combined verbose flag with BNGPATH parameter - bionetgen/modelapi/model.py: combined verbose flag with simplified upstream init - bionetgen/network/network.py: kept module-level logger initialization - bionetgen/simulator/csimulator.py: combined get_conf with BNGSimulatorError import - tests/test_bng_parsing.py: kept both exception tests and parametrized grammar tests
jrfaeder
pushed a commit
that referenced
this pull request
Jul 20, 2026
…s when parsing reaction rates (#104) * 🧹 [code health improvement] properly apply assignment rule adjustments when parsing reaction rates Co-authored-by: akutuva21 <44119804+akutuva21@users.noreply.github.com> * chore: PR #104 remove forbidden artifacts and run black --------- Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
Member
Author
|
It didn't pass CI yet? |
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
PyBioNetGen: Security, Performance, Code Health, and Test Coverage Overhaul
Summary
This PR rolls up 419 commits spanning April 13 – June 4, 2026 into a single contribution against PyBioNetGen. It touches 151 unique files with roughly +10,800 / −9,100 lines changed across the run. The work is a broad maintenance and hardening pass over the codebase — closing security holes, eliminating long-standing
TODO/FIXME/assertdebt, optimizing hot paths, and substantially expanding test coverage — alongside a set of targeted bug fixes in the SBML→BNGL atomizer and the simulator/runner stack.Work was developed with assistance from AI coding agents (Jules), with all commits co-authored and reviewed;
Co-authored-bytrailers creditgoogle-labs-jules[bot]on ~115 commits.Commit breakdown by category
Most-affected files
atomizer/sbml2bngl.py,core/tools/visualize.py,modelapi/runner.py,atomizer/bngModel.py,simulator/csimulator.py,atomizer/libsbml2bngl.py,modelapi/bngfile.py, andmerging/namingDatabase.py, plus a large number of new and expanded test modules undertests/.1. Security fixes
Hardening focused on unsafe deserialization, code injection vectors, XML parsing, path traversal, and leaked secrets.
pickle.loadwithjson.loadinatomizer/contactMap.pyandannotationComparison.py, and fixed insecure deserialization indetectOntology.py.eval()→ast.literal_eval()across the atomizer andpostAnalysis.pyto remove arbitrary-code-execution risk.ast.literal_evalDoS vulnerabilities fixed inpostAnalysis.pyandanalyzeTrends(untrusted assumption strings), with one path further hardened by switching tojson.loads.readBNGXML.pyand a full migration todefusedxmlfor safe XML parsing.tarfile.extractallresolved.yaml.load→yaml.safe_load).pathwaycommons.py; the key is now read from theBIOGRID_API_KEYenvironment variable with a graceful warning-and-skip fallback when unset.molec.namein the atomizer.2. Performance optimizations
NamingDatabaseSQLite layer: persistent connection handling and reduced per-query overhead, reported as a ~3.7x query speedup; fixed an N+1 query in annotation insertion; batched annotation-ID caching to avoid full-table refetches; batched SQL in namespace detection.join/buffered builds inbnglReaction,bnglWriter.py,BNGResult.__repr__,bngmodel.__str__, andside_string.moleculeCreation,smallStructures,classifyReactions, atomizer constant lists).bnglWriter.pyanddistanceToModification; Levenshtein distance memoized inanalyzeSBML.type() == listchecks withisinstance(), removed redundant.keys()lookups andlen() == 0checks, and added early-exit traversal indeleteMolecule.queryActiveSitewithin theresolveSCTloop.3. Code health & refactoring
assertstatements to structuredBNGError/BNGParseErrorplusBNGLoggeracross reactions parsing,csimulatorinit,network.py, and model parsing; replaced bareexceptclauses with specific exceptions; converted silent assignment failures to logged warnings.os.chdir/ CWD discipline: a large sustained effort to eliminate working-directory leaks — refactoredVisResultandvisualize.pyto avoidos.chdir, wrapped directory changes intry/finally, replaced a module-level app instantiation that corrupted CWD, and usedTemporaryDirectorycontexts correctly. This resolved widespread WindowsPermissionError/WinError 32andFileNotFoundErrorfailures in CI.libsbml2bngl.pyandbngModel.pyrefactored to usenetworkxtopological sort (Kahn's algorithm).TODO/FIXMEitems and removed dead code throughout the atomizer, network structs, and model API; standardizedshutilimport (dropped theimport shutil as spawnalias); refactored oversized files (e.g. splittingsbml2bngl.pyhelpers into utility modules) and long methods (ActionList.__init__).blackformatting and removal of stray test/build artifacts.4. Bug fixes
observablesDictwhen overridden by assignment rules. Fixednl/nrassignment when reactants/products appear in rate expressions.Pattern, dimer component classification, volume adjustment for multiple species in rate functions, double-modification queueing inSCTSolver, and parameter namespace collisions inbngModelassignment rules.gdiff): fixed single-node-to-list conversion and nested node recoloring/renaming.bngl2xmlnow runs with a multiprocessing/subprocess timeout; fixedrunner.pySectionProxyattribute error; restored CWD infinallyblocks across visualize/runner/atomizer/simulator.--versionflag (after one revert/re-land cycle); fixedBNGPATHresolution whenBNG2.plis onPATH.ListOfBondstag handling inxmltodictparsing; invalid escape sequences in parameter rate-rule regexes;setup.pyduplicate manifest inclusions.5. New features
poplevel,check_product_scale) and apsasimulation method.sympyinParameterBlock/NetworkBlock.add_item.BNGResultextension-based file filtering; standalonefind_dat_files/load_resultsmethods; consolidated path argument in the constructor.add_bngl_functionhelper migrated into thebngModelclass.6. Test coverage
~88 commits add or expand tests, with new suites for
pathwaycommons(BioGRID/Reactome/Uniprot query paths and HTTPError fallbacks),detectOntology.levenshtein,sbml2jsonutilities, thecsimulator/libRRSimulatorwrappers,BNGSimulatorproperties,gdiff,sympy_odes,Patternequality,ModelObj/ActionBlockoperations, the runner, and thenotebook/graphdiffCLI commands. Several commits specifically add exception-path and edge-case coverage (e.g.add_block,_safe_rmtreeOS errors,_get_color_id).Notes for reviewers
blackformatting,pytest-mock→unittest.mock, Python 3.8 compatibility for parenthesizedwith) that account for some apparent duplication in the log; the net effect is a green, cross-platform test suite.Merging PR #340–#367) and a few others fold in earlier sub-PRs from the same branch series.