diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index af88cbb30257a23b209e67f8fbd96bef6ab5c8d5..ec9e960eeff704bc37447a27f6f2c2a506a162e9 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -15,6 +15,9 @@ Python 2.7 Conda: - CONDA_ENVIRONMENT=.test-py2.yml - curl -L -O -k https://gitlab.tiker.net/inducer/ci-support/raw/master/build-and-test-py-project-within-miniconda.sh - ". ./build-and-test-py-project-within-miniconda.sh" + tags: + - maxima + - linux except: - tags @@ -35,6 +38,20 @@ Python 3.5 Conda: - CONDA_ENVIRONMENT=.test-py3.yml - curl -L -O -k https://gitlab.tiker.net/inducer/ci-support/raw/master/build-and-test-py-project-within-miniconda.sh - ". ./build-and-test-py-project-within-miniconda.sh" + tags: + - maxima + - linux + except: + - tags + +Python 3.5 Apple: + script: + - CONDA_ENVIRONMENT=.test-py3.yml + - curl -L -O -k https://gitlab.tiker.net/inducer/ci-support/raw/master/build-and-test-py-project-within-miniconda.sh + - ". ./build-and-test-py-project-within-miniconda.sh" + tags: + - maxima + - apple except: - tags diff --git a/pymbolic/interop/maxima.py b/pymbolic/interop/maxima.py index 77f1aab3892342d40b6941e60d517cd2dd42438d..2dabf2bcc3fdb32373d87c1adea5d22ec5b94b7f 100644 --- a/pymbolic/interop/maxima.py +++ b/pymbolic/interop/maxima.py @@ -270,10 +270,34 @@ class MaximaKernel: def _initialize(self): + PEXPECT_SHELL = "bash" # noqa + + PRE_MAXIMA_COMMANDS = ( # noqa + # Makes long line inputs possible. + ("stty -icanon",) + ) + import pexpect - self.child = pexpect.spawn(self.executable, - ["--disable-readline", "-q"], - timeout=self.timeout) + self.child = pexpect.spawn(PEXPECT_SHELL, timeout=self.timeout, echo=False) + for command in PRE_MAXIMA_COMMANDS: + self.child.sendline(command) + + # {{{ check for maxima command + + self.child.sendline( + "hash \"{command}\"; echo $?".format(command=self.executable)) + + hash_output = self.child.expect(["0\r\n", "1\r\n"]) + if hash_output != 0: + raise RuntimeError( + "maxima executable \"{command}\" not found" + .format(command=self.executable)) + + # }}} + + self.child.sendline(" ".join( + ['"' + self.executable + '"', "--disable-readline", "-q"])) + self.current_prompt = 0 self._expect_prompt(IN_PROMPT_RE) @@ -321,12 +345,15 @@ class MaximaKernel: # {{{ execution control def restart(self): - from signal import SIGKILL - self.child.kill(SIGKILL) + self.child.close(force=True) self._initialize() def shutdown(self): self._sendline("quit();") + # Exit shell + self._sendline("exit") + from pexpect import EOF + self.child.expect(EOF) self.child.wait() # }}} @@ -340,11 +367,6 @@ class MaximaKernel: def _sendline(self, l): self._check_debug() - - if len(l) > 2048: - raise RuntimeError("input lines longer than 2048 characters " - "don't work, refusing") - self.child.sendline(l) def exec_str(self, s, enforce_prompt_numbering=True): @@ -365,9 +387,6 @@ class MaximaKernel: print("[MAXIMA INPUT]", cmd) self._sendline(cmd) - s_echo = self.child.readline().decode() - - assert s_echo.strip() == cmd.strip() self._expect_prompt(OUT_PROMPT_RE, enforce_prompt_numbering=enforce_prompt_numbering) diff --git a/test/test_maxima.py b/test/test_maxima.py index 94991c0e90eb062be8f13dd35ce959acb9b8158c..7ddbb687dd711b2ff83cadaf8d81c72c0fed8a42 100644 --- a/test/test_maxima.py +++ b/test/test_maxima.py @@ -23,8 +23,6 @@ THE SOFTWARE. """ import pytest -from pytools.test import mark_test - from pymbolic.interop.maxima import MaximaKernel @@ -38,7 +36,8 @@ def test_kernel(): knl.shutdown() -def pytest_funcarg__knl(request): +@pytest.fixture +def knl(request): pytest.importorskip("pexpect") knl = MaximaKernel() @@ -123,13 +122,21 @@ def test_diff(): diff(parse("sqrt(x**2+y**2)"), parse("x")) -@mark_test.xfail def test_long_command(knl): from pymbolic.interop.maxima import set_debug set_debug(4) knl.eval_str("+".join(["1"]*16384)) +def test_restart(knl): + pytest.importorskip("pexpect") + + knl = MaximaKernel() + knl.restart() + knl.eval_str("1") + knl.shutdown() + + if __name__ == "__main__": import sys if len(sys.argv) > 1: