Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(25)

Side by Side Diff: Lib/pprint.py

Issue 19105: pprint doesn't use all width
Patch Set: Created 5 years, 1 month ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | Lib/test/test_pprint.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Author: Fred L. Drake, Jr. 1 # Author: Fred L. Drake, Jr.
2 # fdrake@acm.org 2 # fdrake@acm.org
3 # 3 #
4 # This is a simple little module I wrote to make life easier. I didn't 4 # This is a simple little module I wrote to make life easier. I didn't
5 # see anything quite like it in the library, though I may have overlooked 5 # see anything quite like it in the library, though I may have overlooked
6 # something. I wrote this when I was trying to read some heavily nested 6 # something. I wrote this when I was trying to read some heavily nested
7 # tuples with fairly non-descriptive content. This is modeled very much 7 # tuples with fairly non-descriptive content. This is modeled very much
8 # after Lisp/Scheme - style pretty-printing of lists. If you find it 8 # after Lisp/Scheme - style pretty-printing of lists. If you find it
9 # useful, thank small children who sleep at night. 9 # useful, thank small children who sleep at night.
10 10
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
154 def _format(self, object, stream, indent, allowance, context, level): 154 def _format(self, object, stream, indent, allowance, context, level):
155 level = level + 1 155 level = level + 1
156 objid = id(object) 156 objid = id(object)
157 if objid in context: 157 if objid in context:
158 stream.write(_recursion(object)) 158 stream.write(_recursion(object))
159 self._recursive = True 159 self._recursive = True
160 self._readable = False 160 self._readable = False
161 return 161 return
162 rep = self._repr(object, context, level - 1) 162 rep = self._repr(object, context, level - 1)
163 typ = type(object) 163 typ = type(object)
164 max_width = self._width - 1 - indent - allowance 164 max_width = self._width - indent - allowance
165 sepLines = len(rep) > max_width 165 sepLines = len(rep) > max_width
166 write = stream.write 166 write = stream.write
167 167
168 if sepLines: 168 if sepLines:
169 r = getattr(typ, "__repr__", None) 169 r = getattr(typ, "__repr__", None)
170 if issubclass(typ, dict): 170 if issubclass(typ, dict):
171 write('{') 171 write('{')
172 if self._indent_per_level > 1: 172 if self._indent_per_level > 1:
173 write((self._indent_per_level - 1) * ' ') 173 write((self._indent_per_level - 1) * ' ')
174 length = len(object) 174 length = len(object)
175 if length: 175 if length:
176 context[objid] = 1 176 context[objid] = 1
177 indent = indent + self._indent_per_level
178 if issubclass(typ, _OrderedDict): 177 if issubclass(typ, _OrderedDict):
179 items = list(object.items()) 178 items = list(object.items())
180 else: 179 else:
181 items = sorted(object.items(), key=_safe_tuple) 180 items = sorted(object.items(), key=_safe_tuple)
182 key, ent = items[0] 181 self._format_dict_items(items, stream,
183 rep = self._repr(key, context, level) 182 indent + self._indent_per_level,
184 write(rep) 183 allowance + 1,
185 write(': ') 184 context, level)
186 self._format(ent, stream, indent + len(rep) + 2,
187 allowance + 1, context, level)
188 if length > 1:
189 for key, ent in items[1:]:
190 rep = self._repr(key, context, level)
191 write(',\n%s%s: ' % (' '*indent, rep))
192 self._format(ent, stream, indent + len(rep) + 2,
193 allowance + 1, context, level)
194 indent = indent - self._indent_per_level
195 del context[objid] 185 del context[objid]
196 write('}') 186 write('}')
197 return 187 return
198 188
199 if ((issubclass(typ, list) and r is list.__repr__) or 189 if ((issubclass(typ, list) and r is list.__repr__) or
200 (issubclass(typ, tuple) and r is tuple.__repr__) or 190 (issubclass(typ, tuple) and r is tuple.__repr__) or
201 (issubclass(typ, set) and r is set.__repr__) or 191 (issubclass(typ, set) and r is set.__repr__) or
202 (issubclass(typ, frozenset) and r is frozenset.__repr__) 192 (issubclass(typ, frozenset) and r is frozenset.__repr__)
203 ): 193 ):
204 length = len(object) 194 length = len(object)
205 if issubclass(typ, list): 195 if issubclass(typ, list):
206 write('[') 196 write('[')
207 endchar = ']' 197 endchar = ']'
208 elif issubclass(typ, tuple): 198 elif issubclass(typ, tuple):
209 write('(') 199 write('(')
210 endchar = ')' 200 if length == 1:
201 endchar = ',)'
202 else:
203 endchar = ')'
211 else: 204 else:
212 if not length: 205 if not length:
213 write(rep) 206 write(rep)
214 return 207 return
215 if typ is set: 208 if typ is set:
216 write('{') 209 write('{')
217 endchar = '}' 210 endchar = '}'
218 else: 211 else:
219 write(typ.__name__) 212 write(typ.__name__)
220 write('({') 213 write('({')
221 endchar = '})' 214 endchar = '})'
222 indent += len(typ.__name__) + 1 215 indent += len(typ.__name__) + 1
223 object = sorted(object, key=_safe_key) 216 object = sorted(object, key=_safe_key)
224 if self._indent_per_level > 1: 217 if self._indent_per_level > 1:
225 write((self._indent_per_level - 1) * ' ') 218 write((self._indent_per_level - 1) * ' ')
226 if length: 219 if length:
227 context[objid] = 1 220 context[objid] = 1
228 self._format_items(object, stream, 221 self._format_items(object, stream,
229 indent + self._indent_per_level, 222 indent + self._indent_per_level,
230 allowance + 1, context, level) 223 allowance + len(endchar),
224 context, level)
231 del context[objid] 225 del context[objid]
232 if issubclass(typ, tuple) and length == 1:
233 write(',')
234 write(endchar) 226 write(endchar)
235 return 227 return
236 228
237 if issubclass(typ, str) and len(object) > 0 and r is str.__repr__: 229 if issubclass(typ, str) and len(object) > 0 and r is str.__repr__:
238 chunks = [] 230 chunks = []
239 lines = object.splitlines(True) 231 lines = object.splitlines(True)
240 if level == 1: 232 if level == 1:
241 indent += 1 233 indent += 1
242 max_width -= 2 234 allowance += 1
235 max_width1 = max_width = self._width - indent
243 for i, line in enumerate(lines): 236 for i, line in enumerate(lines):
244 rep = repr(line) 237 rep = repr(line)
245 if len(rep) <= max_width: 238 if i == len(lines) - 1:
239 max_width1 -= allowance
240 if len(rep) <= max_width1:
246 chunks.append(rep) 241 chunks.append(rep)
247 else: 242 else:
248 # A list of alternating (non-space, space) strings 243 # A list of alternating (non-space, space) strings
249 parts = re.split(r'(\s+)', line) + [''] 244 parts = re.findall(r'\S*\s*', line)
245 assert parts
246 assert not parts[-1]
247 parts.pop() # drop empty last part
248 max_width2 = max_width
250 current = '' 249 current = ''
251 for i in range(0, len(parts), 2): 250 for j, part in enumerate(parts):
252 part = parts[i] + parts[i+1]
253 candidate = current + part 251 candidate = current + part
254 if len(repr(candidate)) > max_width: 252 if j == len(parts) - 1 and i == len(lines) - 1:
253 max_width2 -= allowance
254 if len(repr(candidate)) > max_width2:
255 if current: 255 if current:
256 chunks.append(repr(current)) 256 chunks.append(repr(current))
257 current = part 257 current = part
258 else: 258 else:
259 current = candidate 259 current = candidate
260 if current: 260 if current:
261 chunks.append(repr(current)) 261 chunks.append(repr(current))
262 if len(chunks) == 1: 262 if len(chunks) == 1:
263 write(rep) 263 write(rep)
264 return 264 return
265 if level == 1: 265 if level == 1:
266 write('(') 266 write('(')
267 for i, rep in enumerate(chunks): 267 for i, rep in enumerate(chunks):
268 if i > 0: 268 if i > 0:
269 write('\n' + ' '*indent) 269 write('\n' + ' '*indent)
270 write(rep) 270 write(rep)
271 if level == 1: 271 if level == 1:
272 write(')') 272 write(')')
273 return 273 return
274 write(rep) 274 write(rep)
275
276 def _format_dict_items(self, items, stream, indent, allowance, context,
277 level):
278 write = stream.write
279 delimnl = ',\n' + ' ' * indent
280 last_index = len(items) - 1
281 for i, (key, ent) in enumerate(items):
282 last = i == last_index
283 rep = self._repr(key, context, level)
284 write(rep)
285 write(': ')
286 self._format(ent, stream, indent + len(rep) + 2,
287 allowance if last else 1,
288 context, level)
289 if not last:
290 write(delimnl)
275 291
276 def _format_items(self, items, stream, indent, allowance, context, level): 292 def _format_items(self, items, stream, indent, allowance, context, level):
277 write = stream.write 293 write = stream.write
278 delimnl = ',\n' + ' ' * indent 294 delimnl = ',\n' + ' ' * indent
279 delim = '' 295 delim = ''
280 width = max_width = self._width - indent - allowance + 2 296 width = max_width = self._width - indent + 1
281 for ent in items: 297 it = iter(items)
298 try:
299 next_ent = next(it)
300 except StopIteration:
301 return
302 last = False
303 while not last:
304 ent = next_ent
305 try:
306 next_ent = next(it)
307 except StopIteration:
308 last = True
309 max_width -= allowance
310 width -= allowance
282 if self._compact: 311 if self._compact:
283 rep = self._repr(ent, context, level) 312 rep = self._repr(ent, context, level)
284 w = len(rep) + 2 313 w = len(rep) + 2
285 if width < w: 314 if width < w:
286 width = max_width 315 width = max_width
287 if delim: 316 if delim:
288 delim = delimnl 317 delim = delimnl
289 if width >= w: 318 if width >= w:
290 width -= w 319 width -= w
291 write(delim) 320 write(delim)
292 delim = ', ' 321 delim = ', '
293 write(rep) 322 write(rep)
294 continue 323 continue
295 write(delim) 324 write(delim)
296 delim = delimnl 325 delim = delimnl
297 self._format(ent, stream, indent, allowance, context, level) 326 self._format(ent, stream, indent,
327 allowance if last else 1,
328 context, level)
298 329
299 def _repr(self, object, context, level): 330 def _repr(self, object, context, level):
300 repr, readable, recursive = self.format(object, context.copy(), 331 repr, readable, recursive = self.format(object, context.copy(),
301 self._depth, level) 332 self._depth, level)
302 if not readable: 333 if not readable:
303 self._readable = False 334 self._readable = False
304 if recursive: 335 if recursive:
305 self._recursive = True 336 self._recursive = True
306 return repr 337 return repr
307 338
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
413 t1 = time.time() 444 t1 = time.time()
414 _safe_repr(object, {}, None, 0) 445 _safe_repr(object, {}, None, 0)
415 t2 = time.time() 446 t2 = time.time()
416 p.pformat(object) 447 p.pformat(object)
417 t3 = time.time() 448 t3 = time.time()
418 print("_safe_repr:", t2 - t1) 449 print("_safe_repr:", t2 - t1)
419 print("pformat:", t3 - t2) 450 print("pformat:", t3 - t2)
420 451
421 if __name__ == "__main__": 452 if __name__ == "__main__":
422 _perfcheck() 453 _perfcheck()
OLDNEW
« no previous file with comments | « no previous file | Lib/test/test_pprint.py » ('j') | no next file with comments »

RSS Feeds Recent Issues | This issue
This is Rietveld 894c83f36cb7+