This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: Switch to make pprint.pprint display ints and longs in hex
Type: enhancement Stage:
Components: Library (Lib) Versions:
process
Status: closed Resolution: accepted
Dependencies: Superseder:
Assigned To: anthonybaxter Nosy List: anthonybaxter, doerwalter, georg.brandl, georg.brandl, gvanrossum, markhirota, rhettinger
Priority: normal Keywords:

Created on 2005-11-08 21:29 by markhirota, last changed 2022-04-11 14:56 by admin. This issue is now closed.

Files
File name Uploaded Description Edit
pprintmod.py markhirota, 2005-11-14 19:20 Modified pprint.py
pprint.diff doerwalter, 2005-11-16 18:29
Messages (17)
msg54663 - (view) Author: Mark Hirota (markhirota) Date: 2005-11-08 21:29
It would be nice to have some sort of switch or hook to 
allow 'pretty-printing' of integers and long integers in 
hexidecimal. So, for example:

>>> import pprint
>>> pprint.pprint(range(10)) # instead of this:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> pprint.hexint = True
>>> pprint.pprint(range(10)) # you would get this:
[0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9]
>>> pprint.pprint(range(0x100000000,0x100000010)) # 
and this:
[0x100000000L,
 0x100000001L,
 0x100000002L,
 0x100000003L,
 0x100000004L,
 0x100000005L,
 0x100000006L,
 0x100000007L,
 0x100000008L,
 0x100000009L,
 0x10000000AL,
 0x10000000BL,
 0x10000000CL,
 0x10000000DL,
 0x10000000EL,
 0x10000000FL]
>>>

Thanks,
--MH
msg54664 - (view) Author: Georg Brandl (georg.brandl) * (Python committer) Date: 2005-11-09 21:45
Logged In: YES 
user_id=1188172

Moving to Feature Requests.
msg54665 - (view) Author: Walter Dörwald (doerwalter) * (Python committer) Date: 2005-11-10 22:56
Logged In: YES 
user_id=89016

In theory this should be possible by subclassing
pprint.PrettyPrinter and overwritting the format method:

import pprint

class MyPrettyPrinter(pprint.PrettyPrinter):
  def format(self, object, context, maxlevels, level):
    if isinstance(object, int):
      return hex(object), True, False
    else:
      return pprint.PrettyPrinter.format(self, object,
context, maxlevels, level)

mpp = MyPrettyPrinter()
mpp.pprint(range(50))

This doesn't work reliable though: When the string is short
enough, format() seems to be bypassed and repr() is called
directly.
msg54666 - (view) Author: Mark Hirota (markhirota) Date: 2005-11-11 17:47
Logged In: YES 
user_id=1375527

Is this bypassing considered a limitation or a bug?  I am, 
however, able to workaround the issue by setting the 
width=1: "mpp = MyPrettyPrinter(1,1)" -- it just means that 
instead of:

>>> mpp.pprint(range(10))
[0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9]

I get instead:

>>> mpp.pprint(range(10))
[0x0,
 0x1,
 0x2,
 0x3,
 0x4,
 0x5,
 0x6,
 0x7,
 0x8,
 0x9]

...which is OK for my uses.  Thanks!
msg54667 - (view) Author: Walter Dörwald (doerwalter) * (Python committer) Date: 2005-11-12 19:29
Logged In: YES 
user_id=89016

I think it's more of a limitation. I seems to me the main
focus in implementing pprint was speed not extensibility.
The code uses every trick in the book (e.g. turning globals
and builtins into locals, using bound methods etc.). I think
it was never ment to do anything other than what repr()
does, but with better formatting. However IMHO making pprint
extensible would be a worthwile project.
msg54668 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2005-11-12 20:02
Logged In: YES 
user_id=80475

IMO, such a rewrite would expose too many of pprint's
internals and make the module harder to
use/understand/maintain.  Wouldn't it be better to stick
with the usual idiom for controlling the repr() formatting
of specific types by using a class wrapper:

>>> from pprint import pprint
>>> class Int(int):
	def __repr__(self):
		return hex(self)

>>> pprint([Int(x) for x in range(0x10000000,0x10000010)])
[0x10000000,
 0x10000001,
 0x10000002,
 0x10000003,
 0x10000004,
 0x10000005,
 0x10000006,
 0x10000007,
 0x10000008,
 0x10000009,
 0x1000000a,
 0x1000000b,
 0x1000000c,
 0x1000000d,
 0x1000000e,
 0x1000000f]
msg54669 - (view) Author: Walter Dörwald (doerwalter) * (Python committer) Date: 2005-11-14 09:54
Logged In: YES 
user_id=89016

I find pprint.py hard to understand as it is. I've been
staring at the code for several days now and the difference
between PrettyPrinter._format(), PrettyPrinter.format(),
PrettyPrinter._repr() and _safe_repr() is still not entirely
clear to me.

Using a subclass of int only makes sense, if it's your own
data structure that you're outputting. If you get it from
somewhere else, traversing it and replacing every int with
an Int just for output really isn't an option.
msg54670 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2005-11-14 11:19
Logged In: YES 
user_id=80475

Fred, any thoughts on the vision for your module?

IMHO,  pprinting containers with ints represented in hex is
not an especially compelling motivation for a total rewrite.
 OTOH, it would be nice if the module were easily extensible..
msg54671 - (view) Author: Mark Hirota (markhirota) Date: 2005-11-14 17:04
Logged In: YES 
user_id=1375527

Sorry, but maybe I could just interject here. Walter's sub-
classing example works fine, except for the fact that if the 
string is short enough, it gets handled slightly differently and 
the format() override gets bypassed.  I worked around this by 
shortening the width, but I've found that this screws with a lot 
of the nice formatting of other structures, and so basically 
creates a new set of problems.  If the "format() bypass" 
limitation can be removed, I think it would allow for more 
reliable extensibility by subclassing PrettyPrinter.
msg54672 - (view) Author: Mark Hirota (markhirota) Date: 2005-11-14 18:33
Logged In: YES 
user_id=1375527

Did some digging into the code and found that the "if 
sepLines:" condition in the PrettyPrinter._format() method 
was the source of the limitation.

I've attached a modified version of pprint.py where the "if 
sepLines" is more embedded.  It gives the following results:

>>> import pprintmod
>>> class MyPrettyPrinter(pprintmod.PrettyPrinter):
	def format(self, object, context, maxlevels, level):
		if isinstance(object, int):
			return hex(object), True, 
False
		else:
			return 
pprintmod.PrettyPrinter.format(
				self, object, 
context, maxlevels, level)

		
>>> mpp = MyPrettyPrinter()
>>> mpp.pprint(range(10))
[0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9]
>>> mpp.pprint(range(0x10000000,0x10000010))
[0x10000000,
 0x10000001,
 0x10000002,
 0x10000003,
 0x10000004,
 0x10000005,
 0x10000006,
 0x10000007,
 0x10000008,
 0x10000009,
 0x1000000a,
 0x1000000b,
 0x1000000c,
 0x1000000d,
 0x1000000e,
 0x1000000f]
>>> 

Would this be an acceptable change?  Thanks,
msg54673 - (view) Author: Walter Dörwald (doerwalter) * (Python committer) Date: 2005-11-16 18:29
Logged In: YES 
user_id=89016

Here's your modified version as a patch against svn HEAD.
(Most of the patch is indentation changes. "svn diff
--diff-cmd diff -x -b Lib/pprint.py" gives this diff:

134d133
<         if sepLines:
154a154
>                         if sepLines:
155a156,157
>                         else:
>                             write(', %s: ' % rep)
180a183
>                         if sepLines:
181a185,186
>                         else:
>                             write(', ')
190d194
< 
192a197
>

The patch looks good, but it still has a problem that the
original pprint has: For each call to format() the object is
formatted twice, once to determine if it fits on one line
and once for the final output.
msg54674 - (view) Author: Mark Hirota (markhirota) Date: 2005-11-17 01:04
Logged In: YES 
user_id=1375527

Walter, I agree that there still seems to be an issue with 
_format() calling _repr() multiple times, however this 
patch seems to enable my feature request using sub-
classing.  Can the other issue (which exists presently 
also) be ignored for now?  Could you submit the patch, or 
is that something I should do?  Thanks.
msg54675 - (view) Author: Walter Dörwald (doerwalter) * (Python committer) Date: 2005-11-22 20:56
Logged In: YES 
user_id=89016

I think this patch can go in. Any objections from Raymond or
Fred against this?
msg54676 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2006-04-05 23:11
Logged In: YES 
user_id=6380

What's this waiting for?
msg54677 - (view) Author: Walter Dörwald (doerwalter) * (Python committer) Date: 2006-04-06 13:02
Logged In: YES 
user_id=89016

Can this still be checked in after 2.5a1 is out the door? It
is a new feature not just a bug fix.
msg54678 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2006-04-06 18:13
Logged In: YES 
user_id=6380

IMO yes. Assigning to Anthony for pronouncement (it's a
pretty small feature as features go). Feature freeze isn't
until beta 1 is shipped (although for bigger features we'd
like to see them in, in rough form, sooner, of course).

Anthony, feel free to assign back to Walter to check it in
if you're ok with that.
msg61269 - (view) Author: Georg Brandl (georg.brandl) * (Python committer) Date: 2008-01-20 11:13
Committed to trunk in r60131.
History
Date User Action Args
2022-04-11 14:56:14adminsetgithub: 42570
2008-01-20 11:13:42georg.brandlsetstatus: open -> closed
nosy: + georg.brandl
resolution: accepted
messages: + msg61269
2005-11-08 21:29:22markhirotacreate