python
The atago project wrote these specs on its own initiative and runs them in its own CI, to exercise atago against a real program. They are not python’s official test suite, and the python project is not affiliated with atago.
Summary #
2 suites · 8 scenarios
Contents #
- python3 + changes (bytecode cache footprint) — 2 scenarios
- python3 REPL (interactive pty testbed) — 6 scenarios
python3 + changes (bytecode cache footprint) #
Running a Python script quietly writes files you did not ask for: importing a
local module leaves a compiled .pyc behind in __pycache__, while the
entry script itself is never cached. That asymmetry surprises people, so it
is pinned here exactly.
The paired scenario pins the escape hatch: with PYTHONDONTWRITEBYTECODE
set, the same run creates nothing at all — an empty delta, which is the
strongest form this assertion can take.
Source: test/e2e/thirdparty/python/changes.atago.yaml
Scenario: importing a local module writes exactly one .pyc #
only when python3 --version succeeds
Given #
- Fixture file
mymod.pyis created. - Fixture file
main.pyis created.
Inputs #
Fixture mymod.py:
def val():
return 42
Fixture main.py:
import mymod
print(mymod.val())
When #
python3 main.py
Then #
- exit code is
0 - stdout equals an exact value
- the step changed exactly created
__pycache__/*.pyc, modified nothing, deleted nothing
Scenario: PYTHONDONTWRITEBYTECODE suppresses the cache entirely #
only when python3 --version succeeds
Given #
- Fixture file
mymod.pyis created. - Fixture file
main.pyis created. - Environment variables are set: PYTHONDONTWRITEBYTECODE.
Inputs #
Fixture mymod.py:
def val():
return 42
Fixture main.py:
import mymod
print(mymod.val())
When #
python3 main.py
Then #
- exit code is
0 - stdout equals an exact value
- the step changed exactly created nothing, modified nothing, deleted nothing
python3 REPL (interactive pty testbed) #
The Python REPL is the canonical long-lived interactive session: it prints a prompt, waits, answers, and prompts again, for as many exchanges as you want.
That conversational shape is what this suite pins — recognizing the >>>
prompt, carrying on a multi-step exchange where each answer depends on the
last, getting a traceback back for bad input without the session dying, and
exiting cleanly on end-of-input. Python also behaves differently when it
detects a terminal, so that branch is exercised too.
Python is on every CI image, which makes this the most portable worked example here of testing an interactive program — and a template to copy for your own REPL.
Source: test/e2e/thirdparty/python/python.atago.yaml
Scenario: version and -c contracts (non-interactive) #
only when python3 --version succeeds
When #
python3 --version
python3 -c "print('hello from python')"
Then #
- after
python3 --version:- exit code is
0 - stdout matches
/^Python 3\./
- exit code is
- after
python3 -c "print('hello from python')":- exit code is
0 - stdout equals an exact value
- exit code is
Scenario: a missing script exits 2 with a can’t-open-file error #
only when python3 --version succeeds
When #
python3 no_such_script.py
Then #
- exit code is
2 - stderr contains
can't open file
Scenario: stdout is a pipe under run but a tty under pty #
only when python3 --version succeeds · skipped on Windows
When #
python3 -c "import sys; print(sys.stdout.isatty())"
# interactive (pty): python3 -c "import sys; print(sys.stdout.isatty())"
Then #
- exit code is
0 - stdout equals an exact value
- exit code is
0 - stdout contains
True
Scenario: an interactive session drives the REPL across exchanges #
only when python3 --version succeeds · skipped on Windows
When #
# interactive (pty): python3 -q
Then #
- exit code is
0 - stdout contains
2,120
Scenario: EOF (ctrl-d) ends the session cleanly #
only when python3 --version succeeds · skipped on Windows
When #
# interactive (pty): python3 -q
Then #
- exit code is
0
Scenario: a traceback is reported and the REPL recovers #
only when python3 --version succeeds · skipped on Windows
When #
# interactive (pty): python3 -q
Then #
- exit code is
0 - stdout contains
ZeroDivisionError,recovered