Add window methods and module functions that report curses state which could
previously only be set: the window getters is_cleared(), is_idcok(),
is_idlok(), is_immedok(), is_keypad(), is_leaveok(), is_nodelay(),
is_notimeout(), is_pad(), is_scrollok(), is_subwin(), is_syncok(),
getdelay(), getparent() and getscrreg(), and the functions is_cbreak(),
is_echo(), is_nl() and is_raw(). They are available when built against an
ncurses with NCURSES_EXT_FUNCS.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add alloc_pair(), find_pair(), free_pair() and reset_color_pairs(),
wrapping the ncurses extended-color dynamic pair management. They are
available only when built against a wide-character ncurses with
extended-color support.
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add the X/Open Curses SCREEN API for driving more than one terminal:
newterm() and set_term(), plus the ncurses extension new_prescr().
A new screen object wraps the C SCREEN. It exposes the terminal's
standard window as screen.stdscr. Each window keeps a reference to its
screen (like a subwindow does to its parent window), so the screen is
deleted automatically once it and all of its windows are unreferenced.
The ncurses use_screen()/use_window() locking helpers are exposed as
the screen.use() and window.use() methods.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add docstrings for the curses.window, curses.error, curses.panel.panel
and curses.panel.error classes. Document the panel class and its error
exception in curses.panel.rst, using the real lowercase panel name.
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Tcl 8.x crashes when title-casing a non-BMP character during Tk
initialization, so such a className is now rejected with a ValueError.
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
The character-cell window methods now accept a full character cell -- a
spacing character optionally followed by combining characters (up to
CCHARW_MAX wide characters) -- in addition to a single int or byte
character. This affects addch(), bkgd(), bkgdset(), border(), box(),
echochar(), hline(), insch() and vline(); they dispatch to the ncursesw
wide-character functions (wadd_wch(), wbkgrnd(), wborder_set(),
wecho_wchar(), whline_set(), wins_wch(), wvline_set(), ...) when given a
string. border() and box() cannot mix integer or byte characters with
wide string characters in a single call. A cell is one spacing character
optionally followed by combining characters, so an extra spacing or
control character (such as "ab") is rejected with ValueError rather than
being silently truncated by setcchar().
Also add the wide-character read methods get_wstr() and in_wstr(), the
counterparts of getstr() and instr() that return a str rather than a
bytes object, and the module functions erasewchar(), killwchar() and
wunctrl(), the wide-character counterparts of erasechar(), killchar()
and unctrl().
All of this is available only when built against the wide-character
ncursesw library.
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Character class escapes (``\d``, ``\D``, ``\s``, ``\S``, ``\w`` and
``\W``) that occur outside a character set are now compiled directly to a
single CATEGORY opcode instead of being wrapped in an IN block. This
removes the IN wrapper (three code words) and an indirect charset() call,
and makes such an escape a simple repeatable unit so that, for example,
``\d+`` uses the REPEAT_ONE fast path; a CATEGORY case is added to
SRE(count).
The transformation preserves behaviour exactly. For category-heavy
patterns the compiled byte code is about 20% smaller and matching is up
to ~2x faster, with no effect on patterns that do not use bare category
escapes.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Wrap the ncurses nofilter() function, which undoes the effect of
filter(). Without it there is no way to restore normal screen sizing
after a curses.filter() call in the same process.
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Tcl/Tk 9 may embed the Tk script library in the Tk DLL on Windows. This embedded library is not found by Tcl by default.
Mount the loaded Tk DLL as a zipfs archive before calling Tk_Init(), so Tk can find its embedded tk_library using its existing library discovery logic.
Preserve Tk_Init()'s normal path if the library is not embedded.
The module-global curses_screen_encoding stored a borrowed pointer to the
encoding owned by the window returned by the first initscr() call. That
window can be deallocated while unctrl() and ungetch(), which have no window
of their own, still use the pointer to encode non-ASCII characters.
Keep a private copy of the encoding instead.
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The initial implementation of PEP 820 worsened the error message
when non-types are given as base types in Py_tp_bases & Py_tp_base.
Bring back the 'bases must be types' wording and add a 'got' note for
easier debugging.
Improve slot ID documentation, and soft-deprecate Py_tp_base
(as per the PEP).
* snprintf() is not async-signal-safe: replace it with
_Py_DumpDecimal().
* Fix tid type from 'long' to 'unsigned long'.
* Replace PyLong_AsLong() with PyLong_AsInt().
* Avoid unnecessary narrowing cast on _Py_write_noraise() call.
Replace also _PyObject_HashFast() with PyObject_Hash()
in _collections._count_elements().
Rename _PyObject_HashFast() to _PyObject_HashDictKey(),
and mark it as Py_ALWAYS_INLINE.
Only use _PyObject_HashDictKey() on dictionaries.
The standard says that a call to `memcpy` must pass a valid source and
destination pointer even if the size is 0, so we must avoid calling
`memcpy` when our source pointer is NULL. If we don't, an optimizing
compiler can decide that the pointer must be non-NULL based on the
presence of UB, and optimize out checks for null pointers.
Specifically, note that the standard says:
Where an argument declared as size_t n specifies the length of the
array for a function, n can have the value zero on a call to that
function. Unless explicitly stated otherwise in the description of
a particular function in this subclause, pointer arguments on such
a call shall still have valid values, as described in 7.1.4.
And section 7.1.4 says:
If an argument to a function has an invalid value (such as a value
outside the domain of the function, or a pointer outside the address
space of the program, or a null pointer, or a pointer to
non-modifiable storage when the corresponding parameter is not
const-qualified) or a type (after default argument promotion) not
expected by a function with a variable number of arguments, the
behavior is undefined.
The specification for `memcpy` doesn't state that it's allowed to be
called with null pointers, and Linux's `/usr/include/string.h` declares
`memcpy` as `__nonnull ((1, 2))`.
Append parsed values to the result list with _PyList_AppendTakeRef and
insert key/value pairs with _PyDict_SetItem_Take2, which take ownership of
the references instead of incref-ing on insert and then decref-ing the
local. This removes a reference-count round-trip per element (and, on the
free-threaded build, a per-append lock).
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Fix crashes in socket.sendmsg() and socket.recvmsg_into() that could
occur if buffer sequences are mutated re-entrantly during argument
parsing via __buffer__ protocol callbacks.
The bug occurs because:
1. PySequence_Fast() returns the original list object when the input
is already a list (not a copy).
2. During iteration, PyObject_GetBuffer() triggers __buffer__
callbacks which may clear the list.
3. Subsequent iterations access invalid memory (heap OOB read).
The fix replaces PySequence_Fast() with PySequence_Tuple() which
always creates a new tuple, ensuring the sequence cannot be mutated
during iteration.
Co-authored-by: tonghuaroot <23011166+tonghuaroot@users.noreply.github.com>
TextIOWrapper keeps its underlying stream in a member called
`self->buffer`. That stream can be detached by user code, such as custom
`.flush` implementations resulting in `self->buffer` being set to NULL.
The implementation often checked at the start of functions if
`self->buffer` is in a good state, but did not always recheck after
other Python code was called which could modify `self->buffer`.
The cases which need to be re-checked are hard to spot so rather than
rely on reviewer effort create better safety by making all self->buffer
access go through helper functions.
Thank you yihong0618 for the test, NEWS and initial implementation in
gh-143041.
Co-authored-by: yihong0618 <zouzou0208@gmail.com>
Co-authored-by: Victor Stinner <vstinner@python.org>