Moved make_hashable() to django.utils and added tests.
This commit is contained in:
parent
6752c2756e
commit
834c4ec8e4
|
@ -9,6 +9,7 @@ from django.db.models import fields
|
||||||
from django.db.models.query_utils import Q
|
from django.db.models.query_utils import Q
|
||||||
from django.utils.deconstruct import deconstructible
|
from django.utils.deconstruct import deconstructible
|
||||||
from django.utils.functional import cached_property
|
from django.utils.functional import cached_property
|
||||||
|
from django.utils.hashable import make_hashable
|
||||||
|
|
||||||
|
|
||||||
class SQLiteNumericMixin:
|
class SQLiteNumericMixin:
|
||||||
|
@ -138,16 +139,6 @@ class Combinable:
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def make_hashable(value):
|
|
||||||
if isinstance(value, list):
|
|
||||||
return tuple(map(make_hashable, value))
|
|
||||||
if isinstance(value, dict):
|
|
||||||
return tuple([
|
|
||||||
(key, make_hashable(nested_value)) for key, nested_value in value.items()
|
|
||||||
])
|
|
||||||
return value
|
|
||||||
|
|
||||||
|
|
||||||
@deconstructible
|
@deconstructible
|
||||||
class BaseExpression:
|
class BaseExpression:
|
||||||
"""Base class for all query expressions."""
|
"""Base class for all query expressions."""
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
def make_hashable(value):
|
||||||
|
if isinstance(value, list):
|
||||||
|
return tuple(map(make_hashable, value))
|
||||||
|
if isinstance(value, dict):
|
||||||
|
return tuple([
|
||||||
|
(key, make_hashable(nested_value))
|
||||||
|
for key, nested_value in value.items()
|
||||||
|
])
|
||||||
|
return value
|
|
@ -0,0 +1,25 @@
|
||||||
|
from django.test import SimpleTestCase
|
||||||
|
from django.utils.hashable import make_hashable
|
||||||
|
|
||||||
|
|
||||||
|
class TestHashable(SimpleTestCase):
|
||||||
|
def test_equal(self):
|
||||||
|
tests = (
|
||||||
|
([], ()),
|
||||||
|
(['a', 1], ('a', 1)),
|
||||||
|
({}, ()),
|
||||||
|
({'a'}, {'a'}),
|
||||||
|
(frozenset({'a'}), {'a'}),
|
||||||
|
({'a': 1}, (('a', 1),)),
|
||||||
|
)
|
||||||
|
for value, expected in tests:
|
||||||
|
with self.subTest(value=value):
|
||||||
|
self.assertEqual(make_hashable(value), expected)
|
||||||
|
|
||||||
|
def test_count_equal(self):
|
||||||
|
tests = (
|
||||||
|
({'a': 1, 'b': ['a', 1]}, (('a', 1), ('b', ('a', 1)))),
|
||||||
|
)
|
||||||
|
for value, expected in tests:
|
||||||
|
with self.subTest(value=value):
|
||||||
|
self.assertCountEqual(make_hashable(value), expected)
|
Loading…
Reference in New Issue