diff --git a/Lib/curses/ascii.py b/Lib/curses/ascii.py index 6a466e00786..5b243be6811 100644 --- a/Lib/curses/ascii.py +++ b/Lib/curses/ascii.py @@ -53,19 +53,19 @@ def _ctoi(c): def isalnum(c): return isalpha(c) or isdigit(c) def isalpha(c): return isupper(c) or islower(c) -def isascii(c): return _ctoi(c) <= 127 # ? +def isascii(c): return 0 <= _ctoi(c) <= 127 # ? def isblank(c): return _ctoi(c) in (9, 32) -def iscntrl(c): return _ctoi(c) <= 31 or _ctoi(c) == 127 -def isdigit(c): return _ctoi(c) >= 48 and _ctoi(c) <= 57 -def isgraph(c): return _ctoi(c) >= 33 and _ctoi(c) <= 126 -def islower(c): return _ctoi(c) >= 97 and _ctoi(c) <= 122 -def isprint(c): return _ctoi(c) >= 32 and _ctoi(c) <= 126 +def iscntrl(c): return 0 <= _ctoi(c) <= 31 or _ctoi(c) == 127 +def isdigit(c): return 48 <= _ctoi(c) <= 57 +def isgraph(c): return 33 <= _ctoi(c) <= 126 +def islower(c): return 97 <= _ctoi(c) <= 122 +def isprint(c): return 32 <= _ctoi(c) <= 126 def ispunct(c): return isgraph(c) and not isalnum(c) def isspace(c): return _ctoi(c) in (9, 10, 11, 12, 13, 32) -def isupper(c): return _ctoi(c) >= 65 and _ctoi(c) <= 90 +def isupper(c): return 65 <= _ctoi(c) <= 90 def isxdigit(c): return isdigit(c) or \ - (_ctoi(c) >= 65 and _ctoi(c) <= 70) or (_ctoi(c) >= 97 and _ctoi(c) <= 102) -def isctrl(c): return _ctoi(c) < 32 + (65 <= _ctoi(c) <= 70) or (97 <= _ctoi(c) <= 102) +def isctrl(c): return 0 <= _ctoi(c) < 32 def ismeta(c): return _ctoi(c) > 127 def ascii(c): diff --git a/Lib/test/test_curses.py b/Lib/test/test_curses.py index d020fd2ccab..25284ad522b 100644 --- a/Lib/test/test_curses.py +++ b/Lib/test/test_curses.py @@ -436,6 +436,25 @@ class TestAscii(unittest.TestCase): check(curses.ascii.ispunct, c in string.punctuation) check(curses.ascii.isxdigit, c in string.hexdigits) + for i in (-2, -1, 256, sys.maxunicode, sys.maxunicode+1): + self.assertFalse(curses.ascii.isalnum(i)) + self.assertFalse(curses.ascii.isalpha(i)) + self.assertFalse(curses.ascii.isdigit(i)) + self.assertFalse(curses.ascii.islower(i)) + self.assertFalse(curses.ascii.isspace(i)) + self.assertFalse(curses.ascii.isupper(i)) + + self.assertFalse(curses.ascii.isascii(i)) + self.assertFalse(curses.ascii.isctrl(i)) + self.assertFalse(curses.ascii.iscntrl(i)) + self.assertFalse(curses.ascii.isblank(i)) + self.assertFalse(curses.ascii.isgraph(i)) + self.assertFalse(curses.ascii.isprint(i)) + self.assertFalse(curses.ascii.ispunct(i)) + self.assertFalse(curses.ascii.isxdigit(i)) + + self.assertFalse(curses.ascii.ismeta(-1)) + def test_ascii(self): ascii = curses.ascii.ascii self.assertEqual(ascii('\xc1'), 'A') diff --git a/Misc/NEWS b/Misc/NEWS index 82f147d6dbd..9c972b1e32f 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -140,6 +140,9 @@ Core and Builtins Library ------- +- Issue #9770: curses.ascii predicates now work correctly with negative + integers. + - Issue #28427: old keys should not remove new values from WeakValueDictionary when collecting from another thread.