1_class_registry_cache = {}
2_field_list_cache = []
3
4
5def _import_class(cls_name):
6    """Cache mechanism for imports.
7
8    Due to complications of circular imports mongoengine needs to do lots of
9    inline imports in functions.  This is inefficient as classes are
10    imported repeated throughout the mongoengine code.  This is
11    compounded by some recursive functions requiring inline imports.
12
13    :mod:`mongoengine.common` provides a single point to import all these
14    classes.  Circular imports aren't an issue as it dynamically imports the
15    class when first needed.  Subsequent calls to the
16    :func:`~mongoengine.common._import_class` can then directly retrieve the
17    class from the :data:`mongoengine.common._class_registry_cache`.
18    """
19    if cls_name in _class_registry_cache:
20        return _class_registry_cache.get(cls_name)
21
22    doc_classes = (
23        "Document",
24        "DynamicEmbeddedDocument",
25        "EmbeddedDocument",
26        "MapReduceDocument",
27    )
28
29    # Field Classes
30    if not _field_list_cache:
31        from mongoengine.fields import __all__ as fields
32
33        _field_list_cache.extend(fields)
34        from mongoengine.base.fields import __all__ as fields
35
36        _field_list_cache.extend(fields)
37
38    field_classes = _field_list_cache
39
40    deref_classes = ("DeReference",)
41
42    if cls_name == "BaseDocument":
43        from mongoengine.base import document as module
44
45        import_classes = ["BaseDocument"]
46    elif cls_name in doc_classes:
47        from mongoengine import document as module
48
49        import_classes = doc_classes
50    elif cls_name in field_classes:
51        from mongoengine import fields as module
52
53        import_classes = field_classes
54    elif cls_name in deref_classes:
55        from mongoengine import dereference as module
56
57        import_classes = deref_classes
58    else:
59        raise ValueError("No import set for: %s" % cls_name)
60
61    for cls in import_classes:
62        _class_registry_cache[cls] = getattr(module, cls)
63
64    return _class_registry_cache.get(cls_name)
65