Skip to content

Commit f887257

Browse files
authored
Deprecate database functions that appear in Django 3.0+ (#735)
1 parent 40da1f9 commit f887257

File tree

4 files changed

+106
-7
lines changed

4 files changed

+106
-7
lines changed

HISTORY.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,13 @@ History
1313
1414
connection.vendor == "mysql" and connection.mysql_is_mariadb
1515
16+
* Deprecate database functions which exist in Django 3.0+:
17+
18+
* ``Sign``
19+
* ``MD5``
20+
* ``SHA1``
21+
* ``SHA2``
22+
1623
4.5.0 (2022-01-23)
1724
------------------
1825

docs/database_functions.rst

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,11 @@ Numeric Functions
6060
6161
.. class:: Sign(expression)
6262

63+
.. note::
64+
65+
This function is deprecated. Use
66+
:class:`django.db.models.functions.Sign` instead.
67+
6368
Returns the sign of the argument as -1, 0, or 1, depending on whether
6469
``expression`` is negative, zero, or positive.
6570

@@ -299,6 +304,11 @@ Encryption Functions
299304

300305
.. class:: MD5(expression)
301306

307+
.. note::
308+
309+
This function is deprecated. Use
310+
:class:`django.db.models.functions.MD5` instead.
311+
302312
Calculates an MD5 128-bit checksum for the string ``expression``.
303313

304314
Docs:
@@ -314,6 +324,11 @@ Encryption Functions
314324
315325
.. class:: SHA1(expression)
316326

327+
.. note::
328+
329+
This function is deprecated. Use
330+
:class:`django.db.models.functions.SHA1` instead.
331+
317332
Calculates an SHA-1 160-bit checksum for the string ``expression``, as
318333
described in RFC 3174 (Secure Hash Algorithm).
319334

@@ -330,6 +345,14 @@ Encryption Functions
330345
331346
.. class:: SHA2(expression, hash_len=512)
332347

348+
.. note::
349+
350+
This function is deprecated. Use
351+
:class:`django.db.models.functions.SHA224`,
352+
:class:`~django.db.models.functions.SHA256`,
353+
:class:`~django.db.models.functions.SHA384`, or
354+
:class:`~django.db.models.functions.SHA512` instead.
355+
333356
Given a string ``expression``, calculates a SHA-2 checksum, which is
334357
considered more cryptographically secure than its SHA-1 equivalent. The
335358
SHA-2 family includes SHA-224, SHA-256, SHA-384, and SHA-512, and the

src/django_mysql/models/functions.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import datetime as dt
44
import json
5+
import warnings
56
from typing import Any, Union
67

78
from django.db import DEFAULT_DB_ALIAS, connections
@@ -58,6 +59,17 @@ class Sign(SingleArgFunc):
5859
function = "SIGN"
5960
output_field_class = IntegerField
6061

62+
def __init__(self, *args: Any, **kwargs: Any) -> None:
63+
warnings.warn(
64+
(
65+
"This function is deprecated. Use "
66+
+ "django.db.models.functions.Sign instead."
67+
),
68+
DeprecationWarning,
69+
stacklevel=2,
70+
)
71+
super().__init__(*args, **kwargs)
72+
6173

6274
# String Functions
6375

@@ -159,11 +171,27 @@ class MD5(SingleArgFunc):
159171
function = "MD5"
160172
output_field_class = CharField
161173

174+
def __init__(self, *args: Any, **kwargs: Any) -> None:
175+
warnings.warn(
176+
"This function is deprecated. Use django.db.models.functions.MD5 instead.",
177+
DeprecationWarning,
178+
stacklevel=2,
179+
)
180+
super().__init__(*args, **kwargs)
181+
162182

163183
class SHA1(SingleArgFunc):
164184
function = "SHA1"
165185
output_field_class = CharField
166186

187+
def __init__(self, *args: Any, **kwargs: Any) -> None:
188+
warnings.warn(
189+
"This function is deprecated. Use django.db.models.functions.SHA1 instead.",
190+
DeprecationWarning,
191+
stacklevel=2,
192+
)
193+
super().__init__(*args, **kwargs)
194+
167195

168196
class SHA2(Func):
169197
function = "SHA2"
@@ -176,6 +204,14 @@ def __init__(self, expression: ExpressionArgument, hash_len: int = 512) -> None:
176204
",".join(str(x) for x in self.hash_lens)
177205
)
178206
)
207+
warnings.warn(
208+
(
209+
"This function is deprecated. Use "
210+
+ "django.db.models.functions.SHA{hash_len} instead."
211+
),
212+
DeprecationWarning,
213+
stacklevel=2,
214+
)
179215
super().__init__(expression, Value(hash_len), output_field=TextField())
180216

181217

tests/testapp/test_functions.py

Lines changed: 40 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -135,9 +135,18 @@ def test_crc32(self):
135135

136136
def test_sign(self):
137137
Alphabet.objects.create(a=123, b=0, c=-999)
138-
ab = Alphabet.objects.annotate(
139-
asign=Sign("a"), bsign=Sign("b"), csign=Sign("c")
140-
).first()
138+
139+
with self.assertWarnsMessage(
140+
DeprecationWarning, "This function is deprecated."
141+
):
142+
kwargs = {
143+
"asign": Sign("a"),
144+
"bsign": Sign("b"),
145+
"csign": Sign("c"),
146+
}
147+
148+
ab = Alphabet.objects.annotate(**kwargs).first()
149+
141150
assert ab.asign == 1
142151
assert ab.bsign == 0
143152
assert ab.csign == -1
@@ -287,14 +296,26 @@ def test_md5_string(self):
287296
string = "A string"
288297
Alphabet.objects.create(d=string)
289298
pymd5 = hashlib.md5(string.encode("ascii")).hexdigest()
290-
ab = Alphabet.objects.annotate(md5=MD5("d")).first()
299+
300+
with self.assertWarnsMessage(
301+
DeprecationWarning, "This function is deprecated."
302+
):
303+
md5 = MD5("d")
304+
ab = Alphabet.objects.annotate(md5=md5).first()
305+
291306
assert ab.md5 == pymd5
292307

293308
def test_sha1_string(self):
294309
string = "A string"
295310
Alphabet.objects.create(d=string)
296311
pysha1 = hashlib.sha1(string.encode("ascii")).hexdigest()
297-
ab = Alphabet.objects.annotate(sha=SHA1("d")).first()
312+
313+
with self.assertWarnsMessage(
314+
DeprecationWarning, "This function is deprecated."
315+
):
316+
sha1 = SHA1("d")
317+
ab = Alphabet.objects.annotate(sha=sha1).first()
318+
298319
assert ab.sha == pysha1
299320

300321
def test_sha2_string(self):
@@ -304,14 +325,26 @@ def test_sha2_string(self):
304325
for hash_len in (224, 256, 384, 512):
305326
sha_func = getattr(hashlib, f"sha{hash_len}")
306327
pysha = sha_func(string.encode("ascii")).hexdigest()
307-
ab = Alphabet.objects.annotate(sha=SHA2("d", hash_len)).first()
328+
329+
with self.assertWarnsMessage(
330+
DeprecationWarning, "This function is deprecated."
331+
):
332+
sha2 = SHA2("d", hash_len)
333+
ab = Alphabet.objects.annotate(sha=sha2).first()
334+
308335
assert ab.sha == pysha
309336

310337
def test_sha2_string_hash_len_default(self):
311338
string = "A string"
312339
Alphabet.objects.create(d=string)
313340
pysha512 = hashlib.sha512(string.encode("ascii")).hexdigest()
314-
ab = Alphabet.objects.annotate(sha=SHA2("d")).first()
341+
342+
with self.assertWarnsMessage(
343+
DeprecationWarning, "This function is deprecated."
344+
):
345+
sha2 = SHA2("d")
346+
ab = Alphabet.objects.annotate(sha=sha2).first()
347+
315348
assert ab.sha == pysha512
316349

317350
def test_sha2_bad_hash_len(self):

0 commit comments

Comments
 (0)