Skip to content

Instantly share code, notes, and snippets.

@droogie
Created April 23, 2022 07:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save droogie/b343ff6cf61104640c21d5f492592594 to your computer and use it in GitHub Desktop.
Save droogie/b343ff6cf61104640c21d5f492592594 to your computer and use it in GitHub Desktop.
python displayhook wrapper for printing ints in hex
from collections.abc import Generator, Iterable, Mapping
import builtins
import itertools
import sys
# this is a fork of https://github.com/CouleeApps/hex_integers
# modified for use with the default python interpreter
# place in ~/.pyrc
# $ export PYTHONSTARTUP=~/.pyrc
original_displayhook = sys.__displayhook__
GENERATOR_MAX_LENGTH = 100
def convert_to_hexint(value, seen, top=False):
if value in seen:
return "<recursion>"
seen = seen + [value]
if isinstance(value, (bool,)):
return repr(value)
elif value is None:
return
elif isinstance(value, (int,)):
# Could be an enum or something else with a custom repr()
if value.__repr__.__qualname__ != 'int.__repr__':
if top:
# Enums already include the decimal in repr()
if f"{value}" in repr(value):
return f"{repr(value)} / 0x{value:x}"
else:
return f"{repr(value)} / {value} / 0x{value:x}"
else:
return repr(value)
else:
if top:
return f"{value} / 0x{value:x}"
else:
return f"0x{value:x}"
elif isinstance(value, (float,)) and (value % 1) < 0.0001:
value = int(value)
if top:
return f"~{value} / ~0x{value:x}"
else:
return f"~0x{value:x}"
elif isinstance(value, (str,)):
return repr(value)
elif isinstance(value, (tuple,)):
return '(' + ', '.join(convert_to_hexint(v, seen) for v in value) + ')'
elif isinstance(value, (list,)):
return '[' + ', '.join(convert_to_hexint(v, seen) for v in value) + ']'
elif isinstance(value, (dict,)):
return '{' + ', '.join(convert_to_hexint(k, seen) + ': ' + convert_to_hexint(v, seen) for k,v in value.items()) + '}'
elif isinstance(value, (set,)):
return '{' + ', '.join(convert_to_hexint(v, seen) for v in value) + '}'
elif value is Ellipsis:
return '...'
else:
return repr(value)
def new_displayhook(value):
# Python docs say:
# Set '_' to None to avoid recursion
builtins._ = None
value_copy = value
if (isinstance(value, (Generator,)) or hasattr(type(value), '__next__')):
# Save generator state so we don't consume _
value_copy, value = itertools.tee(value, 2)
conts = []
for v in value:
if len(conts) >= GENERATOR_MAX_LENGTH:
conts.append(Ellipsis)
break
conts.append(v)
print('(generator) ' + convert_to_hexint(conts, [], True))
else:
result = convert_to_hexint(value, [], True)
if result:
print(result)
builtins._ = value_copy
setattr(sys, 'displayhook', new_displayhook)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment