xnd 0.2.0dev3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (93) hide show
  1. checksums.yaml +7 -0
  2. data/CONTRIBUTING.md +42 -0
  3. data/Gemfile +3 -0
  4. data/History.md +0 -0
  5. data/README.md +7 -0
  6. data/Rakefile +135 -0
  7. data/ext/ruby_xnd/extconf.rb +70 -0
  8. data/ext/ruby_xnd/float_pack_unpack.c +277 -0
  9. data/ext/ruby_xnd/float_pack_unpack.h +39 -0
  10. data/ext/ruby_xnd/gc_guard.c +36 -0
  11. data/ext/ruby_xnd/gc_guard.h +12 -0
  12. data/ext/ruby_xnd/include/xnd.h +449 -0
  13. data/ext/ruby_xnd/lib/libxnd.a +0 -0
  14. data/ext/ruby_xnd/lib/libxnd.so +1 -0
  15. data/ext/ruby_xnd/lib/libxnd.so.0 +1 -0
  16. data/ext/ruby_xnd/lib/libxnd.so.0.2.0dev3 +0 -0
  17. data/ext/ruby_xnd/memory_block_object.c +32 -0
  18. data/ext/ruby_xnd/memory_block_object.h +33 -0
  19. data/ext/ruby_xnd/ruby_xnd.c +1953 -0
  20. data/ext/ruby_xnd/ruby_xnd.h +61 -0
  21. data/ext/ruby_xnd/ruby_xnd_internal.h +85 -0
  22. data/ext/ruby_xnd/util.h +170 -0
  23. data/ext/ruby_xnd/xnd/AUTHORS.txt +5 -0
  24. data/ext/ruby_xnd/xnd/INSTALL.txt +134 -0
  25. data/ext/ruby_xnd/xnd/LICENSE.txt +29 -0
  26. data/ext/ruby_xnd/xnd/MANIFEST.in +3 -0
  27. data/ext/ruby_xnd/xnd/Makefile.in +80 -0
  28. data/ext/ruby_xnd/xnd/README.rst +44 -0
  29. data/ext/ruby_xnd/xnd/config.guess +1530 -0
  30. data/ext/ruby_xnd/xnd/config.h.in +22 -0
  31. data/ext/ruby_xnd/xnd/config.sub +1782 -0
  32. data/ext/ruby_xnd/xnd/configure +4867 -0
  33. data/ext/ruby_xnd/xnd/configure.ac +164 -0
  34. data/ext/ruby_xnd/xnd/doc/Makefile +14 -0
  35. data/ext/ruby_xnd/xnd/doc/_static/copybutton.js +66 -0
  36. data/ext/ruby_xnd/xnd/doc/conf.py +26 -0
  37. data/ext/ruby_xnd/xnd/doc/index.rst +44 -0
  38. data/ext/ruby_xnd/xnd/doc/libxnd/data-structures.rst +186 -0
  39. data/ext/ruby_xnd/xnd/doc/libxnd/functions.rst +148 -0
  40. data/ext/ruby_xnd/xnd/doc/libxnd/index.rst +25 -0
  41. data/ext/ruby_xnd/xnd/doc/releases/index.rst +34 -0
  42. data/ext/ruby_xnd/xnd/doc/xnd/align-pack.rst +96 -0
  43. data/ext/ruby_xnd/xnd/doc/xnd/buffer-protocol.rst +42 -0
  44. data/ext/ruby_xnd/xnd/doc/xnd/index.rst +30 -0
  45. data/ext/ruby_xnd/xnd/doc/xnd/quickstart.rst +62 -0
  46. data/ext/ruby_xnd/xnd/doc/xnd/types.rst +674 -0
  47. data/ext/ruby_xnd/xnd/install-sh +527 -0
  48. data/ext/ruby_xnd/xnd/libxnd/Makefile.in +102 -0
  49. data/ext/ruby_xnd/xnd/libxnd/Makefile.vc +112 -0
  50. data/ext/ruby_xnd/xnd/libxnd/bitmaps.c +345 -0
  51. data/ext/ruby_xnd/xnd/libxnd/contrib.h +313 -0
  52. data/ext/ruby_xnd/xnd/libxnd/copy.c +944 -0
  53. data/ext/ruby_xnd/xnd/libxnd/equal.c +1216 -0
  54. data/ext/ruby_xnd/xnd/libxnd/inline.h +154 -0
  55. data/ext/ruby_xnd/xnd/libxnd/overflow.h +147 -0
  56. data/ext/ruby_xnd/xnd/libxnd/split.c +286 -0
  57. data/ext/ruby_xnd/xnd/libxnd/tests/Makefile.in +39 -0
  58. data/ext/ruby_xnd/xnd/libxnd/tests/Makefile.vc +44 -0
  59. data/ext/ruby_xnd/xnd/libxnd/tests/README.txt +2 -0
  60. data/ext/ruby_xnd/xnd/libxnd/tests/runtest.c +101 -0
  61. data/ext/ruby_xnd/xnd/libxnd/tests/test.h +48 -0
  62. data/ext/ruby_xnd/xnd/libxnd/tests/test_fixed.c +108 -0
  63. data/ext/ruby_xnd/xnd/libxnd/xnd.c +1304 -0
  64. data/ext/ruby_xnd/xnd/libxnd/xnd.h +449 -0
  65. data/ext/ruby_xnd/xnd/python/test_xnd.py +3144 -0
  66. data/ext/ruby_xnd/xnd/python/xnd/__init__.py +290 -0
  67. data/ext/ruby_xnd/xnd/python/xnd/_xnd.c +2822 -0
  68. data/ext/ruby_xnd/xnd/python/xnd/contrib/pretty.py +850 -0
  69. data/ext/ruby_xnd/xnd/python/xnd/docstrings.h +129 -0
  70. data/ext/ruby_xnd/xnd/python/xnd/pyxnd.h +200 -0
  71. data/ext/ruby_xnd/xnd/python/xnd/util.h +182 -0
  72. data/ext/ruby_xnd/xnd/python/xnd_randvalue.py +1121 -0
  73. data/ext/ruby_xnd/xnd/python/xnd_support.py +106 -0
  74. data/ext/ruby_xnd/xnd/setup.py +303 -0
  75. data/ext/ruby_xnd/xnd/vcbuild/INSTALL.txt +42 -0
  76. data/ext/ruby_xnd/xnd/vcbuild/runtest32.bat +16 -0
  77. data/ext/ruby_xnd/xnd/vcbuild/runtest64.bat +14 -0
  78. data/ext/ruby_xnd/xnd/vcbuild/vcbuild32.bat +29 -0
  79. data/ext/ruby_xnd/xnd/vcbuild/vcbuild64.bat +29 -0
  80. data/ext/ruby_xnd/xnd/vcbuild/vcclean.bat +13 -0
  81. data/ext/ruby_xnd/xnd/vcbuild/vcdistclean.bat +14 -0
  82. data/lib/ruby_xnd.so +0 -0
  83. data/lib/xnd.rb +306 -0
  84. data/lib/xnd/monkeys.rb +29 -0
  85. data/lib/xnd/version.rb +6 -0
  86. data/spec/debug_spec.rb +9 -0
  87. data/spec/gc_guard_spec.rb +10 -0
  88. data/spec/leakcheck.rb +9 -0
  89. data/spec/spec_helper.rb +877 -0
  90. data/spec/type_inference_spec.rb +81 -0
  91. data/spec/xnd_spec.rb +2921 -0
  92. data/xnd.gemspec +47 -0
  93. metadata +215 -0
@@ -0,0 +1,850 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ Python advanced pretty printer. This pretty printer is intended to
4
+ replace the old `pprint` python module which does not allow developers
5
+ to provide their own pretty print callbacks.
6
+
7
+ This module is based on ruby's `prettyprint.rb` library by `Tanaka Akira`.
8
+
9
+
10
+ Example Usage
11
+ -------------
12
+
13
+ To directly print the representation of an object use `pprint`::
14
+
15
+ from pretty import pprint
16
+ pprint(complex_object)
17
+
18
+ To get a string of the output use `pretty`::
19
+
20
+ from pretty import pretty
21
+ string = pretty(complex_object)
22
+
23
+
24
+ Extending
25
+ ---------
26
+
27
+ The pretty library allows developers to add pretty printing rules for their
28
+ own objects. This process is straightforward. All you have to do is to
29
+ add a `_repr_pretty_` method to your object and call the methods on the
30
+ pretty printer passed::
31
+
32
+ class MyObject(object):
33
+
34
+ def _repr_pretty_(self, p, cycle):
35
+ ...
36
+
37
+ Here is an example implementation of a `_repr_pretty_` method for a list
38
+ subclass::
39
+
40
+ class MyList(list):
41
+
42
+ def _repr_pretty_(self, p, cycle):
43
+ if cycle:
44
+ p.text('MyList(...)')
45
+ else:
46
+ with p.group(8, 'MyList([', '])'):
47
+ for idx, item in enumerate(self):
48
+ if idx:
49
+ p.text(',')
50
+ p.breakable()
51
+ p.pretty(item)
52
+
53
+ The `cycle` parameter is `True` if pretty detected a cycle. You *have* to
54
+ react to that or the result is an infinite loop. `p.text()` just adds
55
+ non breaking text to the output, `p.breakable()` either adds a whitespace
56
+ or breaks here. If you pass it an argument it's used instead of the
57
+ default space. `p.pretty` prettyprints another object using the pretty print
58
+ method.
59
+
60
+ The first parameter to the `group` function specifies the extra indentation
61
+ of the next line. In this example the next item will either be on the same
62
+ line (if the items are short enough) or aligned with the right edge of the
63
+ opening bracket of `MyList`.
64
+
65
+ If you just want to indent something you can use the group function
66
+ without open / close parameters. You can also use this code::
67
+
68
+ with p.indent(2):
69
+ ...
70
+
71
+ Inheritance diagram:
72
+
73
+ .. inheritance-diagram:: IPython.lib.pretty
74
+ :parts: 3
75
+
76
+ :copyright: 2007 by Armin Ronacher.
77
+ Portions (c) 2009 by Robert Kern.
78
+ :license: BSD License.
79
+ """
80
+ from contextlib import contextmanager
81
+ import sys
82
+ import types
83
+ import re
84
+ import datetime
85
+ from collections import deque
86
+ from io import StringIO
87
+ from warnings import warn
88
+
89
+ from inspect import signature
90
+
91
+ __all__ = ['pretty', 'pprint', 'PrettyPrinter', 'RepresentationPrinter',
92
+ 'for_type', 'for_type_by_name']
93
+
94
+
95
+ MAX_SEQ_LENGTH = 1000
96
+ # The language spec says that dicts preserve order from 3.7, but CPython
97
+ # does so from 3.6, so it seems likely that people will expect that.
98
+ DICT_IS_ORDERED = sys.version_info >= (3, 6)
99
+ _re_pattern_type = type(re.compile(''))
100
+
101
+ def _safe_getattr(obj, attr, default=None):
102
+ """Safe version of getattr.
103
+
104
+ Same as getattr, but will return ``default`` on any Exception,
105
+ rather than raising.
106
+ """
107
+ try:
108
+ return getattr(obj, attr, default)
109
+ except Exception:
110
+ return default
111
+
112
+ def _sorted_for_pprint(items):
113
+ """
114
+ Sort the given items for pretty printing. Since some predictable
115
+ sorting is better than no sorting at all, we sort on the string
116
+ representation if normal sorting fails.
117
+ """
118
+ items = list(items)
119
+ try:
120
+ return sorted(items)
121
+ except Exception:
122
+ try:
123
+ return sorted(items, key=str)
124
+ except Exception:
125
+ return items
126
+
127
+ def pretty(obj, verbose=False, max_width=79, newline='\n', max_seq_length=MAX_SEQ_LENGTH):
128
+ """
129
+ Pretty print the object's representation.
130
+ """
131
+ stream = StringIO()
132
+ printer = RepresentationPrinter(stream, verbose, max_width, newline, max_seq_length=max_seq_length)
133
+ printer.pretty(obj)
134
+ printer.flush()
135
+ return stream.getvalue()
136
+
137
+
138
+ def pprint(obj, verbose=False, max_width=79, newline='\n', max_seq_length=MAX_SEQ_LENGTH):
139
+ """
140
+ Like `pretty` but print to stdout.
141
+ """
142
+ printer = RepresentationPrinter(sys.stdout, verbose, max_width, newline, max_seq_length=max_seq_length)
143
+ printer.pretty(obj)
144
+ printer.flush()
145
+ sys.stdout.write(newline)
146
+ sys.stdout.flush()
147
+
148
+ class _PrettyPrinterBase(object):
149
+
150
+ @contextmanager
151
+ def indent(self, indent):
152
+ """with statement support for indenting/dedenting."""
153
+ self.indentation += indent
154
+ try:
155
+ yield
156
+ finally:
157
+ self.indentation -= indent
158
+
159
+ @contextmanager
160
+ def group(self, indent=0, open='', close=''):
161
+ """like begin_group / end_group but for the with statement."""
162
+ self.begin_group(indent, open)
163
+ try:
164
+ yield
165
+ finally:
166
+ self.end_group(indent, close)
167
+
168
+ class PrettyPrinter(_PrettyPrinterBase):
169
+ """
170
+ Baseclass for the `RepresentationPrinter` prettyprinter that is used to
171
+ generate pretty reprs of objects. Contrary to the `RepresentationPrinter`
172
+ this printer knows nothing about the default pprinters or the `_repr_pretty_`
173
+ callback method.
174
+ """
175
+
176
+ def __init__(self, output, max_width=79, newline='\n', max_seq_length=MAX_SEQ_LENGTH):
177
+ self.output = output
178
+ self.max_width = max_width
179
+ self.newline = newline
180
+ self.max_seq_length = max_seq_length
181
+ self.output_width = 0
182
+ self.buffer_width = 0
183
+ self.buffer = deque()
184
+
185
+ root_group = Group(0)
186
+ self.group_stack = [root_group]
187
+ self.group_queue = GroupQueue(root_group)
188
+ self.indentation = 0
189
+
190
+ def _break_outer_groups(self):
191
+ while self.max_width < self.output_width + self.buffer_width:
192
+ group = self.group_queue.deq()
193
+ if not group:
194
+ return
195
+ while group.breakables:
196
+ x = self.buffer.popleft()
197
+ self.output_width = x.output(self.output, self.output_width)
198
+ self.buffer_width -= x.width
199
+ while self.buffer and isinstance(self.buffer[0], Text):
200
+ x = self.buffer.popleft()
201
+ self.output_width = x.output(self.output, self.output_width)
202
+ self.buffer_width -= x.width
203
+
204
+ def text(self, obj):
205
+ """Add literal text to the output."""
206
+ width = len(obj)
207
+ if self.buffer:
208
+ text = self.buffer[-1]
209
+ if not isinstance(text, Text):
210
+ text = Text()
211
+ self.buffer.append(text)
212
+ text.add(obj, width)
213
+ self.buffer_width += width
214
+ self._break_outer_groups()
215
+ else:
216
+ self.output.write(obj)
217
+ self.output_width += width
218
+
219
+ def breakable(self, sep=' '):
220
+ """
221
+ Add a breakable separator to the output. This does not mean that it
222
+ will automatically break here. If no breaking on this position takes
223
+ place the `sep` is inserted which default to one space.
224
+ """
225
+ width = len(sep)
226
+ group = self.group_stack[-1]
227
+ if group.want_break:
228
+ self.flush()
229
+ self.output.write(self.newline)
230
+ self.output.write(' ' * self.indentation)
231
+ self.output_width = self.indentation
232
+ self.buffer_width = 0
233
+ else:
234
+ self.buffer.append(Breakable(sep, width, self))
235
+ self.buffer_width += width
236
+ self._break_outer_groups()
237
+
238
+ def break_(self):
239
+ """
240
+ Explicitly insert a newline into the output, maintaining correct indentation.
241
+ """
242
+ self.flush()
243
+ self.output.write(self.newline)
244
+ self.output.write(' ' * self.indentation)
245
+ self.output_width = self.indentation
246
+ self.buffer_width = 0
247
+
248
+ def begin_group(self, indent=0, open=''):
249
+ """
250
+ Begin a group. If you want support for python < 2.5 which doesn't has
251
+ the with statement this is the preferred way:
252
+
253
+ p.begin_group(1, '{')
254
+ ...
255
+ p.end_group(1, '}')
256
+
257
+ The python 2.5 expression would be this:
258
+
259
+ with p.group(1, '{', '}'):
260
+ ...
261
+
262
+ The first parameter specifies the indentation for the next line (usually
263
+ the width of the opening text), the second the opening text. All
264
+ parameters are optional.
265
+ """
266
+ if open:
267
+ self.text(open)
268
+ group = Group(self.group_stack[-1].depth + 1)
269
+ self.group_stack.append(group)
270
+ self.group_queue.enq(group)
271
+ self.indentation += indent
272
+
273
+ def _enumerate(self, seq):
274
+ """like enumerate, but with an upper limit on the number of items"""
275
+ for idx, x in enumerate(seq):
276
+ if self.max_seq_length and idx >= self.max_seq_length:
277
+ self.text(',')
278
+ self.breakable()
279
+ self.text('...')
280
+ return
281
+ yield idx, x
282
+
283
+ def end_group(self, dedent=0, close=''):
284
+ """End a group. See `begin_group` for more details."""
285
+ self.indentation -= dedent
286
+ group = self.group_stack.pop()
287
+ if not group.breakables:
288
+ self.group_queue.remove(group)
289
+ if close:
290
+ self.text(close)
291
+
292
+ def flush(self):
293
+ """Flush data that is left in the buffer."""
294
+ for data in self.buffer:
295
+ self.output_width += data.output(self.output, self.output_width)
296
+ self.buffer.clear()
297
+ self.buffer_width = 0
298
+
299
+
300
+ def _get_mro(obj_class):
301
+ """ Get a reasonable method resolution order of a class and its superclasses
302
+ for both old-style and new-style classes.
303
+ """
304
+ if not hasattr(obj_class, '__mro__'):
305
+ # Old-style class. Mix in object to make a fake new-style class.
306
+ try:
307
+ obj_class = type(obj_class.__name__, (obj_class, object), {})
308
+ except TypeError:
309
+ # Old-style extension type that does not descend from object.
310
+ # FIXME: try to construct a more thorough MRO.
311
+ mro = [obj_class]
312
+ else:
313
+ mro = obj_class.__mro__[1:-1]
314
+ else:
315
+ mro = obj_class.__mro__
316
+ return mro
317
+
318
+
319
+ class RepresentationPrinter(PrettyPrinter):
320
+ """
321
+ Special pretty printer that has a `pretty` method that calls the pretty
322
+ printer for a python object.
323
+
324
+ This class stores processing data on `self` so you must *never* use
325
+ this class in a threaded environment. Always lock it or reinstanciate
326
+ it.
327
+
328
+ Instances also have a verbose flag callbacks can access to control their
329
+ output. For example the default instance repr prints all attributes and
330
+ methods that are not prefixed by an underscore if the printer is in
331
+ verbose mode.
332
+ """
333
+
334
+ def __init__(self, output, verbose=False, max_width=79, newline='\n',
335
+ singleton_pprinters=None, type_pprinters=None, deferred_pprinters=None,
336
+ max_seq_length=MAX_SEQ_LENGTH):
337
+
338
+ PrettyPrinter.__init__(self, output, max_width, newline, max_seq_length=max_seq_length)
339
+ self.verbose = verbose
340
+ self.stack = []
341
+ if singleton_pprinters is None:
342
+ singleton_pprinters = _singleton_pprinters.copy()
343
+ self.singleton_pprinters = singleton_pprinters
344
+ if type_pprinters is None:
345
+ type_pprinters = _type_pprinters.copy()
346
+ self.type_pprinters = type_pprinters
347
+ if deferred_pprinters is None:
348
+ deferred_pprinters = _deferred_type_pprinters.copy()
349
+ self.deferred_pprinters = deferred_pprinters
350
+
351
+ def pretty(self, obj):
352
+ """Pretty print the given object."""
353
+ obj_id = id(obj)
354
+ cycle = obj_id in self.stack
355
+ self.stack.append(obj_id)
356
+ self.begin_group()
357
+ try:
358
+ obj_class = _safe_getattr(obj, '__class__', None) or type(obj)
359
+ # First try to find registered singleton printers for the type.
360
+ try:
361
+ printer = self.singleton_pprinters[obj_id]
362
+ except (TypeError, KeyError):
363
+ pass
364
+ else:
365
+ return printer(obj, self, cycle)
366
+ # Next walk the mro and check for either:
367
+ # 1) a registered printer
368
+ # 2) a _repr_pretty_ method
369
+ for cls in _get_mro(obj_class):
370
+ if cls in self.type_pprinters:
371
+ # printer registered in self.type_pprinters
372
+ return self.type_pprinters[cls](obj, self, cycle)
373
+ else:
374
+ # deferred printer
375
+ printer = self._in_deferred_types(cls)
376
+ if printer is not None:
377
+ return printer(obj, self, cycle)
378
+ else:
379
+ # Finally look for special method names.
380
+ # Some objects automatically create any requested
381
+ # attribute. Try to ignore most of them by checking for
382
+ # callability.
383
+ if '_repr_pretty_' in cls.__dict__:
384
+ meth = cls._repr_pretty_
385
+ if callable(meth):
386
+ return meth(obj, self, cycle)
387
+ if cls is not object \
388
+ and callable(cls.__dict__.get('__repr__')):
389
+ return _repr_pprint(obj, self, cycle)
390
+
391
+ return _default_pprint(obj, self, cycle)
392
+ finally:
393
+ self.end_group()
394
+ self.stack.pop()
395
+
396
+ def _in_deferred_types(self, cls):
397
+ """
398
+ Check if the given class is specified in the deferred type registry.
399
+
400
+ Returns the printer from the registry if it exists, and None if the
401
+ class is not in the registry. Successful matches will be moved to the
402
+ regular type registry for future use.
403
+ """
404
+ mod = _safe_getattr(cls, '__module__', None)
405
+ name = _safe_getattr(cls, '__name__', None)
406
+ key = (mod, name)
407
+ printer = None
408
+ if key in self.deferred_pprinters:
409
+ # Move the printer over to the regular registry.
410
+ printer = self.deferred_pprinters.pop(key)
411
+ self.type_pprinters[cls] = printer
412
+ return printer
413
+
414
+
415
+ class Printable(object):
416
+
417
+ def output(self, stream, output_width):
418
+ return output_width
419
+
420
+
421
+ class Text(Printable):
422
+
423
+ def __init__(self):
424
+ self.objs = []
425
+ self.width = 0
426
+
427
+ def output(self, stream, output_width):
428
+ for obj in self.objs:
429
+ stream.write(obj)
430
+ return output_width + self.width
431
+
432
+ def add(self, obj, width):
433
+ self.objs.append(obj)
434
+ self.width += width
435
+
436
+
437
+ class Breakable(Printable):
438
+
439
+ def __init__(self, seq, width, pretty):
440
+ self.obj = seq
441
+ self.width = width
442
+ self.pretty = pretty
443
+ self.indentation = pretty.indentation
444
+ self.group = pretty.group_stack[-1]
445
+ self.group.breakables.append(self)
446
+
447
+ def output(self, stream, output_width):
448
+ self.group.breakables.popleft()
449
+ if self.group.want_break:
450
+ stream.write(self.pretty.newline)
451
+ stream.write(' ' * self.indentation)
452
+ return self.indentation
453
+ if not self.group.breakables:
454
+ self.pretty.group_queue.remove(self.group)
455
+ stream.write(self.obj)
456
+ return output_width + self.width
457
+
458
+
459
+ class Group(Printable):
460
+
461
+ def __init__(self, depth):
462
+ self.depth = depth
463
+ self.breakables = deque()
464
+ self.want_break = False
465
+
466
+
467
+ class GroupQueue(object):
468
+
469
+ def __init__(self, *groups):
470
+ self.queue = []
471
+ for group in groups:
472
+ self.enq(group)
473
+
474
+ def enq(self, group):
475
+ depth = group.depth
476
+ while depth > len(self.queue) - 1:
477
+ self.queue.append([])
478
+ self.queue[depth].append(group)
479
+
480
+ def deq(self):
481
+ for stack in self.queue:
482
+ for idx, group in enumerate(reversed(stack)):
483
+ if group.breakables:
484
+ del stack[idx]
485
+ group.want_break = True
486
+ return group
487
+ for group in stack:
488
+ group.want_break = True
489
+ del stack[:]
490
+
491
+ def remove(self, group):
492
+ try:
493
+ self.queue[group.depth].remove(group)
494
+ except ValueError:
495
+ pass
496
+
497
+
498
+ def _default_pprint(obj, p, cycle):
499
+ """
500
+ The default print function. Used if an object does not provide one and
501
+ it's none of the builtin objects.
502
+ """
503
+ klass = _safe_getattr(obj, '__class__', None) or type(obj)
504
+ if _safe_getattr(klass, '__repr__', None) is not object.__repr__:
505
+ # A user-provided repr. Find newlines and replace them with p.break_()
506
+ _repr_pprint(obj, p, cycle)
507
+ return
508
+ p.begin_group(1, '<')
509
+ p.pretty(klass)
510
+ p.text(' at 0x%x' % id(obj))
511
+ if cycle:
512
+ p.text(' ...')
513
+ elif p.verbose:
514
+ first = True
515
+ for key in dir(obj):
516
+ if not key.startswith('_'):
517
+ try:
518
+ value = getattr(obj, key)
519
+ except AttributeError:
520
+ continue
521
+ if isinstance(value, types.MethodType):
522
+ continue
523
+ if not first:
524
+ p.text(',')
525
+ p.breakable()
526
+ p.text(key)
527
+ p.text('=')
528
+ step = len(key) + 1
529
+ p.indentation += step
530
+ p.pretty(value)
531
+ p.indentation -= step
532
+ first = False
533
+ p.end_group(1, '>')
534
+
535
+
536
+ def _seq_pprinter_factory(start, end):
537
+ """
538
+ Factory that returns a pprint function useful for sequences. Used by
539
+ the default pprint for tuples, dicts, and lists.
540
+ """
541
+ def inner(obj, p, cycle):
542
+ if cycle:
543
+ return p.text(start + '...' + end)
544
+ step = len(start)
545
+ p.begin_group(step, start)
546
+ for idx, x in p._enumerate(obj):
547
+ if idx:
548
+ p.text(',')
549
+ p.breakable()
550
+ p.pretty(x)
551
+ if len(obj) == 1 and type(obj) is tuple:
552
+ # Special case for 1-item tuples.
553
+ p.text(',')
554
+ p.end_group(step, end)
555
+ return inner
556
+
557
+
558
+ def _set_pprinter_factory(start, end):
559
+ """
560
+ Factory that returns a pprint function useful for sets and frozensets.
561
+ """
562
+ def inner(obj, p, cycle):
563
+ if cycle:
564
+ return p.text(start + '...' + end)
565
+ if len(obj) == 0:
566
+ # Special case.
567
+ p.text(type(obj).__name__ + '()')
568
+ else:
569
+ step = len(start)
570
+ p.begin_group(step, start)
571
+ # Like dictionary keys, we will try to sort the items if there aren't too many
572
+ if not (p.max_seq_length and len(obj) >= p.max_seq_length):
573
+ items = _sorted_for_pprint(obj)
574
+ else:
575
+ items = obj
576
+ for idx, x in p._enumerate(items):
577
+ if idx:
578
+ p.text(',')
579
+ p.breakable()
580
+ p.pretty(x)
581
+ p.end_group(step, end)
582
+ return inner
583
+
584
+
585
+ def _dict_pprinter_factory(start, end):
586
+ """
587
+ Factory that returns a pprint function used by the default pprint of
588
+ dicts and dict proxies.
589
+ """
590
+ def inner(obj, p, cycle):
591
+ if cycle:
592
+ return p.text('{...}')
593
+ step = len(start)
594
+ p.begin_group(step, start)
595
+ keys = obj.keys()
596
+ # if dict isn't large enough to be truncated, sort keys before displaying
597
+ # From Python 3.7, dicts preserve order by definition, so we don't sort.
598
+ if not DICT_IS_ORDERED \
599
+ and not (p.max_seq_length and len(obj) >= p.max_seq_length):
600
+ keys = _sorted_for_pprint(keys)
601
+ for idx, key in p._enumerate(keys):
602
+ if idx:
603
+ p.text(',')
604
+ p.breakable()
605
+ p.pretty(key)
606
+ p.text(': ')
607
+ p.pretty(obj[key])
608
+ p.end_group(step, end)
609
+ return inner
610
+
611
+
612
+ def _super_pprint(obj, p, cycle):
613
+ """The pprint for the super type."""
614
+ p.begin_group(8, '<super: ')
615
+ p.pretty(obj.__thisclass__)
616
+ p.text(',')
617
+ p.breakable()
618
+ p.pretty(obj.__self__)
619
+ p.end_group(8, '>')
620
+
621
+
622
+ def _re_pattern_pprint(obj, p, cycle):
623
+ """The pprint function for regular expression patterns."""
624
+ p.text('re.compile(')
625
+ pattern = repr(obj.pattern)
626
+ if pattern[:1] in 'uU':
627
+ pattern = pattern[1:]
628
+ prefix = 'ur'
629
+ else:
630
+ prefix = 'r'
631
+ pattern = prefix + pattern.replace('\\\\', '\\')
632
+ p.text(pattern)
633
+ if obj.flags:
634
+ p.text(',')
635
+ p.breakable()
636
+ done_one = False
637
+ for flag in ('TEMPLATE', 'IGNORECASE', 'LOCALE', 'MULTILINE', 'DOTALL',
638
+ 'UNICODE', 'VERBOSE', 'DEBUG'):
639
+ if obj.flags & getattr(re, flag):
640
+ if done_one:
641
+ p.text('|')
642
+ p.text('re.' + flag)
643
+ done_one = True
644
+ p.text(')')
645
+
646
+
647
+ def _type_pprint(obj, p, cycle):
648
+ """The pprint for classes and types."""
649
+ # Heap allocated types might not have the module attribute,
650
+ # and others may set it to None.
651
+
652
+ # Checks for a __repr__ override in the metaclass. Can't compare the
653
+ # type(obj).__repr__ directly because in PyPy the representation function
654
+ # inherited from type isn't the same type.__repr__
655
+ if [m for m in _get_mro(type(obj)) if "__repr__" in vars(m)][:1] != [type]:
656
+ _repr_pprint(obj, p, cycle)
657
+ return
658
+
659
+ mod = _safe_getattr(obj, '__module__', None)
660
+ try:
661
+ name = obj.__qualname__
662
+ if not isinstance(name, str):
663
+ # This can happen if the type implements __qualname__ as a property
664
+ # or other descriptor in Python 2.
665
+ raise Exception("Try __name__")
666
+ except Exception:
667
+ name = obj.__name__
668
+ if not isinstance(name, str):
669
+ name = '<unknown type>'
670
+
671
+ if mod in (None, '__builtin__', 'builtins', 'exceptions'):
672
+ p.text(name)
673
+ else:
674
+ p.text(mod + '.' + name)
675
+
676
+
677
+ def _repr_pprint(obj, p, cycle):
678
+ """A pprint that just redirects to the normal repr function."""
679
+ # Find newlines and replace them with p.break_()
680
+ output = repr(obj)
681
+ for idx,output_line in enumerate(output.splitlines()):
682
+ if idx:
683
+ p.break_()
684
+ p.text(output_line)
685
+
686
+
687
+ def _function_pprint(obj, p, cycle):
688
+ """Base pprint for all functions and builtin functions."""
689
+ name = _safe_getattr(obj, '__qualname__', obj.__name__)
690
+ mod = obj.__module__
691
+ if mod and mod not in ('__builtin__', 'builtins', 'exceptions'):
692
+ name = mod + '.' + name
693
+ try:
694
+ func_def = name + str(signature(obj))
695
+ except ValueError:
696
+ func_def = name
697
+ p.text('<function %s>' % func_def)
698
+
699
+
700
+ def _exception_pprint(obj, p, cycle):
701
+ """Base pprint for all exceptions."""
702
+ name = getattr(obj.__class__, '__qualname__', obj.__class__.__name__)
703
+ if obj.__class__.__module__ not in ('exceptions', 'builtins'):
704
+ name = '%s.%s' % (obj.__class__.__module__, name)
705
+ step = len(name) + 1
706
+ p.begin_group(step, name + '(')
707
+ for idx, arg in enumerate(getattr(obj, 'args', ())):
708
+ if idx:
709
+ p.text(',')
710
+ p.breakable()
711
+ p.pretty(arg)
712
+ p.end_group(step, ')')
713
+
714
+
715
+ #: the exception base
716
+ try:
717
+ _exception_base = BaseException
718
+ except NameError:
719
+ _exception_base = Exception
720
+
721
+
722
+ #: printers for builtin types
723
+ _type_pprinters = {
724
+ int: _repr_pprint,
725
+ float: _repr_pprint,
726
+ str: _repr_pprint,
727
+ tuple: _seq_pprinter_factory('(', ')'),
728
+ list: _seq_pprinter_factory('[', ']'),
729
+ dict: _dict_pprinter_factory('{', '}'),
730
+
731
+ set: _set_pprinter_factory('{', '}'),
732
+ frozenset: _set_pprinter_factory('frozenset({', '})'),
733
+ super: _super_pprint,
734
+ _re_pattern_type: _re_pattern_pprint,
735
+ type: _type_pprint,
736
+ types.FunctionType: _function_pprint,
737
+ types.BuiltinFunctionType: _function_pprint,
738
+ types.MethodType: _repr_pprint,
739
+
740
+ datetime.datetime: _repr_pprint,
741
+ datetime.timedelta: _repr_pprint,
742
+ _exception_base: _exception_pprint
743
+ }
744
+
745
+ try:
746
+ # In PyPy, types.DictProxyType is dict, setting the dictproxy printer
747
+ # using dict.setdefault avoids overwritting the dict printer
748
+ _type_pprinters.setdefault(types.DictProxyType,
749
+ _dict_pprinter_factory('dict_proxy({', '})'))
750
+ _type_pprinters[types.ClassType] = _type_pprint
751
+ _type_pprinters[types.SliceType] = _repr_pprint
752
+ except AttributeError: # Python 3
753
+ _type_pprinters[types.MappingProxyType] = \
754
+ _dict_pprinter_factory('mappingproxy({', '})')
755
+ _type_pprinters[slice] = _repr_pprint
756
+
757
+ try:
758
+ _type_pprinters[long] = _repr_pprint
759
+ _type_pprinters[unicode] = _repr_pprint
760
+ except NameError:
761
+ _type_pprinters[range] = _repr_pprint
762
+ _type_pprinters[bytes] = _repr_pprint
763
+
764
+ #: printers for types specified by name
765
+ _deferred_type_pprinters = {
766
+ }
767
+
768
+ def for_type(typ, func):
769
+ """
770
+ Add a pretty printer for a given type.
771
+ """
772
+ oldfunc = _type_pprinters.get(typ, None)
773
+ if func is not None:
774
+ # To support easy restoration of old pprinters, we need to ignore Nones.
775
+ _type_pprinters[typ] = func
776
+ return oldfunc
777
+
778
+ def for_type_by_name(type_module, type_name, func):
779
+ """
780
+ Add a pretty printer for a type specified by the module and name of a type
781
+ rather than the type object itself.
782
+ """
783
+ key = (type_module, type_name)
784
+ oldfunc = _deferred_type_pprinters.get(key, None)
785
+ if func is not None:
786
+ # To support easy restoration of old pprinters, we need to ignore Nones.
787
+ _deferred_type_pprinters[key] = func
788
+ return oldfunc
789
+
790
+
791
+ #: printers for the default singletons
792
+ _singleton_pprinters = dict.fromkeys(map(id, [None, True, False, Ellipsis,
793
+ NotImplemented]), _repr_pprint)
794
+
795
+
796
+ def _defaultdict_pprint(obj, p, cycle):
797
+ name = obj.__class__.__name__
798
+ with p.group(len(name) + 1, name + '(', ')'):
799
+ if cycle:
800
+ p.text('...')
801
+ else:
802
+ p.pretty(obj.default_factory)
803
+ p.text(',')
804
+ p.breakable()
805
+ p.pretty(dict(obj))
806
+
807
+ def _ordereddict_pprint(obj, p, cycle):
808
+ name = obj.__class__.__name__
809
+ with p.group(len(name) + 1, name + '(', ')'):
810
+ if cycle:
811
+ p.text('...')
812
+ elif len(obj):
813
+ p.pretty(list(obj.items()))
814
+
815
+ def _deque_pprint(obj, p, cycle):
816
+ name = obj.__class__.__name__
817
+ with p.group(len(name) + 1, name + '(', ')'):
818
+ if cycle:
819
+ p.text('...')
820
+ else:
821
+ p.pretty(list(obj))
822
+
823
+
824
+ def _counter_pprint(obj, p, cycle):
825
+ name = obj.__class__.__name__
826
+ with p.group(len(name) + 1, name + '(', ')'):
827
+ if cycle:
828
+ p.text('...')
829
+ elif len(obj):
830
+ p.pretty(dict(obj))
831
+
832
+ for_type_by_name('collections', 'defaultdict', _defaultdict_pprint)
833
+ for_type_by_name('collections', 'OrderedDict', _ordereddict_pprint)
834
+ for_type_by_name('collections', 'deque', _deque_pprint)
835
+ for_type_by_name('collections', 'Counter', _counter_pprint)
836
+
837
+ if __name__ == '__main__':
838
+ from random import randrange
839
+ class Foo(object):
840
+ def __init__(self):
841
+ self.foo = 1
842
+ self.bar = re.compile(r'\s+')
843
+ self.blub = dict.fromkeys(range(30), randrange(1, 40))
844
+ self.hehe = 23424.234234
845
+ self.list = ["blub", "blah", self]
846
+
847
+ def get_foo(self):
848
+ print("foo")
849
+
850
+ pprint(Foo(), verbose=True)