filesize.py 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. # coding: utf-8
  2. """Functions for reporting filesizes. Borrowed from https://github.com/PyFilesystem/pyfilesystem2
  3. The functions declared in this module should cover the different
  4. use cases needed to generate a string representation of a file size
  5. using several different units. Since there are many standards regarding
  6. file size units, three different functions have been implemented.
  7. See Also:
  8. * `Wikipedia: Binary prefix <https://en.wikipedia.org/wiki/Binary_prefix>`_
  9. """
  10. __all__ = ["decimal"]
  11. from typing import Iterable, List, Optional, Tuple
  12. def _to_str(
  13. size: int,
  14. suffixes: Iterable[str],
  15. base: int,
  16. *,
  17. precision: Optional[int] = 1,
  18. separator: Optional[str] = " ",
  19. ) -> str:
  20. if size == 1:
  21. return "1 byte"
  22. elif size < base:
  23. return "{:,} bytes".format(size)
  24. for i, suffix in enumerate(suffixes, 2): # noqa: B007
  25. unit = base**i
  26. if size < unit:
  27. break
  28. return "{:,.{precision}f}{separator}{}".format(
  29. (base * size / unit),
  30. suffix,
  31. precision=precision,
  32. separator=separator,
  33. )
  34. def pick_unit_and_suffix(size: int, suffixes: List[str], base: int) -> Tuple[int, str]:
  35. """Pick a suffix and base for the given size."""
  36. for i, suffix in enumerate(suffixes):
  37. unit = base**i
  38. if size < unit * base:
  39. break
  40. return unit, suffix
  41. def decimal(
  42. size: int,
  43. *,
  44. precision: Optional[int] = 1,
  45. separator: Optional[str] = " ",
  46. ) -> str:
  47. """Convert a filesize in to a string (powers of 1000, SI prefixes).
  48. In this convention, ``1000 B = 1 kB``.
  49. This is typically the format used to advertise the storage
  50. capacity of USB flash drives and the like (*256 MB* meaning
  51. actually a storage capacity of more than *256 000 000 B*),
  52. or used by **Mac OS X** since v10.6 to report file sizes.
  53. Arguments:
  54. int (size): A file size.
  55. int (precision): The number of decimal places to include (default = 1).
  56. str (separator): The string to separate the value from the units (default = " ").
  57. Returns:
  58. `str`: A string containing a abbreviated file size and units.
  59. Example:
  60. >>> filesize.decimal(30000)
  61. '30.0 kB'
  62. >>> filesize.decimal(30000, precision=2, separator="")
  63. '30.00kB'
  64. """
  65. return _to_str(
  66. size,
  67. ("kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"),
  68. 1000,
  69. precision=precision,
  70. separator=separator,
  71. )