djangopython-sphinxautodoc

Sphinx mock issue with django `get_user_model` in a custom pakage for django


I am creating a custom package for a django project. The package contains two authentication backends. I have modules configured as below,

# Backend 1 module
from django.contrib.auth import get_user_model
from django.contrib.auth.backends import ModelBackend

UserModel = get_user_model()
# ModelBackend = object  # This will fix actual import issue and uses mocked import only

class AuthBackendOne(ModelBackend):
    pass
# Backend 2 module
from django.contrib.auth import get_user_model
from django.contrib.auth.backends import ModelBackend

UserModel = get_user_model()  # here calls actual django method

class AuthBackendTwo(ModelBackend):
    pass

In my sphinx conf.py I haveautodoc_mock_imports = [ "django.conf", "django.contrib.auth" ]

Issue:

The problem is when I generate sphinx-build for docs, in module 2 it is trying to call actual django get_user_model(). It is not considering that was mocked. By trying myself, I found the issue was when I use ModelBackend to base my custom backend class. No issue in importing ModelBackend, but using that breaks the module 2. Just before using ModelBackend, I have re-assigned to object and run sphinx-build with successful.

Findings:

For my test trials I have printed the UserModel and its type in the above two methods, (I didn't call the get_user_model function in this test)

cognito - CustomBackend 1 ldap - CustomBackend 2

Note type of ldap in both : as function and as class

So, what should I do to fix the issue, I have tried including ModelBackend in autodoc mock as well..


Solution

  • To resolve some django imports during sphinx-doc build for my package, I have made the below changes.

    1. mocked django.contrib.auth.__init__ (get_user_model is defined in there)
    2. Also to work other django functionality I have setup a minimal django settings.
    # doc/source/conf.py  - configuration sphinx documentation
    
    # ... other sphinx doc configuration
    
    # this resolves importing issue of settings from django.conf
    autodoc_mock_imports = [
        "django.conf",
        # ... rest of other mock modules
    ]
    
    # this resolved get_user_model issue
    sys.modules["django.contrib.auth.__init__"] = MagicMock()
    
    
    # django minimal settings config
    import django
    from django.conf import settings
    
    DJANGO_APPS = [
        "django.contrib.auth",
        "django.contrib.contenttypes",
    ]
    settings.configure(DEBUG=True, INSTALLED_APPS=DJANGO_APPS)
    django.setup()
    

    my previous answer did worked at that time, idk how!! But not working now, however this, completely fixes issues with sphinx-doc build now :-)