mirror of
https://github.com/rocky/python-uncompyle6.git
synced 2024-11-30 08:30:50 +00:00
235 lines
6.5 KiB
Python
Executable File
235 lines
6.5 KiB
Python
Executable File
#!/usr/bin/env python
|
|
# emacs-mode: -*-python-*-
|
|
"""
|
|
test_pyenvlib -- uncompyle and verify Python libraries
|
|
|
|
Usage-Examples:
|
|
|
|
test_pyenvlib.py --all # decompile all tests (suite + libs)
|
|
test_pyenvlib.py --all --verify # decomyile all tests and verify results
|
|
test_pyenvlib.py --test # decompile only the testsuite
|
|
test_pyenvlib.py --2.7.12 --verify # decompile and verify python lib 2.7.11
|
|
test_pyenvlib.py --3.6.4 --max 10 # decompile first 10 of 3.6.4
|
|
|
|
Adding own test-trees:
|
|
|
|
Step 1) Edit this file and add a new entry to 'test_options', eg.
|
|
test_options['mylib'] = ('/usr/lib/mylib', PYOC, 'mylib')
|
|
Step 2: Run the test:
|
|
test_pyenvlib --mylib # decompile 'mylib'
|
|
test_pyenvlib --mylib --verify # decompile verify 'mylib'
|
|
"""
|
|
|
|
from __future__ import print_function
|
|
|
|
import os, time, re, shutil, sys
|
|
from fnmatch import fnmatch
|
|
|
|
from uncompyle6 import main, PYTHON3
|
|
import xdis.magics as magics
|
|
|
|
# ----- configure this for your needs
|
|
|
|
python_versions = [v for v in magics.python_versions if re.match("^[0-9.]+$", v)]
|
|
|
|
# FIXME: we should remove Python versions that we don't support.
|
|
# These include Jython, and Python bytecode changes pre release.
|
|
|
|
TEST_VERSIONS = (
|
|
"pypy3-2.4.0",
|
|
"pypy-2.6.1",
|
|
"pypy-5.0.1",
|
|
"pypy-5.3.1",
|
|
"pypy3.5-5.7.1-beta",
|
|
"pypy3.5-5.9.0",
|
|
"pypy3.5-6.0.0",
|
|
"pypy3.6-7.1.0",
|
|
"pypy3.6-7.1.1",
|
|
"pypy3.6-7.2.0",
|
|
"native",
|
|
) + tuple(python_versions)
|
|
|
|
|
|
target_base = "/tmp/py-dis/"
|
|
lib_prefix = os.path.join(os.environ["HOME"], ".pyenv/versions")
|
|
|
|
PYC = ("*.pyc",)
|
|
PYO = ("*.pyo",)
|
|
PYOC = ("*.pyc", "*.pyo")
|
|
|
|
# -----
|
|
|
|
test_options = {
|
|
# name: (src_basedir, pattern, output_base_suffix)
|
|
"test": ("./test", PYOC, "test"),
|
|
"max=": 200,
|
|
}
|
|
|
|
for vers in TEST_VERSIONS:
|
|
if vers.startswith("pypy"):
|
|
if vers.startswith("pypy3."):
|
|
short_vers = vers[4:6]
|
|
else:
|
|
short_vers = vers[0:-2]
|
|
|
|
test_options[vers] = (
|
|
os.path.join(lib_prefix, vers, "lib_pypy"),
|
|
PYC,
|
|
"python-lib" + short_vers,
|
|
)
|
|
else:
|
|
if vers == "native":
|
|
short_vers = os.path.basename(sys.path[-1])
|
|
from xdis import PYTHON_VERSION
|
|
if PYTHON_VERSION > 3.0:
|
|
PYC = "*.cpython-%d.pyc" % int(PYTHON_VERSION * 10)
|
|
test_options[vers] = (sys.path[-1], PYC, short_vers)
|
|
else:
|
|
short_vers = vers[:3]
|
|
test_options[vers] = (
|
|
os.path.join(lib_prefix, vers, "lib", "python" + short_vers),
|
|
PYC,
|
|
"python-lib" + short_vers,
|
|
)
|
|
|
|
|
|
def do_tests(
|
|
src_dir, patterns, target_dir, start_with=None, do_verify=False, max_files=200
|
|
):
|
|
def visitor(files, dirname, names):
|
|
files.extend(
|
|
[
|
|
os.path.normpath(os.path.join(dirname, n))
|
|
for n in names
|
|
for pat in patterns
|
|
if fnmatch(n, pat)
|
|
]
|
|
)
|
|
|
|
files = []
|
|
cwd = os.getcwd()
|
|
os.chdir(src_dir)
|
|
if PYTHON3:
|
|
for root, dirname, names in os.walk(os.curdir):
|
|
files.extend(
|
|
[
|
|
os.path.normpath(os.path.join(root, n))
|
|
for n in names
|
|
for pat in patterns
|
|
if fnmatch(n, pat)
|
|
]
|
|
)
|
|
pass
|
|
pass
|
|
else:
|
|
os.path.walk(os.curdir, visitor, files)
|
|
os.chdir(cwd)
|
|
files.sort()
|
|
|
|
if start_with:
|
|
try:
|
|
start_with = files.index(start_with)
|
|
files = files[start_with:]
|
|
print(">>> starting with file", files[0])
|
|
except ValueError:
|
|
pass
|
|
|
|
if len(files) > max_files:
|
|
files = [file for file in files if not "site-packages" in file and (file.endswith(".pyo") or file.endswith(".pyc"))]
|
|
files = [file for file in files if not "test" in file and (file.endswith(".pyo") or file.endswith(".pyc"))]
|
|
if len(files) > max_files:
|
|
# print("Number of files %d - truncating to last 200" % len(files))
|
|
print(
|
|
"Number of files %d - truncating to first %s" % (len(files), max_files)
|
|
)
|
|
files = files[:max_files]
|
|
|
|
print(time.ctime())
|
|
(tot_files, okay_files, failed_files, verify_failed_files) = main.main(
|
|
src_dir, target_dir, files, [], do_verify=do_verify
|
|
)
|
|
print(time.ctime())
|
|
return verify_failed_files + failed_files
|
|
|
|
|
|
if __name__ == "__main__":
|
|
import getopt, sys
|
|
|
|
do_coverage = do_verify = False
|
|
test_dirs = []
|
|
start_with = None
|
|
|
|
test_options_keys = list(test_options.keys())
|
|
test_options_keys.sort()
|
|
opts, args = getopt.getopt(
|
|
sys.argv[1:],
|
|
"",
|
|
[
|
|
"start-with=",
|
|
"verify",
|
|
"verify-run",
|
|
"syntax-verify",
|
|
"max=",
|
|
"coverage",
|
|
"all",
|
|
]
|
|
+ test_options_keys,
|
|
)
|
|
vers = ""
|
|
|
|
for opt, val in opts:
|
|
if opt == "--verify":
|
|
do_verify = "strong"
|
|
elif opt == "--syntax-verify":
|
|
do_verify = "weak"
|
|
elif opt == "--verify-run":
|
|
do_verify = "verify-run"
|
|
elif opt == "--coverage":
|
|
do_coverage = True
|
|
elif opt == "--start-with":
|
|
start_with = val
|
|
elif opt[2:] in test_options_keys:
|
|
triple = test_options[opt[2:]]
|
|
vers = triple[-1]
|
|
test_dirs.append(triple)
|
|
elif opt == "--max":
|
|
test_options["max="] = int(val)
|
|
elif opt == "--all":
|
|
vers = "all"
|
|
for val in test_options_keys:
|
|
test_dirs.append(test_options[val])
|
|
|
|
if do_coverage:
|
|
os.environ["SPARK_PARSER_COVERAGE"] = "/tmp/spark-grammar-%s.cover" % vers
|
|
|
|
failed = 0
|
|
for src_dir, pattern, target_dir in test_dirs:
|
|
if os.path.exists(src_dir):
|
|
target_dir = os.path.join(target_base, target_dir)
|
|
if os.path.exists(target_dir):
|
|
shutil.rmtree(target_dir, ignore_errors=1)
|
|
failed += do_tests(
|
|
src_dir,
|
|
pattern,
|
|
target_dir,
|
|
start_with,
|
|
do_verify,
|
|
test_options["max="],
|
|
)
|
|
else:
|
|
print("### Path %s doesn't exist; skipping" % src_dir)
|
|
pass
|
|
pass
|
|
sys.exit(failed)
|
|
|
|
# python 1.5:
|
|
|
|
# test/re_tests memory error
|
|
# test/test_b1 memory error
|
|
|
|
# Verification notes:
|
|
# - xdrlib fails verification due the same lambda used twice
|
|
# (verification is successful when using original .pyo as
|
|
# input)
|
|
#
|