From 6fa2e6c8f5f01e6808d0fd97761d4d463e53d71d Mon Sep 17 00:00:00 2001 From: Kristian Klette Date: Wed, 27 Oct 2021 20:35:20 +0200 Subject: [PATCH] Use object.__hash__ for Node.__hash This fixes a regression in commit 60293416db69782fd048a7820667afa4ae7c423b that changed the `__hash__` implementation of Node from the default pointer hash, to a hash based on the node fields. Since these fields contains list objects, they are not hashable, making every call to `Node.__hash__` fail. This breaks some third-party usage such as in `django-compressor` (See: https://github.com/django-compressor/django-compressor/issues/1060) This changed reverts the hash method back to using `object.__hash__` as the hash implementation. --- CHANGES.rst | 1 + src/jinja2/nodes.py | 2 +- tests/test_node_hash.py | 4 ++++ 3 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 tests/test_node_hash.py diff --git a/CHANGES.rst b/CHANGES.rst index 14830e058..4c06a6699 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -5,6 +5,7 @@ Version 3.1.0 Unreleased +- Change Node.__hash__ behavior to use object.__hash__. :issue:`1521` Version 3.0.2 ------------- diff --git a/src/jinja2/nodes.py b/src/jinja2/nodes.py index 226e729c0..94ecb8219 100644 --- a/src/jinja2/nodes.py +++ b/src/jinja2/nodes.py @@ -242,7 +242,7 @@ def __eq__(self, other: t.Any) -> bool: return tuple(self.iter_fields()) == tuple(other.iter_fields()) def __hash__(self) -> int: - return hash(tuple(self.iter_fields())) + return object.__hash__(self) def __repr__(self) -> str: args_str = ", ".join(f"{a}={getattr(self, a, None)!r}" for a in self.fields) diff --git a/tests/test_node_hash.py b/tests/test_node_hash.py new file mode 100644 index 000000000..3b7779833 --- /dev/null +++ b/tests/test_node_hash.py @@ -0,0 +1,4 @@ +class TestHashing: + def test_template_hash(self, env): + template = env.parse("hash test") + assert hash(template)