def test_bitmath_div_number_is_bitmath(self): """bitmath / number = bitmath""" bm1 = bitmath.KiB(1) num1 = 2 result = bm1 / num1 self.assertEqual(result, bitmath.KiB(0.5)) self.assertIs(type(result), bitmath.KiB)
def test_number_mul_bitmath_is_number(self): """number * bitmath = bitmath""" num1 = 2 bm1 = bitmath.KiB(1) result = num1 * bm1 self.assertEqual(result, bitmath.KiB(2.0)) self.assertIs(type(result), bitmath.KiB)
def test_bitmath_mul_bitmath_is_bitmath(self): """bitmath * bitmath = bitmath""" bm1 = bitmath.KiB(1) bm2 = bitmath.KiB(2) result = bm1 * bm2 self.assertEqual(result, bitmath.KiB(2048.0)) self.assertIs(type(result), bitmath.KiB)
def test_with_format(self): """bitmath.format context mgr sets and restores formatting""" to_print = [ bitmath.Byte(101), bitmath.KiB(202), bitmath.MB(303), bitmath.GiB(404), bitmath.TB(505), bitmath.PiB(606), bitmath.EB(707) ] str_reps = [ "101.00-Byte", "202.00-KiB", "303.00-MB", "404.00-GiB", "505.00-TB", "606.00-PiB", "707.00-EB" ] # Make sure formatting looks right BEFORE the context manager self.assertEqual(str(bitmath.KiB(1.337)), "1.337 KiB") with bitmath.format("{value:.2f}-{unit}"): for (inst, inst_str) in zip(to_print, str_reps): self.assertEqual(str(inst), inst_str) # Make sure formatting looks right AFTER the context manager self.assertEqual(str(bitmath.KiB(1.337)), "1.337 KiB")
def test_subtracting_with_different_base_units(self): """Subtracting a bit based type with a byte based type""" kib_sized_bit_from_bytes = bitmath.Bit(self.kib_in_bits) kib = bitmath.KiB(1) subtracted = kib_sized_bit_from_bytes - kib zero_kib = bitmath.KiB(0) self.assertEqual(subtracted, zero_kib)
def test_bitmath_sub_bitmath_is_bitmath(self): """bitmath - bitmath = bitmath""" bm1 = bitmath.KiB(1) bm2 = bitmath.KiB(2) result = bm1 - bm2 self.assertEqual(result, bitmath.KiB(-1)) self.assertIs(type(result), bitmath.KiB)
def test_add_same_type_equal_same_type(self): """Adding the same bitmath types is equal to result as the same type""" kib1 = bitmath.KiB(1) kib2 = bitmath.KiB(1) added_two_kib = kib1 + kib2 two_kib = bitmath.KiB(2) self.assertEqual(added_two_kib, two_kib)
def test_bitmath_div_bitmath_is_number(self): """bitmath / bitmath = number""" bm1 = bitmath.KiB(1) bm2 = bitmath.KiB(2) result = bm1 / bm2 self.assertEqual(result, 0.5) self.assertIs(type(result), float)
def test_adding_with_different_base_units(self): """Adding a bit based type with a byte based type""" kib_sized_bit_from_bytes = bitmath.Bit(self.kib_in_bits) kib = bitmath.KiB(1) added = kib_sized_bit_from_bytes + kib two_kib = bitmath.KiB(2) self.assertEqual(added, two_kib)
def test_parse_string_unsafe_request_NIST(self): """parse_string_unsafe can convert to NIST on request""" unsafe_input = "100M" _parsed = bitmath.parse_string_unsafe(unsafe_input, system=bitmath.NIST) expected = bitmath.MiB(100) self.assertEqual(_parsed, expected) self.assertIs(type(_parsed), type(expected)) unsafe_input2 = "100k" _parsed2 = bitmath.parse_string_unsafe(unsafe_input2, system=bitmath.NIST) expected2 = bitmath.KiB(100) self.assertEqual(_parsed2, expected2) self.assertIs(type(_parsed2), type(expected2)) unsafe_input3 = "100" _parsed3 = bitmath.parse_string_unsafe(unsafe_input3, system=bitmath.NIST) expected3 = bitmath.Byte(100) self.assertEqual(_parsed3, expected3) self.assertIs(type(_parsed3), type(expected3)) unsafe_input4 = "100kb" _parsed4 = bitmath.parse_string_unsafe(unsafe_input4, system=bitmath.NIST) expected4 = bitmath.KiB(100) self.assertEqual(_parsed4, expected4) self.assertIs(type(_parsed4), type(expected4))
def test_bitmath_mul_number_is_bitmath(self): """bitmath * number = bitmath""" bm1 = bitmath.KiB(1) num1 = 2 result = bm1 * num1 self.assertEqual(result, bitmath.KiB(2)) self.assertIs(type(result), bitmath.KiB)
def bitmath_add_bitmath_is_bitmath(self): """bitmath + bitmath = bitmath""" bm1 = bitmath.KiB(1) bm2 = bitmath.KiB(2) result = bm1 + bm2 self.assertEqual(result, bitmath.KiB(3)) self.assertIs(type(result), bitmath.Byte)
def test_number_sub_bitmath_is_number(self): """number - bitmath = number""" num1 = 2 bm1 = bitmath.KiB(1) result = num1 - bm1 self.assertEqual(result, 1.0) self.assertIs(type(result), float)
def test_number_add_bitmath_is_number(self): """number + bitmath = number""" num1 = 2 bm1 = bitmath.KiB(1) result = num1 + bm1 self.assertEqual(result, 3.0) self.assertIs(type(result), float)
def test_bitmath_add_number_is_number(self): """bitmath + number = number""" bm1 = bitmath.KiB(1) num1 = 2 result = bm1 + num1 self.assertEqual(result, 3.0) self.assertIs(type(result), float)
def test_BitmathType_good_spaces_in_value(self): """Argparse: BitmathType - 'Quoted values' can be separated from the units by whitespace""" args = "--two-args '100 MiB' '200 KiB'" result = self._parse_two_args(args) self.assertEqual(len(result.two_args), 2) self.assertIn(bitmath.MiB(100), result.two_args) self.assertIn(bitmath.KiB(200), result.two_args)
def test_parse_unsafe_NIST(self): """parse_string_unsafe can parse all accepted NIST inputs""" # Begin with the kilo unit because it's the most tricky (SI # defines the unit as a lower-case 'k') kilo_inputs = [ '100ki', '100Ki', '100kib', '100KiB', '100kiB' ] expected_kilo_result = bitmath.KiB(100) for ki in kilo_inputs: _parsed = bitmath.parse_string_unsafe(ki) self.assertEqual(_parsed, expected_kilo_result) self.assertIs(type(_parsed), type(expected_kilo_result)) # Now check for other easier to parse prefixes other_inputs = [ '100gi', '100Gi', '100gib', '100giB', '100GiB' ] expected_gig_result = bitmath.GiB(100) for gi in other_inputs: _parsed = bitmath.parse_string_unsafe(gi) self.assertEqual(_parsed, expected_gig_result) self.assertIs(type(_parsed), type(expected_gig_result))
def test_number_truediv_bitmath_is_number(self): """truediv: number // bitmath = number""" num1 = 2 bm1 = bitmath.KiB(1) result = bm1.__rdiv__(num1) self.assertEqual(result, 2.0) self.assertIs(type(result), float)
def test_bitmath_sub_number_is_number(self): """bitmath - number = number""" bm1 = bitmath.KiB(1) num1 = 2 result = bm1 - num1 self.assertEqual(result, -1.0) self.assertIs(type(result), float)
def test_longer_formatting_string(self): """KiB(12345) as a MiB (12.0556640625) truncates to 5 digits""" expected_result = "12.05566 MiB" fmt_str = "{value:.5f} {unit}" instance = bitmath.KiB(12345).to_MiB() actual_result = instance.format(fmt_str) self.assertEqual(expected_result, actual_result)
def kib_to_bytes(size): """Convert KiB to size in bytes. :param size: The number of Kilobytes. :returns: The size in Kilobytes. """ return bitmath.KiB(size).to_Byte().value
def test_cli_script_main_from_unit(self): """CLI script returns correct if given FROM units""" args = ['-f', 'MiB', '0.5'] # Testing FROM 0.5 MiB TO best human readable unit (512 KiB) results = bitmath.cli_script_main(args) self.assertEqual(results[0], bitmath.KiB(512)) self.assertIs(type(results[0]), bitmath.KiB)
def test_number_div_bitmath_is_number(self): """number / bitmath = number""" num1 = 2 bm1 = bitmath.KiB(1) result = num1 / bm1 self.assertEqual(result, 2.0) self.assertIs(type(result), float)
def test_init_bytes(self): """Instantiation works with the 'bytes' kw arg""" bm = bitmath.Byte(bytes=1024) # 1024 bytes is 1 KiB, these should be equal self.assertEqual(bm, bitmath.KiB(1)) self.assertEqual(bm.bytes, 1024)
def __init__( self, *, obj_store: Optional[ObjStore] = None, replacement_policy: Union[str, ReplacementPolicy] = "gdsize", size: Union[int, str, bitmath.Bitmath] = bitmath.KiB(100), pickler: Pickler = pickle, lock: Optional[RWLock] = None, fine_grain_persistence: bool = False, fine_grain_eviction: bool = False, extra_system_state: Callable[[], Any] = Constant(None), temporary: bool = False, ) -> None: """Construct a memoized group. Use with :py:function:Memoized. :param obj_store: The object store to use for return values. :param replacement_policy: See policies submodule for options. You can pass an object conforming to the ReplacementPolicy protocol or one of REPLACEMENT_POLICIES. :param size: The size as an int (in bytes), as a string (e.g. "3 MiB"), or as a `bitmath.Bitmath`_. :param pickler: A de/serialization to use on the index, conforming to the Pickler protocol. :param lock: A ReadersWriterLock to achieve exclusion. If the lock is wrong but the obj_store is atomic, then the memoization is still *correct*, but it may not be able to borrow values that another machine computed. Defaults to a FileRWLock. :param fine_grain_persistence: De/serialize the index at every access. This is useful if you need to update the cache for multiple simultaneous processes, but it compromises performance in the single-process case. :param fine_grain_eviction: Maintain the cache's size through eviction at every access (rather than just the de/serialization points). This is useful if the caches size would not otherwise fit in memory, but it compromises performance if not needed. :param extra_system_state: A callable that returns "extra" system state. If the system state changes, the cache is dumped. :param temporary: Whether the cache should be cleared at the end of the process; This is useful for tests. .. _`bitmath.Bitmath`: https://pypi.org/project/bitmath/ """ self._obj_store = ( obj_store if obj_store is not None else DirObjStore(path=DEFAULT_OBJ_STORE_PATH) ) self._replacement_policy = ( REPLACEMENT_POLICIES[replacement_policy.lower()]() if isinstance(replacement_policy, str) else replacement_policy ) self._size = ( size if isinstance(size, bitmath.Bitmath) else bitmath.Byte(size) if isinstance(size, int) else bitmath.parse_string(size) ) self._pickler = pickler self._index_lock = lock if lock is not None else FileRWLock(DEFAULT_LOCK_PATH) self._fine_grain_persistence = fine_grain_persistence self._fine_grain_eviction = fine_grain_eviction self._extra_system_state = extra_system_state self._index_key = 0 self.time_cost = DefaultDict[str, datetime.timedelta](datetime.timedelta) self.time_saved = DefaultDict[str, datetime.timedelta](datetime.timedelta) self.temporary = temporary self.__setstate__({}) if self.temporary: atexit.register(self._obj_store.clear) # atexit handlers are run in the opposite order they are registered. atexit.register(self._index_write)
def test_add_different_types_equal_bitmath_type(self): """Adding two different bitmath types is equal to another type of the same size""" # One Kibibyte + 1024 Bytes = 2048 bytes = Byte(2048) kib1 = bitmath.KiB(1) byte1 = bitmath.Byte(1024) added_different_types = kib1 + byte1 two_kib_in_bytes = bitmath.Byte(2048) self.assertEqual(added_different_types, two_kib_in_bytes)
def test_change_format_string(self): """KiB(1.0) looks right if changing fmt str in bitmath.KiB NOTE: This does NOT make use of the bitmath.format context manager. There is a separate test suite for that: test_context_manager""" orig_fmt_str = bitmath.format_string bitmath.format_string = "{unit} {value:.3f}" kib = bitmath.KiB(1) self.assertEqual(self.kib_str_changed, str(kib)) bitmath.format_string = orig_fmt_str
def to_MiB(n): if "K" in n[1]: return int(round(bitmath.KiB(n[0]).to_MiB())) elif "M" in n[1]: return int(round(bitmath.MiB(n[0]).to_MiB())) elif "G" in n[1]: return int(round(bitmath.GiB(n[0]).to_MiB())) elif "T" in n[1]: return int(round(bitmath.TiB(n[0]).to_MiB())) else: return int(round(float(n[0])))
def test_click_BitmathType_good_spaces_in_value(self): @click.command() @click.argument('arg1', type=BitmathType()) @click.argument('arg2', type=BitmathType()) def func(arg1, arg2): click.echo(arg1) click.echo(arg2) result = self.runner.invoke(func, ['100 MiB', '200 KiB']) self.assertFalse(result.exception) self.assertEqual(result.output.splitlines(), [str(bitmath.MiB(100)), str(bitmath.KiB(200))])
def test_sort_heterogeneous_list(self): """Different types in a list can be sorted properly Define these with the bytes keyword so we don't lose our minds trying to figure out if the results are correct.""" first = bitmath.KiB(bytes=0) second = bitmath.GiB(bytes=1337) third = bitmath.Eb(bytes=2048) fourth = bitmath.Byte(bytes=96783) unsorted_list = [fourth, second, first, third] sorted_list = sorted(unsorted_list) self.assertIs(sorted_list[0], first) self.assertIs(sorted_list[1], second) self.assertIs(sorted_list[2], third) self.assertIs(sorted_list[3], fourth)