From 794bf0558874a73d63c829222664363462af7449 Mon Sep 17 00:00:00 2001 From: archibate <1931127624@qq.com> Date: Tue, 23 Jun 2020 16:35:09 +0800 Subject: [PATCH] revert idle --- .gitignore | 1 - python/taichi/idle_hacker.py | 41 ---------- python/taichi/lang/impl.py | 2 - python/taichi/lang/shell.py | 151 ----------------------------------- python/taichi/main.py | 16 +--- 5 files changed, 4 insertions(+), 207 deletions(-) delete mode 100644 python/taichi/idle_hacker.py diff --git a/.gitignore b/.gitignore index de60a3ed65b6f..50ccd25a77145 100644 --- a/.gitignore +++ b/.gitignore @@ -55,7 +55,6 @@ __pycache__ *.ini *.egg-info .tlang_cache -.tmp_idle_* /taichi/common/version.h /taichi/common/commit_hash.h /python/test_env diff --git a/python/taichi/idle_hacker.py b/python/taichi/idle_hacker.py deleted file mode 100644 index 280bdf86501e2..0000000000000 --- a/python/taichi/idle_hacker.py +++ /dev/null @@ -1,41 +0,0 @@ -# A dirty hack injector for python/taichi/lang/shell.py - -our_code = "(lambda o,k:o.path.exists(k+'ppid_'+str(o.getpid()))and(lambda f:(f.write(f'\\n===\\n'+source),f.close()))(open(k+'source','a')))(__import__('os'),'.tmp_idle_')\n" - -def main(): - import code - import shutil - - print('Injection dest:', code.__file__) - - with open(code.__file__) as f: - if our_code[:20] in f.read(): - print('Taichi hijacking code already exists') - return 1 - - shutil.copy(code.__file__, '.tmp_idle_backup.code.py') - print('Backup saved in .tmp_idle_backup.code.py') - - with open(code.__file__) as f: - ret = '' - for x in f.readlines(): - i = x.find('# Case 3') - if i == -1: - ret += x - else: - ret += x + x[:i] + our_code - - if our_code not in ret: - print('Error: Signature "# Case 3" not found!') - return 2 - - print('Writing back result...') - - with open(code.__file__, 'w') as f: - f.write(ret) - - print('Done, thank for trusting!') - return 0 - -if __name__ == '__main__': - exit(main()) diff --git a/python/taichi/lang/impl.py b/python/taichi/lang/impl.py index 12f2d6990529a..8e8e7a789dc0b 100644 --- a/python/taichi/lang/impl.py +++ b/python/taichi/lang/impl.py @@ -229,8 +229,6 @@ def reset(): for k in old_kernels: k.reset() taichi_lang_core.reset_default_compile_config() - from .shell import reset_callback - reset_callback() def inside_kernel(): diff --git a/python/taichi/lang/shell.py b/python/taichi/lang/shell.py index 9056dabb0f2ae..1fefad9fcd872 100644 --- a/python/taichi/lang/shell.py +++ b/python/taichi/lang/shell.py @@ -2,44 +2,11 @@ class ShellType: NATIVE = 'Python shell' - IDLE = 'Python IDLE shell' IPYTHON = 'IPython TerminalInteractiveShell' JUPYTER = 'IPython ZMQInteractiveShell' IPYBASED = 'IPython Based Shell' SCRIPT = None -def _show_idle_error_message(): - import code - try: - path = code.__file__ - except: - path = '/usr/lib/python3.8/code.py' - print('It\'s detected that you are using Python IDLE in **interactive mode**.') - print('However, Taichi could not be fully functional due to IDLE limitation, sorry :(') - print('Either run Taichi directly from script, or use IPython notebook instead.') - print('We do care about your experience, no matter which shell you prefer to use.') - print('So, if you would like to play with Taichi in your favorite IDLE, we may do a dirty hack:') - print(f'Open "{path}" and add the following line to `InteractiveInterpreter.runsource`, right below `# Case 3`:') - print(''' -class InteractiveInterpreter: - ... - - def runsource(self, source, filename="", symbol="single"): - ... - - # Case 3 - (lambda o,k:o.path.exists(k+'ppid_'+str(o.getpid()))and(lambda f:(f.write(f'\\n===\\n'+source),f.close()))(open(k+'source','a')))(__import__('os'),'.tmp_idle_') # Add this line! - self.runcode(code) - return False - - ... - - ''') - print('If you don\'t find where to add, we provided a script to automatically inject the code:') - print(' sudo python3 -m taichi idle_hacker') - print('') - print('Then, restart IDLE and enjoy, the sky is blue and we are wizards!') - def get_shell_name(): """ @@ -69,31 +36,6 @@ def get_shell_name(): if hasattr(__builtins__, '__IPYTHON__'): return ShellType.IPYBASED - if os.path.basename(sys.executable) == 'pythonw.exe': # Windows Python IDLE? - return ShellType.IDLE - - if os.path.basename(os.environ.get('_', '')) == 'idle': # /usr/bin/idle? - return ShellType.IDLE - - try: - import psutil - # XXX: Is psutil a hard dep of taichi? What if user didn't install it? - proc = psutil.Process().parent() - if proc.name() == 'idle': # launched from KDE win menu? - return ShellType.IDLE - cmdline = proc.cmdline() - # launched with: python -m idlelib? - if 'idlelib' in cmdline: - return ShellType.IDLE - # sh-bomb: /usr/bin/python /usr/bin/idle? - if len(cmdline) >= 2 and os.path.basename(cmdline[1]) == 'idle': - return ShellType.IDLE - except: - pass - - if 'idlelib' in sys.modules: - return ShellType.IDLE - try: if getattr(sys, 'ps1', sys.flags.interactive): return ShellType.NATIVE @@ -130,71 +72,6 @@ def __init__(self): self.getsourcelines = dill.source.getsourcelines self.getsourcefile = dill.source.getsourcefile - elif self.name == ShellType.IDLE: - # `.tmp_idle_source` for "Python IDLE shell" - # Thanks to IDLE's lack of support with `inspect`, - # we have to use a dirty hack to support Taichi there. - self.idle_cache = {} - - ppid_file = '.tmp_idle_ppid_' + str(os.getppid()) - with open(ppid_file, 'w') as f: - import taichi as ti - ti.info(f'[Taichi] touching {ppid_file}') - f.write('taichi') - - def getsource(o): - func_name = o.__name__ - if func_name in self.idle_cache: - return self.idle_cache[func_name] - src = None - try: - with open('.tmp_idle_source') as f: - src = f.read() - except FileNotFoundError as e: - _show_idle_error_message() - raise e - - # If user added our 'hacker-code' correctly, - # then the content of .tmp_idle_source should be: - # - # === - # import taichi as ti - # - # === - # @ti.kernel - # def func(): # x.find('def ') locate to here - # pass - # - # === - # func() - # - # - # Thanking IDLE dev :( It works anyway :) - for x in src.split('==='): - x = x.strip() - i = x.find('def ') - if i == -1: - continue - name = x[i + 4:].split(':', maxsplit=1)[0] - name = name.split('(', maxsplit=1)[0] - if name.strip() == func_name: - self.idle_cache[func_name] = x - return x - else: - raise NameError(f'Could not find source for {o.__name__}!') - - def getsourcelines(o): - lineno = 2 # TODO: consider include lineno in .tmp_idle_source? - lines = getsource(o).split('\n') - return lines, lineno - - def getsourcefile(o): - return '' - - self.getsource = getsource - self.getsourcelines = getsourcelines - self.getsourcefile = getsourcefile - elif self.name.startswith('IPython'): # `IPython.core.oinspect` for "IPython advanced shell" def getsource(o): @@ -219,31 +96,3 @@ def getsourcefile(o): oinspect = None - -def _try_clean(filename): - try: - os.unlink(filename) - except: - pass - else: - import taichi as ti - ti.info('File ".tmp_idle_source" cleaned') - -def reset_callback(): - global oinspect - oinspect = ShellInspectorWrapper() - - def is_idle_oinspect(): - return isinstance(oinspect, ShellInspectorWrapper) and \ - oinspect.name == ShellType.IDLE - - if is_idle_oinspect(): - _try_clean('.tmp_idle_source') - - def exit_callback(): - if is_idle_oinspect(): - _try_clean('.tmp_idle_source') - _try_clean('.tmp_idle_ppid_' + os.getppid()) - atexit.register(exit_callback) - -reset_callback() diff --git a/python/taichi/main.py b/python/taichi/main.py index 55436d1eb2c9a..bccfbfa0ea897 100644 --- a/python/taichi/main.py +++ b/python/taichi/main.py @@ -899,21 +899,13 @@ def debug(self, arguments: list = sys.argv[2:]): # Short circuit for testing if self.test_mode: return args - os.environ['TI_DEBUG'] = '1' - os.environ['TI_LOG_LEVEL'] = 'debug' ti.core.set_core_trigger_gdb_when_crash(True) - runpy.run_path(args.filename, run_name='__main__') + with open(args.filename) as script: + script = script.read() - @register - def idle_hacker(self, arguments: list = sys.argv[2:]): - """Run idle hack code injector""" - parser = argparse.ArgumentParser(prog='ti idle_hacker', - description=f"{self.idle_hacker.__doc__}") - args = parser.parse_args(arguments) - - from .idle_hacker import main - return main() + # FIXME: exec is a security risk here! + exec(script, {'__name__': '__main__'}) @register def run(self, arguments: list = sys.argv[2:]):