Add support for django-configurations
Add support for django-configurations.
This is enabled if you add a django_configuration value to the Plugins settings.
I'm with @sobolevn on that. I can extract code for settings initialization to make it more pluggable. We can design some kind of hooks to be able to extend library. @sobolevn @hishnash Could you think of any other examples of django third party apps for which we'd need hooks?
@mkurnikov @sobolevn more pluggable settings initialisation would be the best option yes.
@mkurnikov I use https://github.com/sobolevn/django-split-settings, it almost works with django-stubs as is, but sometimes requires extra env vars:
from split_settings.tools import include
from os import environ
ENV = environ.get('DJANGO_ENV') or 'development' # here
base_settings = [
'components/common.py',
'components/database.py',
# Select the right env:
'environments/{0}.py'.format(ENV),
]
# Include settings:
include(*base_settings)
@hishnash I tried different refactorings a bit, but I don't really know what would work best. If you have bandwidth, could you make a PR with refactoring you need? Like, extracting initialization into the separate pluggable class or smth.
@mkurnikov I will give it a spin tomorrow, I will need to check how to ensure Mypy inits plugins in the correct order.
or we could have a config param in in the Django-stubs plugin config that points to an alternative package name for init?
@hishnash @mkurnikov Has there been any progress here? This is an exciting feature.
Is there anything I (or others) could contribute to help?
any news with this?
We have decided to use some sort of a callback, like this:
[mypy.plugins.django-stubs]
django_settings_module = mysettings
django_setup_callback = path.to.your.function
And the function itself should look like so (probably we will call it from here):
# path/to/your.py
def function(settings_module: str) -> None:
# By default it will do this:
from django.conf import settings
settings._setup()
This way, you will be able to support any configuration framework of your choice. And we will not have to add the support to the core library.
I will review and merge a PR with the described feature with great pleause. @hishnash are you still interested? 🙂
Can be achieved without additional support and non intrusively with a custom plugin package
;setup.cfg
[mypy]
plugins = ./mypy_django_plugin.py
# mypy_django_plugin.py
from configurations import importer
from mypy_django_plugin.main import plugin
importer.install()
Like this, when the mypy django plugin initialize the settings, the import hook of django-configurations will be installed.
the workaround by ticosax is great if you don't need multiple plugins, but in case anyone does, i've created a gist that returns a no-op plugin and sets up the importer
thanks ticosax, i used your snippet as a base :)
Can be achieved without additional support and non intrusively with a custom plugin package
;setup.cfg [mypy] plugins = ./mypy_django_plugin.py# mypy_django_plugin.py from configurations import importer from mypy_django_plugin.main import plugin importer.install()Like this, when the mypy django plugin initialize the settings, the import hook of django-configurations will be installed.
Thank you for sharing. It works well! For more specific:
# configurations_mypy_django_plugin.py
import os
from configurations.importer import install
from mypy.version import __version__
from mypy_django_plugin import main
def plugin(version):
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "django_project.config")
os.environ.setdefault("DJANGO_CONFIGURATION", "Local")
install()
return main.plugin(version)
# mypy.ini
[mypy]
plugins = ./configurations_mypy_django_plugin.py
[mypy.plugins.django-stubs]
django_settings_module = "django_project.config"
In case it's useful to anyone, @wlf100220 solution here worked for me with a couple tweaks.
Our top-level package is not at the repo root but instead in a src folder, and settings is at ./src/project_name/settings.py. I was getting path issues, resolved by specifying the mypy_path:
# pyproject.toml
[tool.mypy]
mypy_path = "./src"
plugins = ["./src/configurations_mypy_django_plugin.py"]
[tool.django-stubs]
django_settings_module = "project_name.settings"
Will this ever get integrated?
@Brodan this project is open-source. If you want something, you can provide a design description, get an approval and then send a PR.
Hello everyone, I am stuck with this problem. I cannot make proposed solutions to work in my case, and I don't unserstand @ticosax solution. `
mypy_django_plugin.py
from configurations import importer
from mypy_django_plugin.main import plugin
importer.install()`
It seems like importing from mypy_django_plugin.main inside mypy_django_plugin.py. Can anyone explain to me what is going on here?
@Matje1979 just name your plugin something else.
For me, the proposed solution doesn't work, though.