Fixed #32712 -- Deprecated django.utils.baseconv module.

This commit is contained in:
Hasan Ramezani 2021-05-05 23:28:08 +02:00 committed by Mariusz Felisiak
parent c4ee3b208a
commit 028f10fac6
6 changed files with 57 additions and 6 deletions

View File

@ -40,13 +40,13 @@ import time
import zlib import zlib
from django.conf import settings from django.conf import settings
from django.utils import baseconv
from django.utils.crypto import constant_time_compare, salted_hmac from django.utils.crypto import constant_time_compare, salted_hmac
from django.utils.encoding import force_bytes from django.utils.encoding import force_bytes
from django.utils.module_loading import import_string from django.utils.module_loading import import_string
from django.utils.regex_helper import _lazy_re_compile from django.utils.regex_helper import _lazy_re_compile
_SEP_UNSAFE = _lazy_re_compile(r'^[A-z0-9-_=]*$') _SEP_UNSAFE = _lazy_re_compile(r'^[A-z0-9-_=]*$')
BASE62_ALPHABET = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
class BadSignature(Exception): class BadSignature(Exception):
@ -59,6 +59,31 @@ class SignatureExpired(BadSignature):
pass pass
def b62_encode(s):
if s == 0:
return '0'
sign = '-' if s < 0 else ''
s = abs(s)
encoded = ''
while s > 0:
s, remainder = divmod(s, 62)
encoded = BASE62_ALPHABET[remainder] + encoded
return sign + encoded
def b62_decode(s):
if s == '0':
return 0
sign = 1
if s[0] == '-':
s = s[1:]
sign = -1
decoded = 0
for digit in s:
decoded = decoded * 62 + BASE62_ALPHABET.index(digit)
return sign * decoded
def b64_encode(s): def b64_encode(s):
return base64.urlsafe_b64encode(s).strip(b'=') return base64.urlsafe_b64encode(s).strip(b'=')
@ -187,7 +212,7 @@ class Signer:
class TimestampSigner(Signer): class TimestampSigner(Signer):
def timestamp(self): def timestamp(self):
return baseconv.base62.encode(int(time.time())) return b62_encode(int(time.time()))
def sign(self, value): def sign(self, value):
value = '%s%s%s' % (value, self.sep, self.timestamp()) value = '%s%s%s' % (value, self.sep, self.timestamp())
@ -200,7 +225,7 @@ class TimestampSigner(Signer):
""" """
result = super().unsign(value) result = super().unsign(value)
value, timestamp = result.rsplit(self.sep, 1) value, timestamp = result.rsplit(self.sep, 1)
timestamp = baseconv.base62.decode(timestamp) timestamp = b62_decode(timestamp)
if max_age is not None: if max_age is not None:
if isinstance(max_age, datetime.timedelta): if isinstance(max_age, datetime.timedelta):
max_age = max_age.total_seconds() max_age = max_age.total_seconds()

View File

@ -1,3 +1,4 @@
# RemovedInDjango50Warning
# Copyright (c) 2010 Guilherme Gondim. All rights reserved. # Copyright (c) 2010 Guilherme Gondim. All rights reserved.
# Copyright (c) 2009 Simon Willison. All rights reserved. # Copyright (c) 2009 Simon Willison. All rights reserved.
# Copyright (c) 2002 Drew Perttula. All rights reserved. # Copyright (c) 2002 Drew Perttula. All rights reserved.
@ -36,6 +37,15 @@ Sample usage::
-1234 -1234
""" """
import warnings
from django.utils.deprecation import RemovedInDjango50Warning
warnings.warn(
'The django.utils.baseconv module is deprecated.',
category=RemovedInDjango50Warning,
stacklevel=2,
)
BASE2_ALPHABET = '01' BASE2_ALPHABET = '01'
BASE16_ALPHABET = '0123456789ABCDEF' BASE16_ALPHABET = '0123456789ABCDEF'

View File

@ -17,6 +17,8 @@ details on these changes.
* The ``SERIALIZE`` test setting will be removed. * The ``SERIALIZE`` test setting will be removed.
* The undocumented ``django.utils.baseconv`` module will be removed.
.. _deprecation-removed-in-4.1: .. _deprecation-removed-in-4.1:
4.1 4.1

View File

@ -432,6 +432,8 @@ Miscellaneous
:attr:`~django.test.TestCase.databases` with the :attr:`~django.test.TestCase.databases` with the
:ref:`serialized_rollback <test-case-serialized-rollback>` option enabled. :ref:`serialized_rollback <test-case-serialized-rollback>` option enabled.
* The undocumented ``django.utils.baseconv`` module is deprecated.
Features removed in 4.0 Features removed in 4.0
======================= =======================

View File

@ -195,3 +195,10 @@ class TestTimestampSigner(SimpleTestCase):
self.assertEqual(signer.unsign(ts, max_age=datetime.timedelta(seconds=11)), value) self.assertEqual(signer.unsign(ts, max_age=datetime.timedelta(seconds=11)), value)
with self.assertRaises(signing.SignatureExpired): with self.assertRaises(signing.SignatureExpired):
signer.unsign(ts, max_age=10) signer.unsign(ts, max_age=10)
class TestBase62(SimpleTestCase):
def test_base62(self):
tests = [-10 ** 10, 10 ** 10, 1620378259, *range(-100, 100)]
for i in tests:
self.assertEqual(i, signing.b62_decode(signing.b62_encode(i)))

View File

@ -1,10 +1,15 @@
from unittest import TestCase from unittest import TestCase
from django.utils.baseconv import ( from django.test import ignore_warnings
BaseConverter, base2, base16, base36, base56, base62, base64, from django.utils.deprecation import RemovedInDjango50Warning
)
with ignore_warnings(category=RemovedInDjango50Warning):
from django.utils.baseconv import (
BaseConverter, base2, base16, base36, base56, base62, base64,
)
# RemovedInDjango50Warning
class TestBaseConv(TestCase): class TestBaseConv(TestCase):
def test_baseconv(self): def test_baseconv(self):