┌──────────────────────────────────────────────────┐
│ c o d e c h u — t e r m │
│ $ _ │
│ ····TTY detection · alt buffer · raw mode······ │
└──────────────────────────────────────────────────┘
Terminal capability detection and low-level control, stdlib-only.
codechu-term
Stdlib-only terminal-capability detection and low-level terminal
control — extracted from the codechu/cli-py
private _term module and expanded with the bits Codechu CLIs
actually use. No external dependencies. Python 3.10+, POSIX-first.
Install
pip install codechu-term
API
import os, sys
from codechu_term import (
is_tty, terminal_size, capabilities,
with_alt_buffer, with_raw_mode, on_resize,
hide_cursor, show_cursor, clear_line, clear_screen,
)
is_tty(sys.stderr) # → True / False
terminal_size() # → (cols, rows), e.g. (120, 40)
terminal_size(env={"COLUMNS": "100", "LINES": "30"}) # explicit env
capabilities(sys.stdout, env=os.environ)
# → {'color': True, 'truecolor': True, 'unicode': True,
# 'emoji': True, 'mouse': True, 'alt_buffer': True}
with with_alt_buffer() as out: # full-screen mode
out.write("hello, alt buffer\n"); out.flush()
with with_raw_mode() as fd: # char-by-char input
ch = os.read(fd, 1)
remove = on_resize(lambda: print("resized!"))
# ... later
remove()
hide_cursor(); show_cursor()
clear_line(); clear_screen()
is_tty(stream)
Defensive isatty() — accepts None and any object, swallows
exceptions, returns False for anything that isn't a confirmed TTY.
terminal_size(stream=sys.stderr, *, env=None)
Resolution ladder:
os.get_terminal_size(stream.fileno())when available.COLUMNS/LINESfromenv(defaults toos.environ).(80, 24)as a final fallback.
Never raises.
capabilities(stream, env=None)
Returns six boolean flags:
| Key | True when |
|---|---|
color |
stream is a TTY, TERM != "dumb", and NO_COLOR is unset |
truecolor |
color and COLORTERM in {"truecolor", "24bit"} |
unicode |
LC_ALL / LC_CTYPE / LANG advertises UTF-8 |
emoji |
unicode and (TERM_PROGRAM is a known emoji emulator or xterm-family) |
mouse |
TTY and xterm-family TERM |
alt_buffer |
xterm-family TERM |
env is taken explicitly — pass env=os.environ for the live
process environment.
with_alt_buffer(stream=sys.stdout)
Context manager that switches to the alt screen buffer
(\x1b[?1049h) on entry and restores the main buffer
(\x1b[?1049l) on exit — even when the block raises.
with_raw_mode(fd=sys.stdin.fileno())
termios/tty raw mode for char-by-char input. Restores the
original terminal attributes in a finally block, so the terminal
never gets stuck. POSIX only.
on_resize(callback)
Installs callback as a SIGWINCH handler and returns a remover
function that restores the previous handler. The callback is invoked
with no arguments. POSIX only.
hide_cursor() / show_cursor() / clear_line() / clear_screen()
Best-effort emitters for the corresponding ANSI sequences
(\x1b[?25l, \x1b[?25h, \x1b[2K\r, \x1b[2J\x1b[H). They never
raise — a closed stream is silently ignored.
Design
- Pure stdlib. Zero third-party dependencies.
- Explicit env. Capability detection never reads
os.environimplicitly — the caller passes the dict. Makes testing trivial and avoids surprises in nested processes. - Defensive. Helpers tolerate
Nonestreams, closed streams, and missing methods. They never raise from a "best-effort" path. - POSIX-first.
with_raw_modeandon_resizeare POSIX-only (termios / SIGWINCH); they raiseOSErroron Windows rather than silently no-op.
Tests
pip install -e ".[dev]"
pytest -q
Tests that require a real TTY (raw mode, SIGWINCH propagation) skip themselves when running headless.
License
MIT — see LICENSE.
Metadata
Release files for codechu-term 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| codechu_term-0.1.0.tar.gz | 13.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| codechu_term-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 23.7 kB
Release files / codechu_term-0.1.0.tar.gz
| Download URL | codechu_term-0.1.0.tar.gz |
|---|---|
| Size | 13.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
ae89d59f870924ab6f8a9106a2916667c10183609479910039f5221c6596e83e
|
|
BLAKE2b-256 checksum How to use checksums |
2459c893d6db78beeb82765736ac802c3b46cb03a93219a088851fd98e6ef464
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on May 20, 2026.
Transparency logRelease files / codechu_term-0.1.0-py3-none-any.whl
| Download URL | codechu_term-0.1.0-py3-none-any.whl |
|---|---|
| Size | 10.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
b5b6472cde61cfaef837a38cd8a34ace328fc9c71dbeec35d8f5a9fc5569c54a
|
|
BLAKE2b-256 checksum How to use checksums |
1a917d79e78ebb16316e076e1587ab5b622c2dff0b2b5cab3a2e2019caffffe4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on May 20, 2026.
Transparency log