Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

""" 

Lazy format strings 

""" 

from __future__ import print_function 

 

 

class LazyFormat(str): 

""" 

Lazy format strings 

 

.. NOTE:: 

 

We recommend to use :func:`sage.misc.lazy_string.lazy_string` instead, 

which is both faster and more flexible. 

 

An instance of :class:`LazyFormat` behaves like a usual format 

string, except that the evaluation of the ``__repr__`` method of 

the formated arguments it postponed until actual printing. 

 

EXAMPLES: 

 

Under normal circumstances, :class:`Lazyformat` strings 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 

 

To demonstrate the lazyness, let us build an object with a broken 

``__repr__`` method:: 

 

sage: class IDontLikeBeingPrinted(object): 

....: def __repr__(self): 

....: raise ValueError("Don't ever try to print me !") 

 

There is no error when binding a lazy format with the broken object:: 

 

sage: lf = LazyFormat("<%s>")%IDontLikeBeingPrinted() 

 

The error only occurs upon printing:: 

 

sage: lf 

<repr(<sage.misc.lazy_format.LazyFormat at 0x...>) failed: ValueError: Don't ever try to print me !> 

 

.. rubric:: 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 ``x`` in 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 :mod:`unittest` or :class:`TestSuite` executions:: 

 

sage: QQ._tester().assertTrue(0 in 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 ``QQ`` in 

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: Don't 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() 

 

We now check that :class:`LazyFormat` indeed 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: <unprintable AssertionError object> 

""" 

 

def __mod__(self, args): 

""" 

Binds the lazy format string with its parameters 

 

EXAMPLES:: 

 

sage: from sage.misc.lazy_format import LazyFormat 

sage: form = LazyFormat("<%s>") 

sage: form 

unbound LazyFormat("<%s>") 

sage: form%"params" 

<params> 

""" 

if hasattr(self, "_args"): # self is already bound... 

self = LazyFormat(""+self) 

self._args = args 

return self 

 

def __repr__(self): 

""" 

TESTS:: 

 

sage: from sage.misc.lazy_format import LazyFormat 

sage: form = LazyFormat("<%s>"); 

sage: form 

unbound LazyFormat("<%s>") 

sage: print(form) 

unbound LazyFormat("<%s>") 

sage: form%"toto" 

<toto> 

sage: print(form % "toto") 

<toto> 

sage: print(str(form % "toto")) 

<toto> 

sage: print((form % "toto").__repr__()) 

<toto> 

""" 

try: 

args = self._args 

except AttributeError: 

return "unbound LazyFormat(\""+self+"\")" 

else: 

return str.__mod__(self, args) 

 

__str__ = __repr__