from __future__ import absolute_import

import sys
import threading

_class_registry_cache = {}
_field_list_cache = []

from mongoengine import connection

class ReadOnlyContext(object):
    """Make the current context read-only.

    Usage:
        with ReadOnlyContext():
            ... # stuff that should not be allowed to modify the database.

    This applies only to the current thread.
    """
    thread = threading.local()

    def __enter__(self):
        ReadOnlyContext.activate()

    def __exit__(self, *args):
        ReadOnlyContext.deactivate()

    @classmethod
    def isActive(cls):
        # The read_only attribute is the count of the number of times we have entered a ReadOnlyContext.
        return bool(getattr(ReadOnlyContext.thread, 'read_only', 0))

    @classmethod
    def activate(cls):
        ReadOnlyContext.thread.read_only = getattr(ReadOnlyContext.thread, 'read_only', 0) + 1

    @classmethod
    def deactivate(cls):
        state = getattr(ReadOnlyContext.thread, 'read_only', 0)
        ReadOnlyContext.thread.read_only = (state - 1) if state > 0 else 0

def _import_class(cls_name):
    """Cache mechanism for imports.

    Due to complications of circular imports mongoengine needs to do lots of
    inline imports in functions.  This is inefficient as classes are
    imported repeated throughout the mongoengine code.  This is
    compounded by some recursive functions requiring inline imports.

    :mod:`mongoengine.common` provides a single point to import all these
    classes.  Circular imports aren't an issue as it dynamically imports the
    class when first needed.  Subsequent calls to the
    :func:`~mongoengine.common._import_class` can then directly retrieve the
    class from the :data:`mongoengine.common._class_registry_cache`.
    """
    if cls_name in _class_registry_cache:
        return _class_registry_cache.get(cls_name)

    doc_classes = ('Document', 'DynamicEmbeddedDocument', 'EmbeddedDocument',
                   'MapReduceDocument')

    # Field Classes
    if not _field_list_cache:
        from mongoengine.fields import __all__ as fields
        _field_list_cache.extend(fields)
        from mongoengine.base.fields import __all__ as fields
        _field_list_cache.extend(fields)

    field_classes = _field_list_cache

    queryset_classes = ('OperationError',)
    deref_classes = ('DeReference',)

    if cls_name in doc_classes:
        from mongoengine import document as module
        import_classes = doc_classes
    elif cls_name in field_classes:
        from mongoengine import fields as module
        import_classes = field_classes
    elif cls_name in queryset_classes:
        from mongoengine import queryset as module
        import_classes = queryset_classes
    elif cls_name in deref_classes:
        from mongoengine import dereference as module
        import_classes = deref_classes
    else:
        raise ValueError('No import set for: ' % cls_name)

    for cls in import_classes:
        _class_registry_cache[cls] = getattr(module, cls)

    return _class_registry_cache.get(cls_name)


def is_py_39():
    """check if current python version is 3.9"""
    return sys.version_info.major == 3 and sys.version_info.minor == 9

from __future__ import absolute_import

import sys
import threading

_class_registry_cache = {}
_field_list_cache = []

from mongoengine import connection

class ReadOnlyContext(object):
    """Make the current context read-only.

    Usage:
        with ReadOnlyContext():
            ... # stuff that should not be allowed to modify the database.

    This applies only to the current thread.
    """
    thread = threading.local()

    def __enter__(self):
        ReadOnlyContext.activate()

    def __exit__(self, *args):
        ReadOnlyContext.deactivate()

    @classmethod
    def isActive(cls):
        # The read_only attribute is the count of the number of times we have entered a ReadOnlyContext.
        return bool(getattr(ReadOnlyContext.thread, 'read_only', 0))

    @classmethod
    def activate(cls):
        ReadOnlyContext.thread.read_only = getattr(ReadOnlyContext.thread, 'read_only', 0) + 1

    @classmethod
    def deactivate(cls):
        state = getattr(ReadOnlyContext.thread, 'read_only', 0)
        ReadOnlyContext.thread.read_only = (state - 1) if state > 0 else 0

def _import_class(cls_name):
    """Cache mechanism for imports.

    Due to complications of circular imports mongoengine needs to do lots of
    inline imports in functions.  This is inefficient as classes are
    imported repeated throughout the mongoengine code.  This is
    compounded by some recursive functions requiring inline imports.

    :mod:`mongoengine.common` provides a single point to import all these
    classes.  Circular imports aren't an issue as it dynamically imports the
    class when first needed.  Subsequent calls to the
    :func:`~mongoengine.common._import_class` can then directly retrieve the
    class from the :data:`mongoengine.common._class_registry_cache`.
    """
    if cls_name in _class_registry_cache:
        return _class_registry_cache.get(cls_name)

    doc_classes = ('Document', 'DynamicEmbeddedDocument', 'EmbeddedDocument',
                   'MapReduceDocument')

    # Field Classes
    if not _field_list_cache:
        from mongoengine.fields import __all__ as fields
        _field_list_cache.extend(fields)
        from mongoengine.base.fields import __all__ as fields
        _field_list_cache.extend(fields)

    field_classes = _field_list_cache

    queryset_classes = ('OperationError',)
    deref_classes = ('DeReference',)

    if cls_name in doc_classes:
        from mongoengine import document as module
        import_classes = doc_classes
    elif cls_name in field_classes:
        from mongoengine import fields as module
        import_classes = field_classes
    elif cls_name in queryset_classes:
        from mongoengine import queryset as module
        import_classes = queryset_classes
    elif cls_name in deref_classes:
        from mongoengine import dereference as module
        import_classes = deref_classes
    else:
        raise ValueError('No import set for: ' % cls_name)

    for cls in import_classes:
        _class_registry_cache[cls] = getattr(module, cls)

    return _class_registry_cache.get(cls_name)


def is_py_39():
    """check if current python version is 3.9"""
    return sys.version_info.major == 3 and sys.version_info.minor == 9

Make the current context read-only.      Usage:         with ReadOnlyContext():             ... # stuff that should not be allowed to modify the database.      This applies only to the current thread. # The read_only attribute is the count of the number of times we have entered a ReadOnlyContext. Cache mechanism for imports.      Due to complications of circular imports mongoengine needs to do lots of     inline imports in functions.  This is inefficient as classes are     imported repeated throughout the mongoengine code.  This is     compounded by some recursive functions requiring inline imports.      :mod:`mongoengine.common` provides a single point to import all these     classes.  Circular imports aren't an issue as it dynamically imports the     class when first needed.  Subsequent calls to the     :func:`~mongoengine.common._import_class` can then directly retrieve the     class from the :data:`mongoengine.common._class_registry_cache`. # Field Classes check if current python version is 3.9