Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion bionetgen/modelapi/rulemod.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
from bionetgen.core.exc import BNGParseError


class RuleMod:
"""
Rule modifiers class for storage and printing.
Expand Down Expand Up @@ -42,4 +45,6 @@ def type(self, val):
if val in self.valid_mod_names or val is None:
self._type = val
else:
print(f"Rule modifier type {val} is not a valid type")
raise BNGParseError(
message=f": Rule modifier type {val} is not a valid type"
)
9 changes: 7 additions & 2 deletions bionetgen/modelapi/structs.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ def line_label(self, val) -> None:
try:
ll = int(val)
self._line_label = "{} ".format(ll)
except:
except (TypeError, ValueError):
self._line_label = "{}: ".format(val)

def print_line(self) -> str:
Expand Down Expand Up @@ -423,7 +423,12 @@ def set_rate_constants(self, rate_cts):
self.rate_constants = [rate_cts[0], rate_cts[1]]
self.bidirectional = True
else:
print("1 or 2 rate constants allowed")
raise BNGParseError(
message=(
f": Rule {self.name} requires 1 or 2 rate constants, "
f"got {len(rate_cts)}"
)
)

def gen_string(self):
if self.bidirectional:
Expand Down
29 changes: 20 additions & 9 deletions bionetgen/network/networkparser.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import re, os
from bionetgen.core.exc import BNGParseError
from bionetgen.core.utils.logging import BNGLogger
from bionetgen.main import BioNetGen
from bionetgen.network.blocks import (
NetworkGroupBlock,
Expand All @@ -16,6 +18,7 @@
app.setup()
conf = app.config["bionetgen"]
def_bng_path = conf["bngpath"]
logger = BNGLogger()


class BNGNetworkParser:
Expand Down Expand Up @@ -92,16 +95,25 @@ def parse_network(self, network_obj) -> None:
spec_block = NetworkSpeciesBlock()
for iline in range(sblock[0] + 1, sblock[1]):
m = re.match("([^#]*)(#.*)?", self.network_lines[iline])
if m.group(1).strip() != "":
splt = m.group(1).split()
if m is None:
continue
line_text = m.group(1) or ""
if line_text.strip() != "":
splt = line_text.split()
if len(splt) < 3:
msg = (
f"Malformed species line at {self.path}:{iline + 1}; "
"expected '<id> <species> <count>', "
f"got {line_text.strip()!r}"
)
logger.error(
msg,
loc=f"{__file__} : BNGNetworkParser.parse_network()",
)
raise BNGParseError(self.path, message=f": {msg}")
sid = splt[0]
name = splt[1]
try:
count = splt[2]
except:
import IPython

IPython.embed()
count = splt[2]
spec_block.add_species(sid, name, count)
network_obj.add_block(spec_block)
# add reactions
Expand Down Expand Up @@ -137,4 +149,3 @@ def parse_network(self, network_obj) -> None:
comment = m.group(2)
grps_block.add_group(rid, name, members, comment=comment)
network_obj.add_block(grps_block)
# import IPython,sys;IPython.embed();sys.exit()
2 changes: 1 addition & 1 deletion bionetgen/network/structs.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ def line_label(self, val) -> None:
try:
ll = int(val)
self._line_label = "{} ".format(ll)
except:
except (TypeError, ValueError):
self._line_label = "{}: ".format(val)

def print_line(self) -> str:
Expand Down
88 changes: 88 additions & 0 deletions tests/test_networkparser_structs_errors.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
from unittest.mock import patch

import pytest

from bionetgen.core.exc import BNGParseError
from bionetgen.modelapi.rulemod import RuleMod
from bionetgen.modelapi.structs import Parameter, Rule
from bionetgen.network.structs import NetworkObj


class FakePattern:
def __init__(self, text):
self._text = text

def __str__(self):
return self._text


NET_MALFORMED_SPECIES = """\
# NET file
begin species
1 A(b)
end species
"""


def test_networkparser_malformed_species_line_raises_parse_error(tmp_path):
net_file = tmp_path / "bad_species.net"
net_file.write_text(NET_MALFORMED_SPECIES)
from bionetgen.network import networkparser as networkparser_module
from bionetgen.network.network import Network

with patch.object(networkparser_module, "logger") as mock_logger:
with pytest.raises(BNGParseError, match="Malformed species line"):
Network(str(net_file))

mock_logger.error.assert_called_once()
error_args, error_kwargs = mock_logger.error.call_args
assert "Malformed species line" in error_args[0]
assert "expected '<id> <species> <count>'" in error_args[0]
assert "bad_species.net:3" in error_args[0]
assert "BNGNetworkParser.parse_network()" in error_kwargs["loc"]


def test_model_struct_line_label_none_uses_string_fallback():
parameter = Parameter("k1", "1")
parameter.line_label = None
assert parameter.line_label == "None: "


def test_network_struct_line_label_none_uses_string_fallback():
obj = NetworkObj()
obj.line_label = None
assert obj.line_label == "None: "


def test_rule_set_rate_constants_invalid_length_raises_parse_error():
rule = Rule(
name="r",
reactants=[FakePattern("A()")],
products=[FakePattern("B()")],
rate_constants=("k1",),
)
with pytest.raises(BNGParseError, match="1 or 2 rate constants"):
rule.set_rate_constants(("k1", "k2", "k3"))
assert rule.bidirectional is False
assert rule.rate_constants == ["k1"]


def test_rule_init_without_rate_constants_raises_parse_error():
with pytest.raises(BNGParseError, match="1 or 2 rate constants"):
Rule(
name="r",
reactants=[FakePattern("A()")],
products=[FakePattern("B()")],
)


def test_rulemod_invalid_init_raises_parse_error():
with pytest.raises(BNGParseError, match="Rule modifier type InvalidMod"):
RuleMod(mod_type="InvalidMod")


def test_rulemod_invalid_setter_raises_parse_error():
rule_mod = RuleMod()
with pytest.raises(BNGParseError, match="Rule modifier type BadType"):
rule_mod.type = "BadType"
assert rule_mod.type is None
Loading