https://github.com/python/cpython/commit/161054cbfe5a5fb566698c3514ad6bc2078b00d8
commit: 161054cbfe5a5fb566698c3514ad6bc2078b00d8
branch: main
author: Serhiy Storchaka <[email protected]>
committer: serhiy-storchaka <[email protected]>
date: 2026-09-03T10:18:08+03:00
summary:

gh-156347: Fix wrong statements in the curses documentation (GH-156354)

window.encoding does not encode the string arguments on a build with
wide-character support: the curses library converts the characters itself.

In the HOWTO: getch() returns -1, not curses.ERR, when there is no input,
and half-delay mode does the same as no-delay mode.  getkey() returns the
key name only for a special key.  leaveok() is not a synonym for curs_set().
getstr() returns a bytes object, interprets the erase and kill characters,
and limits bytes.  The ACS_* constants are not all larger than 255.

Also document get_wch() before getch(), mention complexchar and complexstr,
and read whole characters in the examples.

files:
M Doc/howto/curses.rst
M Doc/library/curses.rst

diff --git a/Doc/howto/curses.rst b/Doc/howto/curses.rst
index 7bcf63c0b458962..14f46efc1ec0fea 100644
--- a/Doc/howto/curses.rst
+++ b/Doc/howto/curses.rst
@@ -295,17 +295,21 @@ underline, reverse code, or in color.  They'll be 
explained in more detail in
 the next subsection.
 
 
-The :meth:`~curses.window.addstr` method takes a Python string or
-bytestring as the value to be displayed.  The contents of bytestrings
-are sent to the terminal as-is.  Strings are encoded to bytes using
-the value of the window's :attr:`~window.encoding` attribute; this defaults to
-the default system encoding as returned by :func:`locale.getencoding`.
+The :meth:`~curses.window.addstr` method takes a Python string, bytestring
+or :class:`~curses.complexstr` as the value to be displayed.  The contents
+of bytestrings are sent to the terminal as-is.
+On a build without wide-character support strings are encoded
+using the value of the window's :attr:`~window.encoding` attribute;
+this defaults to the default system encoding
+as returned by :func:`locale.getencoding`.
 
 The :meth:`~curses.window.addch` methods take a character, which can be
-either a string of length 1, a bytestring of length 1, or an integer.
+either a string of length 1, a bytestring of length 1, an integer, or a
+:class:`~curses.complexchar`.
 
-Constants are provided for extension characters; these constants are
-integers greater than 255.  For example, :const:`ACS_PLMINUS` is a +/-
+Constants are provided for the characters of the terminal's alternate
+character set.
+For example, :const:`ACS_PLMINUS` is a +/-
 symbol, and :const:`ACS_ULCORNER` is the upper left corner of a box
 (handy for drawing borders).  You can also use the appropriate Unicode
 character.
@@ -319,11 +323,11 @@ won't be distracting; it can be confusing to have the 
cursor blinking at some
 apparently random location.
 
 If your application doesn't need a blinking cursor at all, you can
-call ``curs_set(False)`` to make it invisible.  For compatibility
-with older curses versions, there's a ``leaveok(bool)`` function
-that's a synonym for :func:`~curses.curs_set`.  When *bool* is true, the
-curses library will attempt to suppress the flashing cursor, and you
-won't need to worry about leaving it in odd locations.
+call ``curs_set(False)`` to make it invisible.
+The window method :meth:`~curses.window.leaveok` does something different:
+when its argument is true,
+curses leaves the cursor wherever the last update put it,
+instead of moving it back to the window's cursor position.
 
 
 Attributes and Color
@@ -364,6 +368,14 @@ could code::
                  curses.A_REVERSE)
    stdscr.refresh()
 
+A :class:`~curses.complexchar` carries its attributes and color pair
+together with the text of one character cell,
+and a :class:`~curses.complexstr` is a run of such cells.
+They are what :meth:`~curses.window.in_wch` and
+:meth:`~curses.window.in_wchstr` return,
+so a part of the screen can be read and written back
+with its appearance intact.
+
 The curses library also supports color on those terminals that provide it. The
 most common such terminal is probably the Linux console, followed by color
 xterms.
@@ -429,40 +441,48 @@ The C curses library offers only very simple input 
mechanisms. Python's
 :mod:`curses` module adds a basic text-input widget.  (Other libraries
 such as :pypi:`Urwid` have more extensive collections of widgets.)
 
-There are two methods for getting input from a window:
+There are three methods for getting input from a window:
 
-* :meth:`~curses.window.getch` refreshes the screen and then waits for
+* :meth:`~curses.window.get_wch` refreshes the screen and then waits for
   the user to hit a key, displaying the key if :func:`~curses.echo` has been
   called earlier.  You can optionally specify a coordinate to which
   the cursor should be moved before pausing.
 
-* :meth:`~curses.window.getkey` does the same thing but converts the
-  integer to a string.  Individual characters are returned as
-  1-character strings, and special keys such as function keys return
-  longer strings containing a key name such as ``KEY_UP`` or ``^G``.
+* :meth:`~curses.window.getch` does the same thing but returns the code of
+  the key instead of a character.
+  With ncurses this is a single byte of the key's encoding in the current
+  locale, so a character encoded with several bytes takes several calls,
+  one byte per call.
+
+* :meth:`~curses.window.getkey` does the same as :meth:`!getch` but returns
+  a string:
+  an ordinary key as a 1-character string,
+  and a special key as its name, such as ``KEY_UP``.
 
 It's possible to not wait for the user using the
 :meth:`~curses.window.nodelay` window method. After ``nodelay(True)``,
-:meth:`!getch` and :meth:`!getkey` for the window become
-non-blocking. To signal that no input is ready, :meth:`!getch` returns
-``curses.ERR`` (a value of -1) and :meth:`!getkey` raises an exception.
+the reads for the window become non-blocking.
+To signal that no input is ready,
+:meth:`!get_wch` and :meth:`!getkey` raise an exception,
+and :meth:`!getch` returns ``-1``.
 There's also a :func:`~curses.halfdelay` function, which can be used to (in
-effect) set a timer on each :meth:`!getch`; if no input becomes
+effect) set a timer on each read; if no input becomes
 available within a specified delay (measured in tenths of a second),
-curses raises an exception.
+the read fails the same way.
 
-The :meth:`!getch` method returns an integer; if it's between 0 and 255, it
-represents the ASCII code of the key pressed.  Values greater than 255 are
-special keys such as Page Up, Home, or the cursor keys. You can compare the
-value returned to constants such as :const:`curses.KEY_PPAGE`,
+Special keys such as Page Up, Home, or the cursor keys are returned by all
+three as one of the :ref:`KEY_* constants <curses-key-constants>`,
+all larger than 255.
+You can compare the value returned to constants such as
+:const:`curses.KEY_PPAGE`,
 :const:`curses.KEY_HOME`, or :const:`curses.KEY_LEFT`.  The main loop of
 your program may look something like this::
 
    while True:
-       c = stdscr.getch()
-       if c == ord('p'):
+       c = stdscr.get_wch()
+       if c == 'p':
            PrintDocument()
-       elif c == ord('q'):
+       elif c == 'q':
            break  # Exit the while loop
        elif c == curses.KEY_HOME:
            x = y = 0
@@ -474,16 +494,17 @@ conversion functions  that take either integer or 
1-character-string arguments
 and return the same type.  For example, :func:`curses.ascii.ctrl` returns the
 control character corresponding to its argument.
 
-There's also a method to retrieve an entire string,
-:meth:`~curses.window.getstr`.  It isn't used very often, because its
+There's also a method to retrieve an entire line,
+:meth:`~curses.window.get_wstr`.  It isn't used very often, because its
 functionality is quite limited; the only editing keys available are
-the backspace key and the Enter key, which terminates the string.  It
-can optionally be limited to a fixed number of characters. ::
+the erase and kill characters, and the Enter key, which terminates the line.
+It can optionally be limited to a fixed number of characters;
+:meth:`~curses.window.getstr` returns a bytes object instead. ::
 
    curses.echo()            # Enable echoing of characters
 
-   # Get a 15-character string, with the cursor on the top line
-   s = stdscr.getstr(0,0, 15)
+   # Get a line of at most 15 characters, with the cursor on the top line
+   s = stdscr.get_wstr(0,0, 15)
 
 The :mod:`curses.textpad` module supplies a text box that supports an
 Emacs-like set of keybindings.  Various methods of the
diff --git a/Doc/library/curses.rst b/Doc/library/curses.rst
index 858371f927f4fad..bcf2ef47d48898a 100644
--- a/Doc/library/curses.rst
+++ b/Doc/library/curses.rst
@@ -2002,7 +2002,8 @@ Other
 
 .. attribute:: window.encoding
 
-   Encoding used to encode method arguments (Unicode strings and characters).
+   Encoding used to encode the string arguments of the methods and to decode
+   their results on a build without wide-character support.
    The encoding attribute is inherited from the parent window when a subwindow
    is created, for example with :meth:`window.subwin`.
    By default, current locale encoding is used (see 
:func:`locale.getencoding`).

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]

Reply via email to