Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
44 changes: 38 additions & 6 deletions src/bytecode/cfg.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,18 +42,50 @@ def __init__(
if instructions:
super().__init__(instructions)

_VALID_TYPES = (SetLineno, Instr, TryBegin, TryEnd)

@staticmethod
def _check_instr(instr: Any) -> None:
if not isinstance(instr, (SetLineno, Instr, TryBegin, TryEnd)):
raise ValueError(
"BasicBlock must only contain SetLineno and Instr objects, "
"but %s was found" % instr.__class__.__name__
)

def append(self, instr: Union[Instr, SetLineno, TryBegin, TryEnd]) -> None:
self._check_instr(instr)
super().append(instr)

def insert(
self, index: SupportsIndex, instr: Union[Instr, SetLineno, TryBegin, TryEnd]
) -> None:
self._check_instr(instr)
super().insert(index, instr)

def extend(
self, instrs: Iterable[Union[Instr, SetLineno, TryBegin, TryEnd]]
) -> None:
instrs = list(instrs)
for instr in instrs:
self._check_instr(instr)
super().extend(instrs)

def __setitem__(self, index, value):
if isinstance(index, slice):
values = list(value)
for instr in values:
self._check_instr(instr)
super().__setitem__(index, values)
else:
self._check_instr(value)
super().__setitem__(index, value)

def __iter__(self) -> Iterator[Union[Instr, SetLineno, TryBegin, TryEnd]]:
index = 0
while index < len(self):
instr = self[index]
index += 1

if not isinstance(instr, (SetLineno, Instr, TryBegin, TryEnd)):
raise ValueError(
"BasicBlock must only contain SetLineno and Instr objects, "
"but %s was found" % instr.__class__.__name__
)

if isinstance(instr, Instr) and instr.has_jump():
if index < len(self) and any(
isinstance(self[i], Instr) for i in range(index, len(self))
Expand Down
9 changes: 5 additions & 4 deletions tests/test_cfg.py
Comment thread
P403n1x87 marked this conversation as resolved.
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,14 @@ def disassemble(

class BlockTests(unittest.TestCase):
def test_iter_invalid_types(self):
# Labels are not allowed in basic blocks
# Labels are not allowed in basic blocks — caught at insertion time
block = BasicBlock()
block.append(Label())
with self.assertRaises(ValueError):
list(block)
block.append(Label())
with self.assertRaises(ValueError):
block.legalize(1)
block.extend([Label()])
with self.assertRaises(ValueError):
block.insert(0, Label())

# Only one jump allowed and only at the end
block = BasicBlock()
Expand Down