Skip to content

Commit bcd7c17

Browse files
author
Release Manager
committed
gh-40252: Don't install sage/tests/cmdline.py with meson It contains tests that are not relevant for the meson build We extract the `test_executable` function to `__init__.py`, since it is still used in other files, and leave only the tests in `cmdline.py`. URL: #40252 Reported by: Antonio Rojas Reviewer(s): Tobias Diez
2 parents 3f80b5d + 6729597 commit bcd7c17

File tree

6 files changed

+742
-739
lines changed

6 files changed

+742
-739
lines changed

src/sage/repl/interpreter.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -722,7 +722,7 @@ def get_test_shell():
722722
723723
Check that :issue:`14070` has been resolved::
724724
725-
sage: from sage.tests.cmdline import test_executable
725+
sage: from sage.tests import test_executable
726726
sage: cmd = 'from sage.repl.interpreter import get_test_shell; shell = get_test_shell()'
727727
sage: (out, err, ret) = test_executable(["sage", "-c", cmd])
728728
sage: out + err

src/sage/tests/__init__.py

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
from subprocess import Popen, PIPE
2+
import os
3+
import sys
4+
import select
5+
6+
7+
def test_executable(args, input='', timeout=100.0, pydebug_ignore_warnings=False, **kwds):
8+
r"""
9+
Run the program defined by ``args`` using the string ``input`` on
10+
the standard input.
11+
12+
INPUT:
13+
14+
- ``args`` -- list of program arguments, the first being the
15+
executable
16+
17+
- ``input`` -- string serving as standard input; usually, this
18+
should end with a newline
19+
20+
- ``timeout`` -- if the program produces no output for ``timeout``
21+
seconds, a :exc:`RuntimeError` is raised
22+
23+
- ``pydebug_ignore_warnings`` -- boolean. Set the PYTHONWARNINGS environment variable to ignore
24+
Python warnings when on a Python debug build (`--with-pydebug`, e.g. from building with
25+
`SAGE_DEBUG=yes`). Debug builds do not install the default warning filters, which can break
26+
some doctests. Unfortunately the environment variable does not support regex message filters,
27+
so the filter will catch a bit more than the default filters. Hence we only enable it on debug
28+
builds.
29+
30+
- ``**kwds`` -- additional keyword arguments passed to the
31+
:class:`Popen` constructor
32+
33+
OUTPUT: a tuple ``(out, err, ret)`` with the standard output,
34+
standard error and exitcode of the program run.
35+
36+
EXAMPLES::
37+
38+
sage: from sage.tests import test_executable
39+
sage: (out, err, ret) = test_executable(["cat"], "Hello World!")
40+
sage: out
41+
'Hello World!'
42+
sage: err
43+
''
44+
sage: ret
45+
0
46+
47+
We test the timeout option::
48+
49+
sage: (out, err, ret) = test_executable(["sleep", "1"], timeout=0.1)
50+
Traceback (most recent call last):
51+
...
52+
RuntimeError: timeout in test_executable()
53+
"""
54+
pexpect_env = dict(os.environ)
55+
try:
56+
del pexpect_env["TERM"]
57+
except KeyError:
58+
pass
59+
60+
__with_pydebug = hasattr(sys, 'gettotalrefcount') # This is a Python debug build (--with-pydebug)
61+
if __with_pydebug and pydebug_ignore_warnings:
62+
pexpect_env['PYTHONWARNINGS'] = ','.join([
63+
'ignore::DeprecationWarning',
64+
])
65+
66+
kwds['encoding'] = kwds.pop('encoding', 'utf-8')
67+
68+
p = Popen(args, stdin=PIPE, stdout=PIPE, stderr=PIPE, env=pexpect_env,
69+
**kwds)
70+
if input:
71+
p.stdin.write(input)
72+
73+
p.stdin.close()
74+
fdout = p.stdout.fileno()
75+
fderr = p.stderr.fileno()
76+
out = []
77+
err = []
78+
79+
while True:
80+
# Try reading from fdout and fderr
81+
rfd = []
82+
if fdout:
83+
rfd.append(fdout)
84+
if fderr:
85+
rfd.append(fderr)
86+
if len(rfd) == 0:
87+
break
88+
timeout = float(timeout)
89+
rlist = select.select(rfd, [], [], timeout)[0]
90+
91+
if len(rlist) == 0:
92+
# Timeout!
93+
p.terminate()
94+
raise RuntimeError("timeout in test_executable()")
95+
if fdout in rlist:
96+
s = p.stdout.read(1024)
97+
if not s:
98+
fdout = None # EOF
99+
p.stdout.close()
100+
out.append(s)
101+
if fderr in rlist:
102+
s = p.stderr.read(1024)
103+
if not s:
104+
fderr = None # EOF
105+
p.stderr.close()
106+
err.append(s)
107+
108+
# In case out or err contains a quoted string, force the use of
109+
# double quotes so that the output is enclosed in single
110+
# quotes. This avoids some doctest failures with some versions of
111+
# OS X and Xcode.
112+
out = ''.join(out)
113+
out = out.replace("'", '"')
114+
err = ''.join(err)
115+
err = err.replace("'", '"')
116+
117+
return (out, err, p.wait())

0 commit comments

Comments
 (0)