fpgmaas/deptry

Support for Django

Opened this issue ยท 5 comments

estahn commented

Is your feature request related to a problem? Please describe.

We use aws-xray-sdk with our Django app.

deptry reports:

pyproject.toml: DEP002 'aws-xray-sdk' defined as a dependency but not used in the codebase

I assume the reason for this is that the module is only referenced as part of the INSTALLED_APPS setting:

    INSTALLED_APPS: List[str] = [
        ...
        "aws_xray_sdk.ext.django",
		...
    ]

Describe the solution you would like

I have seen the following used in other projects:

[tool.django-stubs]
django_settings_module = "app.settings"

This could possibly be adopted:

[tool.deptry]
django_settings_module = "app.settings"

Alternatively could code coverage reports be used to complete a better picture on what is executed?

I'm looking for the same feature, haven't found any unused dependency checker yet which is pluggable enough to add a special case for Django INSTALLED_APPS deferred framework imports without hacking it into the checker itself

Thanks for the feedback! I have not used Django myself, but I am assuming what needs to happen for this;

  • Add an argument django_settings_module/django-settings-module to cli.py and core.py
  • Create a class that parses the INSTALLED_APPS from the django-settings-module file.
  • And then here use that to modify the following line
for module, locations in get_imported_modules_for_list_of_files(all_python_files).items()

into something like

for module, locations in (
   get_imported_modules_for_list_of_files(all_python_files) + 
   get_imported_modules_for_django(django_settings_module)
   ).items()

Although that line and the lines around it might need some refactoring because it has become quite a long list comprehension.

I am a bit busy at this time, but if I have time in the near future I will try to get around to this. I will also tag this with 'Good first issue', so if someone else needs it earlier or feels like contributing, I hope the above lines can give some idea on how to get started.

Not at all against implementing that, but depending on how the settings definition is implemented in a Django project, INSTALLED_APPS could sometimes be defined once in a file, then overrode later on in the same file, or in multiple files, if for instance you want to append some apps only on a dev environment.

So this would probably only be implemented as a "best effort", should we go with parsing the attribute with AST, given how dynamic this could be. Ideally, we would resolve the attribute through an import, but this is not something we would want to do, as we don't want to tie deptry to runtime resolution of parsed Python code.

Yes I think it's not solvable in most general case without importing Django settings file, I can see why you wouldn't want to do that.

In which case maybe my solution would be something like a custom Django manage.py command which parses the INSTALLED_APPS and updates the deptry config to make exceptions for them.

It wouldn't have to be part of deptry. Could be run automatically as a pre-commit hook.

It would need a way to map from import names back to PyPI package names, but I guess that exists somewhere in deptry already that it could borrow.

I'd be very interested in such a feature as well, since deptry indeed shows some false positives when used on a Django project.

Although I'm not currently in the capacity to participate on the technical discussion for this support, I believe there is at least a couple more settings that should be mentioned: In Django, Databases and caches configuration are made through the DATABASES and CACHES settings, with a more complex format, looking as follows

CACHES = {
    "default": {
        "BACKEND": "django_redis.cache.RedisCache",  # String representing module path
        "LOCATION": REDIS_URL,
        "OPTIONS": {"CLIENT_CLASS": "django_redis.client.DefaultClient"},
    }
}

Edit: Added the rest of my message... I pressed enter too soon ๐Ÿ™ˆ.