diff --git a/pyrepl/python_reader.py b/pyrepl/python_reader.py index c3f4092..5e2d4e7 100644 --- a/pyrepl/python_reader.py +++ b/pyrepl/python_reader.py @@ -179,7 +179,8 @@ def run_user_init_file(self): else: return try: - execfile(initfile, self.locals, self.locals) + with open(initfile, "r") as f: + exec(compile(f.read(), initfile, "exec"), self.locals, self.locals) except: etype, value, tb = sys.exc_info() traceback.print_exception(etype, value, tb.tb_next) diff --git a/pyrepl/unix_console.py b/pyrepl/unix_console.py index 3ec9a7b..281c200 100644 --- a/pyrepl/unix_console.py +++ b/pyrepl/unix_console.py @@ -401,7 +401,8 @@ def restore(self): def __sigwinch(self, signum, frame): self.height, self.width = self.getheightwidth() self.event_queue.insert(Event('resize', None)) - self.old_sigwinch(signum, frame) + if self.old_sigwinch != signal.SIG_DFL: + self.old_sigwinch(signum, frame) def push_char(self, char): trace('push char {char!r}', char=char) diff --git a/testing/test_functional.py b/testing/test_functional.py index 1e491ec..f1f555b 100644 --- a/testing/test_functional.py +++ b/testing/test_functional.py @@ -3,27 +3,98 @@ # License: MIT # some functional tests, to see if this is really working -import pytest +import os +import signal import sys +import textwrap + +import pytest + +try: + import pexpect +except ImportError as exc: + pytest.skip("could not import pexpect: {}".format(exc), + allow_module_level=True) @pytest.fixture -def child(request): - try: - pexpect = pytest.importorskip('pexpect') - except SyntaxError: - pytest.skip('pexpect wont work on py3k') - child = pexpect.spawn(sys.executable, ['-S'], timeout=10) - if sys.version_info >= (3, ): - child.logfile = sys.stdout.buffer - else: - child.logfile = sys.stdout - child.sendline('from pyrepl.python_reader import main') - child.sendline('main()') +def start_child(): + ret_childs = [] + + def start_child_func(env_update=None): + assert not ret_childs, "child started already" + + env = {k: v for k, v in os.environ.items() if k in ( + "TERM", + )} + if env_update: + env.update(env_update) + child = pexpect.spawn(sys.executable, timeout=5, env=env) + if sys.version_info >= (3, ): + child.logfile = sys.stdout.buffer + else: + child.logfile = sys.stdout + child.expect_exact(">>> ") + child.sendline('from pyrepl.python_reader import main') + ret_childs.append(child) + return child + + yield start_child_func + + assert ret_childs, "child was not started" + child = ret_childs[0] + + child.sendeof() + child.expect_exact(">>> ") + # Verify there's no error, e.g. when signal.SIG_DFL would be called. + before = child.before.decode() + assert "Traceback (most recent call last):" not in before + child.sendeof() + assert child.wait() == 0 + + +@pytest.fixture +def child(start_child): + child = start_child() + child.sendline("main()") return child def test_basic(child): - child.sendline('a = 3') + child.expect_exact("->> ") + child.sendline('a = 40 + 2') + child.expect_exact("->> ") child.sendline('a') - child.expect('3') + child.expect_exact('42') + child.expect_exact("->> ") + + +def test_sigwinch_default(child): + child.expect_exact("->> ") + os.kill(child.pid, signal.SIGWINCH) + + +def test_sigwinch_forwarded(start_child, tmpdir): + with open(str(tmpdir.join("initfile")), "w") as initfile: + initfile.write(textwrap.dedent( + """ + import signal + + called = [] + + def custom_handler(signum, frame): + called.append([signum, frame]) + + signal.signal(signal.SIGWINCH, custom_handler) + + print("PYREPLSTARTUP called") + """ + )) + + child = start_child(env_update={"PYREPLSTARTUP": initfile.name}) + child.sendline("main()") + child.expect_exact("PYREPLSTARTUP called") + child.expect_exact("->> ") + os.kill(child.pid, signal.SIGWINCH) + child.sendline('"called={}".format(len(called))') + child.expect_exact("called=1")