Skip to content

Commit e8c87ba

Browse files
authored
fix parsing of unit strings with 2 letters (fixes #300) (#301)
1 parent 127264d commit e8c87ba

File tree

4 files changed

+67
-5
lines changed

4 files changed

+67
-5
lines changed

.pre-commit-config.yaml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,13 @@ repos:
1010
- id: end-of-file-fixer
1111
- id: trailing-whitespace
1212
- repo: https://github.com/pycqa/isort
13-
rev: 5.13.2
13+
rev: 6.0.0
1414
hooks:
1515
- id: isort
1616
name: isort (python)
1717
args: ["--settings-path", "pyproject.toml"]
1818
- repo: https://github.com/pre-commit/mirrors-mypy
19-
rev: v1.14.1
19+
rev: v1.15.0
2020
hooks:
2121
- id: mypy
2222
args: ["--config-file", "pyproject.toml"]
@@ -27,7 +27,7 @@ repos:
2727
- types-requests
2828
- repo: https://github.com/astral-sh/ruff-pre-commit
2929
# Ruff version.
30-
rev: v0.9.3
30+
rev: v0.9.5
3131
hooks:
3232
# Run the linter.
3333
- id: ruff
@@ -61,7 +61,7 @@ repos:
6161
- id: yamllint
6262
additional_dependencies: [pyyaml]
6363
- repo: https://github.com/codespell-project/codespell
64-
rev: v2.4.0
64+
rev: v2.4.1
6565
hooks:
6666
- id: codespell
6767
additional_dependencies: [tomli]

src/pydistcheck/_utils.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
not specific to package distributions
44
"""
55

6+
import re
67
from typing import Tuple
78

89
# references:
@@ -47,7 +48,10 @@ def from_number(cls, num: int) -> "_FileSize":
4748

4849
@classmethod
4950
def from_string(cls, size_str: str) -> "_FileSize":
50-
return cls(num=float(size_str[:-1]), unit_str=size_str[-1])
51+
parsed = re.search(r"^([0-9\.]+)([A-Za-z]+)$", size_str.strip())
52+
if parsed is None:
53+
raise ValueError(f"Could not parse '{size_str}' as a file size.")
54+
return cls(num=float(parsed.group(1)), unit_str=parsed.group(2))
5155

5256
@property
5357
def total_size_bytes(self) -> int:

tests/test_cli.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,7 @@ def test_check_respects_max_allowed_files(distro_file):
426426
[
427427
"1K",
428428
"3.999K",
429+
"0.005KB",
429430
"0.0002M",
430431
"0.00000008G",
431432
"708B",
@@ -453,11 +454,45 @@ def test_check_respects_max_allowed_size_compressed(size_str, distro_file):
453454
_assert_log_matches_pattern(result, "errors found while checking\\: 1")
454455

455456

457+
@pytest.mark.parametrize(
458+
"size_str",
459+
[
460+
"1",
461+
"K",
462+
"1-KB",
463+
"GB1",
464+
"1G-B",
465+
],
466+
)
467+
@pytest.mark.parametrize(
468+
"cli_arg",
469+
[
470+
"--max-allowed-size-compressed",
471+
"--max-allowed-size-uncompressed",
472+
],
473+
)
474+
def test_check_raises_informative_error_for_malformed_file_size_config(
475+
cli_arg, size_str
476+
):
477+
with pytest.raises(
478+
ValueError, match=rf"Could not parse '{size_str}' as a file size"
479+
):
480+
CliRunner().invoke(
481+
check,
482+
[
483+
os.path.join(TEST_DATA_DIR, BASE_PACKAGES[0]),
484+
f"{cli_arg}={size_str}",
485+
],
486+
catch_exceptions=False,
487+
)
488+
489+
456490
@pytest.mark.parametrize(
457491
"size_str",
458492
[
459493
"1K",
460494
"3.999K",
495+
"0.005KB",
461496
"0.0002M",
462497
"0.00000008G",
463498
"708B",

tests/test_utils.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,29 @@ def test_file_size_from_different_inputs_all_parsed_consistently(file_size):
5858
assert file_size == _FileSize(num=3.0, unit_str="M")
5959

6060

61+
def test_file_size_from_string_works():
62+
# 1 letter
63+
assert _FileSize.from_string("57B").total_size_bytes == 57
64+
assert _FileSize.from_string("57K").total_size_bytes == 57 * 1024
65+
assert _FileSize.from_string("57M").total_size_bytes == 57 * 1024**2
66+
assert _FileSize.from_string("57G").total_size_bytes == 57 * 1024**3
67+
68+
# 2 letter
69+
assert _FileSize.from_string("57KB").total_size_bytes == 57 * 1e3
70+
assert _FileSize.from_string("57MB").total_size_bytes == 57 * 1e6
71+
assert _FileSize.from_string("57GB").total_size_bytes == 57 * 1e9
72+
73+
# decimals
74+
assert _FileSize.from_string("0.005GB").total_size_bytes == 0.005 * 1e9
75+
assert _FileSize.from_string("0.05GB").total_size_bytes == 0.05 * 1e9
76+
assert _FileSize.from_string("0.5GB").total_size_bytes == 0.5 * 1e9
77+
assert _FileSize.from_string("5.0GB").total_size_bytes == 5 * 1e9
78+
assert _FileSize.from_string("5.000GB").total_size_bytes == 5 * 1e9
79+
assert _FileSize.from_string("5.1GB").total_size_bytes == 5.1 * 1e9
80+
assert _FileSize.from_string("5.17GB").total_size_bytes == 5.17 * 1e9
81+
assert _FileSize.from_string("5.234GB").total_size_bytes == 5.234 * 1e9
82+
83+
6184
def test_file_size_from_number_switches_unit_str_based_on_size():
6285
assert _FileSize.from_number(1.1) == _FileSize(num=1.1, unit_str="B")
6386
# fractional bytes don't make sense here, so some rounding happens

0 commit comments

Comments
 (0)