Skip to content
Open
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
36 changes: 27 additions & 9 deletions memory/space.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,10 +87,15 @@ def write(self, *values):
self._update_label_pointers()

def clear(self, value):
try:
values = [value] * (len(self) // len(value))
except:
# int-like fills (incl. IntEnum/IntFlag, whose len() returns a popcount
# on Python 3.11+) occupy one byte each.
if isinstance(value, int):
values = [value] * len(self)
else:
try:
values = [value] * (len(self) // len(value))
except:
values = [value] * len(self)
Comment on lines +95 to +98

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

Avoid using a bare except: clause as it can catch unexpected exceptions like SystemExit or KeyboardInterrupt, making debugging harder and preventing proper program interruption. Since len(value) can raise a TypeError (if the object has no length) or ZeroDivisionError (if the length is zero), it is better to catch these specific exceptions explicitly.

Suggested change
try:
values = [value] * (len(self) // len(value))
except:
values = [value] * len(self)
try:
values = [value] * (len(self) // len(value))
except (TypeError, ZeroDivisionError):
values = [value] * len(self)
References
  1. PEP 8 recommends avoiding bare except clauses because they catch SystemExit and KeyboardInterrupt exceptions, making it harder to interrupt a program with Control-C. (link)


values = self._invoke_callables(values)
assert len(self) == len(values) # do values evenly fill space?
Expand Down Expand Up @@ -175,10 +180,18 @@ def _parse_labels(self, values):
index += size
else:
new_values.append(value)
try:
index += len(value)
except:
# A flattened scalar byte value occupies one byte. int covers
# plain ints and IntEnum/IntFlag members (e.g. Flash, Status).
# NB: Python 3.11+ added len() to IntFlag (returns the popcount),
# so we must NOT use len() to size int-like values or the byte
# count desyncs and label pointers land at the wrong address.
if isinstance(value, int):
index += 1
else:
try:
index += len(value)
except TypeError:
index += 1
return new_values

def _update_label_pointers(self):
Expand Down Expand Up @@ -287,10 +300,15 @@ def Write(destination, data, description):
data = flatten(data)
for value in data:
if not isinstance(value, str):
try:
size += len(value)
except TypeError:
# int-like values (incl. IntEnum/IntFlag, whose len() returns a
# popcount on Python 3.11+) occupy one byte each.
if isinstance(value, int):
size += 1
else:
try:
size += len(value)
except TypeError:
size += 1

if isinstance(destination, Bank):
space = Allocate(destination, size, description)
Expand Down