Skip to content

Commit a49ac99

Browse files
authored
bpo-32677: Add .isascii() to str, bytes and bytearray (pythonGH-5342)
1 parent 85527cf commit a49ac99

13 files changed

Lines changed: 110 additions & 2 deletions

File tree

Doc/library/stdtypes.rst

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1653,6 +1653,15 @@ expression support in the :mod:`re` module).
16531653
from the "Alphabetic" property defined in the Unicode Standard.
16541654

16551655

1656+
.. method:: str.isascii()
1657+
1658+
Return true if the string is empty or all characters in the string are ASCII,
1659+
false otherwise.
1660+
ASCII characters have code points in the range U+0000-U+007F.
1661+
1662+
.. versionadded:: 3.7
1663+
1664+
16561665
.. method:: str.isdecimal()
16571666

16581667
Return true if all characters in the string are decimal
@@ -2941,6 +2950,16 @@ place, and instead produce new objects.
29412950
False
29422951

29432952

2953+
.. method:: bytes.isascii()
2954+
bytearray.isascii()
2955+
2956+
Return true if the sequence is empty or all bytes in the sequence are ASCII,
2957+
false otherwise.
2958+
ASCII bytes are in the range 0-0x7F.
2959+
2960+
.. versionadded:: 3.7
2961+
2962+
29442963
.. method:: bytes.isdigit()
29452964
bytearray.isdigit()
29462965

Include/bytes_methods.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
extern PyObject* _Py_bytes_isspace(const char *cptr, Py_ssize_t len);
1010
extern PyObject* _Py_bytes_isalpha(const char *cptr, Py_ssize_t len);
1111
extern PyObject* _Py_bytes_isalnum(const char *cptr, Py_ssize_t len);
12+
extern PyObject* _Py_bytes_isascii(const char *cptr, Py_ssize_t len);
1213
extern PyObject* _Py_bytes_isdigit(const char *cptr, Py_ssize_t len);
1314
extern PyObject* _Py_bytes_islower(const char *cptr, Py_ssize_t len);
1415
extern PyObject* _Py_bytes_isupper(const char *cptr, Py_ssize_t len);
@@ -37,6 +38,7 @@ extern PyObject* _Py_bytes_maketrans(Py_buffer *frm, Py_buffer *to);
3738
extern const char _Py_isspace__doc__[];
3839
extern const char _Py_isalpha__doc__[];
3940
extern const char _Py_isalnum__doc__[];
41+
extern const char _Py_isascii__doc__[];
4042
extern const char _Py_isdigit__doc__[];
4143
extern const char _Py_islower__doc__[];
4244
extern const char _Py_isupper__doc__[];

Lib/collections/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1214,6 +1214,7 @@ def index(self, sub, start=0, end=_sys.maxsize):
12141214
return self.data.index(sub, start, end)
12151215
def isalpha(self): return self.data.isalpha()
12161216
def isalnum(self): return self.data.isalnum()
1217+
def isascii(self): return self.data.isascii()
12171218
def isdecimal(self): return self.data.isdecimal()
12181219
def isdigit(self): return self.data.isdigit()
12191220
def isidentifier(self): return self.data.isidentifier()

Lib/test/string_tests.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -909,6 +909,14 @@ def test_isalnum(self):
909909
self.checkequal(False, 'abc\n', 'isalnum')
910910
self.checkraises(TypeError, 'abc', 'isalnum', 42)
911911

912+
def test_isascii(self):
913+
self.checkequal(True, '', 'isascii')
914+
self.checkequal(True, '\x00', 'isascii')
915+
self.checkequal(True, '\x7f', 'isascii')
916+
self.checkequal(True, '\x00\x7f', 'isascii')
917+
self.checkequal(False, '\x80', 'isascii')
918+
self.checkequal(False, '\xe9', 'isascii')
919+
912920
def test_isdigit(self):
913921
self.checkequal(False, '', 'isdigit')
914922
self.checkequal(False, 'a', 'isdigit')

Lib/test/test_doctest.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -659,7 +659,7 @@ def non_Python_modules(): r"""
659659
660660
>>> import builtins
661661
>>> tests = doctest.DocTestFinder().find(builtins)
662-
>>> 790 < len(tests) < 810 # approximate number of objects with docstrings
662+
>>> 800 < len(tests) < 820 # approximate number of objects with docstrings
663663
True
664664
>>> real_tests = [t for t in tests if len(t.examples) > 0]
665665
>>> len(real_tests) # objects that actually have doctests

Lib/test/test_unicode.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -638,6 +638,11 @@ def test_isalpha(self):
638638
self.assertFalse('\U0001F40D'.isalpha())
639639
self.assertFalse('\U0001F46F'.isalpha())
640640

641+
def test_isascii(self):
642+
super().test_isascii()
643+
self.assertFalse("\u20ac".isascii())
644+
self.assertFalse("\U0010ffff".isascii())
645+
641646
def test_isdecimal(self):
642647
self.checkequalnofix(False, '', 'isdecimal')
643648
self.checkequalnofix(False, 'a', 'isdecimal')
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Add ``.isascii()`` method to ``str``, ``bytes`` and ``bytearray``.
2+
It can be used to test that string contains only ASCII characters.

Objects/bytearrayobject.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2159,6 +2159,8 @@ bytearray_methods[] = {
21592159
_Py_isalnum__doc__},
21602160
{"isalpha", (PyCFunction)stringlib_isalpha, METH_NOARGS,
21612161
_Py_isalpha__doc__},
2162+
{"isascii", (PyCFunction)stringlib_isascii, METH_NOARGS,
2163+
_Py_isascii__doc__},
21622164
{"isdigit", (PyCFunction)stringlib_isdigit, METH_NOARGS,
21632165
_Py_isdigit__doc__},
21642166
{"islower", (PyCFunction)stringlib_islower, METH_NOARGS,

Objects/bytes_methods.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,26 @@ _Py_bytes_isalnum(const char *cptr, Py_ssize_t len)
9292
}
9393

9494

95+
PyDoc_STRVAR_shared(_Py_isascii__doc__,
96+
"B.isascii() -> bool\n\
97+
\n\
98+
Return True if B is empty or all characters in B are ASCII,\n\
99+
False otherwise.");
100+
101+
PyObject*
102+
_Py_bytes_isascii(const char *cptr, Py_ssize_t len)
103+
{
104+
const unsigned char *p = (unsigned char *) cptr;
105+
const unsigned char *e = p + len;
106+
for (; p < e; p++) {
107+
if (*p >= 128) {
108+
Py_RETURN_FALSE;
109+
}
110+
}
111+
Py_RETURN_TRUE;
112+
}
113+
114+
95115
PyDoc_STRVAR_shared(_Py_isdigit__doc__,
96116
"B.isdigit() -> bool\n\
97117
\n\

Objects/bytesobject.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2459,6 +2459,8 @@ bytes_methods[] = {
24592459
_Py_isalnum__doc__},
24602460
{"isalpha", (PyCFunction)stringlib_isalpha, METH_NOARGS,
24612461
_Py_isalpha__doc__},
2462+
{"isascii", (PyCFunction)stringlib_isascii, METH_NOARGS,
2463+
_Py_isascii__doc__},
24622464
{"isdigit", (PyCFunction)stringlib_isdigit, METH_NOARGS,
24632465
_Py_isdigit__doc__},
24642466
{"islower", (PyCFunction)stringlib_islower, METH_NOARGS,

0 commit comments

Comments
 (0)