5959 dict (prefix = 't' , divider = 1024 ** 4 , singular = 'TB' , plural = 'TB' ),
6060 dict (prefix = 'p' , divider = 1024 ** 5 , singular = 'PB' , plural = 'PB' ))
6161
62+ # Common disk size units based on IEEE 1541.
63+ disk_size_units_ieee = (dict (prefix = 'b' , divider = 1 , singular = 'byte' , plural = 'bytes' ),
64+ dict (prefix = 'k' , divider = 1000 ** 1 , singular = 'KB' , plural = 'KB' ),
65+ dict (prefix = 'm' , divider = 1000 ** 2 , singular = 'MB' , plural = 'MB' ),
66+ dict (prefix = 'g' , divider = 1000 ** 3 , singular = 'GB' , plural = 'GB' ),
67+ dict (prefix = 't' , divider = 1000 ** 4 , singular = 'TB' , plural = 'TB' ),
68+ dict (prefix = 'p' , divider = 1000 ** 5 , singular = 'PB' , plural = 'PB' ))
69+
6270# Common length size units, used for formatting and parsing.
6371length_size_units = (dict (prefix = 'nm' , divider = 1e-09 , singular = 'nm' , plural = 'nm' ),
6472 dict (prefix = 'mm' , divider = 1e-03 , singular = 'mm' , plural = 'mm' ),
@@ -104,7 +112,7 @@ def coerce_boolean(value):
104112 return bool (value )
105113
106114
107- def format_size (num_bytes , keep_width = False ):
115+ def format_size (num_bytes , keep_width = False , correct = False ):
108116 """
109117 Format a byte count as a human readable file size.
110118
@@ -128,15 +136,20 @@ def format_size(num_bytes, keep_width=False):
128136 '1 MB'
129137 >>> format_size(1024 ** 3 * 4)
130138 '4 GB'
139+ >>> format_size(1000 ** 3 * 4, correct=True)
140+ '4 GB'
131141 """
132- for unit in reversed (disk_size_units ):
142+ units = disk_size_units
143+ if correct :
144+ units = disk_size_units_ieee
145+ for unit in reversed (units ):
133146 if num_bytes >= unit ['divider' ]:
134147 number = round_number (float (num_bytes ) / unit ['divider' ], keep_width = keep_width )
135148 return pluralize (number , unit ['singular' ], unit ['plural' ])
136149 return pluralize (num_bytes , 'byte' )
137150
138151
139- def parse_size (size ):
152+ def parse_size (size , correct = False ):
140153 """
141154 Parse a human readable data size and return the number of bytes.
142155
@@ -155,6 +168,8 @@ def parse_size(size):
155168 5120
156169 >>> parse_size('1.5 GB')
157170 1610612736
171+ >>> parse_size('1.5 GB', correct=True)
172+ 1500000000
158173 """
159174 tokens = tokenize (size )
160175 if tokens and isinstance (tokens [0 ], numbers .Number ):
@@ -165,7 +180,10 @@ def parse_size(size):
165180 if len (tokens ) == 2 and is_string (tokens [1 ]):
166181 normalized_unit = tokens [1 ].lower ()
167182 # Try to match the first letter of the unit.
168- for unit in disk_size_units :
183+ units = disk_size_units
184+ if correct :
185+ units = disk_size_units_ieee
186+ for unit in units :
169187 if normalized_unit .startswith (unit ['prefix' ]):
170188 return int (tokens [0 ] * unit ['divider' ])
171189 # We failed to parse the size specification.
0 commit comments