diff --git a/.travis.yml b/.travis.yml index 6e50ec3..d5039b2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,13 +4,18 @@ notifications: branches: only: - master + - format-method after_success: - coveralls matrix: include: - python: "2.7" env: CI=ci2 - - python: "3.3" + - python: "3.4" + env: CI=ci3 + - python: "3.5" + env: CI=ci3 + - python: "3.6" env: CI=ci3 script: make $CI install: "" diff --git a/bitmath/__init__.py b/bitmath/__init__.py index 1198fd0..db0a284 100644 --- a/bitmath/__init__.py +++ b/bitmath/__init__.py @@ -413,6 +413,19 @@ def __str__(self): global format_string return self.format(format_string) + def __format__(self, format_spec): + """String representation of this object with custom formatting, such as specified number of digits.""" + global format_string + try: + # replace any format spec added into global format_string with the format_spec used in this invocation + value_end = format_string.index('{value') + 6 + brace_index = format_string.index('}', value_end) + format_string_custom = format_string[:value_end] + ':' + format_spec + format_string[brace_index:] + except ValueError: + # no {value} found in format_string, so cannot customize; fall back to global format_string + format_string_custom = format_string + return self.format(format_string_custom) + def format(self, fmt): """Return a representation of this instance formatted with user supplied syntax""" diff --git a/setup.py b/setup.py index c723c69..6872216 100644 --- a/setup.py +++ b/setup.py @@ -59,9 +59,9 @@ 'Programming Language :: Python :: 2.6', 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.1', - 'Programming Language :: Python :: 3.2', - 'Programming Language :: Python :: 3.3', + 'Programming Language :: Python :: 3.4', + 'Programming Language :: Python :: 3.5', + 'Programming Language :: Python :: 3.6', 'Programming Language :: Python', 'Topic :: Scientific/Engineering :: Mathematics', 'Topic :: Software Development :: Libraries :: Python Modules', diff --git a/tests/test_representation.py b/tests/test_representation.py index 1403eb0..a1cf37c 100644 --- a/tests/test_representation.py +++ b/tests/test_representation.py @@ -146,3 +146,39 @@ def test_print_byte_singular(self): one_Byte = bitmath.Byte(1.0) actual_result = one_Byte.format(fmt_str) self.assertEqual(expected_result, actual_result) + + def test_inline_format(self): + """Inline string formatting interpolates default format_string values""" + expected_result = 'size: 3.1215 MiB' + size = bitmath.MiB(3.1215) + actual_result = 'size: {size}'.format(size=size) + self.assertEqual(expected_result, actual_result) + + def test_inline_format_customized(self): + """Inline formats obey inline format specifications""" + expected_result = 'size: 3.1 MiB' + size = bitmath.MiB(3.1215) + actual_result = 'size: {size:.1f}'.format(size=size) + self.assertEqual(expected_result, actual_result) + + def test_inline_format_override(self): + """Inline formats use module defaults, overriding only format spec""" + orig_fmt_str = bitmath.format_string + bitmath.format_string = "{unit} {value:.3f}" + expected_result = 'size: MiB 3.1' + size = bitmath.MiB(3.1215) + actual_result = 'size: {size:.1f}'.format(size=size) + self.assertEqual(expected_result, actual_result) + bitmath.format_string = orig_fmt_str + + def test_inline_format_cant_override(self): + """Inline formats use module defaults, changing nothing if no {value} component""" + orig_fmt_str = bitmath.format_string + bitmath.format_string = "{power} {binary}" + expected_result = 'size: 20 0b1100011111000110101001111' + size = bitmath.MiB(3.1215) + # will not obey instant formatting, because global format_string doesn't allow that; + # obeys the global format_string instead + actual_result = 'size: {size:.1f}'.format(size=size) + self.assertEqual(expected_result, actual_result) + bitmath.format_string = orig_fmt_str