general pep8 and more clean-up
This commit is contained in:
		@@ -1,5 +1,6 @@
 | 
			
		||||
import weakref
 | 
			
		||||
import itertools
 | 
			
		||||
 | 
			
		||||
from mongoengine.common import _import_class
 | 
			
		||||
from mongoengine.errors import DoesNotExist, MultipleObjectsReturned
 | 
			
		||||
 | 
			
		||||
@@ -20,7 +21,7 @@ class BaseDict(dict):
 | 
			
		||||
        if isinstance(instance, (Document, EmbeddedDocument)):
 | 
			
		||||
            self._instance = weakref.proxy(instance)
 | 
			
		||||
        self._name = name
 | 
			
		||||
        return super(BaseDict, self).__init__(dict_items)
 | 
			
		||||
        super(BaseDict, self).__init__(dict_items)
 | 
			
		||||
 | 
			
		||||
    def __getitem__(self, key, *args, **kwargs):
 | 
			
		||||
        value = super(BaseDict, self).__getitem__(key)
 | 
			
		||||
@@ -65,7 +66,7 @@ class BaseDict(dict):
 | 
			
		||||
 | 
			
		||||
    def clear(self, *args, **kwargs):
 | 
			
		||||
        self._mark_as_changed()
 | 
			
		||||
        return super(BaseDict, self).clear(*args, **kwargs)
 | 
			
		||||
        return super(BaseDict, self).clear()
 | 
			
		||||
 | 
			
		||||
    def pop(self, *args, **kwargs):
 | 
			
		||||
        self._mark_as_changed()
 | 
			
		||||
@@ -73,7 +74,7 @@ class BaseDict(dict):
 | 
			
		||||
 | 
			
		||||
    def popitem(self, *args, **kwargs):
 | 
			
		||||
        self._mark_as_changed()
 | 
			
		||||
        return super(BaseDict, self).popitem(*args, **kwargs)
 | 
			
		||||
        return super(BaseDict, self).popitem()
 | 
			
		||||
 | 
			
		||||
    def setdefault(self, *args, **kwargs):
 | 
			
		||||
        self._mark_as_changed()
 | 
			
		||||
@@ -189,7 +190,7 @@ class BaseList(list):
 | 
			
		||||
 | 
			
		||||
    def reverse(self, *args, **kwargs):
 | 
			
		||||
        self._mark_as_changed()
 | 
			
		||||
        return super(BaseList, self).reverse(*args, **kwargs)
 | 
			
		||||
        return super(BaseList, self).reverse()
 | 
			
		||||
 | 
			
		||||
    def sort(self, *args, **kwargs):
 | 
			
		||||
        self._mark_as_changed()
 | 
			
		||||
@@ -368,25 +369,31 @@ class StrictDict(object):
 | 
			
		||||
    __slots__ = ()
 | 
			
		||||
    _special_fields = set(['get', 'pop', 'iteritems', 'items', 'keys', 'create'])
 | 
			
		||||
    _classes = {}
 | 
			
		||||
 | 
			
		||||
    def __init__(self, **kwargs):
 | 
			
		||||
        for k,v in kwargs.iteritems():
 | 
			
		||||
        for k, v in kwargs.iteritems():
 | 
			
		||||
            setattr(self, k, v)
 | 
			
		||||
 | 
			
		||||
    def __getitem__(self, key):
 | 
			
		||||
        key = '_reserved_' + key if key in self._special_fields else key
 | 
			
		||||
        try:
 | 
			
		||||
            return getattr(self, key)
 | 
			
		||||
        except AttributeError:
 | 
			
		||||
            raise KeyError(key)
 | 
			
		||||
 | 
			
		||||
    def __setitem__(self, key, value):
 | 
			
		||||
        key = '_reserved_' + key if key in self._special_fields else key
 | 
			
		||||
        return setattr(self, key, value)
 | 
			
		||||
 | 
			
		||||
    def __contains__(self, key):
 | 
			
		||||
        return hasattr(self, key)
 | 
			
		||||
 | 
			
		||||
    def get(self, key, default=None):
 | 
			
		||||
        try:
 | 
			
		||||
            return self[key]
 | 
			
		||||
        except KeyError:
 | 
			
		||||
            return default
 | 
			
		||||
 | 
			
		||||
    def pop(self, key, default=None):
 | 
			
		||||
        v = self.get(key, default)
 | 
			
		||||
        try:
 | 
			
		||||
@@ -394,19 +401,26 @@ class StrictDict(object):
 | 
			
		||||
        except AttributeError:
 | 
			
		||||
            pass
 | 
			
		||||
        return v
 | 
			
		||||
 | 
			
		||||
    def iteritems(self):
 | 
			
		||||
        for key in self:
 | 
			
		||||
            yield key, self[key]
 | 
			
		||||
 | 
			
		||||
    def items(self):
 | 
			
		||||
        return [(k, self[k]) for k in iter(self)]
 | 
			
		||||
 | 
			
		||||
    def keys(self):
 | 
			
		||||
        return list(iter(self))
 | 
			
		||||
 | 
			
		||||
    def __iter__(self):
 | 
			
		||||
        return (key for key in self.__slots__ if hasattr(self, key))
 | 
			
		||||
 | 
			
		||||
    def __len__(self):
 | 
			
		||||
        return len(list(self.iteritems()))
 | 
			
		||||
 | 
			
		||||
    def __eq__(self, other):
 | 
			
		||||
        return self.items() == other.items()
 | 
			
		||||
 | 
			
		||||
    def __neq__(self, other):
 | 
			
		||||
        return self.items() != other.items()
 | 
			
		||||
 | 
			
		||||
@@ -417,8 +431,10 @@ class StrictDict(object):
 | 
			
		||||
        if allowed_keys not in cls._classes:
 | 
			
		||||
            class SpecificStrictDict(cls):
 | 
			
		||||
                __slots__ = allowed_keys_tuple
 | 
			
		||||
 | 
			
		||||
                def __repr__(self):
 | 
			
		||||
                    return "{%s}" % ', '.join('"{0!s}": {0!r}'.format(k,v) for (k,v) in self.iteritems())
 | 
			
		||||
                    return "{%s}" % ', '.join('"{0!s}": {0!r}'.format(k, v) for (k, v) in self.iteritems())
 | 
			
		||||
 | 
			
		||||
            cls._classes[allowed_keys] = SpecificStrictDict
 | 
			
		||||
        return cls._classes[allowed_keys]
 | 
			
		||||
 | 
			
		||||
@@ -426,6 +442,7 @@ class StrictDict(object):
 | 
			
		||||
class SemiStrictDict(StrictDict):
 | 
			
		||||
    __slots__ = ('_extras')
 | 
			
		||||
    _classes = {}
 | 
			
		||||
 | 
			
		||||
    def __getattr__(self, attr):
 | 
			
		||||
        try:
 | 
			
		||||
            super(SemiStrictDict, self).__getattr__(attr)
 | 
			
		||||
@@ -434,6 +451,7 @@ class SemiStrictDict(StrictDict):
 | 
			
		||||
                return self.__getattribute__('_extras')[attr]
 | 
			
		||||
            except KeyError as e:
 | 
			
		||||
                raise AttributeError(e)
 | 
			
		||||
 | 
			
		||||
    def __setattr__(self, attr, value):
 | 
			
		||||
        try:
 | 
			
		||||
            super(SemiStrictDict, self).__setattr__(attr, value)
 | 
			
		||||
 
 | 
			
		||||
@@ -14,7 +14,6 @@ from mongoengine.common import _import_class
 | 
			
		||||
from mongoengine.errors import (ValidationError, InvalidDocumentError,
 | 
			
		||||
                                LookUpError, FieldDoesNotExist)
 | 
			
		||||
from mongoengine.python_support import PY3, txt_type
 | 
			
		||||
 | 
			
		||||
from mongoengine.base.common import get_document, ALLOW_INHERITANCE
 | 
			
		||||
from mongoengine.base.datastructures import (
 | 
			
		||||
    BaseDict,
 | 
			
		||||
@@ -621,7 +620,7 @@ class BaseDocument(object):
 | 
			
		||||
        else:
 | 
			
		||||
            set_data = doc
 | 
			
		||||
            if '_id' in set_data:
 | 
			
		||||
                del(set_data['_id'])
 | 
			
		||||
                del set_data['_id']
 | 
			
		||||
 | 
			
		||||
        # Determine if any changed items were actually unset.
 | 
			
		||||
        for path, value in set_data.items():
 | 
			
		||||
@@ -632,7 +631,7 @@ class BaseDocument(object):
 | 
			
		||||
            default = None
 | 
			
		||||
            if (self._dynamic and len(parts) and parts[0] in
 | 
			
		||||
                    self._dynamic_fields):
 | 
			
		||||
                del(set_data[path])
 | 
			
		||||
                del set_data[path]
 | 
			
		||||
                unset_data[path] = 1
 | 
			
		||||
                continue
 | 
			
		||||
            elif path in self._fields:
 | 
			
		||||
@@ -666,7 +665,7 @@ class BaseDocument(object):
 | 
			
		||||
            if default != value:
 | 
			
		||||
                continue
 | 
			
		||||
 | 
			
		||||
            del(set_data[path])
 | 
			
		||||
            del set_data[path]
 | 
			
		||||
            unset_data[path] = 1
 | 
			
		||||
        return set_data, unset_data
 | 
			
		||||
 | 
			
		||||
@@ -821,7 +820,6 @@ class BaseDocument(object):
 | 
			
		||||
            parts = key.split('.')
 | 
			
		||||
            if parts in (['pk'], ['id'], ['_id']):
 | 
			
		||||
                key = '_id'
 | 
			
		||||
                fields = []
 | 
			
		||||
            else:
 | 
			
		||||
                fields = cls._lookup_field(parts)
 | 
			
		||||
                parts = []
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,6 @@ import pymongo
 | 
			
		||||
 | 
			
		||||
from mongoengine.common import _import_class
 | 
			
		||||
from mongoengine.errors import ValidationError
 | 
			
		||||
 | 
			
		||||
from mongoengine.base.common import ALLOW_INHERITANCE
 | 
			
		||||
from mongoengine.base.datastructures import (
 | 
			
		||||
    BaseDict, BaseList, EmbeddedDocumentList
 | 
			
		||||
@@ -23,7 +22,6 @@ UPDATE_OPERATORS = set(['set', 'unset', 'inc', 'dec', 'pop', 'push',
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class BaseField(object):
 | 
			
		||||
 | 
			
		||||
    """A base class for fields in a MongoDB document. Instances of this class
 | 
			
		||||
    may be added to subclasses of `Document` to define a document's schema.
 | 
			
		||||
 | 
			
		||||
@@ -212,7 +210,6 @@ class BaseField(object):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ComplexBaseField(BaseField):
 | 
			
		||||
 | 
			
		||||
    """Handles complex fields, such as lists / dictionaries.
 | 
			
		||||
 | 
			
		||||
    Allows for nesting of embedded documents inside complex types.
 | 
			
		||||
@@ -330,8 +327,8 @@ class ComplexBaseField(BaseField):
 | 
			
		||||
                return GenericReferenceField().to_mongo(value)
 | 
			
		||||
            cls = value.__class__
 | 
			
		||||
            val = value.to_mongo()
 | 
			
		||||
            # If we its a document thats not inherited add _cls
 | 
			
		||||
            if (isinstance(value, EmbeddedDocument)):
 | 
			
		||||
            # If it's a document that is not inherited add _cls
 | 
			
		||||
            if isinstance(value, EmbeddedDocument):
 | 
			
		||||
                val['_cls'] = cls.__name__
 | 
			
		||||
            return val
 | 
			
		||||
 | 
			
		||||
@@ -370,8 +367,8 @@ class ComplexBaseField(BaseField):
 | 
			
		||||
                elif hasattr(v, 'to_mongo'):
 | 
			
		||||
                    cls = v.__class__
 | 
			
		||||
                    val = v.to_mongo()
 | 
			
		||||
                    # If we its a document thats not inherited add _cls
 | 
			
		||||
                    if (isinstance(v, (Document, EmbeddedDocument))):
 | 
			
		||||
                    # If it's a document that is not inherited add _cls
 | 
			
		||||
                    if isinstance(v, (Document, EmbeddedDocument)):
 | 
			
		||||
                        val['_cls'] = cls.__name__
 | 
			
		||||
                    value_dict[k] = val
 | 
			
		||||
                else:
 | 
			
		||||
@@ -422,7 +419,6 @@ class ComplexBaseField(BaseField):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ObjectIdField(BaseField):
 | 
			
		||||
 | 
			
		||||
    """A field wrapper around MongoDB's ObjectIds.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
@@ -454,7 +450,6 @@ class ObjectIdField(BaseField):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class GeoJsonBaseField(BaseField):
 | 
			
		||||
 | 
			
		||||
    """A geo json field storing a geojson style object.
 | 
			
		||||
 | 
			
		||||
    .. versionadded:: 0.8
 | 
			
		||||
 
 | 
			
		||||
@@ -14,7 +14,6 @@ __all__ = ('DocumentMetaclass', 'TopLevelDocumentMetaclass')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class DocumentMetaclass(type):
 | 
			
		||||
 | 
			
		||||
    """Metaclass for all documents.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
@@ -250,7 +249,6 @@ class DocumentMetaclass(type):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class TopLevelDocumentMetaclass(DocumentMetaclass):
 | 
			
		||||
 | 
			
		||||
    """Metaclass for top-level documents (i.e. documents that have their own
 | 
			
		||||
    collection in the database.
 | 
			
		||||
    """
 | 
			
		||||
@@ -260,7 +258,7 @@ class TopLevelDocumentMetaclass(DocumentMetaclass):
 | 
			
		||||
        super_new = super(TopLevelDocumentMetaclass, cls).__new__
 | 
			
		||||
 | 
			
		||||
        # Set default _meta data if base class, otherwise get user defined meta
 | 
			
		||||
        if (attrs.get('my_metaclass') == TopLevelDocumentMetaclass):
 | 
			
		||||
        if attrs.get('my_metaclass') == TopLevelDocumentMetaclass:
 | 
			
		||||
            # defaults
 | 
			
		||||
            attrs['_meta'] = {
 | 
			
		||||
                'abstract': True,
 | 
			
		||||
@@ -279,7 +277,7 @@ class TopLevelDocumentMetaclass(DocumentMetaclass):
 | 
			
		||||
            attrs['_meta'].update(attrs.get('meta', {}))
 | 
			
		||||
        else:
 | 
			
		||||
            attrs['_meta'] = attrs.get('meta', {})
 | 
			
		||||
            # Explictly set abstract to false unless set
 | 
			
		||||
            # Explicitly set abstract to false unless set
 | 
			
		||||
            attrs['_meta']['abstract'] = attrs['_meta'].get('abstract', False)
 | 
			
		||||
            attrs['_is_base_cls'] = False
 | 
			
		||||
 | 
			
		||||
@@ -294,7 +292,7 @@ class TopLevelDocumentMetaclass(DocumentMetaclass):
 | 
			
		||||
 | 
			
		||||
        # Clean up top level meta
 | 
			
		||||
        if 'meta' in attrs:
 | 
			
		||||
            del(attrs['meta'])
 | 
			
		||||
            del attrs['meta']
 | 
			
		||||
 | 
			
		||||
        # Find the parent document class
 | 
			
		||||
        parent_doc_cls = [b for b in flattened_bases
 | 
			
		||||
@@ -307,7 +305,7 @@ class TopLevelDocumentMetaclass(DocumentMetaclass):
 | 
			
		||||
                and not parent_doc_cls._meta.get('abstract', True)):
 | 
			
		||||
            msg = "Trying to set a collection on a subclass (%s)" % name
 | 
			
		||||
            warnings.warn(msg, SyntaxWarning)
 | 
			
		||||
            del(attrs['_meta']['collection'])
 | 
			
		||||
            del attrs['_meta']['collection']
 | 
			
		||||
 | 
			
		||||
        # Ensure abstract documents have abstract bases
 | 
			
		||||
        if attrs.get('_is_base_cls') or attrs['_meta'].get('abstract'):
 | 
			
		||||
@@ -425,7 +423,6 @@ class TopLevelDocumentMetaclass(DocumentMetaclass):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class MetaDict(dict):
 | 
			
		||||
 | 
			
		||||
    """Custom dictionary for meta classes.
 | 
			
		||||
    Handles the merging of set indexes
 | 
			
		||||
    """
 | 
			
		||||
@@ -440,6 +437,5 @@ class MetaDict(dict):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class BasesTuple(tuple):
 | 
			
		||||
 | 
			
		||||
    """Special class to handle introspection of bases tuple in __new__"""
 | 
			
		||||
    pass
 | 
			
		||||
 
 | 
			
		||||
@@ -120,7 +120,8 @@ def get_connection(alias=DEFAULT_CONNECTION_NAME, reconnect=False):
 | 
			
		||||
        try:
 | 
			
		||||
            connection = None
 | 
			
		||||
            # check for shared connections
 | 
			
		||||
            connection_settings_iterator = ((db_alias, settings.copy()) for db_alias, settings in _connection_settings.iteritems())
 | 
			
		||||
            connection_settings_iterator = (
 | 
			
		||||
                (db_alias, settings.copy()) for db_alias, settings in _connection_settings.iteritems())
 | 
			
		||||
            for db_alias, connection_settings in connection_settings_iterator:
 | 
			
		||||
                connection_settings.pop('name', None)
 | 
			
		||||
                connection_settings.pop('username', None)
 | 
			
		||||
 
 | 
			
		||||
@@ -11,7 +11,6 @@ from document import Document, EmbeddedDocument
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class DeReference(object):
 | 
			
		||||
 | 
			
		||||
    def __call__(self, items, max_depth=1, instance=None, name=None):
 | 
			
		||||
        """
 | 
			
		||||
        Cheaply dereferences the items to a set depth.
 | 
			
		||||
@@ -49,8 +48,8 @@ class DeReference(object):
 | 
			
		||||
 | 
			
		||||
                if is_list and all([i.__class__ == doc_type for i in items]):
 | 
			
		||||
                    return items
 | 
			
		||||
                elif not is_list and all([i.__class__ == doc_type
 | 
			
		||||
                                         for i in items.values()]):
 | 
			
		||||
                elif not is_list and all(
 | 
			
		||||
                        [i.__class__ == doc_type for i in items.values()]):
 | 
			
		||||
                    return items
 | 
			
		||||
                elif not field.dbref:
 | 
			
		||||
                    if not hasattr(items, 'items'):
 | 
			
		||||
 
 | 
			
		||||
@@ -3,6 +3,7 @@ import pymongo
 | 
			
		||||
import re
 | 
			
		||||
 | 
			
		||||
from pymongo.read_preferences import ReadPreference
 | 
			
		||||
from bson import ObjectId
 | 
			
		||||
from bson.dbref import DBRef
 | 
			
		||||
from mongoengine import signals
 | 
			
		||||
from mongoengine.common import _import_class
 | 
			
		||||
@@ -46,7 +47,6 @@ class InvalidCollectionError(Exception):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class EmbeddedDocument(BaseDocument):
 | 
			
		||||
 | 
			
		||||
    """A :class:`~mongoengine.Document` that isn't stored in its own
 | 
			
		||||
    collection.  :class:`~mongoengine.EmbeddedDocument`\ s should be used as
 | 
			
		||||
    fields on :class:`~mongoengine.Document`\ s through the
 | 
			
		||||
@@ -89,7 +89,6 @@ class EmbeddedDocument(BaseDocument):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Document(BaseDocument):
 | 
			
		||||
 | 
			
		||||
    """The base class used for defining the structure and properties of
 | 
			
		||||
    collections of documents stored in MongoDB. Inherit from this class, and
 | 
			
		||||
    add fields as class attributes to define a document's structure.
 | 
			
		||||
@@ -160,7 +159,9 @@ class Document(BaseDocument):
 | 
			
		||||
 | 
			
		||||
        def fset(self, value):
 | 
			
		||||
            return setattr(self, self._meta['id_field'], value)
 | 
			
		||||
 | 
			
		||||
        return property(fget, fset)
 | 
			
		||||
 | 
			
		||||
    pk = pk()
 | 
			
		||||
 | 
			
		||||
    @classmethod
 | 
			
		||||
@@ -455,7 +456,7 @@ class Document(BaseDocument):
 | 
			
		||||
            if kwargs.get('upsert', False):
 | 
			
		||||
                query = self.to_mongo()
 | 
			
		||||
                if "_cls" in query:
 | 
			
		||||
                    del(query["_cls"])
 | 
			
		||||
                    del query["_cls"]
 | 
			
		||||
                return self._qs.filter(**query).update_one(**kwargs)
 | 
			
		||||
            else:
 | 
			
		||||
                raise OperationError(
 | 
			
		||||
@@ -580,8 +581,8 @@ class Document(BaseDocument):
 | 
			
		||||
        if not self.pk:
 | 
			
		||||
            raise self.DoesNotExist("Document does not exist")
 | 
			
		||||
        obj = self._qs.read_preference(ReadPreference.PRIMARY).filter(
 | 
			
		||||
            **self._object_key).only(*fields).limit(1
 | 
			
		||||
                                                    ).select_related(max_depth=max_depth)
 | 
			
		||||
            **self._object_key).only(*fields).limit(
 | 
			
		||||
            1).select_related(max_depth=max_depth)
 | 
			
		||||
 | 
			
		||||
        if obj:
 | 
			
		||||
            obj = obj[0]
 | 
			
		||||
@@ -640,11 +641,11 @@ class Document(BaseDocument):
 | 
			
		||||
                     for class_name in document_cls._subclasses
 | 
			
		||||
                     if class_name != document_cls.__name__] + [document_cls]
 | 
			
		||||
 | 
			
		||||
        for cls in classes:
 | 
			
		||||
        for klass in classes:
 | 
			
		||||
            for document_cls in documents:
 | 
			
		||||
                delete_rules = cls._meta.get('delete_rules') or {}
 | 
			
		||||
                delete_rules = klass._meta.get('delete_rules') or {}
 | 
			
		||||
                delete_rules[(document_cls, field_name)] = rule
 | 
			
		||||
                cls._meta['delete_rules'] = delete_rules
 | 
			
		||||
                klass._meta['delete_rules'] = delete_rules
 | 
			
		||||
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def drop_collection(cls):
 | 
			
		||||
@@ -769,7 +770,7 @@ class Document(BaseDocument):
 | 
			
		||||
                                        **index_opts)
 | 
			
		||||
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def list_indexes(cls, go_up=True, go_down=True):
 | 
			
		||||
    def list_indexes(cls):
 | 
			
		||||
        """ Lists all of the indexes that should be created for given
 | 
			
		||||
        collection. It includes all the indexes from super- and sub-classes.
 | 
			
		||||
        """
 | 
			
		||||
@@ -816,8 +817,8 @@ class Document(BaseDocument):
 | 
			
		||||
            return indexes
 | 
			
		||||
 | 
			
		||||
        indexes = []
 | 
			
		||||
        for cls in classes:
 | 
			
		||||
            for index in get_indexes_spec(cls):
 | 
			
		||||
        for klass in classes:
 | 
			
		||||
            for index in get_indexes_spec(klass):
 | 
			
		||||
                if index not in indexes:
 | 
			
		||||
                    indexes.append(index)
 | 
			
		||||
 | 
			
		||||
@@ -856,7 +857,6 @@ class Document(BaseDocument):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class DynamicDocument(Document):
 | 
			
		||||
 | 
			
		||||
    """A Dynamic Document class allowing flexible, expandable and uncontrolled
 | 
			
		||||
    schemas.  As a :class:`~mongoengine.Document` subclass, acts in the same
 | 
			
		||||
    way as an ordinary document but has expando style properties.  Any data
 | 
			
		||||
@@ -888,7 +888,6 @@ class DynamicDocument(Document):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class DynamicEmbeddedDocument(EmbeddedDocument):
 | 
			
		||||
 | 
			
		||||
    """A Dynamic Embedded Document class allowing flexible, expandable and
 | 
			
		||||
    uncontrolled schemas. See :class:`~mongoengine.DynamicDocument` for more
 | 
			
		||||
    information about dynamic documents.
 | 
			
		||||
@@ -915,7 +914,6 @@ class DynamicEmbeddedDocument(EmbeddedDocument):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class MapReduceDocument(object):
 | 
			
		||||
 | 
			
		||||
    """A document returned from a map/reduce query.
 | 
			
		||||
 | 
			
		||||
    :param collection: An instance of :class:`~pymongo.Collection`
 | 
			
		||||
 
 | 
			
		||||
@@ -115,6 +115,7 @@ class ValidationError(AssertionError):
 | 
			
		||||
            else:
 | 
			
		||||
                return unicode(source)
 | 
			
		||||
            return errors_dict
 | 
			
		||||
 | 
			
		||||
        if not self.errors:
 | 
			
		||||
            return {}
 | 
			
		||||
        return build_dict(self.errors)
 | 
			
		||||
 
 | 
			
		||||
@@ -47,12 +47,10 @@ __all__ = [
 | 
			
		||||
    'SequenceField', 'UUIDField', 'MultiPointField', 'MultiLineStringField',
 | 
			
		||||
    'MultiPolygonField', 'GeoJsonBaseField']
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
RECURSIVE_REFERENCE_CONSTANT = 'self'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class StringField(BaseField):
 | 
			
		||||
 | 
			
		||||
    """A unicode string field.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
@@ -112,7 +110,6 @@ class StringField(BaseField):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class URLField(StringField):
 | 
			
		||||
 | 
			
		||||
    """A field that validates input as an URL.
 | 
			
		||||
 | 
			
		||||
    .. versionadded:: 0.3
 | 
			
		||||
@@ -159,7 +156,6 @@ class URLField(StringField):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class EmailField(StringField):
 | 
			
		||||
 | 
			
		||||
    """A field that validates input as an E-Mail-Address.
 | 
			
		||||
 | 
			
		||||
    .. versionadded:: 0.4
 | 
			
		||||
@@ -181,7 +177,6 @@ class EmailField(StringField):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class IntField(BaseField):
 | 
			
		||||
 | 
			
		||||
    """An 32-bit integer field.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
@@ -216,7 +211,6 @@ class IntField(BaseField):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class LongField(BaseField):
 | 
			
		||||
 | 
			
		||||
    """An 64-bit integer field.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
@@ -251,7 +245,6 @@ class LongField(BaseField):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class FloatField(BaseField):
 | 
			
		||||
 | 
			
		||||
    """An floating point number field.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
@@ -286,7 +279,6 @@ class FloatField(BaseField):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class DecimalField(BaseField):
 | 
			
		||||
 | 
			
		||||
    """A fixed-point decimal number field.
 | 
			
		||||
 | 
			
		||||
    .. versionchanged:: 0.8
 | 
			
		||||
@@ -360,7 +352,6 @@ class DecimalField(BaseField):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class BooleanField(BaseField):
 | 
			
		||||
 | 
			
		||||
    """A boolean field type.
 | 
			
		||||
 | 
			
		||||
    .. versionadded:: 0.1.2
 | 
			
		||||
@@ -379,7 +370,6 @@ class BooleanField(BaseField):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class DateTimeField(BaseField):
 | 
			
		||||
 | 
			
		||||
    """A datetime field.
 | 
			
		||||
 | 
			
		||||
    Uses the python-dateutil library if available alternatively use time.strptime
 | 
			
		||||
@@ -447,7 +437,6 @@ class DateTimeField(BaseField):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ComplexDateTimeField(StringField):
 | 
			
		||||
 | 
			
		||||
    """
 | 
			
		||||
    ComplexDateTimeField handles microseconds exactly instead of rounding
 | 
			
		||||
    like DateTimeField does.
 | 
			
		||||
@@ -531,7 +520,6 @@ class ComplexDateTimeField(StringField):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class EmbeddedDocumentField(BaseField):
 | 
			
		||||
 | 
			
		||||
    """An embedded document field - with a declared document_type.
 | 
			
		||||
    Only valid values are subclasses of :class:`~mongoengine.EmbeddedDocument`.
 | 
			
		||||
    """
 | 
			
		||||
@@ -585,7 +573,6 @@ class EmbeddedDocumentField(BaseField):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class GenericEmbeddedDocumentField(BaseField):
 | 
			
		||||
 | 
			
		||||
    """A generic embedded document field - allows any
 | 
			
		||||
    :class:`~mongoengine.EmbeddedDocument` to be stored.
 | 
			
		||||
 | 
			
		||||
@@ -624,7 +611,6 @@ class GenericEmbeddedDocumentField(BaseField):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class DynamicField(BaseField):
 | 
			
		||||
 | 
			
		||||
    """A truly dynamic field type capable of handling different and varying
 | 
			
		||||
    types of data.
 | 
			
		||||
 | 
			
		||||
@@ -641,9 +627,9 @@ class DynamicField(BaseField):
 | 
			
		||||
            cls = value.__class__
 | 
			
		||||
            val = value.to_mongo()
 | 
			
		||||
            # If we its a document thats not inherited add _cls
 | 
			
		||||
            if (isinstance(value,   Document)):
 | 
			
		||||
            if isinstance(value, Document):
 | 
			
		||||
                val = {"_ref": value.to_dbref(), "_cls": cls.__name__}
 | 
			
		||||
            if (isinstance(value, EmbeddedDocument)):
 | 
			
		||||
            if isinstance(value, EmbeddedDocument):
 | 
			
		||||
                val['_cls'] = cls.__name__
 | 
			
		||||
            return val
 | 
			
		||||
 | 
			
		||||
@@ -678,7 +664,6 @@ class DynamicField(BaseField):
 | 
			
		||||
 | 
			
		||||
    def prepare_query_value(self, op, value):
 | 
			
		||||
        if isinstance(value, basestring):
 | 
			
		||||
            from mongoengine.fields import StringField
 | 
			
		||||
            return StringField().prepare_query_value(op, value)
 | 
			
		||||
        return super(DynamicField, self).prepare_query_value(op, self.to_mongo(value))
 | 
			
		||||
 | 
			
		||||
@@ -689,7 +674,6 @@ class DynamicField(BaseField):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ListField(ComplexBaseField):
 | 
			
		||||
 | 
			
		||||
    """A list field that wraps a standard field, allowing multiple instances
 | 
			
		||||
    of the field to be used as a list in the database.
 | 
			
		||||
 | 
			
		||||
@@ -749,7 +733,6 @@ class EmbeddedDocumentListField(ListField):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class SortedListField(ListField):
 | 
			
		||||
 | 
			
		||||
    """A ListField that sorts the contents of its list before writing to
 | 
			
		||||
    the database in order to ensure that a sorted list is always
 | 
			
		||||
    retrieved.
 | 
			
		||||
@@ -801,7 +784,6 @@ def key_has_dot_or_dollar(d):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class DictField(ComplexBaseField):
 | 
			
		||||
 | 
			
		||||
    """A dictionary field that wraps a standard Python dictionary. This is
 | 
			
		||||
    similar to an embedded document, but the structure is not defined.
 | 
			
		||||
 | 
			
		||||
@@ -857,7 +839,6 @@ class DictField(ComplexBaseField):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class MapField(DictField):
 | 
			
		||||
 | 
			
		||||
    """A field that maps a name to a specified field type. Similar to
 | 
			
		||||
    a DictField, except the 'value' of each item must match the specified
 | 
			
		||||
    field type.
 | 
			
		||||
@@ -873,7 +854,6 @@ class MapField(DictField):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ReferenceField(BaseField):
 | 
			
		||||
 | 
			
		||||
    """A reference to a document that will be automatically dereferenced on
 | 
			
		||||
    access (lazily).
 | 
			
		||||
 | 
			
		||||
@@ -1010,7 +990,6 @@ class ReferenceField(BaseField):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class CachedReferenceField(BaseField):
 | 
			
		||||
 | 
			
		||||
    """
 | 
			
		||||
    A referencefield with cache fields to purpose pseudo-joins
 | 
			
		||||
    
 | 
			
		||||
@@ -1025,7 +1004,6 @@ class CachedReferenceField(BaseField):
 | 
			
		||||
        """
 | 
			
		||||
        if not isinstance(document_type, basestring) and \
 | 
			
		||||
                not issubclass(document_type, (Document, basestring)):
 | 
			
		||||
 | 
			
		||||
            self.error('Argument to CachedReferenceField constructor must be a'
 | 
			
		||||
                       ' document class or a string')
 | 
			
		||||
 | 
			
		||||
@@ -1036,6 +1014,7 @@ class CachedReferenceField(BaseField):
 | 
			
		||||
 | 
			
		||||
    def start_listener(self):
 | 
			
		||||
        from mongoengine import signals
 | 
			
		||||
 | 
			
		||||
        signals.post_save.connect(self.on_document_pre_save,
 | 
			
		||||
                                  sender=self.document_type)
 | 
			
		||||
 | 
			
		||||
@@ -1089,7 +1068,6 @@ class CachedReferenceField(BaseField):
 | 
			
		||||
    def to_mongo(self, document):
 | 
			
		||||
        id_field_name = self.document_type._meta['id_field']
 | 
			
		||||
        id_field = self.document_type._fields[id_field_name]
 | 
			
		||||
        doc_tipe = self.document_type
 | 
			
		||||
 | 
			
		||||
        if isinstance(document, Document):
 | 
			
		||||
            # We need the id from the saved object to create the DBRef
 | 
			
		||||
@@ -1099,6 +1077,7 @@ class CachedReferenceField(BaseField):
 | 
			
		||||
                           ' been saved to the database')
 | 
			
		||||
        else:
 | 
			
		||||
            self.error('Only accept a document object')
 | 
			
		||||
            # TODO: should raise here or will fail next statement
 | 
			
		||||
 | 
			
		||||
        value = SON((
 | 
			
		||||
            ("_id", id_field.to_mongo(id_)),
 | 
			
		||||
@@ -1150,7 +1129,6 @@ class CachedReferenceField(BaseField):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class GenericReferenceField(BaseField):
 | 
			
		||||
 | 
			
		||||
    """A reference to *any* :class:`~mongoengine.document.Document` subclass
 | 
			
		||||
    that will be automatically dereferenced on access (lazily).
 | 
			
		||||
 | 
			
		||||
@@ -1232,7 +1210,6 @@ class GenericReferenceField(BaseField):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class BinaryField(BaseField):
 | 
			
		||||
 | 
			
		||||
    """A binary data field.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
@@ -1264,7 +1241,6 @@ class GridFSError(Exception):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class GridFSProxy(object):
 | 
			
		||||
 | 
			
		||||
    """Proxy object to handle writing and reading of files to and from GridFS
 | 
			
		||||
 | 
			
		||||
    .. versionadded:: 0.4
 | 
			
		||||
@@ -1410,7 +1386,6 @@ class GridFSProxy(object):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class FileField(BaseField):
 | 
			
		||||
 | 
			
		||||
    """A GridFS storage field.
 | 
			
		||||
 | 
			
		||||
    .. versionadded:: 0.4
 | 
			
		||||
@@ -1494,7 +1469,6 @@ class FileField(BaseField):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ImageGridFsProxy(GridFSProxy):
 | 
			
		||||
 | 
			
		||||
    """
 | 
			
		||||
    Proxy for ImageField
 | 
			
		||||
 | 
			
		||||
@@ -1518,6 +1492,7 @@ class ImageGridFsProxy(GridFSProxy):
 | 
			
		||||
            raise ValidationError('Invalid image: %s' % e)
 | 
			
		||||
 | 
			
		||||
        # Progressive JPEG
 | 
			
		||||
        # TODO: fixme, at least unused, at worst bad implementation
 | 
			
		||||
        progressive = img.info.get('progressive') or False
 | 
			
		||||
 | 
			
		||||
        if (kwargs.get('progressive') and
 | 
			
		||||
@@ -1633,7 +1608,6 @@ class ImproperlyConfigured(Exception):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ImageField(FileField):
 | 
			
		||||
 | 
			
		||||
    """
 | 
			
		||||
    A Image File storage field.
 | 
			
		||||
 | 
			
		||||
@@ -1672,7 +1646,6 @@ class ImageField(FileField):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class SequenceField(BaseField):
 | 
			
		||||
 | 
			
		||||
    """Provides a sequential counter see:
 | 
			
		||||
     http://www.mongodb.org/display/DOCS/Object+IDs#ObjectIDs-SequenceNumbers
 | 
			
		||||
 | 
			
		||||
@@ -1796,7 +1769,6 @@ class SequenceField(BaseField):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class UUIDField(BaseField):
 | 
			
		||||
 | 
			
		||||
    """A UUID field.
 | 
			
		||||
 | 
			
		||||
    .. versionadded:: 0.6
 | 
			
		||||
@@ -1843,13 +1815,12 @@ class UUIDField(BaseField):
 | 
			
		||||
            if not isinstance(value, basestring):
 | 
			
		||||
                value = str(value)
 | 
			
		||||
            try:
 | 
			
		||||
                value = uuid.UUID(value)
 | 
			
		||||
                uuid.UUID(value)
 | 
			
		||||
            except Exception, exc:
 | 
			
		||||
                self.error('Could not convert to UUID: %s' % exc)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class GeoPointField(BaseField):
 | 
			
		||||
 | 
			
		||||
    """A list storing a longitude and latitude coordinate.
 | 
			
		||||
 | 
			
		||||
    .. note:: this represents a generic point in a 2D plane and a legacy way of
 | 
			
		||||
@@ -1879,7 +1850,6 @@ class GeoPointField(BaseField):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class PointField(GeoJsonBaseField):
 | 
			
		||||
 | 
			
		||||
    """A GeoJSON field storing a longitude and latitude coordinate.
 | 
			
		||||
 | 
			
		||||
    The data is represented as:
 | 
			
		||||
@@ -1900,7 +1870,6 @@ class PointField(GeoJsonBaseField):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class LineStringField(GeoJsonBaseField):
 | 
			
		||||
 | 
			
		||||
    """A GeoJSON field storing a line of longitude and latitude coordinates.
 | 
			
		||||
 | 
			
		||||
    The data is represented as:
 | 
			
		||||
@@ -1920,7 +1889,6 @@ class LineStringField(GeoJsonBaseField):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class PolygonField(GeoJsonBaseField):
 | 
			
		||||
 | 
			
		||||
    """A GeoJSON field storing a polygon of longitude and latitude coordinates.
 | 
			
		||||
 | 
			
		||||
    The data is represented as:
 | 
			
		||||
@@ -1943,7 +1911,6 @@ class PolygonField(GeoJsonBaseField):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class MultiPointField(GeoJsonBaseField):
 | 
			
		||||
 | 
			
		||||
    """A GeoJSON field storing a list of Points.
 | 
			
		||||
 | 
			
		||||
    The data is represented as:
 | 
			
		||||
@@ -1964,7 +1931,6 @@ class MultiPointField(GeoJsonBaseField):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class MultiLineStringField(GeoJsonBaseField):
 | 
			
		||||
 | 
			
		||||
    """A GeoJSON field storing a list of LineStrings.
 | 
			
		||||
 | 
			
		||||
    The data is represented as:
 | 
			
		||||
@@ -1985,7 +1951,6 @@ class MultiLineStringField(GeoJsonBaseField):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class MultiPolygonField(GeoJsonBaseField):
 | 
			
		||||
 | 
			
		||||
    """A GeoJSON field storing  list of Polygons.
 | 
			
		||||
 | 
			
		||||
    The data is represented as:
 | 
			
		||||
 
 | 
			
		||||
@@ -14,6 +14,7 @@ PY3 = sys.version_info[0] == 3
 | 
			
		||||
if PY3:
 | 
			
		||||
    import codecs
 | 
			
		||||
    from io import BytesIO as StringIO
 | 
			
		||||
 | 
			
		||||
    # return s converted to binary.  b('test') should be equivalent to b'test'
 | 
			
		||||
    def b(s):
 | 
			
		||||
        return codecs.latin_1_encode(s)[0]
 | 
			
		||||
 
 | 
			
		||||
@@ -43,7 +43,6 @@ RE_TYPE = type(re.compile(''))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class BaseQuerySet(object):
 | 
			
		||||
 | 
			
		||||
    """A set of results returned from a query. Wraps a MongoDB cursor,
 | 
			
		||||
    providing :class:`~mongoengine.Document` objects as the results.
 | 
			
		||||
    """
 | 
			
		||||
@@ -597,7 +596,8 @@ class BaseQuerySet(object):
 | 
			
		||||
                doc_map[doc['_id']] = self._get_as_pymongo(doc)
 | 
			
		||||
        else:
 | 
			
		||||
            for doc in docs:
 | 
			
		||||
                doc_map[doc['_id']] = self._document._from_son(doc,
 | 
			
		||||
                doc_map[doc['_id']] = self._document._from_son(
 | 
			
		||||
                    doc,
 | 
			
		||||
                    only_fields=self.only_fields,
 | 
			
		||||
                    _auto_dereference=self._auto_dereference)
 | 
			
		||||
 | 
			
		||||
@@ -830,7 +830,6 @@ class BaseQuerySet(object):
 | 
			
		||||
        cleaned_fields = []
 | 
			
		||||
        for key, value in kwargs.items():
 | 
			
		||||
            parts = key.split('__')
 | 
			
		||||
            op = None
 | 
			
		||||
            if parts[0] in operators:
 | 
			
		||||
                op = parts.pop(0)
 | 
			
		||||
                value = {'$' + op: value}
 | 
			
		||||
@@ -1616,7 +1615,7 @@ class BaseQuerySet(object):
 | 
			
		||||
 | 
			
		||||
        return frequencies
 | 
			
		||||
 | 
			
		||||
    def _fields_to_dbfields(self, fields, subdoc=False):
 | 
			
		||||
    def _fields_to_dbfields(self, fields):
 | 
			
		||||
        """Translate fields paths to its db equivalents"""
 | 
			
		||||
        ret = []
 | 
			
		||||
        subclasses = []
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,3 @@
 | 
			
		||||
 | 
			
		||||
__all__ = ('QueryFieldList',)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -61,7 +61,6 @@ class QuerySet(BaseQuerySet):
 | 
			
		||||
            data[-1] = "...(remaining elements truncated)..."
 | 
			
		||||
        return repr(data)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    def _iter_results(self):
 | 
			
		||||
        """A generator for iterating over the result cache.
 | 
			
		||||
 | 
			
		||||
@@ -74,7 +73,7 @@ class QuerySet(BaseQuerySet):
 | 
			
		||||
            upper = len(self._result_cache)
 | 
			
		||||
            while pos < upper:
 | 
			
		||||
                yield self._result_cache[pos]
 | 
			
		||||
                pos = pos + 1
 | 
			
		||||
                pos += 1
 | 
			
		||||
            if not self._has_more:
 | 
			
		||||
                raise StopIteration
 | 
			
		||||
            if len(self._result_cache) <= pos:
 | 
			
		||||
 
 | 
			
		||||
@@ -11,7 +11,6 @@ from mongoengine.python_support import IS_PYMONGO_3
 | 
			
		||||
 | 
			
		||||
__all__ = ('query', 'update')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
COMPARISON_OPERATORS = ('ne', 'gt', 'gte', 'lt', 'lte', 'in', 'nin', 'mod',
 | 
			
		||||
                        'all', 'size', 'exists', 'not', 'elemMatch', 'type')
 | 
			
		||||
GEO_OPERATORS = ('within_distance', 'within_spherical_distance',
 | 
			
		||||
@@ -27,7 +26,7 @@ MATCH_OPERATORS = (COMPARISON_OPERATORS + GEO_OPERATORS +
 | 
			
		||||
                   STRING_OPERATORS + CUSTOM_OPERATORS)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def query(_doc_cls=None, _field_operation=False, **query):
 | 
			
		||||
def query(_doc_cls=None, **query):
 | 
			
		||||
    """Transform a query from Django-style format to Mongo format.
 | 
			
		||||
    """
 | 
			
		||||
    mongo_query = {}
 | 
			
		||||
@@ -359,6 +358,7 @@ def _infer_geometry(value):
 | 
			
		||||
        raise InvalidQueryError("Invalid $geometry dictionary should have "
 | 
			
		||||
                                "type and coordinates keys")
 | 
			
		||||
    elif isinstance(value, (list, set)):
 | 
			
		||||
        # TODO: shouldn't we test value[0][0][0][0] to see if it is MultiPolygon?
 | 
			
		||||
        try:
 | 
			
		||||
            value[0][0][0]
 | 
			
		||||
            return {"$geometry": {"type": "Polygon", "coordinates": value}}
 | 
			
		||||
 
 | 
			
		||||
@@ -6,6 +6,7 @@ __all__ = ['pre_init', 'post_init', 'pre_save', 'pre_save_post_validation',
 | 
			
		||||
signals_available = False
 | 
			
		||||
try:
 | 
			
		||||
    from blinker import Namespace
 | 
			
		||||
 | 
			
		||||
    signals_available = True
 | 
			
		||||
except ImportError:
 | 
			
		||||
    class Namespace(object):
 | 
			
		||||
@@ -27,6 +28,7 @@ except ImportError:
 | 
			
		||||
            raise RuntimeError('signalling support is unavailable '
 | 
			
		||||
                               'because the blinker library is '
 | 
			
		||||
                               'not installed.')
 | 
			
		||||
 | 
			
		||||
        send = lambda *a, **kw: None
 | 
			
		||||
        connect = disconnect = has_receivers_for = receivers_for = \
 | 
			
		||||
            temporarily_connected_to = _fail
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user