Skip to content

gh-80480: Emit DeprecationWarning for array's 'u' type code #95760

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 14 commits into from
Jun 11, 2023
Merged
2 changes: 1 addition & 1 deletion Doc/library/array.rst
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ Notes:
``Py_UNICODE``. This change doesn't affect its behavior because
``Py_UNICODE`` is alias of ``wchar_t`` since Python 3.3.

.. deprecated-removed:: 3.3 4.0
.. deprecated-removed:: 3.3 3.16
Please migrate to ``'w'`` typecode.


Expand Down
5 changes: 5 additions & 0 deletions Doc/whatsnew/3.13.rst
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,11 @@ Deprecated
They will be removed in Python 3.15.
(Contributed by Victor Stinner in :gh:`105096`.)

* :mod:`array`'s ``'u'`` format code, deprecated in docs since Python 3.3,
emits :exc:`DeprecationWarning` since 3.13
and will be removed in Python 3.16.
Use the ``'w'`` format code instead.
(contributed by Hugo van Kemenade in :gh:`80480`)

Removed
=======
Expand Down
19 changes: 18 additions & 1 deletion Lib/test/test_array.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,14 @@
import operator
import struct
import sys
import warnings

import array
from array import _array_reconstructor as array_reconstructor

sizeof_wchar = array.array('u').itemsize
with warnings.catch_warnings():
warnings.simplefilter('ignore', DeprecationWarning)
sizeof_wchar = array.array('u').itemsize


class ArraySubclass(array.array):
Expand Down Expand Up @@ -93,8 +96,16 @@ def test_empty(self):
UTF32_LE = 20
UTF32_BE = 21


class ArrayReconstructorTest(unittest.TestCase):

def setUp(self):
warnings.filterwarnings(
"ignore",
message="The 'u' type code is deprecated and "
"will be removed in Python 3.16",
category=DeprecationWarning)

def test_error(self):
self.assertRaises(TypeError, array_reconstructor,
"", "b", 0, b"")
Expand Down Expand Up @@ -1208,10 +1219,16 @@ def test_issue17223(self):
self.assertRaises(ValueError, a.tounicode)
self.assertRaises(ValueError, str, a)

def test_typecode_u_deprecation(self):
with self.assertWarns(DeprecationWarning):
array.array("u")


class UCS4Test(UnicodeTest):
typecode = 'w'
minitemsize = 4


class NumberTest(BaseTest):

def test_extslice(self):
Expand Down
16 changes: 10 additions & 6 deletions Lib/test/test_buffer.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import sys, array, io, os
from decimal import Decimal
from fractions import Fraction
from test.support import warnings_helper

try:
from _testbuffer import *
Expand Down Expand Up @@ -3217,12 +3218,6 @@ def test_memoryview_compare_special_cases(self):
nd[0] = (-1, float('nan'))
self.assertNotEqual(memoryview(nd), nd)

# Depends on issue #15625: the struct module does not understand 'u'.
a = array.array('u', 'xyz')
v = memoryview(a)
self.assertNotEqual(a, v)
self.assertNotEqual(v, a)

# Some ctypes format strings are unknown to the struct module.
if ctypes:
# format: "T{>l:x:>l:y:}"
Expand All @@ -3236,6 +3231,15 @@ class BEPoint(ctypes.BigEndianStructure):
self.assertNotEqual(point, a)
self.assertRaises(NotImplementedError, a.tolist)

@warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-80480 array('u')
def test_memoryview_compare_special_cases_deprecated_u_type_code(self):

# Depends on issue #15625: the struct module does not understand 'u'.
a = array.array('u', 'xyz')
v = memoryview(a)
self.assertNotEqual(a, v)
self.assertNotEqual(v, a)

def test_memoryview_compare_ndim_zero(self):

nd1 = ndarray(1729, shape=[], format='@L')
Expand Down
5 changes: 3 additions & 2 deletions Lib/test/test_re.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from test.support import (gc_collect, bigmemtest, _2G,
cpython_only, captured_stdout,
check_disallow_instantiation, is_emscripten, is_wasi,
SHORT_TIMEOUT)
warnings_helper, SHORT_TIMEOUT)
import locale
import re
import string
Expand Down Expand Up @@ -1522,10 +1522,11 @@ def test_bug_6561(self):
for x in not_decimal_digits:
self.assertIsNone(re.match(r'^\d$', x))

@warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-80480 array('u')
def test_empty_array(self):
# SF buf 1647541
import array
for typecode in 'bBuhHiIlLfd':
for typecode in 'bBhuwHiIlLfd':
a = array.array(typecode)
self.assertIsNone(re.compile(b"bla").match(a))
self.assertEqual(re.compile(b"").match(a).groups(), ())
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Emit :exc:`DeprecationWarning` for :mod:`array`'s ``'u'`` type code,
deprecated in docs since Python 3.3.
9 changes: 9 additions & 0 deletions Modules/arraymodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -2679,6 +2679,15 @@ array_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
return NULL;
}

if (c == 'u') {
if (PyErr_WarnEx(PyExc_DeprecationWarning,
"The 'u' type code is deprecated and "
"will be removed in Python 3.16",
1)) {
return NULL;
}
}

bool is_unicode = c == 'u' || c == 'w';

if (initial && !is_unicode) {
Expand Down