Skip to content

Commit ee65ebd

Browse files
authored
gh-134978: deprecate string keyword parameter for hash function constructors (#134979)
1 parent ac75110 commit ee65ebd

File tree

6 files changed

+70
-5
lines changed

6 files changed

+70
-5
lines changed

Doc/deprecations/pending-removal-in-3.19.rst

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,19 @@ Pending removal in Python 3.19
66
* Implicitly switching to the MSVC-compatible struct layout by setting
77
:attr:`~ctypes.Structure._pack_` but not :attr:`~ctypes.Structure._layout_`
88
on non-Windows platforms.
9+
10+
* :mod:`hashlib`:
11+
12+
- In hash function constructors such as :func:`~hashlib.new` or the
13+
direct hash-named constructors such as :func:`~hashlib.md5` and
14+
:func:`~hashlib.sha256`, their optional initial data parameter could
15+
also be passed a keyword argument named ``data=`` or ``string=`` in
16+
various :mod:`!hashlib` implementations.
17+
18+
Support for the ``string`` keyword argument name is now deprecated
19+
and slated for removal in Python 3.19.
20+
21+
Before Python 3.13, the ``string`` keyword parameter was not correctly
22+
supported depending on the backend implementation of hash functions.
23+
Prefer passing the initial data as a positional argument for maximum
24+
backwards compatibility.

Doc/library/hashlib.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,13 @@ accessible by name via :func:`new`. See :data:`algorithms_available`.
9494
OpenSSL does not provide we fall back to a verified implementation from
9595
the `HACL\* project`_.
9696

97+
.. deprecated-removed:: 3.15 3.19
98+
The undocumented ``string`` keyword parameter in :func:`!_hashlib.new`
99+
and hash-named constructors such as :func:`!_md5.md5` is deprecated.
100+
Prefer passing the initial data as a positional argument for maximum
101+
backwards compatibility.
102+
103+
97104
Usage
98105
-----
99106

Doc/whatsnew/3.15.rst

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -146,8 +146,20 @@ module_name
146146
Deprecated
147147
==========
148148

149-
* module_name:
150-
TODO
149+
hashlib
150+
-------
151+
152+
* In hash function constructors such as :func:`~hashlib.new` or the
153+
direct hash-named constructors such as :func:`~hashlib.md5` and
154+
:func:`~hashlib.sha256`, their optional initial data parameter could
155+
also be passed a keyword argument named ``data=`` or ``string=`` in
156+
various :mod:`hashlib` implementations.
157+
158+
Support for the ``string`` keyword argument name is now deprecated and
159+
is slated for removal in Python 3.19. Prefer passing the initial data as
160+
a positional argument for maximum backwards compatibility.
161+
162+
(Contributed by Bénédikt Tran in :gh:`134978`.)
151163

152164

153165
.. Add deprecations above alphabetically, not here at the end.

Lib/test/test_hashlib.py

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,14 @@ def read_vectors(hash_name):
9898
yield parts
9999

100100

101+
DEPRECATED_STRING_PARAMETER = re.escape(
102+
"the 'string' keyword parameter is deprecated since "
103+
"Python 3.15 and slated for removal in Python 3.19; "
104+
"use the 'data' keyword parameter or pass the data "
105+
"to hash as a positional argument instead"
106+
)
107+
108+
101109
class HashLibTestCase(unittest.TestCase):
102110
supported_hash_names = ( 'md5', 'MD5', 'sha1', 'SHA1',
103111
'sha224', 'SHA224', 'sha256', 'SHA256',
@@ -255,17 +263,23 @@ def test_clinic_signature(self):
255263
with self.subTest(constructor.__name__):
256264
constructor(b'')
257265
constructor(data=b'')
258-
constructor(string=b'') # should be deprecated in the future
266+
with self.assertWarnsRegex(DeprecationWarning,
267+
DEPRECATED_STRING_PARAMETER):
268+
constructor(string=b'')
259269

260270
digest_name = constructor(b'').name
261271
with self.subTest(digest_name):
262272
hashlib.new(digest_name, b'')
263273
hashlib.new(digest_name, data=b'')
264-
hashlib.new(digest_name, string=b'')
274+
with self.assertWarnsRegex(DeprecationWarning,
275+
DEPRECATED_STRING_PARAMETER):
276+
hashlib.new(digest_name, string=b'')
265277
if self._hashlib:
266278
self._hashlib.new(digest_name, b'')
267279
self._hashlib.new(digest_name, data=b'')
268-
self._hashlib.new(digest_name, string=b'')
280+
with self.assertWarnsRegex(DeprecationWarning,
281+
DEPRECATED_STRING_PARAMETER):
282+
self._hashlib.new(digest_name, string=b'')
269283

270284
@unittest.skipIf(get_fips_mode(), "skip in FIPS mode")
271285
def test_clinic_signature_errors(self):
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
:mod:`hashlib`: Supporting the ``string`` keyword parameter in hash function
2+
constructors such as :func:`~hashlib.new` or the direct hash-named constructors
3+
such as :func:`~hashlib.md5` and :func:`~hashlib.sha256` is now deprecated and
4+
slated for removal in Python 3.19.
5+
Prefer passing the initial data as a positional argument for maximum backwards
6+
compatibility.
7+
Patch by Bénédikt Tran.

Modules/hashlib.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,15 @@ _Py_hashlib_data_argument(PyObject **res, PyObject *data, PyObject *string)
8686
}
8787
else if (data == NULL && string != NULL) {
8888
// called as H(string=...)
89+
if (PyErr_WarnEx(PyExc_DeprecationWarning,
90+
"the 'string' keyword parameter is deprecated since "
91+
"Python 3.15 and slated for removal in Python 3.19; "
92+
"use the 'data' keyword parameter or pass the data "
93+
"to hash as a positional argument instead", 1) < 0)
94+
{
95+
*res = NULL;
96+
return -1;
97+
}
8998
*res = string;
9099
return 1;
91100
}

0 commit comments

Comments
 (0)