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:]):