Run black over validate.py

This commit is contained in:
rocky
2019-08-20 18:23:52 -04:00
parent 4a4a20995e
commit 8daedaf063

View File

@@ -1,16 +1,20 @@
# future # future
from __future__ import print_function from __future__ import print_function
# std # std
import os import os
import difflib import difflib
import subprocess import subprocess
import tempfile import tempfile
import functools import functools
# uncompyle6 / xdis # uncompyle6 / xdis
from uncompyle6 import PYTHON_VERSION, PYTHON3, IS_PYPY, code_deparse from uncompyle6 import PYTHON_VERSION, PYTHON3, IS_PYPY, code_deparse
# TODO : I think we can get xdis to support the dis api (python 3 version) by doing something like this there # TODO : I think we can get xdis to support the dis api (python 3 version) by doing something like this there
from xdis.bytecode import Bytecode from xdis.bytecode import Bytecode
from xdis.main import get_opcode from xdis.main import get_opcode
opc = get_opcode(PYTHON_VERSION, IS_PYPY) opc = get_opcode(PYTHON_VERSION, IS_PYPY)
Bytecode = functools.partial(Bytecode, opc=opc) Bytecode = functools.partial(Bytecode, opc=opc)
import six import six
@@ -20,6 +24,7 @@ if PYTHON3:
else: else:
from StringIO import StringIO from StringIO import StringIO
def _dis_to_text(co): def _dis_to_text(co):
return Bytecode(co).dis() return Bytecode(co).dis()
@@ -33,36 +38,32 @@ def print_diff(original, uncompyled):
:param original: Text describing the original code object. :param original: Text describing the original code object.
:param uncompyled: Text describing the uncompyled code object. :param uncompyled: Text describing the uncompyled code object.
""" """
original_lines = original.split('\n') original_lines = original.split("\n")
uncompyled_lines = uncompyled.split('\n') uncompyled_lines = uncompyled.split("\n")
args = original_lines, uncompyled_lines, 'original', 'uncompyled' args = original_lines, uncompyled_lines, "original", "uncompyled"
try: try:
from bs4 import BeautifulSoup from bs4 import BeautifulSoup
diff = difflib.HtmlDiff().make_file(*args) diff = difflib.HtmlDiff().make_file(*args)
diff = BeautifulSoup(diff, "html.parser") diff = BeautifulSoup(diff, "html.parser")
diff.select_one('table[summary="Legends"]').extract() diff.select_one('table[summary="Legends"]').extract()
except ImportError: except ImportError:
print('\nTo display diff highlighting run:\n pip install BeautifulSoup4') print("\nTo display diff highlighting run:\n pip install BeautifulSoup4")
diff = difflib.HtmlDiff().make_table(*args) diff = difflib.HtmlDiff().make_table(*args)
with tempfile.NamedTemporaryFile(delete=False) as f: with tempfile.NamedTemporaryFile(delete=False) as f:
f.write(str(diff).encode('utf-8')) f.write(str(diff).encode("utf-8"))
try: try:
print() print()
html = subprocess.check_output([ html = subprocess.check_output(
'elinks', ["elinks", "-dump", "-no-references", "-dump-color-mode", "1", f.name]
'-dump', ).decode("utf-8")
'-no-references',
'-dump-color-mode',
'1',
f.name,
]).decode('utf-8')
print(html) print(html)
except: except:
print('\nFor side by side diff install elinks') print("\nFor side by side diff install elinks")
diff = difflib.Differ().compare(original_lines, uncompyled_lines) diff = difflib.Differ().compare(original_lines, uncompyled_lines)
print('\n'.join(diff)) print("\n".join(diff))
finally: finally:
os.unlink(f.name) os.unlink(f.name)
@@ -80,18 +81,19 @@ def are_instructions_equal(i1, i2):
:return: True if the two instructions are approximately equal, otherwise False. :return: True if the two instructions are approximately equal, otherwise False.
""" """
result = (1 == 1 result = (
1 == 1
and i1.opname == i2.opname and i1.opname == i2.opname
and i1.opcode == i2.opcode and i1.opcode == i2.opcode
and i1.arg == i2.arg and i1.arg == i2.arg
# ignore differences due to code objects # ignore differences due to code objects
# TODO : Better way of ignoring address # TODO : Better way of ignoring address
and (i1.argval == i2.argval or '<code object' in str(i1.argval)) and (i1.argval == i2.argval or "<code object" in str(i1.argval))
# TODO : Should probably recurse to check code objects # TODO : Should probably recurse to check code objects
and (i1.argrepr == i2.argrepr or '<code object' in i1.argrepr) and (i1.argrepr == i2.argrepr or "<code object" in i1.argrepr)
and i1.offset == i2.offset and i1.offset == i2.offset
# ignore differences in line numbers # ignore differences in line numbers
#and i1.starts_line # and i1.starts_line
and i1.is_jump_target == i2.is_jump_target and i1.is_jump_target == i2.is_jump_target
) )
return result return result
@@ -115,22 +117,21 @@ def are_code_objects_equal(co1, co2):
return True return True
def validate_uncompyle(text, mode='exec'): def validate_uncompyle(text, mode="exec"):
""" """
Validate decompilation of the given source code. Validate decompilation of the given source code.
:param text: Source to validate decompilation of. :param text: Source to validate decompilation of.
""" """
original_code = compile(text, '<string>', mode) original_code = compile(text, "<string>", mode)
original_dis = _dis_to_text(original_code) original_dis = _dis_to_text(original_code)
original_text = text original_text = text
deparsed = code_deparse(original_code, deparsed = code_deparse(
out=six.StringIO(), original_code, out=six.StringIO(), version=PYTHON_VERSION, compile_mode=mode
version=PYTHON_VERSION, )
compile_mode=mode)
uncompyled_text = deparsed.text uncompyled_text = deparsed.text
uncompyled_code = compile(uncompyled_text, '<string>', 'exec') uncompyled_code = compile(uncompyled_text, "<string>", "exec")
if not are_code_objects_equal(uncompyled_code, original_code): if not are_code_objects_equal(uncompyled_code, original_code):
@@ -138,15 +139,17 @@ def validate_uncompyle(text, mode='exec'):
def output(text, dis): def output(text, dis):
width = 60 width = 60
return '\n\n'.join([ return "\n\n".join(
' SOURCE CODE '.center(width, '#'), [
text.strip(), " SOURCE CODE ".center(width, "#"),
' BYTECODE '.center(width, '#'), text.strip(),
dis " BYTECODE ".center(width, "#"),
]) dis,
]
)
original = output(original_text, original_dis) original = output(original_text, original_dis)
uncompyled = output(uncompyled_text, uncompyled_dis) uncompyled = output(uncompyled_text, uncompyled_dis)
print_diff(original, uncompyled) print_diff(original, uncompyled)
assert 'original' == 'uncompyled' assert "original" == "uncompyled"