Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for django-configurations #180

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open

Add support for django-configurations #180

wants to merge 1 commit into from

Conversation

hishnash
Copy link

Add support for django-configurations.

This is enabled if you add a django_configuration value to the Plugins settings.

Copy link
Member

@sobolevn sobolevn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @hishnash!

However, my vote goes against this change for two reasons:

  1. This is not django-native approach
  2. It will bring unneeded complexity to the code and start a pattern of accepting 3rd party code into django-stubs

I see this as a separate plugin.

@mkurnikov
Copy link
Member

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?

@hishnash
Copy link
Author

@mkurnikov @sobolevn more pluggable settings initialisation would be the best option yes.

@sobolevn
Copy link
Member

sobolevn commented Sep 23, 2019

@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)

@mkurnikov mkurnikov added this to the 1.2.0 milestone Sep 24, 2019
@mkurnikov
Copy link
Member

@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 mkurnikov modified the milestones: 1.2.0, 1.2.1 Sep 30, 2019
@hishnash
Copy link
Author

hishnash commented Oct 1, 2019

@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?

@mkurnikov mkurnikov removed this from the 1.2.1 milestone Nov 12, 2019
@brianhelba
Copy link
Contributor

@hishnash @mkurnikov Has there been any progress here? This is an exciting feature.

Is there anything I (or others) could contribute to help?

@psdon
Copy link

psdon commented Sep 9, 2020

any news with this?

@sobolevn
Copy link
Member

sobolevn commented Sep 9, 2020

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? 🙂

@ticosax
Copy link
Contributor

ticosax commented Sep 29, 2020

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.

@ghost
Copy link

ghost commented Nov 12, 2020

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 :)

@Dimitri-WEI-Lingfeng
Copy link

Dimitri-WEI-Lingfeng commented Apr 15, 2021

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"

@john-sandall
Copy link

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"

@Brodan
Copy link

Brodan commented Mar 12, 2024

Will this ever get integrated?

@sobolevn
Copy link
Member

@Brodan this project is open-source. If you want something, you can provide a design description, get an approval and then send a PR.

@Matje1979
Copy link

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?

@bwo
Copy link

bwo commented Aug 28, 2024

@Matje1979 just name your plugin something else.

For me, the proposed solution doesn't work, though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.