Source code for pandagg.utils

#!/usr/bin/env python
# -*- coding: utf-8 -*-


# adapted from https://github.com/elastic/elasticsearch-dsl-py/blob/master/elasticsearch_dsl/utils.py#L162
from six import add_metaclass


[docs]class DslMeta(type): """ Base Metaclass for DslBase subclasses that builds a registry of all classes for given DslBase subclass (== all the query types for the Query subclass of DslBase). It then uses the information from that registry (as well as `name` and `deserializer` attributes from the base class) to construct any subclass based on it's name. """ _types = {} def __init__(cls, name, bases, attrs): super(DslMeta, cls).__init__(name, bases, attrs) # skip for DSLMixin if not hasattr(cls, "_type_name") or cls._type_name is None: return if not hasattr(cls, "KEY") or cls.KEY is None: # abstract base class, register its shortcut cls._types[cls._type_name] = cls # and create a registry for subclasses if not hasattr(cls, "_classes"): cls._classes = {} elif cls.KEY not in cls._classes: # normal class, register it cls._classes[cls.KEY] = cls
[docs]@add_metaclass(DslMeta) class DSLMixin(object): """Base class for all DSL objects - queries, filters, aggregations etc. Wraps a dictionary representing the object's json.""" @classmethod def _get_dsl_class(cls, name): try: return cls._classes[name] except KeyError: raise NotImplementedError( "DSL class `{}` does not exist in {}.".format(name, cls._type_name) ) @staticmethod def _get_dsl_type(name): try: return DslMeta._types[name] except KeyError: raise ValueError("DSL type %s does not exist." % name)
[docs]def ordered(obj): if isinstance(obj, dict): return sorted((k, ordered(v)) for k, v in obj.items()) if isinstance(obj, list): return sorted(ordered(x) for x in obj) return obj
[docs]def equal_queries(d1, d2): """Compares if two queries are equivalent (do not consider nested list orders).""" return ordered(d1) == ordered(d2)