over/core/misc.py
2015-08-11 21:05:44 +02:00

136 lines
3 KiB
Python

#! /usr/bin/env python3
# encoding: utf-8
import copy
import imp
import math
import os
import sys
# --------------------------------------------------
def import_module(path):
'''
Imports a python file as a module. The path can be relative or absolute.
Based on the work of Yuval Greenfield released into the public domain.
'''
# remove the .py suffix
mod_dn = os.path.dirname(path)
mod_fn = os.path.basename(path)
if mod_fn.endswith('.py'):
mod_name = mod_fn[:-3]
else:
# packages for example
mod_name = mod_fn
fd = None
try:
data = imp.find_module(mod_name, [mod_dn])
module = imp.load_module(mod_name, *data)
fd = data[0]
finally:
if fd is not None:
fd.close()
return module
# --------------------------------------------------
def batch_gen(data, batch_size):
'''
Split data (a sequence) into sequences batch_size elements long.
'''
for i in range(0, len(data), batch_size):
yield data[i:i+batch_size]
# --------------------------------------------------
def console(locals, globals=None, tab_completion=False):
'''
Opens up a Python console.
tab_completion enables completion of object names using TAB, however note
that this will make pasting formatted snippets of code difficult
'''
import code, readline, rlcompleter
environment = copy.copy(locals)
if globals:
for key, value in globals.items():
if key not in environment:
environment[key] = value
if tab_completion:
readline.parse_and_bind('tab: complete')
c = code.InteractiveConsole(environment)
c.interact(banner='')
# --------------------------------------------------
def debugger():
'''
Drops into the Python Debugger where called.
'''
import pdb
pdb.set_trace()
# --------------------------------------------------
def hexdump(data, indent=0, offset=16, show_offsets=True, show_ascii=True, output=sys.stdout):
"""
Writes a hex dump of 'data' to 'output'.
The output text is indented with spaces and contains 'offset' bytes per line.
If show_offsets is True, each line is prefixed with the address of the first byte of that line.
If show_ascii is True, each line is suffixed with its ASCII representation. Unprintable characters
are replaced with a dot.
The 'output' must implement a .write(str) method.
"""
if type(data) is not bytes:
raise ValueError('data must be bytes')
format_str = '%%0%dx ' %(math.ceil(math.log2(len(data)) / 8) * 2)
ptr = 0
while data[ptr:]:
if indent:
output.write(' ' * indent)
if show_offsets:
output.write(format_str %(ptr))
hex_bytes = []
ascii_bytes = []
for local_i, i in enumerate(range(ptr, ptr+offset)):
if i < len(data):
c = data[i]
hex_bytes.append('%02x' %(c))
if 0x20 <= c <= 0x7e:
ascii_bytes.append(chr(c))
else:
ascii_bytes.append('.')
elif i == len(data):
hex_bytes.extend([' '] * (offset - local_i))
output.write(' '.join(hex_bytes))
if show_ascii:
output.write(' ' + ''.join(ascii_bytes))
output.write('\n')
ptr += offset