From aee113d368ebad8a51386baa7c0aec056aca94d5 Mon Sep 17 00:00:00 2001 From: Fred Drake Date: Tue, 2 Apr 2002 05:08:35 +0000 Subject: Add an experimental mechanism to support extending the pprint formatting. Partly responds to SF bug #505152. --- Doc/lib/libpprint.tex | 23 +++++++++++++++++++++++ Lib/pprint.py | 22 +++++++++++++--------- Lib/test/test_pprint.py | 21 +++++++++++++++++++++ 3 files changed, 57 insertions(+), 9 deletions(-) diff --git a/Doc/lib/libpprint.tex b/Doc/lib/libpprint.tex index 3ecc7bc..22ffd7b 100644 --- a/Doc/lib/libpprint.tex +++ b/Doc/lib/libpprint.tex @@ -173,3 +173,26 @@ this returns false. \begin{methoddesc}{isrecursive}{object} Determine if the object requires a recursive representation. \end{methoddesc} + +This method is provided as a hook to allow subclasses to modify the +way objects are converted to strings. The default implementation uses +the internals of the \function{saferepr()} implementation. + +\begin{methoddesc}{format}{object, context, maxlevels, level} +Returns three values: the formatted version of \var{object} as a +string, a flag indicating whether the result is readable, and a flag +indicating whether recursion was detected. The first argument is the +object to be presented. The second is a dictionary which contains the +\function{id()} of objects that are part of the current presentation +context (direct and indirect containers for \var{object} that are +affecting the presentation) as the keys; if an object needs to be +presented which is already represented in \var{context}, the third +return value should be true. Recursive calls to the \method{format()} +method should add additionaly entries for containers to this +dictionary. The fourth argument, \var{maxlevels}, gives the requested +limit to recursion; this will be \code{0} if there is no requested +limit. This argument should be passed unmodified to recursive calls. +The fourth argument, \var{level} gives the current level; recursive +calls should be passed a value less than that of the current call. +\versionadded{2.3} +\end{methoddesc} diff --git a/Lib/pprint.py b/Lib/pprint.py index 5d178a2..82eeac6 100644 --- a/Lib/pprint.py +++ b/Lib/pprint.py @@ -115,15 +115,11 @@ class PrettyPrinter: return sio.getvalue() def isrecursive(self, object): - self.__recursive = 0 - self.__repr(object, {}, 0) - return self.__recursive + return self.format(object, {}, 0)[2] def isreadable(self, object): - self.__recursive = 0 - self.__readable = 1 - self.__repr(object, {}, 0) - return self.__readable and not self.__recursive + s, readable, recursive = self.format(object, {}, 0) + return readable and not recursive def __format(self, object, stream, indent, allowance, context, level): level = level + 1 @@ -196,14 +192,22 @@ class PrettyPrinter: write(rep) def __repr(self, object, context, level): - repr, readable, recursive = _safe_repr(object, context, - self.__depth, level) + repr, readable, recursive = self.format(object, context.copy(), + self.__depth, level) if not readable: self.__readable = 0 if recursive: self.__recursive = 1 return repr + def format(self, object, context, maxlevels, level): + """Format object for a specific context, returning a string + and flags indicating whether the representation is 'readable' + and whether the object represents a recursive construct. + """ + return _safe_repr(object, context, maxlevels, level) + + # Return triple (repr_string, isreadable, isrecursive). def _safe_repr(object, context, maxlevels, level): diff --git a/Lib/test/test_pprint.py b/Lib/test/test_pprint.py index 14626fb..d5e10aa 100644 --- a/Lib/test/test_pprint.py +++ b/Lib/test/test_pprint.py @@ -96,6 +96,27 @@ class QueryTestCase(unittest.TestCase): 'write_io_runtime_us': 43690}""" self.assertEqual(pprint.pformat(o), exp) + def test_subclassing(self): + o = {'names with spaces': 'should be presented using repr()', + 'others.should.not.be': 'like.this'} + exp = """\ +{'names with spaces': 'should be presented using repr()', + others.should.not.be: like.this}""" + self.assertEqual(DottedPrettyPrinter().pformat(o), exp) + + +class DottedPrettyPrinter(pprint.PrettyPrinter): + def format(self, object, context, maxlevels, level): + if isinstance(object, str): + if ' ' in object: + return `object`, 1, 0 + else: + return object, 0, 0 + else: + return pprint.PrettyPrinter.format( + self, object, context, maxlevels, level) + + def test_main(): test_support.run_unittest(QueryTestCase) -- cgit v0.12