Commit e205dbf6 authored by Kirill Smelkov's avatar Kirill Smelkov

gpython: Implement -i (interactive inspect after program run) + promised interactive-mode tests

/reviewed-by @jerome
/reviewed-on nexedi/pygolang!15
parent 2351dd27
Pipeline #14710 passed with stage
in 0 seconds
...@@ -41,7 +41,7 @@ $GPYTHON_RUNTIME=threads. ...@@ -41,7 +41,7 @@ $GPYTHON_RUNTIME=threads.
from __future__ import print_function, absolute_import from __future__ import print_function, absolute_import
_pyopt = "c:m:OVW:X:" _pyopt = "c:im:OVW:X:"
_pyopt_long = ('version',) _pyopt_long = ('version',)
# pymain mimics `python ...` # pymain mimics `python ...`
...@@ -93,6 +93,7 @@ def pymain(argv, init=None): ...@@ -93,6 +93,7 @@ def pymain(argv, init=None):
warnoptions = [] # collected `-W arg` warnoptions = [] # collected `-W arg`
reexec_with = [] # reexecute underlying python with those options (e.g. -O, -S, ...) reexec_with = [] # reexecute underlying python with those options (e.g. -O, -S, ...)
reexec_argv = [] # if reexecuting, reexecute with this application-level argv reexec_argv = [] # if reexecuting, reexecute with this application-level argv
inspect = False # inspect interactively at the end
igetopt = _IGetOpt(argv, _pyopt, _pyopt_long) igetopt = _IGetOpt(argv, _pyopt, _pyopt_long)
for (opt, arg) in igetopt: for (opt, arg) in igetopt:
...@@ -147,6 +148,10 @@ def pymain(argv, init=None): ...@@ -147,6 +148,10 @@ def pymain(argv, init=None):
elif opt == '-W': elif opt == '-W':
warnoptions.append(arg) warnoptions.append(arg)
# -i inspect interactively
elif opt == '-i':
inspect = True
else: else:
print("unknown option: '%s'" % opt, file=sys.stderr) print("unknown option: '%s'" % opt, file=sys.stderr)
sys.exit(2) sys.exit(2)
...@@ -173,7 +178,8 @@ def pymain(argv, init=None): ...@@ -173,7 +178,8 @@ def pymain(argv, init=None):
sys.argv = [''] if len(argv) == 0 else argv # e.g. ['-'] sys.argv = [''] if len(argv) == 0 else argv # e.g. ['-']
sys.path.insert(0, '') # cwd sys.path.insert(0, '') # cwd
if sys.stdin.isatty(): if sys.stdin.isatty() or inspect:
inspect = False # no console after console
def run(mmain): def run(mmain):
mmain.__file__ = '<stdin>' mmain.__file__ = '<stdin>'
_interact(mmain) _interact(mmain)
...@@ -259,11 +265,23 @@ def pymain(argv, init=None): ...@@ -259,11 +265,23 @@ def pymain(argv, init=None):
sys.modules['__main__'] = mmain sys.modules['__main__'] = mmain
# execute -m/-c/file/interactive # execute -m/-c/file/interactive
import traceback
try:
run(mmain) run(mmain)
except:
# print exception becore going to interactive inspect
if inspect:
traceback.print_exc()
else:
raise
finally:
# interactive inspect
if inspect:
_interact(mmain, banner='')
# _interact runs interactive console in mmain namespace. # _interact runs interactive console in mmain namespace.
def _interact(mmain): def _interact(mmain, banner=None):
import code, sys import code, sys
from six.moves import input as raw_input from six.moves import input as raw_input
# like code.interact() but with overridden console.raw_input _and_ # like code.interact() but with overridden console.raw_input _and_
...@@ -287,7 +305,7 @@ def _interact(mmain): ...@@ -287,7 +305,7 @@ def _interact(mmain):
return raw_input('') return raw_input('')
console.raw_input = _ console.raw_input = _
console.interact() console.interact(banner=banner)
# execfile was removed in py3 # execfile was removed in py3
......
...@@ -34,9 +34,10 @@ testprog = join(here, 'testprog') ...@@ -34,9 +34,10 @@ testprog = join(here, 'testprog')
is_pypy = (platform.python_implementation() == 'PyPy') is_pypy = (platform.python_implementation() == 'PyPy')
is_cpython = (platform.python_implementation() == 'CPython') is_cpython = (platform.python_implementation() == 'CPython')
is_gpython = ('GPython' in sys.version)
# @gpython_only is marker to run a test only under gpython # @gpython_only is marker to run a test only under gpython
gpython_only = pytest.mark.skipif('GPython' not in sys.version, reason="gpython-only test") gpython_only = pytest.mark.skipif(not is_gpython, reason="gpython-only test")
# runtime is pytest fixture that yields all variants of should be supported gpython runtimes: # runtime is pytest fixture that yields all variants of should be supported gpython runtimes:
# '' - not specified (gpython should autoselect) # '' - not specified (gpython should autoselect)
...@@ -188,6 +189,31 @@ def test_pymain(): ...@@ -188,6 +189,31 @@ def test_pymain():
_ = pyout(['testdata/hello.py', 'abc', 'def'], cwd=here) _ = pyout(['testdata/hello.py', 'abc', 'def'], cwd=here)
assert _ == b"hello\nworld\n['testdata/hello.py', 'abc', 'def']\n" assert _ == b"hello\nworld\n['testdata/hello.py', 'abc', 'def']\n"
# -i after stdin (also tests interactive mode as -i forces interactive even on non-tty)
d = {
b'hellopy': b(hellopy),
b'ps1': b'' # cpython emits prompt to stderr
}
if is_pypy and not is_gpython:
d['ps1'] = b'>>>> ' # native pypy emits prompt to stdout and >>>> instead of >>>
_ = pyout(['-i'], stdin=b'import hello\n', cwd=testdata)
assert _ == b"%(ps1)shello\nworld\n['']\n%(ps1)s" % d
_ = pyout(['-i', '-'], stdin=b'import hello\n', cwd=testdata)
assert _ == b"%(ps1)shello\nworld\n['-']\n%(ps1)s" % d
_ = pyout(['-i', '-', 'zzz'], stdin=b'import hello\n', cwd=testdata)
assert _ == b"%(ps1)shello\nworld\n['-', 'zzz']\n%(ps1)s" % d
# -i after -c
_ = pyout(['-i', '-c', 'import hello'], stdin=b'hello.tag', cwd=testdata)
assert _ == b"hello\nworld\n['-c']\n%(ps1)s'~~HELLO~~'\n%(ps1)s" % d
# -i after -m
_ = pyout(['-i', '-m', 'hello'], stdin=b'world.tag', cwd=testdata)
assert _ == b"hello\nworld\n['%(hellopy)s']\n%(ps1)s'~~WORLD~~'\n%(ps1)s" % d
# -i after file
_ = pyout(['-i', 'testdata/hello.py'], stdin=b'tag', cwd=here)
assert _ == b"hello\nworld\n['testdata/hello.py']\n%(ps1)s'~~HELLO~~'\n%(ps1)s" % d
# -W <opt> # -W <opt>
_ = pyout(['-Werror', '-Whello', '-W', 'ignore::DeprecationWarning', _ = pyout(['-Werror', '-Whello', '-W', 'ignore::DeprecationWarning',
'testprog/print_warnings_setup.py'], cwd=here) 'testprog/print_warnings_setup.py'], cwd=here)
......
...@@ -6,3 +6,6 @@ import world ...@@ -6,3 +6,6 @@ import world
# sys.argv # sys.argv
import sys import sys
print(sys.argv) print(sys.argv)
# variable in module namespace
tag = '~~HELLO~~'
print('world') print('world')
# variable in module namespace
tag = '~~WORLD~~'
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment