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

settings attributes aren't recorgnized #147

Closed
ghost opened this issue Aug 27, 2019 · 17 comments
Closed

settings attributes aren't recorgnized #147

ghost opened this issue Aug 27, 2019 · 17 comments
Labels
bug Something isn't working

Comments

@ghost
Copy link

ghost commented Aug 27, 2019

When I run mypy, it complains that the Settings object does not have certain attributes. I'm running mypy with PYTHONPATH set correctly and I specified the settings module in my mypy.ini.

mypy command:

PYTHONPATH=${PYTHONPATH}:${pwd} mypy .

mypy.ini:

[mypy]
plugins = mypy_django_plugin.main

[mypy.plugins.django-stubs]
django_settings_module = "pwreset.settings"

mypy output:

pwreset/settings/base.py:12: error: Cannot find module named 'environ'
pwreset/settings/base.py:12: note: See https://mypy.readthedocs.io/en/latest/running_mypy.html#missing-imports
pwreset/settings/production.py:2: error: Cannot find module named 'environ'
pwreset/settings/develop.py:3: error: Cannot find module named 'environ'
pwresetweb/forms.py:25: error: Incompatible types in assignment (expression has type "Type[TextInput]", base class "Field" defined the type as "Widget")
pwresetweb/tests/test_acceptance/seleniumtestcase.py:4: error: No library stub file for module 'django.contrib.staticfiles.testing'
pwresetweb/tests/test_acceptance/seleniumtestcase.py:4: note: (Stub files are from https://github.com/python/typeshed)
pwresetweb/tests/test_acceptance/seleniumtestcase.py:5: error: No library stub file for module 'selenium'
pwresetweb/implementations/simrestmailtokendispatcher.py:25: error: 'Settings' object has no attribute 'SIM_SEND_MAIL_URL'
pwresetweb/implementations/simrestmailtokendispatcher.py:26: error: 'Settings' object has no attribute 'EMAIL_SERVICE_DESK'
pwresetweb/implementations/simrestmailtokendispatcher.py:27: error: 'Settings' object has no attribute 'TOKEN_ENTER_URL'
pwresetweb/healthcheckmiddleware.py:16: error: 'Settings' object has no attribute 'SIM_REST_HEALTH_CHECKER_REQUEST_HANDLER'
pwresetweb/tests/test_acceptance/test_workflow_token_request.py:8: error: 'Settings' object has no attribute 'TEST_SELENIUM'
pwresetweb/tests/test_acceptance/test_workflow_token_request.py:8: error: 'Settings' object has no attribute 'TEST_AGAINST_REAL_SIM_API'
pwresetweb/tests/test_acceptance/test_workflow_token_request.py:13: error: 'Settings' object has no attribute 'TEST_SIM_USER_ID'
pwresetweb/tests/test_acceptance/test_workflow_token_request.py:14: error: 'Settings' object has no attribute 'TEST_SIM_USER_EMAIL'
pwresetweb/tests/test_acceptance/test_workflow_pwreset_with_puk.py:9: error: 'Settings' object has no attribute 'TEST_SELENIUM'
pwresetweb/tests/test_acceptance/test_workflow_pwreset_with_puk.py:33: error: 'Settings' object has no attribute 'TEST_SELENIUM'
pwresetweb/tests/test_acceptance/test_workflow_pwreset_with_puk.py:55: error: 'Settings' object has no attribute 'TEST_SELENIUM'
pwresetweb/tests/test_acceptance/test_workflow_pwreset_with_puk.py:77: error: 'Settings' object has no attribute 'TEST_SELENIUM'
pwresetweb/tests/test_acceptance/test_workflow_pwreset_with_puk.py:99: error: 'Settings' object has no attribute 'TEST_SELENIUM'
pwresetweb/tests/test_acceptance/test_workflow_pwreset_with_puk.py:121: error: 'Settings' object has no attribute 'TEST_SELENIUM'
pwresetweb/tests/test_acceptance/test_user_id_puk_form.py:8: error: 'Settings' object has no attribute 'TEST_SELENIUM'
pwresetweb/tests/test_acceptance/test_token_request_messages.py:11: error: 'Settings' object has no attribute 'TEST_SELENIUM'
pwresetweb/tests/test_acceptance/test_token_request_form.py:8: error: 'Settings' object has no attribute 'TEST_SELENIUM'
pwresetweb/tests/test_acceptance/test_token_enter.py:12: error: 'Settings' object has no attribute 'TEST_SELENIUM'
pwresetweb/tests/test_acceptance/test_token_enter.py:18: error: Cannot determine type of 'some_password'
pwresetweb/tests/test_acceptance/test_real_sim_rest_api.py:10: error: 'Settings' object has no attribute 'TEST_AGAINST_REAL_SIM_API'
pwresetweb/tests/test_acceptance/test_real_sim_rest_api.py:10: error: 'Settings' object has no attribute 'TEST_SELENIUM'
pwresetweb/tests/test_acceptance/test_real_sim_rest_api.py:20: error: 'Settings' object has no attribute 'TEST_SIM_USER_PUK'
pwresetweb/tests/test_acceptance/test_real_sim_rest_api.py:21: error: 'Settings' object has no attribute 'TEST_SIM_USER_ID'
pwresetweb/tests/test_acceptance/test_pw_reset_form.py:8: error: 'Settings' object has no attribute 'TEST_SELENIUM'
pwresetweb/tests/test_acceptance/test_index_page.py:8: error: 'Settings' object has no attribute 'TEST_SELENIUM'
pwresetweb/tests/test_acceptance/test_health_check_fails.py:9: error: 'Settings' object has no attribute 'TEST_SELENIUM'
pwreset/settings/django.py:4: error: Cannot find module named 'environ'
pwresetweb/servicemiddleware.py:65: error: 'Settings' object has no attribute 'SIM_REST_HEALTH_CHECKER_REQUEST_HANDLER'
pwresetweb/servicemiddleware.py:71: error: 'Settings' object has no attribute 'SIM_REST_PUK_AUTHENTICATOR_REQUEST_HANDLER'
pwresetweb/servicemiddleware.py:77: error: 'Settings' object has no attribute 'SIM_REST_TOKEN_AUTHENTICATOR_REQUEST_HANDLER'
pwresetweb/servicemiddleware.py:83: error: 'Settings' object has no attribute 'SIM_REST_PASSWORD_SETTER_REQUEST_HANDLER'
pwresetweb/servicemiddleware.py:89: error: 'Settings' object has no attribute 'SIM_REST_POLICY_RETRIEVER_REQUEST_HANDLER'
pwresetweb/servicemiddleware.py:95: error: 'Settings' object has no attribute 'SIM_REST_EMAIL_USER_VALIDATOR_REQUEST_HANDLER'
pwresetweb/servicemiddleware.py:101: error: 'Settings' object has no attribute 'SIM_REST_TOKEN_REQUESTER_REQUEST_HANDLER'
pwresetweb/servicemiddleware.py:107: error: 'Settings' object has no attribute 'SIM_REST_MAIL_TOKEN_DISPATCHER_REQUEST_HANDLER'
pwresetweb/servicemiddleware.py:110: error: 'Settings' object has no attribute 'MESSAGE_TEMPLATE_LOCATION'
@sobolevn
Copy link
Member

Can you please:

  1. show us what version of django-stubs do you use?
  2. show us the source code that raises some of the given error?

We had ignore_missing_settings setting some time ago, it was working for django-stubs<1

@ghost
Copy link
Author

ghost commented Aug 27, 2019

The version of django stubs is 1.1.0. ignore_missing_settings = true doesn't seem to have any effect.

A sample of the offending code is:

class SimRestMailTokenDispatcher(DispatchTokenInterface):
    def __init__(self, message_template: str, request_handler):
        self.message_template = message_template
        self.request_handler = request_handler
        self.url = settings.SIM_SEND_MAIL_URL
        self.service_desk_contact = settings.EMAIL_SERVICE_DESK
        self.token_enter_url = settings.TOKEN_ENTER_URL

The settings are defined through environ like this in seperate files:

import environ

# set default values and casting
env = environ.Env(
    META_APP_TITLE=(str, 'Password Reset Service'),
)

META_APP_TITLE = env('META_APP_TITLE')

@sobolevn sobolevn added the bug Something isn't working label Aug 27, 2019
@autoferrit
Copy link

I am getting this error as well. Both from a latest install using pip as well as from git using the master branch.
django 2.2.5
mypy 0.730

I have this in my root directory:
image

and my django settings module is config.settings.local. Both runserver and runserver_plus run without issue. The error I get is:

wc/conftest.py:19: Name 'settings.AUTH_USER_MODEL' is not defined
wc/users/tests/test_models.py:8: Name 'settings.AUTH_USER_MODEL' is not defined
wc/users/tests/test_urls.py:9: Name 'settings.AUTH_USER_MODEL' is not defined
wc/users/tests/test_views.py:22: Name 'settings.AUTH_USER_MODEL' is not defined
wc/users/tests/test_views.py:32: Name 'settings.AUTH_USER_MODEL' is not defined
wc/users/tests/test_views.py:47: Name 'settings.AUTH_USER_MODEL' is not defined

But I would also like to note, that settings.AUTH_USER_MODEL is in base.py and local.py imports everything from base.py. If I place that config into local.py I still get the error.

As above also, the setting ignore_missing_settings doesnt seem to have an effect.

here is the relevant parts of my setup.cfg

[mypy]
python_version = 3.7
;check_untyped_defs = True
ignore_errors = False
ignore_missing_imports = True
strict_optional = True
warn_unused_ignores = True
warn_redundant_casts = True
warn_return_any = True
warn_unused_configs = True
plugins =
    mypy_django_plugin.main

; this one is new
[mypy.plugins.django-stubs]
django_settings_module = config.settings.local

[mypy_django_plugin]
ignore_missing_settings = true
ignore_missing_model_attributes = True

[mypy-*.migrations.*]
# Django migrations should not produce any errors:
ignore_errors = True

In my .env I also have this set:

MYPY_DJANGO_CONFIG=./setup.cfg

@mkurnikov
Copy link
Member

Please, try explicitly annotating settings with a type

import environ

# set default values and casting
env = environ.Env(
    META_APP_TITLE=(str, 'Password Reset Service'),
)

META_APP_TITLE: str = env('META_APP_TITLE')

and let me know if it works.

@jordanmkoncz
Copy link

@autoferrit did you ever find a solution? I have the exact same setup as you (guessing you also started your project using https://github.com/pydanny/cookiecutter-django) and I'm getting the same "Name 'settings.AUTH_USER_MODEL' is not defined" errors.

@danifus
Copy link
Contributor

danifus commented Jan 11, 2020

Hi, I can't help with the original report raised but for the Name 'settings.AUTH_USER_MODEL' is not defined errors when user cookiecutter-django:

I've also been getting these errors and they appear to be in the user tests which look like:

import pytest
from django.conf import settings

pytestmark = pytest.mark.django_db


def test_user_get_absolute_url(user: settings.AUTH_USER_MODEL):
    assert user.get_absolute_url() == f"/users/{user.username}/"

Is it possible that settings hasn't been initialised by the time python / mypy examines the function signatures? Assessing the type using reveal_type(settings.AUTH_USER_MODEL) within the function body returns the expected type.

Another problem with cookiecutter-django tests above comes from user: settings.AUTH_USER_MODEL where user is a user instance and settings.AUTH_USER_MODEL is a str from the settings, but that is probably a different bug. I've opened a bug report on cookiecutter-django about that: cookiecutter/cookiecutter-django#2395

@sobolevn
Copy link
Member

sobolevn commented Jan 11, 2020

settings.AUTH_USER_MODEL does not seem like a valid type to me. Why?

  1. settings is a very dynamic thing, moreover it is mutable and context specific
  2. AUTH_USER_MODEL is a django specific string, not mypy specific one

Why won't you use the real type here?
You can have a look at https://github.com/wemake-services/wemake-django-template and how we use types there.

@mkurnikov
Copy link
Member

mkurnikov commented Jan 11, 2020

For AUTH_USER_MODEL you can try get_user_model(), it has plugin support.

UPD. Oh, sorry, I think I got the context a bit wrong. settings.AUTH_USER_MODEL as a type annotation won't work, yeah, it's a string. There's a possibility to add support for

User = get_user_model()
def func(u: User):
    pass

I can look into it if it's useful for you.

@sobolevn
Copy link
Member

Just to be clear:

User = get_user_model()
def func(u: User):
    pass

currently does not work as @mkurnikov said. Currently mypy says that User cannot be used as a type.

@danifus
Copy link
Contributor

danifus commented Jan 14, 2020

The cookiecutter-django errors should be gone in future releases with cookiecutter/cookiecutter-django#2396 now merged.

It now explicitly checks against <your_project_name>.users.models.User.

@oystein-beaufort
Copy link

I have the same issue with mypy==0.942, and django-stubs==1.10.1

pyproject.toml:

[tool.mypy]
strict_optional = true
ignore_missing_imports = true
follow_imports = "normal"
check_untyped_defs = true
show_column_numbers = true

plugins = [
    "mypy_django_plugin.main",
    "mypy_drf_plugin.main]

[tool.django-stubs]
django_settings_module = "beaufort.settings"
ignore_missing_settings = true

@dcrystalj
Copy link

This is still totally broken. Last working release is django-stubs==1.12.0
@mkurnikov suggestion is not working

@iNerV
Copy link

iNerV commented Apr 12, 2023

1.16.0 still broken

@aitorres
Copy link

django-stubs = "4.2.3" still broken

@intgr
Copy link
Collaborator

intgr commented Aug 14, 2023

Does the strict_settings = false option help in these use cases?

See README: How to use a custom library to handle Django settings?

It was introduced in django-stubs 4.2.2 (#1557)

@savostinn
Copy link

savostinn commented Oct 18, 2023

Does the strict_settings = false option help in these use cases?

See README: How to use a custom library to handle Django settings?

It was introduced in django-stubs 4.2.2 (#1557)

Seems it really fix the issue.
@intgr thank you!

@intgr
Copy link
Collaborator

intgr commented Oct 18, 2023

Thanks for confirming, I'll close this issue.

@intgr intgr closed this as completed Oct 18, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Development

No branches or pull requests