diff options
Diffstat (limited to 'python/pytest/_pytest/genscript.py')
-rwxr-xr-x | python/pytest/_pytest/genscript.py | 132 |
1 files changed, 132 insertions, 0 deletions
diff --git a/python/pytest/_pytest/genscript.py b/python/pytest/_pytest/genscript.py new file mode 100755 index 000000000..d2962d8fc --- /dev/null +++ b/python/pytest/_pytest/genscript.py @@ -0,0 +1,132 @@ +""" (deprecated) generate a single-file self-contained version of pytest """ +import os +import sys +import pkgutil + +import py +import _pytest + + + +def find_toplevel(name): + for syspath in sys.path: + base = py.path.local(syspath) + lib = base/name + if lib.check(dir=1): + return lib + mod = base.join("%s.py" % name) + if mod.check(file=1): + return mod + raise LookupError(name) + +def pkgname(toplevel, rootpath, path): + parts = path.parts()[len(rootpath.parts()):] + return '.'.join([toplevel] + [x.purebasename for x in parts]) + +def pkg_to_mapping(name): + toplevel = find_toplevel(name) + name2src = {} + if toplevel.check(file=1): # module + name2src[toplevel.purebasename] = toplevel.read() + else: # package + for pyfile in toplevel.visit('*.py'): + pkg = pkgname(name, toplevel, pyfile) + name2src[pkg] = pyfile.read() + # with wheels py source code might be not be installed + # and the resulting genscript is useless, just bail out. + assert name2src, "no source code found for %r at %r" %(name, toplevel) + return name2src + +def compress_mapping(mapping): + import base64, pickle, zlib + data = pickle.dumps(mapping, 2) + data = zlib.compress(data, 9) + data = base64.encodestring(data) + data = data.decode('ascii') + return data + + +def compress_packages(names): + mapping = {} + for name in names: + mapping.update(pkg_to_mapping(name)) + return compress_mapping(mapping) + +def generate_script(entry, packages): + data = compress_packages(packages) + tmpl = py.path.local(__file__).dirpath().join('standalonetemplate.py') + exe = tmpl.read() + exe = exe.replace('@SOURCES@', data) + exe = exe.replace('@ENTRY@', entry) + return exe + + +def pytest_addoption(parser): + group = parser.getgroup("debugconfig") + group.addoption("--genscript", action="store", default=None, + dest="genscript", metavar="path", + help="create standalone pytest script at given target path.") + +def pytest_cmdline_main(config): + import _pytest.config + genscript = config.getvalue("genscript") + if genscript: + tw = _pytest.config.create_terminal_writer(config) + tw.line("WARNING: usage of genscript is deprecated.", + red=True) + deps = ['py', '_pytest', 'pytest'] # pluggy is vendored + if sys.version_info < (2,7): + deps.append("argparse") + tw.line("generated script will run on python2.6-python3.3++") + else: + tw.line("WARNING: generated script will not run on python2.6 " + "due to 'argparse' dependency. Use python2.6 " + "to generate a python2.6 compatible script", red=True) + script = generate_script( + 'import pytest; raise SystemExit(pytest.cmdline.main())', + deps, + ) + genscript = py.path.local(genscript) + genscript.write(script) + tw.line("generated pytest standalone script: %s" % genscript, + bold=True) + return 0 + + +def pytest_namespace(): + return {'freeze_includes': freeze_includes} + + +def freeze_includes(): + """ + Returns a list of module names used by py.test that should be + included by cx_freeze. + """ + result = list(_iter_all_modules(py)) + result += list(_iter_all_modules(_pytest)) + return result + + +def _iter_all_modules(package, prefix=''): + """ + Iterates over the names of all modules that can be found in the given + package, recursively. + + Example: + _iter_all_modules(_pytest) -> + ['_pytest.assertion.newinterpret', + '_pytest.capture', + '_pytest.core', + ... + ] + """ + if type(package) is not str: + path, prefix = package.__path__[0], package.__name__ + '.' + else: + path = package + for _, name, is_package in pkgutil.iter_modules([path]): + if is_package: + for m in _iter_all_modules(os.path.join(path, name), prefix=name + '.'): + yield prefix + m + else: + yield prefix + name |