str.isprintable()

Distinguish content that survives print() intact from content that would move the cursor or damage the display.

String methodPython 3.0+Live demo
Common call
if s.isprintable():
Returns
True or False
Replaces
a manual `all(unicodedata.category(c) != "Cc" for c in s)` loop
Watch out
EMPTY RETURNS TRUE (like isascii, unlike everything else); SPACE is printable but TAB and NEWLINE are not
str.isprintable()
bool

Demo

Live evaluation
Try:
Inputs
stringstrthe string to test
Output
'hello world'.isprintable()
True

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

Filter loggable content
Guard against log-line-breaking control characters.
if not user_input.isprintable():
    raise ValueError("input contains control characters")
Detect binary or damaged data
Quick check that a string is plausibly display-safe.
if raw.isprintable():
    display(raw)
else:
    display(repr(raw))
Combine with isascii for "safe simple string"
Only ASCII, only printable — no non-Latin, no control, no exotic.
if s.isascii() and s.isprintable():
    ...   # display-safe simple string

Examples

1. Basic text
"hello world".isprintable()
Returns
True
2. With emoji
"café 🎉".isprintable()
Returns
True
3. Tab
"a\tb".isprintable()
Returns
False
4. Newline
"line1\nline2".isprintable()
Returns
False
5. NUL byte
"a\x00b".isprintable()
Returns
False
6. Just space
" ".isprintable()
Returns
True # space IS printable
7. Empty is TRUE
"".isprintable()
Returns
True # like isascii

Pitfalls

1. Empty string returns TRUE
Only isascii and isprintable in the is* family return True on empty. All others return False. Vacuous truth: no character can violate the "every character is printable" rule.
Assumed False
"".isprintable()
True
Guard for non-empty
s and s.isprintable()
True only for non-empty printable
2. Space is PRINTABLE but TAB and NEWLINE are NOT
Python distinguishes "printable" from "visible". Space (U+0020) is a printable character — you can print it and something (a gap) appears. Tab, newline, and carriage return are CONTROL characters — they change the cursor position and return False.
Assumed all whitespace fails
" ".isprintable()
True # space is printable
Tab and newline fail
"\t".isprintable()
"\n".isprintable()
False False
3. Zero-width characters are printable in the technical sense
Zero-width joiner (U+200D), zero-width space (U+200B), and BOM (U+FEFF) are NOT control characters — they are formatting characters (category Cf). Python classifies them as printable even though they are invisible. This is a security surface for lookalike attacks.
Invisible passes
"a\u200bb".isprintable()
True # ZWSP is not a control char
Strict visible check
import unicodedata
all(unicodedata.category(c)[0] not in ("C", "Z") or c == " " for c in s)
4. Not the same as isascii
A common conflation. isprintable rejects control chars but accepts anything Unicode (emoji, accents, non-Latin). isascii rejects anything above U+007F but accepts ASCII control characters. Different filters entirely.
Very different
"café".isascii()      # False
"café".isprintable() # True
different results
Combine for both
s.isascii() and s.isprintable()
True only for ASCII printable

When to use

Use it
  • 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
Reach for something else
  • 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

Complexity
O(n) — one linear scan
Return
bool — True or False (True on empty)
CPython impl
Objects/unicodeobject.c :: unicode_isprintable
Memory
No allocation
Thread-safe
Yes — strings are immutable

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.

History

3.0
isprintable() introduced along with the Unicode-first str type.