GitHub

byte_size

API reference for byte_size.

ByteSize: an exact, non-negative number of bytes (Effect's ByteSize).

A ByteSize is an int (Effect's branded bigint), so it compares, hashes, prints and sorts as one; min / max keep the type. Decimal units (kB, MB, ...) are powers of 1,000 and binary units (KiB, MiB, ...) powers of 1,024::

size = byte_size.mebibytes(2)               # 2097152
byte_size.from_string("1.5 kB")             # 1500
byte_size.format(byte_size.bytes(1536))     # "1.5 KiB"

Constructors raise ValueError for what is not a whole, non-negative number of bytes; the from_* parsers give None instead. Arithmetic that can leave the range (subtract, times, divide) gives None too.

AttributeTypeDescription
ByteSize= NewType('ByteSize', int)
zero= ByteSize(0)
kilobytes= _unit('kB')
megabytes= _unit('MB')
gigabytes= _unit('GB')
terabytes= _unit('TB')
petabytes= _unit('PB')
exabytes= _unit('EB')
zettabytes= _unit('ZB')
yottabytes= _unit('YB')
ronnabytes= _unit('RB')
quettabytes= _unit('QB')
kibibytes= _unit('KiB')
mebibytes= _unit('MiB')
gibibytes= _unit('GiB')
tebibytes= _unit('TiB')
pebibytes= _unit('PiB')
exbibytes= _unit('EiB')
zebibytes= _unit('ZiB')
yobibytes= _unit('YiB')

Functions

bytes

bytes(value) -> ByteSize

value bytes. Raises ValueError when it is negative.

ParameterTypeDescription
valueint

Returns ByteSize

def bytes(value: int) -> ByteSize:
    """``value`` bytes. Raises ``ValueError`` when it is negative."""
    if value < 0:
        raise _invalid(f"expected a non-negative bigint, received {value}")
    return ByteSize(value)

from_string_unsafe

from_string_unsafe(text) -> ByteSize

The size text spells ("10 MB", "1.5KiB", "3 kilobytes"). Raises ValueError for other syntax, an unknown unit, or a size that is not a whole number of bytes.

ParameterTypeDescription
textstr

Returns ByteSize

def from_string_unsafe(text: str) -> ByteSize:
    """The size ``text`` spells (``"10 MB"``, ``"1.5KiB"``, ``"3 kilobytes"``).
    Raises ``ValueError`` for other syntax, an unknown unit, or a size that
    is not a whole number of bytes."""
    match = _SYNTAX.fullmatch(text)
    if match is None:
        raise _invalid(f"unsupported syntax {_quote(text)}")
    whole, fraction, unit = match.group(1), match.group(2) or "", match.group(3)
    factor = _UNITS_BY_NAME.get(unit)
    if factor is None:
        raise _invalid(f"unsupported unit {_quote(unit)}")
    numerator = int(whole + fraction) * factor
    scale = 10 ** len(fraction)
    if numerator % scale != 0:
        raise _invalid(f"{_quote(text)} does not represent an integral number of bytes")
    return ByteSize(numerator // scale)

from_string

from_string(text) -> ByteSize | None

from_string_unsafe, with None in place of the error.

ParameterTypeDescription
textstr

Returns ByteSize | None

def from_string(text: str) -> ByteSize | None:
    """``from_string_unsafe``, with ``None`` in place of the error."""
    try:
        return from_string_unsafe(text)
    except ValueError:
        return None

from_input_unsafe

from_input_unsafe(value) -> ByteSize

A size from an int, a safe-integer float or a string. Raises ValueError for anything else or a negative size.

ParameterTypeDescription
valueInput

Returns ByteSize

def from_input_unsafe(value: Input) -> ByteSize:
    """A size from an ``int``, a safe-integer ``float`` or a string.
    Raises ``ValueError`` for anything else or a negative size."""
    if isinstance(value, str):
        return from_string_unsafe(value)
    if isinstance(value, int):
        return bytes(value)
    whole = _safe_integer(value)
    if whole is None or whole < 0:
        raise _invalid(f"expected a non-negative safe integer, received {js_number(value)}")
    return ByteSize(whole)

from_input

from_input(value) -> ByteSize | None

from_input_unsafe, with None in place of the error.

ParameterTypeDescription
valueInput

Returns ByteSize | None

def from_input(value: Input) -> ByteSize | None:
    """``from_input_unsafe``, with ``None`` in place of the error."""
    try:
        return from_input_unsafe(value)
    except ValueError:
        return None

is_byte_size

is_byte_size(value) -> TypeIs[ByteSize]

value is a non-negative int (not a bool).

ParameterTypeDescription
valueobject

Returns TypeIs[ByteSize]

def is_byte_size(value: object) -> TypeIs[ByteSize]:
    """``value`` is a non-negative ``int`` (not a ``bool``)."""
    return isinstance(value, int) and not isinstance(value, bool) and value >= 0

is_zero

is_zero(size) -> bool
ParameterTypeDescription
sizeByteSize

Returns bool

def is_zero(size: ByteSize) -> bool:
    return size == 0

to_unit

to_unit(size, unit) -> float

size in units, as a float (to_unit(kibibytes(3), "KiB") is 3.0).

ParameterTypeDescription
sizeByteSize
unitUnit

Returns float

def to_unit(size: ByteSize, unit: Unit) -> float:
    """``size`` in ``unit``s, as a ``float`` (``to_unit(kibibytes(3), "KiB")``
    is ``3.0``)."""
    return float(size) / float(_FACTORS[unit])

sum

sum(size, that) -> ByteSize

size + that, still a ByteSize.

ParameterTypeDescription
sizeByteSize
thatByteSize

Returns ByteSize

def sum(size: ByteSize, that: ByteSize) -> ByteSize:
    """``size + that``, still a ``ByteSize``."""
    return ByteSize(size + that)

subtract

subtract(size, that) -> ByteSize | None

size - that, or None when that is larger.

ParameterTypeDescription
sizeByteSize
thatByteSize

Returns ByteSize | None

def subtract(size: ByteSize, that: ByteSize) -> ByteSize | None:
    """``size - that``, or ``None`` when ``that`` is larger."""
    return None if size < that else ByteSize(size - that)

subtract_unsafe

subtract_unsafe(size, that) -> ByteSize

size - that. Raises ValueError when that is larger.

ParameterTypeDescription
sizeByteSize
thatByteSize

Returns ByteSize

def subtract_unsafe(size: ByteSize, that: ByteSize) -> ByteSize:
    """``size - that``. Raises ``ValueError`` when ``that`` is larger."""
    if size < that:
        raise ValueError(f"ByteSize subtraction underflow: {size} - {that}")
    return ByteSize(size - that)

times

times(size, multiplier) -> ByteSize | None

size * multiplier, or None unless multiplier is a non-negative whole number.

ParameterTypeDescription
sizeByteSize
multiplierfloat

Returns ByteSize | None

def times(size: ByteSize, multiplier: float) -> ByteSize | None:
    """``size * multiplier``, or ``None`` unless ``multiplier`` is a
    non-negative whole number."""
    value = _scalar(multiplier, 0)
    return None if value is None else ByteSize(size * value)

divide

divide(size, divisor) -> ByteSize | None

size // divisor, or None unless divisor is a positive whole number.

ParameterTypeDescription
sizeByteSize
divisorfloat

Returns ByteSize | None

def divide(size: ByteSize, divisor: float) -> ByteSize | None:
    """``size // divisor``, or ``None`` unless ``divisor`` is a positive
    whole number."""
    value = _scalar(divisor, 1)
    return None if value is None else ByteSize(size // value)

format

format(size, *, precision=2, trailing_zeros=False, system='binary', unit=None) -> str

size as text in the largest unit of system it fills ("1.5 KiB"), or in unit. precision (0 to 20) is the number of decimals, rounded half up; trailing_zeros keeps zeros after the point.

ParameterTypeDescription
sizeByteSize
precisionint = 2
trailing_zerosbool = False
systemLiteral['binary', 'decimal'] = 'binary'
unitUnit | None = None

Returns str

def format(
    size: ByteSize,
    *,
    precision: int = 2,
    trailing_zeros: bool = False,
    system: Literal["binary", "decimal"] = "binary",
    unit: Unit | None = None,
) -> str:
    """``size`` as text in the largest unit of ``system`` it fills
    (``"1.5 KiB"``), or in ``unit``. ``precision`` (0 to 20) is the number of
    decimals, rounded half up; ``trailing_zeros`` keeps zeros after the
    point."""
    if not 0 <= precision <= 20:
        raise ValueError(
            f"ByteSize format precision must be an integer from 0 to 20, received {precision}"
        )
    if unit is not None:
        return _format_with(size, unit, precision, trailing_zeros)
    if size == 0:
        return "0 B"
    units = _DECIMAL if system == "decimal" else _BINARY
    index = len(units) - 1
    while index > 0 and size < units[index][1]:
        index -= 1
    if index < len(units) - 1:
        scale = 10**precision
        factor = units[index][1]
        rounded = (size * scale * 2 + factor) // (factor * 2)
        if rounded >= units[1][1] * scale:
            index += 1
    return _format_with(size, units[index][0], precision, trailing_zeros)