Lazy format strings¶
- class sage.misc.lazy_format.LazyFormat[source]¶
- Bases: - str- Lazy format strings. - Note - We recommend to use - sage.misc.lazy_string.lazy_string()instead, which is both faster and more flexible.- An instance of - LazyFormatbehaves like a usual format string, except that the evaluation of the- __repr__method of the formatted arguments it postponed until actual printing.- EXAMPLES: - Under normal circumstances, - Lazyformatstrings behave as usual:- sage: from sage.misc.lazy_format import LazyFormat sage: LazyFormat("Got `%s`; expected a list")%3 Got `3`; expected a list sage: LazyFormat("Got `%s`; expected %s")%(3, 2/3) Got `3`; expected 2/3 - >>> from sage.all import * >>> from sage.misc.lazy_format import LazyFormat >>> LazyFormat("Got `%s`; expected a list")%Integer(3) Got `3`; expected a list >>> LazyFormat("Got `%s`; expected %s")%(Integer(3), Integer(2)/Integer(3)) Got `3`; expected 2/3 - To demonstrate the laziness, let us build an object with a broken - __repr__method:- sage: class IDontLikeBeingPrinted(): ....: def __repr__(self): ....: raise ValueError("do not ever try to print me") - >>> from sage.all import * >>> class IDontLikeBeingPrinted(): ... def __repr__(self): ... raise ValueError("do not ever try to print me") - There is no error when binding a lazy format with the broken object: - sage: lf = LazyFormat("<%s>")%IDontLikeBeingPrinted() - >>> from sage.all import * >>> lf = LazyFormat("<%s>")%IDontLikeBeingPrinted() - The error only occurs upon printing: - sage: lf <repr(<sage.misc.lazy_format.LazyFormat at 0x...>) failed: ValueError: do not ever try to print me> - >>> from sage.all import * >>> lf <repr(<sage.misc.lazy_format.LazyFormat at 0x...>) failed: ValueError: do not ever try to print me> - Common use case: - Most of the time, - __repr__methods are only called during user interaction, and therefore need not be fast; and indeed there are objects- xin Sage such- x.__repr__()is time consuming.- There are however some uses cases where many format strings are constructed but not actually printed. This includes error handling messages in - unittestor- TestSuiteexecutions:- sage: QQ._tester().assertIn(0, QQ, ....: "%s doesn't contain 0"%QQ) - >>> from sage.all import * >>> QQ._tester().assertIn(Integer(0), QQ, ... "%s doesn't contain 0"%QQ) - In the above - QQ.__repr__()has been called, and the result immediately discarded. To demonstrate this we replace- QQin the format string argument with our broken object:- sage: QQ._tester().assertTrue(True, ....: "%s doesn't contain 0"%IDontLikeBeingPrinted()) Traceback (most recent call last): ... ValueError: do not ever try to print me - >>> from sage.all import * >>> QQ._tester().assertTrue(True, ... "%s doesn't contain 0"%IDontLikeBeingPrinted()) Traceback (most recent call last): ... ValueError: do not ever try to print me - This behavior can induce major performance penalties when testing. Note that this issue does not impact the usual assert: - sage: assert True, "%s is wrong"%IDontLikeBeingPrinted() - >>> from sage.all import * >>> assert True, "%s is wrong"%IDontLikeBeingPrinted() - We now check that - LazyFormatindeed solves the assertion problem:- sage: QQ._tester().assertTrue(True, ....: LazyFormat("%s is wrong")%IDontLikeBeingPrinted()) sage: QQ._tester().assertTrue(False, ....: LazyFormat("%s is wrong")%IDontLikeBeingPrinted()) Traceback (most recent call last): ... AssertionError: ... - >>> from sage.all import * >>> QQ._tester().assertTrue(True, ... LazyFormat("%s is wrong")%IDontLikeBeingPrinted()) >>> QQ._tester().assertTrue(False, ... LazyFormat("%s is wrong")%IDontLikeBeingPrinted()) Traceback (most recent call last): ... AssertionError: ...