/
valemobil
/
python-future
Обзор
Документация
Войти
/
valemobil
/
python-future
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
docs/other/auto2to3.py
126 строк
4 KB
Joseph Curtis
Update imp to importlib for py3
16 сен 2020, 21:22
16 сен 2020, 21:22
05bc771
Код
Авторство
О чём код?
#!/usr/bin/env python3 """Wrapper to run 2to3 automatically at import time. Usage: auto2to3 -m mypackage.main_module auto2to3 mypackage/script.py By default, all modules imported from a subdirectory of the current directory will be run through `2to3`. To change this behavior, use the `--package` or `--dir` flags to `auto2to3` to specify which packages or directories contain Python 2 code that should be converted. 2to3 output is cached on disk between runs for speed. Based on auto2to3.py by Georg Brandl: http://dev.pocoo.org/hg/sandbox/file/tip/auto2to3.py """ import argparse import os import sys # imp was deprecated in python 3.6 if sys.version_info >= (3, 6): import importlib as imp else: import imp import runpy from io import StringIO from pkgutil import ImpImporter, ImpLoader import runpy import sys import tempfile import lib2to3 from lib2to3.refactor import RefactoringTool, get_fixers_from_package fixes = get_fixers_from_package('lib2to3.fixes') rt = RefactoringTool(fixes) PACKAGES = [] DIRS = [] def maybe_2to3(filename, modname=None): """Returns a python3 version of filename.""" need_2to3 = False filename = os.path.abspath(filename) if any(filename.startswith(d) for d in DIRS): need_2to3 = True elif modname is not None and any(modname.startswith(p) for p in PACKAGES): need_2to3 = True if not need_2to3: return filename outfilename = '/_auto2to3_'.join(os.path.split(filename)) if (not os.path.exists(outfilename) or os.stat(filename).st_mtime > os.stat(outfilename).st_mtime): try: with open(filename) as file: contents = file.read() contents = rt.refactor_docstring(contents, filename) tree = rt.refactor_string(contents, filename) except Exception as err: raise ImportError("2to3 couldn't convert %r" % filename) outfile = open(outfilename, 'wb') outfile.write(str(tree).encode('utf8')) outfile.close() return outfilename class ToThreeImporter(ImpImporter): def find_module(self, fullname, path=None): # this duplicates most of ImpImporter.find_module subname = fullname.split(".")[-1] if subname != fullname and self.path is None: return None if self.path is None: path = None else: path = [os.path.realpath(self.path)] try: file, filename, etc = imp.find_module(subname, path) except ImportError: return None if file and etc[2] == imp.PY_SOURCE: outfilename = maybe_2to3(filename, modname=fullname) if outfilename != filename: file.close() filename = outfilename file = open(filename, 'rb') return ImpLoader(fullname, file, filename, etc) # setup the hook sys.path_hooks.append(ToThreeImporter) for key in sys.path_importer_cache: if sys.path_importer_cache[key] is None: sys.path_importer_cache[key] = ToThreeImporter(key) def main(): parser = argparse.ArgumentParser() parser.add_argument('--package', action='append') parser.add_argument('--dir', action='append') parser.add_argument('-m', action='store', metavar='MODULE') args, rest = parser.parse_known_args() if args.package: PACKAGES.extend(args.package) if args.dir: DIRS.extend(os.path.abspath(d) for d in args.dir) if not PACKAGES and not DIRS: DIRS.append(os.getcwd()) if args.m: sys.argv[1:] = rest runpy.run_module(args.m, run_name='__main__', alter_sys=True) elif rest: sys.argv = rest converted = maybe_2to3(rest[0]) with open(converted) as f: new_globals = dict(__name__='__main__', __file__=rest[0]) exec(f.read(), new_globals) else: import code code.interact() if __name__ == '__main__': main()