Skip to content

Commit 06a8916

Browse files
carlbordummiss-islington
authored andcommitted
bpo-37376: pprint support for SimpleNamespace (GH-14318)
https://bugs.python.org/issue37376
1 parent d52a83a commit 06a8916

File tree

6 files changed

+98
-0
lines changed

6 files changed

+98
-0
lines changed

Doc/library/pprint.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ width constraint.
2525

2626
Dictionaries are sorted by key before the display is computed.
2727

28+
.. versionchanged:: 3.9
29+
Added support for pretty-printing :class:`types.SimpleNamespace`.
30+
2831
The :mod:`pprint` module defines one class:
2932

3033
.. First the implementation class:

Doc/whatsnew/3.9.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,12 @@ threads were never supported in subinterpreters. Previously, the subinterpreter
111111
finalization crashed with a Pyton fatal error if a daemon thread was still
112112
running.
113113

114+
pprint
115+
------
116+
117+
:mod:`pprint` can now pretty-print :class:`types.SimpleNamespace`.
118+
(Contributed by Carl Bordum Hansen in :issue:`37376`.)
119+
114120

115121
Optimizations
116122
=============

Lib/pprint.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,33 @@ def _pprint_mappingproxy(self, object, stream, indent, allowance, context, level
342342

343343
_dispatch[_types.MappingProxyType.__repr__] = _pprint_mappingproxy
344344

345+
def _pprint_simplenamespace(self, object, stream, indent, allowance, context, level):
346+
if type(object) is _types.SimpleNamespace:
347+
# The SimpleNamespace repr is "namespace" instead of the class
348+
# name, so we do the same here. For subclasses; use the class name.
349+
cls_name = 'namespace'
350+
else:
351+
cls_name = object.__class__.__name__
352+
indent += len(cls_name) + 1
353+
delimnl = ',\n' + ' ' * indent
354+
items = object.__dict__.items()
355+
last_index = len(items) - 1
356+
357+
stream.write(cls_name + '(')
358+
for i, (key, ent) in enumerate(items):
359+
stream.write(key)
360+
stream.write('=')
361+
362+
last = i == last_index
363+
self._format(ent, stream, indent + len(key) + 1,
364+
allowance if last else 1,
365+
context, level)
366+
if not last:
367+
stream.write(delimnl)
368+
stream.write(')')
369+
370+
_dispatch[_types.SimpleNamespace.__repr__] = _pprint_simplenamespace
371+
345372
def _format_dict_items(self, items, stream, indent, allowance, context,
346373
level):
347374
write = stream.write

Lib/test/test_pprint.py

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,65 @@ def test_mapping_proxy(self):
346346
('lazy', 7),
347347
('dog', 8)]))""")
348348

349+
def test_empty_simple_namespace(self):
350+
ns = types.SimpleNamespace()
351+
formatted = pprint.pformat(ns)
352+
self.assertEqual(formatted, "namespace()")
353+
354+
def test_small_simple_namespace(self):
355+
ns = types.SimpleNamespace(a=1, b=2)
356+
formatted = pprint.pformat(ns)
357+
self.assertEqual(formatted, "namespace(a=1, b=2)")
358+
359+
def test_simple_namespace(self):
360+
ns = types.SimpleNamespace(
361+
the=0,
362+
quick=1,
363+
brown=2,
364+
fox=3,
365+
jumped=4,
366+
over=5,
367+
a=6,
368+
lazy=7,
369+
dog=8,
370+
)
371+
formatted = pprint.pformat(ns, width=60)
372+
self.assertEqual(formatted, """\
373+
namespace(the=0,
374+
quick=1,
375+
brown=2,
376+
fox=3,
377+
jumped=4,
378+
over=5,
379+
a=6,
380+
lazy=7,
381+
dog=8)""")
382+
383+
def test_simple_namespace_subclass(self):
384+
class AdvancedNamespace(types.SimpleNamespace): pass
385+
ns = AdvancedNamespace(
386+
the=0,
387+
quick=1,
388+
brown=2,
389+
fox=3,
390+
jumped=4,
391+
over=5,
392+
a=6,
393+
lazy=7,
394+
dog=8,
395+
)
396+
formatted = pprint.pformat(ns, width=60)
397+
self.assertEqual(formatted, """\
398+
AdvancedNamespace(the=0,
399+
quick=1,
400+
brown=2,
401+
fox=3,
402+
jumped=4,
403+
over=5,
404+
a=6,
405+
lazy=7,
406+
dog=8)""")
407+
349408
def test_subclassing(self):
350409
o = {'names with spaces': 'should be presented using repr()',
351410
'others.should.not.be': 'like.this'}

Misc/ACKS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -628,6 +628,7 @@ Mark Hammond
628628
Harald Hanche-Olsen
629629
Manus Hand
630630
Milton L. Hankins
631+
Carl Bordum Hansen
631632
Stephen Hansen
632633
Barry Hantman
633634
Lynda Hardman
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
:mod:`pprint` now has support for :class:`types.SimpleNamespace`. Patch by Carl
2+
Bordum Hansen.

0 commit comments

Comments
 (0)