Skip to content
Python Basics: Distinguish Incomplete Input with codeop

Python Basics: Distinguish Incomplete Input with codeop

October 27, 2026

An interactive editor needs to tell “keep typing” apart from invalid syntax. codeop.compile_command returns no code object for incomplete input, returns a code object for complete input, and raises for invalid input. A controlled fixture demonstrates all three outcomes.

Prepare a scratch directory

Tested on Linux with CPython 3.12.14. You need the named runtime, Bash, a text editor, and the standard mktemp, rm, and rmdir utilities. Run Python without -O so the assertions remain enabled. Any generated fixture files live inside an automatically cleaned temporary directory.

Keep using the same terminal. Stop if setup fails, before saving the source:

start_dir="$PWD"
work_dir="$(mktemp -d)" || exit 1
cd -- "$work_dir" || exit 1

Run the example

Save this as demonstrate-codeop.py:

import codeop

incomplete = codeop.compile_command("if True:\n", symbol="exec")
assert incomplete is None
print("Incomplete suite needs more input:", incomplete is None)

compiled = codeop.compile_command("if True:\n    answer = 42\n", symbol="exec")
assert compiled is not None
namespace = {}
exec(compiled, namespace)
assert namespace["answer"] == 42
print("Complete suite result:", namespace["answer"])

try:
    codeop.compile_command("if :\n", symbol="exec")
except SyntaxError:
    print("Invalid syntax: rejected")
else:
    raise AssertionError("Invalid syntax unexpectedly compiled")

blank = codeop.compile_command("# only a comment\n", symbol="exec")
assert blank is not None
print("Comment-only input is complete:", blank is not None)

Run it:

python3 -B demonstrate-codeop.py

Observed output:

Incomplete suite needs more input: True
Complete suite result: 42
Invalid syntax: rejected
Comment-only input is complete: True

Read the result

The unfinished if suite needs more input, so the function returns None. Adding its body makes it compilable; execution then produces the asserted value. The malformed condition cannot be repaired simply by adding a body, so it raises SyntaxError. Comment-only input is a complete no-op rather than a request for another statement.

Apply it carefully

Compilation does not execute the input, but the explicit exec call does. This tutorial executes only a fixed string it owns; do not turn the pattern into an untrusted-code service. The symbol parameter chooses a grammar mode, and this example uses exec for statement suites. CommandCompiler can retain future-statement flags across calls when building a persistent interactive session. Compilation success still does not prove runtime correctness.

The official reference describes the API and its options. The checks above cover the specific fixture, not every possible input or environment.

Clean up

Remove the source and then the empty practice directory:

rm -- demonstrate-codeop.py
cd -- "$start_dir" || exit 1
rmdir -- "$work_dir"
unset start_dir work_dir

If the directory is not empty, inspect the remaining files rather than deleting unknown contents.

Acknowledgements

This post was created with assistance from AI.

Last updated on