str.isprintable()
Distinguish content that survives print() intact from content that would move the cursor or damage the display.
Demo
isprintable() returns True when the string contains no control characters and the empty string. SPACE (U+0020) counts as printable — this surprises people who assumed "printable" meant "visible." TAB (U+0009), NEWLINE (U+000A), CARRIAGE RETURN (U+000D), and NUL (U+0000) are all control characters and return False. Emojis and accented letters pass. Empty string returns True — joining isascii as the "empty is True" exception to the is* family.
Common patterns
if not user_input.isprintable(): raise ValueError("input contains control characters")
if raw.isprintable(): display(raw) else: display(repr(raw))
if s.isascii() and s.isprintable(): ... # display-safe simple string
Examples
Pitfalls
"".isprintable()
s and s.isprintable()
" ".isprintable()
"\t".isprintable() "\n".isprintable()
"a\u200bb".isprintable()
import unicodedata all(unicodedata.category(c)[0] not in ("C", "Z") or c == " " for c in s)
"café".isascii() # False "café".isprintable() # True
s.isascii() and s.isprintable()
When to use
- Safety check before writing to a log line or terminal
- Detecting damaged binary data mixed into text
- Combining with isascii for "simple safe display" validation
- Filtering strings that would move the cursor or corrupt output
- You need to REJECT space too → check explicitly
- You need to reject zero-width chars → use unicodedata
- You want ASCII-only → combine with str.isascii
- Testing whether the string LOOKS printable — display quality is beyond this method
Notes
FAQ
Because Python follows the Unicode categorization: space (U+0020) is in category Zs (space separator), while tab (U+0009) is in category Cc (control). Space is a character that prints as a visible gap; tab moves the cursor. The distinction matters more than it looks.