15 """This class serves as a placeholder for keys in not found during lookup into
16 keyword or positional arguments during a call to TolerateMissingKeyFormatter.
18 It records potential item and attribute lookups, conversion and format_spec to
19 reproduce original replacement_field entry into the formatted string.
24 field_name part of the replacement_field specifier
26 conversion part of the replacement_field specifier
28 format_spec part of the replacement_field specifier
32 replacement_field, field_name, conversion and format_spec have the meaning as outlined in
33 https://docs.python.org/2/library/string.html#format-string-syntax
36 def __init__(self, field_name, conversion=None, format_spec=None):
47 """Record attribute lookup"""
51 """Record item lookup"""
55 """Compose a replacement_field string equivalent to the original replacement_field in the string formatting."""
59 text_in_brackets +=
"!" + self.
conversionconversion
62 text_in_brackets +=
":" + self.
format_specformat_spec
64 replacement_field =
"{" + text_in_brackets +
"}"
65 return replacement_field
70 """A string formatter that implements format most equivalent to the str.format, but does not replace keys,
71 that are not present in the replacements dictionary
75 >>> formatter = TolerateMissingKeyFormatter()
76 >>> template = "{present}_{missing}"
77 >>> partially_substituted = formatter.format(template, present="replaced")
78 >>> print partially_substituted
84 """Retrieves the value that corresponds to the key from either the postional or
85 the keyword arguments given to format
87 Overrides the standard lookup such that missing keys in the keyword arguments or
88 transformed in a NoReplacementField signal object.
91 if isinstance(key, str):
97 return super(TolerateMissingKeyFormatter, self).
get_value(key, args, kwds)
100 """Applies the conversion to the value.
102 Overrides the standard method such that a potential conversion is attached to the NoReplacementField
105 if isinstance(value, NoReplacementField):
106 conversion = conversion
or None
107 value.conversion = conversion
110 return super(TolerateMissingKeyFormatter, self).
convert_field(value, conversion)
113 """Applies the conversion to the value.
115 Overrides the standard method such that a potential format_spec is attached to the NoReplacementField.
116 Than composes the replacement_field specification to be inserted in the formatted string.
117 The outcome should be equivalent to the unformatted string for missing keys.
120 if isinstance(value, NoReplacementField):
121 format_spec = format_spec
or None
122 value.format_spec = format_spec
123 return value.compose()
125 return super(TolerateMissingKeyFormatter, self).
format_field(value, format_spec)
129 """Test the string formatter for cases where the keys are missing"""
132 """Prepare for the string-formatter test"""
137 """Test for a missing key"""
138 template =
"{present}_{missing}"
139 replaced = self.
formatterformatter.format(template, present=
"replaced")
140 self.assertEqual(
"replaced_{missing}", replaced)
143 """Test for a missing key attribute"""
144 template =
"{present}_{missing.field}"
145 replaced = self.
formatterformatter.format(template, present=
"replaced")
146 self.assertEqual(
"replaced_{missing.field}", replaced)
149 """Test for a missing key item"""
150 template =
"{present}_{missing[0]}"
151 replaced = self.
formatterformatter.format(template, present=
"replaced")
152 self.assertEqual(
"replaced_{missing[0]}", replaced)
155 """Test for a missing key item"""
156 template =
"{present}_{missing!s}"
157 replaced = self.
formatterformatter.format(template, present=
"replaced")
158 self.assertEqual(
"replaced_{missing!s}", replaced)
161 """Test for a missing key item"""
162 template =
"{present}_{missing!r}"
163 replaced = self.
formatterformatter.format(template, present=
"replaced")
164 self.assertEqual(
"replaced_{missing!r}", replaced)
167 """Test for a missing key item"""
168 template =
"{present}_{missing!r:^10s}"
169 replaced = self.
formatterformatter.format(template, present=
"replaced")
170 self.assertEqual(
"replaced_{missing!r:^10s}", replaced)
173 """Test for a missing key item"""
174 template =
"{present}_{missing:^10s}"
175 replaced = self.
formatterformatter.format(template, present=
"replaced")
176 self.assertEqual(
"replaced_{missing:^10s}", replaced)
179 if __name__ ==
'__main__':