Skip to main content
   ┌──────────────────────────────────────────────────┐
   │  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:

  1. os.get_terminal_size(stream.fileno()) when available.
  2. COLUMNS / LINES from env (defaults to os.environ).
  3. (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.environ implicitly — the caller passes the dict. Makes testing trivial and avoids surprises in nested processes.
  • Defensive. Helpers tolerate None streams, closed streams, and missing methods. They never raise from a "best-effort" path.
  • POSIX-first. with_raw_mode and on_resize are POSIX-only (termios / SIGWINCH); they raise OSError on 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.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

codechu_term-0.1.0.tar.gz (13.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

codechu_term-0.1.0-py3-none-any.whl (10.4 kB view details)

Uploaded Python 3

File details

Details for the file codechu_term-0.1.0.tar.gz.

File metadata

  • Download URL: codechu_term-0.1.0.tar.gz
  • Upload date:
  • Size: 13.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for codechu_term-0.1.0.tar.gz
Algorithm Hash digest
SHA256 ae89d59f870924ab6f8a9106a2916667c10183609479910039f5221c6596e83e
MD5 17aa1abe7f279097a40e3117e43da192
BLAKE2b-256 2459c893d6db78beeb82765736ac802c3b46cb03a93219a088851fd98e6ef464

See more details on using hashes here.

Provenance

The following attestation bundles were made for codechu_term-0.1.0.tar.gz:

Publisher: release.yml on codechu/term-py

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file codechu_term-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: codechu_term-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 10.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for codechu_term-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 b5b6472cde61cfaef837a38cd8a34ace328fc9c71dbeec35d8f5a9fc5569c54a
MD5 bc6131895deea43afde88dda0ae7a2cd
BLAKE2b-256 1a917d79e78ebb16316e076e1587ab5b622c2dff0b2b5cab3a2e2019caffffe4

See more details on using hashes here.

Provenance

The following attestation bundles were made for codechu_term-0.1.0-py3-none-any.whl:

Publisher: release.yml on codechu/term-py

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page