Skip to content

Storage Class

Storage(value: Union[int, float, str, Decimal], unit: StorageUnit = StorageUnit.AUTO)

A class representing storage with different units.

This class provides methods for converting between different storage units, performing arithmetic operations, and comparing storage sizes. It also includes methods for getting the size of files or directories and parsing storage values from strings.

Attributes:

Name Type Description
value float

The numerical value of the storage as float (backward compatibility).

decimal_value Decimal

The exact decimal value with full precision.

unit StorageUnit

The unit of the storage value.

Class Attributes

_decimal_precision (int): Maximum number of decimal places to display (default: 20).

Decimal Precision

The Storage class uses Python's Decimal module internally to provide exact decimal precision, eliminating floating-point rounding errors. This ensures that values like "6.682" are stored and displayed exactly as "6.682" rather than "6.68200000000000038369".

  • value property: Returns float for backward compatibility
  • decimal_value property: Returns exact Decimal for precision-critical applications
  • String representations use exact decimal formatting

Examples:

>>> storage = Storage(1, StorageUnit.KIB)
>>> print(storage.convert_to_bytes())
1024.0
>>> total = Storage(512, StorageUnit.BYTES) + Storage(1, StorageUnit.KIB)
>>> print(total)
1536.0 BYTES
>>> parsed = Storage.parse("1.5 MB")
>>> print(parsed)
1.5 MB
>>> # Exact decimal precision examples
>>> precise = Storage("6.682", StorageUnit.MB)
>>> print(precise)  # Exact output: 6.682 MB
6.682 MB
>>> precise.decimal_value  # Exact decimal
Decimal('6.682')
>>> precise.value  # Float for compatibility
6.682
>>> # Decimal arithmetic maintains precision
>>> a = Storage("1.1", StorageUnit.GB)
>>> b = Storage("2.2", StorageUnit.GB)
>>> result = a + b
>>> print(result)  # Exact: 3.3 GB
3.3 GB
>>> result.decimal_value
Decimal('3.3')
>>> # Configure decimal precision for display
>>> Storage.set_decimal_precision(10)
>>> small = Storage("0.000123456789012345", StorageUnit.GB)
>>> print(small)  # Will show up to 10 decimal places
0.0001234567890 GB

Parameters:

Name Type Description Default
value Union[int, float, str, Decimal]

The numerical value of the storage, or a string to parse (e.g., "1MB"). Can be int, float, str, or Decimal for exact precision.

required
unit StorageUnit

The unit of the storage value. Defaults to StorageUnit.AUTO for automatic parsing.

AUTO

Raises:

Type Description
TypeError

If value is not a number or string, or unit is not a StorageUnit.

ValueError

If value is negative or parsing fails.

Examples:

>>> storage = Storage(1024, StorageUnit.BYTES)
>>> print(storage)
1024 BYTES
>>> storage = Storage("1.5 MB")  # Automatic parsing
>>> print(storage)
1.5 MB
>>> storage = Storage("2048")  # Defaults to bytes when no unit specified
>>> print(storage)
2048 BYTES
>>> # Using Decimal for exact precision
>>> from decimal import Decimal
>>> storage = Storage(Decimal("6.682"), StorageUnit.MB)
>>> print(storage)
6.682 MB
>>> storage.decimal_value
Decimal('6.682')

Attributes

value: float property

Get the storage value as a float for backward compatibility.

This property maintains backward compatibility with existing code that expects float values. For applications requiring exact decimal precision, use the decimal_value property instead.

Returns:

Name Type Description
float float

The storage value converted to float.

Note

Converting to float may introduce small precision errors for values that cannot be exactly represented in IEEE 754 floating-point format. Use decimal_value for exact precision.

Examples:

>>> storage = Storage("6.682", StorageUnit.MB)
>>> storage.value  # Returns float (may have tiny precision loss)
6.682
>>> storage.decimal_value  # Returns exact Decimal
Decimal('6.682')

decimal_value: Decimal property

Get the exact decimal value with full precision.

This property provides access to the internal Decimal representation that maintains exact precision for all decimal operations. Use this when you need guaranteed precision without any floating-point rounding errors.

Returns:

Name Type Description
Decimal Decimal

The exact decimal value without precision loss.

Examples:

>>> storage = Storage("6.682", StorageUnit.MB)
>>> storage.decimal_value
Decimal('6.682')
>>> 
>>> # Decimal arithmetic maintains exact precision
>>> a = Storage("1.1", StorageUnit.GB)
>>> b = Storage("2.2", StorageUnit.GB)
>>> (a + b).decimal_value
Decimal('3.3')
>>>
>>> # Compare with float precision
>>> (a + b).value  # May show: 3.3000000000000003
3.3
Note

This is the recommended property for financial calculations, scientific applications, or any context where exact decimal precision is required.

BYTES: Storage property

Property to convert to bytes.

KIB: Storage property

Property to convert to kibibytes (KiB).

MIB: Storage property

Property to convert to mebibytes (MiB).

GIB: Storage property

Property to convert to gibibytes (GiB).

TIB: Storage property

Property to convert to tebibytes (TiB).

PIB: Storage property

Property to convert to pebibytes (PiB).

EIB: Storage property

Property to convert to exbibytes (EiB).

ZIB: Storage property

Property to convert to zebibytes (ZiB).

YIB: Storage property

Property to convert to yobibytes (YiB).

KB: Storage property

Property to convert to kilobytes (KB).

MB: Storage property

Property to convert to megabytes (MB).

GB: Storage property

Property to convert to gigabytes (GB).

TB: Storage property

Property to convert to terabytes (TB).

PB: Storage property

Property to convert to petabytes (PB).

EB: Storage property

Property to convert to exabytes (EB).

ZB: Storage property

Property to convert to zettabytes (ZB).

YB: Storage property

Property to convert to yottabytes (YB).

BITS: Storage property

Property to convert to bits.

KILOBITS: Storage property

Property to convert to kilobits.

MEGABITS: Storage property

Property to convert to megabits.

GIGABITS: Storage property

Property to convert to gigabits.

TERABITS: Storage property

Property to convert to terabits.

Functions

set_decimal_precision(precision: int) -> None classmethod

Set the maximum number of decimal places to display in string representations.

This affects how numbers are formatted when converting Storage objects to strings, preventing scientific notation and allowing for precise decimal display.

Parameters:

Name Type Description Default
precision int

Maximum number of decimal places to display. Must be >= 0.

required

Raises:

Type Description
TypeError

If precision is not an integer.

ValueError

If precision is negative.

Examples:

>>> Storage.set_decimal_precision(5)
>>> small = Storage(0.000123456789, StorageUnit.GB)  
>>> print(small)  # Will show: 0.00012 GB
>>> Storage.set_decimal_precision(15)
>>> print(small)  # Will show: 0.000123456789000 GB

get_decimal_precision() -> int classmethod

Get the current maximum number of decimal places used in string representations.

Returns:

Name Type Description
int int

Current decimal precision setting.

Examples:

>>> Storage.set_decimal_precision(10)
>>> print(Storage.get_decimal_precision())
10

parse_from_bytes(value: Union[int, float, Decimal]) -> Storage classmethod

Create a Storage instance from a value in bytes.

Parameters:

Name Type Description Default
value Union[int, float, Decimal]

The value in bytes.

required

Returns:

Name Type Description
Storage Storage

A Storage instance with the value in bytes.

Raises:

Type Description
TypeError

If value is not a number.

ValueError

If value is negative.

Examples:

>>> storage = Storage.parse_from_bytes(1024)
>>> print(storage)
1024 BYTES

convert_to_bytes() -> Decimal

Convert the storage value to bytes with exact decimal precision.

This method returns a Decimal object to maintain exact precision during conversion operations. For backward compatibility with code expecting float values, you can convert the result using float().

Returns:

Name Type Description
Decimal Decimal

The value in bytes with exact precision.

Examples:

>>> storage = Storage(1, StorageUnit.KIB)
>>> storage.convert_to_bytes()
Decimal('1024')
>>> 
>>> # For float compatibility
>>> float(storage.convert_to_bytes())
1024.0
>>>
>>> # Exact decimal precision maintained
>>> precise = Storage("1.5", StorageUnit.KB)
>>> precise.convert_to_bytes()
Decimal('1500')

convert_to(target_unit: StorageUnit) -> Storage

Convert the storage to a different unit.

Parameters:

Name Type Description Default
target_unit StorageUnit

The unit to convert to.

required

Returns:

Name Type Description
Storage Storage

A new Storage instance with the converted value.

Examples:

>>> storage = Storage(1024, StorageUnit.BYTES)
>>> converted = storage.convert_to(StorageUnit.KIB)
>>> print(converted)
1.0 KIB

convert_to_kib() -> Storage

Convert to kibibytes (KiB) - binary unit (1024 bytes).

Returns:

Name Type Description
Storage Storage

New Storage object with value in KiB.

Example

storage = Storage(2048, StorageUnit.BYTES) kib_storage = storage.convert_to_kib() print(kib_storage) 2.0 KIB

convert_to_mib() -> Storage

Convert to mebibytes (MiB) - binary unit (1024^2 bytes).

Returns:

Name Type Description
Storage Storage

New Storage object with value in MiB.

Example

storage = Storage(1, StorageUnit.GIB) mib_storage = storage.convert_to_mib() print(mib_storage) 1024.0 MIB

convert_to_gib() -> Storage

Convert to gibibytes (GiB) - binary unit (1024^3 bytes).

Returns:

Name Type Description
Storage Storage

New Storage object with value in GiB.

Example

storage = Storage(2048, StorageUnit.MIB) gib_storage = storage.convert_to_gib() print(gib_storage) 2.0 GIB

convert_to_tib() -> Storage

Convert to tebibytes (TiB) - binary unit (1024^4 bytes).

Returns:

Name Type Description
Storage Storage

New Storage object with value in TiB.

Example

storage = Storage(1024, StorageUnit.GIB) tib_storage = storage.convert_to_tib() print(tib_storage) 1.0 TIB

convert_to_pib() -> Storage

Convert to pebibytes (PiB) - binary unit (1024^5 bytes).

Returns:

Name Type Description
Storage Storage

New Storage object with value in PiB.

Example

storage = Storage(1024, StorageUnit.TIB) pib_storage = storage.convert_to_pib() print(pib_storage) 1.0 PIB

convert_to_eib() -> Storage

Convert to exbibytes (EiB) - binary unit (1024^6 bytes).

Returns:

Name Type Description
Storage Storage

New Storage object with value in EiB.

Example

storage = Storage(1024, StorageUnit.PIB) eib_storage = storage.convert_to_eib() print(eib_storage) 1.0 EIB

convert_to_zib() -> Storage

Convert to zebibytes (ZiB) - binary unit (1024^7 bytes).

Returns:

Name Type Description
Storage Storage

New Storage object with value in ZiB.

Example

storage = Storage(1024, StorageUnit.EIB) zib_storage = storage.convert_to_zib() print(zib_storage) 1.0 ZIB

convert_to_yib() -> Storage

Convert to yobibytes (YiB) - binary unit (1024^8 bytes).

Returns:

Name Type Description
Storage Storage

New Storage object with value in YiB.

Example

storage = Storage(1024, StorageUnit.ZIB) yib_storage = storage.convert_to_yib() print(yib_storage) 1.0 YIB

convert_to_kb() -> Storage

Convert to kilobytes (KB) - decimal unit (1000 bytes).

Returns:

Name Type Description
Storage Storage

New Storage object with value in KB.

Example

storage = Storage(2000, StorageUnit.BYTES) kb_storage = storage.convert_to_kb() print(kb_storage) 2.0 KB

convert_to_mb() -> Storage

Convert to megabytes (MB) - decimal unit (1000^2 bytes).

Returns:

Name Type Description
Storage Storage

New Storage object with value in MB.

Example

storage = Storage(1, StorageUnit.GB) mb_storage = storage.convert_to_mb() print(mb_storage) 1000.0 MB

convert_to_gb() -> Storage

Convert to gigabytes (GB) - decimal unit (1000^3 bytes).

Returns:

Name Type Description
Storage Storage

New Storage object with value in GB.

Example

storage = Storage(2000, StorageUnit.MB) gb_storage = storage.convert_to_gb() print(gb_storage) 2.0 GB

convert_to_tb() -> Storage

Convert to terabytes (TB) - decimal unit (1000^4 bytes).

Returns:

Name Type Description
Storage Storage

New Storage object with value in TB.

Example

storage = Storage(1000, StorageUnit.GB) tb_storage = storage.convert_to_tb() print(tb_storage) 1.0 TB

convert_to_pb() -> Storage

Convert to petabytes (PB) - decimal unit (1000^5 bytes).

Returns:

Name Type Description
Storage Storage

New Storage object with value in PB.

Example

storage = Storage(1000, StorageUnit.TB) pb_storage = storage.convert_to_pb() print(pb_storage) 1.0 PB

convert_to_eb() -> Storage

Convert to exabytes (EB) - decimal unit (1000^6 bytes).

Returns:

Name Type Description
Storage Storage

New Storage object with value in EB.

Example

storage = Storage(1000, StorageUnit.PB) eb_storage = storage.convert_to_eb() print(eb_storage) 1.0 EB

convert_to_zb() -> Storage

Convert to zettabytes (ZB) - decimal unit (1000^7 bytes).

Returns:

Name Type Description
Storage Storage

New Storage object with value in ZB.

Example

storage = Storage(1000, StorageUnit.EB) zb_storage = storage.convert_to_zb() print(zb_storage) 1.0 ZB

convert_to_yb() -> Storage

Convert to yottabytes (YB) - decimal unit (1000^8 bytes).

Returns:

Name Type Description
Storage Storage

New Storage object with value in YB.

Example

storage = Storage(1000, StorageUnit.ZB) yb_storage = storage.convert_to_yb() print(yb_storage) 1.0 YB

convert_to_bits() -> Storage

Convert to bits - smallest unit (⅛ byte).

Returns:

Name Type Description
Storage Storage

New Storage object with value in bits.

Example

storage = Storage(1, StorageUnit.BYTES) bits_storage = storage.convert_to_bits() print(bits_storage) 8.0 BITS

convert_to_kilobits() -> Storage

Convert to kilobits - decimal bit unit (1000 bits).

Returns:

Name Type Description
Storage Storage

New Storage object with value in kilobits.

Example

storage = Storage(1, StorageUnit.KB) kbits_storage = storage.convert_to_kilobits() print(kbits_storage) 8.0 KILOBITS

convert_to_megabits() -> Storage

Convert to megabits - decimal bit unit (1000^2 bits).

Returns:

Name Type Description
Storage Storage

New Storage object with value in megabits.

Example

storage = Storage(1, StorageUnit.MB) mbits_storage = storage.convert_to_megabits() print(mbits_storage) 8.0 MEGABITS

convert_to_gigabits() -> Storage

Convert to gigabits - decimal bit unit (1000^3 bits).

Returns:

Name Type Description
Storage Storage

New Storage object with value in gigabits.

Example

storage = Storage(1, StorageUnit.GB) gbits_storage = storage.convert_to_gigabits() print(gbits_storage) 8.0 GIGABITS

convert_to_terabits() -> Storage

Convert to terabits - decimal bit unit (1000^4 bits).

Returns:

Name Type Description
Storage Storage

New Storage object with value in terabits.

Example

storage = Storage(1, StorageUnit.TB) tbits_storage = storage.convert_to_terabits() print(tbits_storage) 8.0 TERABITS

parse(string: str, default_unit: Optional[StorageUnit] = None) -> Storage classmethod

Parse a string to create a Storage instance.

The string should be in the format "value unit", where value is a number and unit is one of the supported storage units. The parsing is: - Case insensitive - Supports both '.' and ',' as decimal separators
- Supports spaces and no spaces between value and unit - Uses bytes as default unit if unit is not recognized or provided

Parameters:

Name Type Description Default
string str

A string representing the storage value.

required
default_unit Optional[StorageUnit]

The unit to use if no unit is found or recognized. Defaults to StorageUnit.BYTES.

None

Returns:

Name Type Description
Storage Storage

A Storage instance.

Raises:

Type Description
ValueError

If the input string is invalid or cannot be parsed.

Examples:

>>> storage = Storage.parse("1.5 MB")
>>> print(storage)
1.5 MB
>>> storage = Storage.parse("1,024 KiB")
>>> print(storage) 
1024.0 KIB
>>> storage = Storage.parse("500")  # defaults to bytes
>>> print(storage)
500.0 BYTES

get_size_from_path(path: Union[str, Path]) -> Storage staticmethod

Get the size of a file or directory from the given path.

This method calculates the total size of a file or directory (including all subdirectories and files) using pathlib.

Parameters:

Name Type Description Default
path Union[str, Path]

The path to the file or directory (string or Path object).

required

Returns:

Name Type Description
Storage Storage

A Storage instance representing the total size in bytes.

Raises:

Type Description
FileNotFoundError

If the path does not exist.

PermissionError

If access to the path is denied.

OSError

If an OS-level error occurs while accessing the path.

Examples:

>>> size = Storage.get_size_from_path("/path/to/file.txt")
>>> print(size)
1024.0 BYTES
>>> dir_size = Storage.get_size_from_path("/path/to/directory")
>>> print(dir_size.auto_scale())
15.2 MIB

get_platform_storage() -> Storage staticmethod

Get the appropriate platform-specific storage instance.

This method automatically detects the current platform and returns the corresponding storage handler that may include platform-specific optimizations for file size retrieval.

Returns:

Type Description
Storage

Storage subclass: A platform-specific storage instance.

Raises:

Type Description
ValueError

If the platform is not supported.

Examples:

>>> platform_storage = Storage.get_platform_storage()
>>> size = platform_storage.get_size_from_path("/some/path")

auto_scale(prefer_binary: bool = True) -> Storage

Automatically scale the storage to the most appropriate unit.

This method converts the storage to a unit that results in a value between 1 and 1024 (for binary) or 1000 (for decimal), making it more human-readable.

Parameters:

Name Type Description Default
prefer_binary bool

If True, prefer binary units (KiB, MiB, etc.). If False, prefer decimal units (KB, MB, etc.).

True

Returns:

Name Type Description
Storage Storage

A new Storage instance with an appropriate unit.

Examples:

>>> storage = Storage(1536, StorageUnit.BYTES)
>>> scaled = storage.auto_scale()
>>> print(scaled)
1.5 KIB