/usr/local/lib/python3.9/site-packages/django/utils
""" A class for storing a tree graph. Primarily used for filter constructs in the ORM. """ import copy from django.utils.hashable import make_hashable class Node: """ A single internal node in the tree graph. A Node should be viewed as a connection (the root) with the children being either leaf nodes or other Node instances. """ # Standard connector type. Clients usually won't use this at all and # subclasses will usually override the value. default = "DEFAULT" def __init__(self, children=None, connector=None, negated=False): """Construct a new Node. If no connector is given, use the default.""" self.children = children[:] if children else [] self.connector = connector or self.default self.negated = negated @classmethod def create(cls, children=None, connector=None, negated=False): """ Create a new instance using Node() instead of __init__() as some subclasses, e.g. django.db.models.query_utils.Q, may implement a custom __init__() with a signature that conflicts with the one defined in Node.__init__(). """ obj = Node(children, connector or cls.default, negated) obj.__class__ = cls return obj def __str__(self): template = "(NOT (%s: %s))" if self.negated else "(%s: %s)" return template % (self.connector, ", ".join(str(c) for c in self.children)) def __repr__(self): return "<%s: %s>" % (self.__class__.__name__, self) def __copy__(self): obj = self.create(connector=self.connector, negated=self.negated) obj.children = self.children # Don't [:] as .__init__() via .create() does. return obj copy = __copy__ def __deepcopy__(self, memodict): obj = self.create(connector=self.connector, negated=self.negated) obj.children = copy.deepcopy(self.children, memodict) return obj def __len__(self): """Return the number of children this node has.""" return len(self.children) def __bool__(self): """Return whether or not this node has children.""" return bool(self.children) def __contains__(self, other): """Return True if 'other' is a direct child of this instance.""" return other in self.children def __eq__(self, other): return ( self.__class__ == other.__class__ and self.connector == other.connector and self.negated == other.negated and self.children == other.children ) def __hash__(self): return hash( ( self.__class__, self.connector, self.negated, *make_hashable(self.children), ) ) def add(self, data, conn_type): """ Combine this tree and the data represented by data using the connector conn_type. The combine is done by squashing the node other away if possible. This tree (self) will never be pushed to a child node of the combined tree, nor will the connector or negated properties change. Return a node which can be used in place of data regardless if the node other got squashed or not. """ if self.connector != conn_type: obj = self.copy() self.connector = conn_type self.children = [obj, data] return data elif ( isinstance(data, Node) and not data.negated and (data.connector == conn_type or len(data) == 1) ): # We can squash the other node's children directly into this node. # We are just doing (AB)(CD) == (ABCD) here, with the addition that # if the length of the other node is 1 the connector doesn't # matter. However, for the len(self) == 1 case we don't want to do # the squashing, as it would alter self.connector. self.children.extend(data.children) return self else: # We could use perhaps additional logic here to see if some # children could be used for pushdown here. self.children.append(data) return data def negate(self): """Negate the sense of the root connector.""" self.negated = not self.negated
.
Edit
..
Edit
__init__.py
Edit
__pycache__
Edit
_os.py
Edit
archive.py
Edit
asyncio.py
Edit
autoreload.py
Edit
baseconv.py
Edit
cache.py
Edit
connection.py
Edit
crypto.py
Edit
datastructures.py
Edit
dateformat.py
Edit
dateparse.py
Edit
dates.py
Edit
datetime_safe.py
Edit
deconstruct.py
Edit
decorators.py
Edit
deprecation.py
Edit
duration.py
Edit
encoding.py
Edit
feedgenerator.py
Edit
formats.py
Edit
functional.py
Edit
hashable.py
Edit
html.py
Edit
http.py
Edit
inspect.py
Edit
ipv6.py
Edit
itercompat.py
Edit
jslex.py
Edit
log.py
Edit
lorem_ipsum.py
Edit
module_loading.py
Edit
numberformat.py
Edit
regex_helper.py
Edit
safestring.py
Edit
termcolors.py
Edit
text.py
Edit
timesince.py
Edit
timezone.py
Edit
topological_sort.py
Edit
translation
Edit
tree.py
Edit
version.py
Edit
xmlutils.py
Edit