Skip to content

Reimplement naturalsize as part of pubtools-pulplib [RHELDST-29440] #232

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 26, 2025
Merged
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
1 change: 0 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,4 @@ attrs
frozenlist2
frozendict; python_version >= '3.6'
pubtools>=0.3.0
humanize
monotonic; python_version < '3.3'
3 changes: 1 addition & 2 deletions src/pubtools/pulplib/_impl/client/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,11 @@
Task,
)
from ..log import TimedLogger
from ..util import dict_put
from ..util import dict_put, naturalsize
from .search import search_for_criteria
from .errors import PulpException
from .poller import TaskPoller
from . import retry
from humanize import naturalsize

from .ud_mappings import compile_ud_mappings
from .copy import CopyOptions
Expand Down
28 changes: 28 additions & 0 deletions src/pubtools/pulplib/_impl/util.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
ABSENT = object()
SUFFIXES = ("k", "M", "G", "T", "P", "E")


def lookup(value, key, default=ABSENT):
Expand Down Expand Up @@ -47,3 +48,30 @@ def dict_put(out, key, value):
else:
# Not the last key, so ensure there's a sub-dict.
out = out.setdefault(next_key, {})


def naturalsize(value):
"""
Format a number of bytes like a human-readable filesize.
Uses SI system (metric), so e.g. 10000 B = 10 kB.
"""
base = 1000

if isinstance(value, str):
size_bytes = float(value)
else:
size_bytes = value
abs_bytes = abs(size_bytes)

if abs_bytes == 1:
return f"{size_bytes} Byte"
if abs_bytes < base:
return f"{int(size_bytes)} Bytes"

suffix = ""
for power, suffix in enumerate(SUFFIXES, 2):
unit = base**power
if abs_bytes < unit:
break
size_natural = base * (size_bytes / unit)
return f"{size_natural:.1f} {suffix}B"
22 changes: 22 additions & 0 deletions tests/util/test_naturalsize.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import pytest

from pubtools.pulplib._impl.util import naturalsize


@pytest.mark.parametrize(
"input,output",
[
(1, "1 Byte"),
("10", "10 Bytes"),
(1234, "1.2 kB"),
(1234567, "1.2 MB"),
(678909876543, "678.9 GB"),
(1000000000000, "1.0 TB"),
("874365287928728746529431", "874365.3 EB"),
],
)
def test_naturalsize(input, output):
"""
Format a number of bytes like a human-readable filesize.
"""
assert naturalsize(input) == output