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
4 changes: 4 additions & 0 deletions barcode/codex.py
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,10 @@ def _calculate_checksum(self, encoded: list[int]) -> int:
return sum(cs) % 103

def _build(self) -> list[int]:
# Reset the state that gets mutated while building so that repeated
# calls on the same instance are deterministic (see #143).
self._charset = "C"
self._digit_buffer = ""
encoded: list[int] = [code128.START_CODES[self._charset]]
for i, char in enumerate(self.code):
encoded.extend(self._maybe_switch_charset(i))
Expand Down
31 changes: 31 additions & 0 deletions tests/test_code128.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
from __future__ import annotations

from barcode.codex import Code128


def test_build_is_stable_across_repeated_calls() -> None:
"""Calling build() repeatedly on the same instance must be deterministic.

Regression test for #143: ``_build`` mutated ``_charset`` and
``_digit_buffer`` without resetting them, so a second call started from
stale state and produced a different bit string.
"""
code = Code128("12A")
first = code.build()
assert code.build() == first
assert code.build() == first


def test_encoded_is_stable_across_repeated_calls() -> None:
"""The ``encoded`` property must also be deterministic across calls."""
code = Code128("12A")
first = code.encoded
assert code.encoded == first
assert code.encoded == first


def test_reused_instance_matches_fresh_instance() -> None:
"""A reused instance must encode identically to a freshly built one."""
reused = Code128("123ABC456")
reused.build() # dirties the internal charset/buffer state
assert reused.build() == Code128("123ABC456").build()