Skip to content

Commit 7363e8d

Browse files
gh-133139: Add curses.assume_default_colors() (GH-133145)
This is a refinement of the curses.use_default_colors() function which allows to change the color pair 0.
1 parent 3e256b9 commit 7363e8d

File tree

6 files changed

+135
-28
lines changed

6 files changed

+135
-28
lines changed

Doc/library/curses.rst

+21-8
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,21 @@ The module :mod:`curses` defines the following exception:
6868
The module :mod:`curses` defines the following functions:
6969

7070

71+
.. function:: assume_default_colors(fg, bg)
72+
73+
Allow use of default values for colors on terminals supporting this feature.
74+
Use this to support transparency in your application.
75+
76+
* Assign terminal default foreground/background colors to color number ``-1``.
77+
So ``init_pair(x, COLOR_RED, -1)`` will initialize pair *x* as red
78+
on default background and ``init_pair(x, -1, COLOR_BLUE)`` will
79+
initialize pair *x* as default foreground on blue.
80+
81+
* Change the definition of the color-pair ``0`` to ``(fg, bg)``.
82+
83+
.. versionadded:: next
84+
85+
7186
.. function:: baudrate()
7287

7388
Return the output speed of the terminal in bits per second. On software
@@ -290,9 +305,11 @@ The module :mod:`curses` defines the following functions:
290305
Change the definition of a color-pair. It takes three arguments: the number of
291306
the color-pair to be changed, the foreground color number, and the background
292307
color number. The value of *pair_number* must be between ``1`` and
293-
``COLOR_PAIRS - 1`` (the ``0`` color pair is wired to white on black and cannot
294-
be changed). The value of *fg* and *bg* arguments must be between ``0`` and
295-
``COLORS - 1``, or, after calling :func:`use_default_colors`, ``-1``.
308+
``COLOR_PAIRS - 1`` (the ``0`` color pair can only be changed by
309+
:func:`use_default_colors` and :func:`assume_default_colors`).
310+
The value of *fg* and *bg* arguments must be between ``0`` and
311+
``COLORS - 1``, or, after calling :func:`!use_default_colors` or
312+
:func:`!assume_default_colors`, ``-1``.
296313
If the color-pair was previously initialized, the screen is
297314
refreshed and all occurrences of that color-pair are changed to the new
298315
definition.
@@ -678,11 +695,7 @@ The module :mod:`curses` defines the following functions:
678695

679696
.. function:: use_default_colors()
680697

681-
Allow use of default values for colors on terminals supporting this feature. Use
682-
this to support transparency in your application. The default color is assigned
683-
to the color number ``-1``. After calling this function, ``init_pair(x,
684-
curses.COLOR_RED, -1)`` initializes, for instance, color pair *x* to a red
685-
foreground color on the default background.
698+
Equivalent to ``assume_default_colors(-1, -1)``.
686699

687700

688701
.. function:: wrapper(func, /, *args, **kwargs)

Doc/whatsnew/3.14.rst

+8
Original file line numberDiff line numberDiff line change
@@ -891,6 +891,14 @@ ctypes
891891
making it a :term:`generic type`.
892892
(Contributed by Brian Schubert in :gh:`132168`.)
893893

894+
curses
895+
------
896+
897+
* Add the :func:`~curses.assume_default_colors` function,
898+
a refinement of the :func:`~curses.use_default_colors` function which
899+
allows to change the color pair ``0``.
900+
(Contributed by Serhiy Storchaka in :gh:`133139`.)
901+
894902
datetime
895903
--------
896904

Lib/test/test_curses.py

+16-10
Original file line numberDiff line numberDiff line change
@@ -51,12 +51,6 @@ def wrapped(self, *args, **kwargs):
5151

5252
term = os.environ.get('TERM')
5353
SHORT_MAX = 0x7fff
54-
DEFAULT_PAIR_CONTENTS = [
55-
(curses.COLOR_WHITE, curses.COLOR_BLACK),
56-
(0, 0),
57-
(-1, -1),
58-
(15, 0), # for xterm-256color (15 is for BRIGHT WHITE)
59-
]
6054

6155
# If newterm was supported we could use it instead of initscr and not exit
6256
@unittest.skipIf(not term or term == 'unknown',
@@ -948,8 +942,6 @@ def get_pair_limit(self):
948942

949943
@requires_colors
950944
def test_pair_content(self):
951-
if not hasattr(curses, 'use_default_colors'):
952-
self.assertIn(curses.pair_content(0), DEFAULT_PAIR_CONTENTS)
953945
curses.pair_content(0)
954946
maxpair = self.get_pair_limit() - 1
955947
if maxpair > 0:
@@ -994,13 +986,27 @@ def test_color_attrs(self):
994986
@requires_curses_func('use_default_colors')
995987
@requires_colors
996988
def test_use_default_colors(self):
997-
old = curses.pair_content(0)
998989
try:
999990
curses.use_default_colors()
1000991
except curses.error:
1001992
self.skipTest('cannot change color (use_default_colors() failed)')
1002993
self.assertEqual(curses.pair_content(0), (-1, -1))
1003-
self.assertIn(old, DEFAULT_PAIR_CONTENTS)
994+
995+
@requires_curses_func('assume_default_colors')
996+
@requires_colors
997+
def test_assume_default_colors(self):
998+
try:
999+
curses.assume_default_colors(-1, -1)
1000+
except curses.error:
1001+
self.skipTest('cannot change color (assume_default_colors() failed)')
1002+
self.assertEqual(curses.pair_content(0), (-1, -1))
1003+
curses.assume_default_colors(curses.COLOR_YELLOW, curses.COLOR_BLUE)
1004+
self.assertEqual(curses.pair_content(0), (curses.COLOR_YELLOW, curses.COLOR_BLUE))
1005+
curses.assume_default_colors(curses.COLOR_RED, -1)
1006+
self.assertEqual(curses.pair_content(0), (curses.COLOR_RED, -1))
1007+
curses.assume_default_colors(-1, curses.COLOR_GREEN)
1008+
self.assertEqual(curses.pair_content(0), (-1, curses.COLOR_GREEN))
1009+
curses.assume_default_colors(-1, -1)
10041010

10051011
def test_keyname(self):
10061012
# TODO: key_name()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Add the :func:`curses.assume_default_colors` function, a refinement of the
2+
:func:`curses.use_default_colors` function which allows to change the color
3+
pair ``0``.

Modules/_cursesmodule.c

+36-5
Original file line numberDiff line numberDiff line change
@@ -4720,15 +4720,12 @@ _curses_use_env_impl(PyObject *module, int flag)
47204720
/*[clinic input]
47214721
_curses.use_default_colors
47224722
4723-
Allow use of default values for colors on terminals supporting this feature.
4724-
4725-
Use this to support transparency in your application. The default color
4726-
is assigned to the color number -1.
4723+
Equivalent to assume_default_colors(-1, -1).
47274724
[clinic start generated code]*/
47284725

47294726
static PyObject *
47304727
_curses_use_default_colors_impl(PyObject *module)
4731-
/*[clinic end generated code: output=a3b81ff71dd901be input=656844367470e8fc]*/
4728+
/*[clinic end generated code: output=a3b81ff71dd901be input=99ff0b7c69834d1f]*/
47324729
{
47334730
int code;
47344731

@@ -4744,6 +4741,39 @@ _curses_use_default_colors_impl(PyObject *module)
47444741
return NULL;
47454742
}
47464743
}
4744+
4745+
/*[clinic input]
4746+
_curses.assume_default_colors
4747+
fg: int
4748+
bg: int
4749+
/
4750+
4751+
Allow use of default values for colors on terminals supporting this feature.
4752+
4753+
Assign terminal default foreground/background colors to color number -1.
4754+
Change the definition of the color-pair 0 to (fg, bg).
4755+
4756+
Use this to support transparency in your application.
4757+
[clinic start generated code]*/
4758+
4759+
static PyObject *
4760+
_curses_assume_default_colors_impl(PyObject *module, int fg, int bg)
4761+
/*[clinic end generated code: output=54985397a7d2b3a5 input=7fe301712ef3e9fb]*/
4762+
{
4763+
int code;
4764+
4765+
PyCursesStatefulInitialised(module);
4766+
PyCursesStatefulInitialisedColor(module);
4767+
4768+
code = assume_default_colors(fg, bg);
4769+
if (code != ERR) {
4770+
Py_RETURN_NONE;
4771+
} else {
4772+
cursesmodule_state *state = get_cursesmodule_state(module);
4773+
PyErr_SetString(state->error, "assume_default_colors() returned ERR");
4774+
return NULL;
4775+
}
4776+
}
47474777
#endif /* STRICT_SYSV_CURSES */
47484778

47494779

@@ -4902,6 +4932,7 @@ static PyMethodDef cursesmodule_methods[] = {
49024932
_CURSES_UNGET_WCH_METHODDEF
49034933
_CURSES_USE_ENV_METHODDEF
49044934
_CURSES_USE_DEFAULT_COLORS_METHODDEF
4935+
_CURSES_ASSUME_DEFAULT_COLORS_METHODDEF
49054936
{NULL, NULL} /* sentinel */
49064937
};
49074938

Modules/clinic/_cursesmodule.c.h

+51-5
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)