Skip to content

Commit cb45871

Browse files
[3.14] gh-141004: document curses C API (GH-141254) (#141292)
gh-141004: document `curses` C API (GH-141254) (cherry picked from commit dbe4090) Co-authored-by: Bénédikt Tran <[email protected]>
1 parent afa52a1 commit cb45871

File tree

2 files changed

+147
-1
lines changed

2 files changed

+147
-1
lines changed

Doc/c-api/concrete.rst

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,5 +115,13 @@ Other Objects
115115
gen.rst
116116
coro.rst
117117
contextvars.rst
118-
datetime.rst
119118
typehints.rst
119+
120+
121+
C API for extension modules
122+
===========================
123+
124+
.. toctree::
125+
126+
curses.rst
127+
datetime.rst

Doc/c-api/curses.rst

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
.. highlight:: c
2+
3+
Curses C API
4+
------------
5+
6+
:mod:`curses` exposes a small C interface for extension modules.
7+
Consumers must include the header file :file:`py_curses.h` (which is not
8+
included by default by :file:`Python.h`) and :c:func:`import_curses` must
9+
be invoked, usually as part of the module initialisation function, to populate
10+
:c:var:`PyCurses_API`.
11+
12+
.. warning::
13+
14+
Neither the C API nor the pure Python :mod:`curses` module are compatible
15+
with subinterpreters.
16+
17+
.. c:macro:: import_curses()
18+
19+
Import the curses C API. The macro does not need a semi-colon to be called.
20+
21+
On success, populate the :c:var:`PyCurses_API` pointer.
22+
23+
On failure, set :c:var:`PyCurses_API` to NULL and set an exception.
24+
The caller must check if an error occurred via :c:func:`PyErr_Occurred`:
25+
26+
.. code-block::
27+
28+
import_curses(); // semi-colon is optional but recommended
29+
if (PyErr_Occurred()) { /* cleanup */ }
30+
31+
32+
.. c:var:: void **PyCurses_API
33+
34+
Dynamically allocated object containing the curses C API.
35+
This variable is only available once :c:macro:`import_curses` succeeds.
36+
37+
``PyCurses_API[0]`` corresponds to :c:data:`PyCursesWindow_Type`.
38+
39+
``PyCurses_API[1]``, ``PyCurses_API[2]``, and ``PyCurses_API[3]``
40+
are pointers to predicate functions of type ``int (*)(void)``.
41+
42+
When called, these predicates return whether :func:`curses.setupterm`,
43+
:func:`curses.initscr`, and :func:`curses.start_color` have been called
44+
respectively.
45+
46+
See also the convenience macros :c:macro:`PyCursesSetupTermCalled`,
47+
:c:macro:`PyCursesInitialised`, and :c:macro:`PyCursesInitialisedColor`.
48+
49+
.. note::
50+
51+
The number of entries in this structure is subject to changes.
52+
Consider using :c:macro:`PyCurses_API_pointers` to check if
53+
new fields are available or not.
54+
55+
56+
.. c:macro:: PyCurses_API_pointers
57+
58+
The number of accessible fields (``4``) in :c:var:`PyCurses_API`.
59+
This number is incremented whenever new fields are added.
60+
61+
62+
.. c:var:: PyTypeObject PyCursesWindow_Type
63+
64+
The :ref:`heap type <heap-types>` corresponding to :class:`curses.window`.
65+
66+
67+
.. c:function:: int PyCursesWindow_Check(PyObject *op)
68+
69+
Return true if *op* is a :class:`curses.window` instance, false otherwise.
70+
71+
72+
The following macros are convenience macros expanding into C statements.
73+
In particular, they can only be used as ``macro;`` or ``macro``, but not
74+
``macro()`` or ``macro();``.
75+
76+
.. c:macro:: PyCursesSetupTermCalled
77+
78+
Macro checking if :func:`curses.setupterm` has been called.
79+
80+
The macro expansion is roughly equivalent to:
81+
82+
.. code-block::
83+
84+
{
85+
typedef int (*predicate_t)(void);
86+
predicate_t was_setupterm_called = (predicate_t)PyCurses_API[1];
87+
if (!was_setupterm_called()) {
88+
return NULL;
89+
}
90+
}
91+
92+
93+
.. c:macro:: PyCursesInitialised
94+
95+
Macro checking if :func:`curses.initscr` has been called.
96+
97+
The macro expansion is roughly equivalent to:
98+
99+
.. code-block::
100+
101+
{
102+
typedef int (*predicate_t)(void);
103+
predicate_t was_initscr_called = (predicate_t)PyCurses_API[2];
104+
if (!was_initscr_called()) {
105+
return NULL;
106+
}
107+
}
108+
109+
110+
.. c:macro:: PyCursesInitialisedColor
111+
112+
Macro checking if :func:`curses.start_color` has been called.
113+
114+
The macro expansion is roughly equivalent to:
115+
116+
.. code-block::
117+
118+
{
119+
typedef int (*predicate_t)(void);
120+
predicate_t was_start_color_called = (predicate_t)PyCurses_API[3];
121+
if (!was_start_color_called()) {
122+
return NULL;
123+
}
124+
}
125+
126+
127+
Internal data
128+
-------------
129+
130+
The following objects are exposed by the C API but should be considered
131+
internal-only.
132+
133+
.. c:macro:: PyCurses_CAPSULE_NAME
134+
135+
Name of the curses capsule to pass to :c:func:`PyCapsule_Import`.
136+
137+
Internal usage only. Use :c:macro:`import_curses` instead.
138+

0 commit comments

Comments
 (0)