Summary
When a string like "1024 B" is passed to the constructor, the "B" is matched by a non-capturing alternative in _RE_STR_PARSE and is not placed in group 2. As a result, m.group(2) is None and the units parameter is not updated from the string. If the caller also passed an explicit units keyword argument, that argument (incorrectly) wins.
Every other unit string in the input (e.g. "KiB", "KB") is captured in group 2 and correctly overrides the units parameter; bare "B" is the only exception.
Reproduction
from fsize import FSize
FSize("1024 B", "MB") # returns 1_024_000 bytes — expected 1_024 bytes
FSize("1024 B", "KiB") # returns 1_048_576 bytes — expected 1_024 bytes
Compare with the consistent behaviour for other unit strings:
FSize("1024 KB", "MB") # correctly uses KB from the string → 1_024_000 bytes
Root cause
src/fsize/__init__.py, lines 55–57 & 93–94:
_RE_STR_PARSE = re.compile(
r"(\d*\.?\d+)\s*(?:([KkMmGgTtPpEe]i?[Bb])|[Bb])?\s*$"
)
The [Bb] alternative is outside the capturing group, so m.group(2) is None for "1024 B".
if m.group(2) is not None:
units = m.group(2) # never reached for bare "B"
Fix
Either extend the capturing group to also include bare "B":
r"(\d*\.?\d+)\s*(?P<unit>[KkMmGgTtPpEe]i?[Bb]|[Bb])?\s*$"
Or explicitly set units = "B" when the number is followed by bare "B" and no prefix letter was captured.
Summary
When a string like
"1024 B"is passed to the constructor, the"B"is matched by a non-capturing alternative in_RE_STR_PARSEand is not placed in group 2. As a result,m.group(2)isNoneand theunitsparameter is not updated from the string. If the caller also passed an explicitunitskeyword argument, that argument (incorrectly) wins.Every other unit string in the input (e.g.
"KiB","KB") is captured in group 2 and correctly overrides theunitsparameter; bare"B"is the only exception.Reproduction
Compare with the consistent behaviour for other unit strings:
Root cause
src/fsize/__init__.py, lines 55–57 & 93–94:The
[Bb]alternative is outside the capturing group, som.group(2)isNonefor"1024 B".Fix
Either extend the capturing group to also include bare
"B":r"(\d*\.?\d+)\s*(?P<unit>[KkMmGgTtPpEe]i?[Bb]|[Bb])?\s*$"Or explicitly set
units = "B"when the number is followed by bare"B"and no prefix letter was captured.