From 845667f2d1eb7063c568764a01fc9ee633ec5817 Mon Sep 17 00:00:00 2001 From: Nick Pope Date: Tue, 20 Jul 2021 16:28:25 +0100 Subject: [PATCH] Refs #32948 -- Simplified and optimized Q._combine() and __invert__(). - Removed use of Q.deconstruct() in Q._combine(). - Simplified and optimized Q.__invert__() by taking a shallow copy and swapping the negated attribute only. - Simplified construction in Q._combine(). - Simplified conditions in Q._combine() as Q.conditional = True the first isinstance() check is unnecessary. - Removed copy.copy() branch in Q._combine(). Co-authored-by: Keryn Knight --- django/db/models/query_utils.py | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/django/db/models/query_utils.py b/django/db/models/query_utils.py index 9b5824f89fe..d566cc18838 100644 --- a/django/db/models/query_utils.py +++ b/django/db/models/query_utils.py @@ -5,7 +5,6 @@ Factored out from django.db.models.query to avoid making the main module very large and/or so that they can be used by other modules without getting into circular import difficulties. """ -import copy import functools import inspect import logging @@ -54,17 +53,14 @@ class Q(tree.Node): ) def _combine(self, other, conn): - if not (isinstance(other, Q) or getattr(other, "conditional", False) is True): + if getattr(other, "conditional", False) is False: raise TypeError(other) - if not self: - return other.copy() if hasattr(other, "copy") else copy.copy(other) - elif isinstance(other, Q) and not other: - _, args, kwargs = self.deconstruct() - return type(self)(*args, **kwargs) + return other.copy() + if not other and isinstance(other, Q): + return self.copy() - obj = type(self)() - obj.connector = conn + obj = self.create(connector=conn) obj.add(self, conn) obj.add(other, conn) return obj @@ -79,8 +75,7 @@ class Q(tree.Node): return self._combine(other, self.XOR) def __invert__(self): - obj = type(self)() - obj.add(self, self.AND) + obj = self.copy() obj.negate() return obj