Issue37738
Created on 2019-08-01 13:45 by mgedmin, last changed 2019-08-14 11:01 by vstinner. This issue is now closed.
Pull Requests | |||
---|---|---|---|
URL | Status | Linked | Edit |
PR 15071 | merged | vstinner, 2019-08-01 15:12 | |
PR 15272 | merged | miss-islington, 2019-08-14 10:31 | |
PR 15273 | merged | vstinner, 2019-08-14 10:41 |
Messages (8) | |||
---|---|---|---|
msg348855 - (view) | Author: Marius Gedminas (mgedmin) * | Date: 2019-08-01 13:45 | |
curses.addch() ignores color information if I pass it a string of length one. Color works fine if I pass it a byte string or an int. Here's a reproducer: ### start of example ### import curses def main(stdscr): curses.start_color() curses.use_default_colors() curses.init_pair(1, curses.COLOR_RED, -1) curses.init_pair(2, curses.COLOR_GREEN, -1) curses.curs_set(0) stdscr.addch("a", curses.color_pair(1)) stdscr.addch("b", curses.color_pair(2) | curses.A_BOLD) stdscr.addch(b"c", curses.color_pair(1)) stdscr.addch(b"d", curses.color_pair(2) | curses.A_BOLD) stdscr.addch(ord("e"), curses.color_pair(1)) stdscr.addch(ord("f"), curses.color_pair(2) | curses.A_BOLD) stdscr.refresh() stdscr.getch() curses.wrapper(main) ### end of example ### On Python 2.7 this prints 'abcdef' in alternating red and green. On Python 3.5 through 3.8 this prints 'ab' in white and the rest in red/green. Note that only color pair information is lost -- the bold attribute is correctly set on the 'b'. |
|||
msg348862 - (view) | Author: STINNER Victor (vstinner) * ![]() |
Date: 2019-08-01 15:13 | |
stdscr.addch(str, color_pair) is implemented with: setcchar(&wcval, wstr, attr, 0, NULL); rtn = wadd_wch(self->win, &wcval); whereas stdscr.addch(bytes, color_pair) is implemented with: rtn = waddch(self->win, cch | (attr_t) attr); The 4th argument of setcchar() is "short color_pair": Python always pass 0. It seems to be your bug. Attached PR 15071 fix this bug. Note: Python 3.5 and 3.6 don't accept bugfixes anymore, only security fixes. |
|||
msg348863 - (view) | Author: STINNER Victor (vstinner) * ![]() |
Date: 2019-08-01 15:18 | |
I'm able to reproduce the issue on Fedora 30: Python 3.7.4 with ncurses-libs-6.1-10.20180923.fc30.x86_64. vstinner@apu$ cat /etc/fedora-release Fedora release 30 (Thirty) vstinner@apu$ python3 -VV Python 3.7.4 (default, Jul 9 2019, 16:32:37) [GCC 9.1.1 20190503 (Red Hat 9.1.1-1)] vstinner@apu$ python3 -c 'import _curses; print(_curses.__file__)' /usr/lib64/python3.7/lib-dynload/_curses.cpython-37m-x86_64-linux-gnu.so vstinner@apu$ ldd $(python3 -c 'import _curses; print(_curses.__file__)') linux-vdso.so.1 (0x00007ffe6f1b4000) libncursesw.so.6 => /lib64/libncursesw.so.6 (0x00007f1acf456000) libtinfo.so.6 => /lib64/libtinfo.so.6 (0x00007f1acf427000) libpython3.7m.so.1.0 => /lib64/libpython3.7m.so.1.0 (0x00007f1acf0de000) libc.so.6 => /lib64/libc.so.6 (0x00007f1acef18000) libdl.so.2 => /lib64/libdl.so.2 (0x00007f1acef12000) libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f1aceef1000) libutil.so.1 => /lib64/libutil.so.1 (0x00007f1aceeea000) libm.so.6 => /lib64/libm.so.6 (0x00007f1aceda4000) /lib64/ld-linux-x86-64.so.2 (0x00007f1acf4dc000) vstinner@apu$ rpm -qf /lib64/libncursesw.so.6 ncurses-libs-6.1-10.20180923.fc30.x86_64 |
|||
msg349672 - (view) | Author: STINNER Victor (vstinner) * ![]() |
Date: 2019-08-14 10:31 | |
New changeset 077af8c2c93dd71086e2c5e5ff1e634b6da8f214 by Victor Stinner in branch 'master': bpo-37738: Fix curses addch(str, color_pair) (GH-15071) https://github.com/python/cpython/commit/077af8c2c93dd71086e2c5e5ff1e634b6da8f214 |
|||
msg349673 - (view) | Author: STINNER Victor (vstinner) * ![]() |
Date: 2019-08-14 10:40 | |
On my Fedora 30 with libncursesw, A_COLOR = 0xff00. After my change, _curses uses: static inline short attr_to_color_pair(int attr) { return (short)((attr & A_COLOR) >> 8); } ... setcchar(&wcval, wstr, attr, attr_to_color_pair(attr), NULL); ... If someone gets troubles with attr passed "directly" as the 3rd argument of setcchar(), we can try to pass (attr & ~A_COLOR) instead. On my Linux, it would mean: only pass the low 8 bits of attr. But since it "just" works on my Linux, I prefer to only make minimum changes to fix this issue on Linux. |
|||
msg349674 - (view) | Author: miss-islington (miss-islington) | Date: 2019-08-14 10:49 | |
New changeset 984226962bc35254551d92771b5c8fb074507903 by Miss Islington (bot) in branch '3.8': bpo-37738: Fix curses addch(str, color_pair) (GH-15071) https://github.com/python/cpython/commit/984226962bc35254551d92771b5c8fb074507903 |
|||
msg349676 - (view) | Author: STINNER Victor (vstinner) * ![]() |
Date: 2019-08-14 11:00 | |
New changeset 7eef81ee766c8df23e522b4e46a930cc1d360ad7 by Victor Stinner in branch '3.7': bpo-37738: Fix curses addch(str, color_pair) (GH-15071) (GH-15273) https://github.com/python/cpython/commit/7eef81ee766c8df23e522b4e46a930cc1d360ad7 |
|||
msg349677 - (view) | Author: STINNER Victor (vstinner) * ![]() |
Date: 2019-08-14 11:01 | |
I fixed the bug in 3.7, 3.8 and master (future 3.9) branches. Thanks Marius Gedminas for the bug report. In the meanwhile, you have to pass bytes strings to addch() :-( |
History | |||
---|---|---|---|
Date | User | Action | Args |
2019-08-14 11:01:28 | vstinner | set | status: open -> closed resolution: fixed messages: + msg349677 stage: patch review -> resolved |
2019-08-14 11:00:30 | vstinner | set | messages: + msg349676 |
2019-08-14 10:49:16 | miss-islington | set | nosy:
+ miss-islington messages: + msg349674 |
2019-08-14 10:41:55 | vstinner | set | pull_requests: + pull_request14995 |
2019-08-14 10:40:24 | vstinner | set | messages: + msg349673 |
2019-08-14 10:31:57 | vstinner | set | messages: + msg349672 |
2019-08-14 10:31:54 | miss-islington | set | pull_requests: + pull_request14994 |
2019-08-01 16:03:23 | vstinner | set | versions: + Python 3.9, - Python 3.5, Python 3.6 |
2019-08-01 15:18:31 | vstinner | set | messages: + msg348863 |
2019-08-01 15:13:21 | vstinner | set | nosy:
+ vstinner messages: + msg348862 |
2019-08-01 15:12:29 | vstinner | set | keywords:
+ patch stage: patch review pull_requests: + pull_request14818 |
2019-08-01 13:45:15 | mgedmin | create |