I have a problem with ModuleNotFoundError even tho...
# general
c
I have a problem with ModuleNotFoundError even though I use module mapping on django app. Can anybody help out? I want to add package as app when loading settings.py. Currently, jazzmin, crispy_form are not working. BUILD file
Copy code
python_requirements(
    name="requirements",
    module_mapping={
        "django-ninja": ["ninja"],
        "python-dotenv": ["dotenv"],
        "django_log_request_id": ["log_request_id"],
        "django-jazzmin": ["jazzmin"],
        "django_admin_cursor_paginator": ["admin_cursor_paginator"],
        "django_crispy_forms": ["crispy_forms"],
        "django-celery-beat": ["django_celery_beat"],
    },
)
settings.py
Copy code
DJANGO_APPS = [
    "django.contrib.auth",
    "django.contrib.contenttypes",
    "django.contrib.sessions",
    "django.contrib.sites",
    "django.contrib.messages",
    "django.contrib.staticfiles",
    # "django.contrib.humanize", # Handy template tags
    # "grappelli",  # this app must be before django admin app
    "jazzmin",
    "django.contrib.admin",
    "admin_cursor_paginator",
]
THIRD_PARTY_APPS = [
    "crispy_forms",
    "rest_framework",
    "django_celery_beat",
    "simple_history",
    "django_mysql",
    "corsheaders",
    "django_filters",
    "drf_yasg",
    "django_slack",
    "django_user_agents",
    "django_migration_linter",
    "taggit",
    "taggit_autosuggest",
]
error trace
Copy code
17:12:40.71 [WARN] Failed to generate JUnit XML data for payhere/customers/tests/api/test_customer.py:tests.
17:12:40.71 [ERROR] Completed: Run Pytest - payhere/customers/tests/api/test_customer.py:tests failed (exit code 1).
Traceback (most recent call last):
  File "/private/var/folders/jd/znnczw0j2n9_hfy_9kj5_5sw0000gn/T/pants-sandbox-fqwLut/.cache/pex_root/venvs/6d4a9de78703d30bcbe4e7c4b80df143e68dc32c/91bd7b41fccc3fdcc0bbea862ae7f7b017df774c/pex", line 245, in <module>
    sys.exit(func())
  File "/Users/szto/.cache/pants/named_caches/pex_root/venvs/6d4a9de78703d30bcbe4e7c4b80df143e68dc32c/91bd7b41fccc3fdcc0bbea862ae7f7b017df774c/lib/python3.9/site-packages/_pytest/config/__init__.py", line 185, in console_main
    code = main()
  File "/Users/szto/.cache/pants/named_caches/pex_root/venvs/6d4a9de78703d30bcbe4e7c4b80df143e68dc32c/91bd7b41fccc3fdcc0bbea862ae7f7b017df774c/lib/python3.9/site-packages/_pytest/config/__init__.py", line 143, in main
    config = _prepareconfig(args, plugins)
  File "/Users/szto/.cache/pants/named_caches/pex_root/venvs/6d4a9de78703d30bcbe4e7c4b80df143e68dc32c/91bd7b41fccc3fdcc0bbea862ae7f7b017df774c/lib/python3.9/site-packages/_pytest/config/__init__.py", line 318, in _prepareconfig
    config = pluginmanager.hook.pytest_cmdline_parse(
  File "/Users/szto/.cache/pants/named_caches/pex_root/venvs/6d4a9de78703d30bcbe4e7c4b80df143e68dc32c/91bd7b41fccc3fdcc0bbea862ae7f7b017df774c/lib/python3.9/site-packages/pluggy/_hooks.py", line 265, in __call__
    return self._hookexec(self.name, self.get_hookimpls(), kwargs, firstresult)
  File "/Users/szto/.cache/pants/named_caches/pex_root/venvs/6d4a9de78703d30bcbe4e7c4b80df143e68dc32c/91bd7b41fccc3fdcc0bbea862ae7f7b017df774c/lib/python3.9/site-packages/pluggy/_manager.py", line 80, in _hookexec
    return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
  File "/Users/szto/.cache/pants/named_caches/pex_root/venvs/6d4a9de78703d30bcbe4e7c4b80df143e68dc32c/91bd7b41fccc3fdcc0bbea862ae7f7b017df774c/lib/python3.9/site-packages/pluggy/_callers.py", line 55, in _multicall
    gen.send(outcome)
  File "/Users/szto/.cache/pants/named_caches/pex_root/venvs/6d4a9de78703d30bcbe4e7c4b80df143e68dc32c/91bd7b41fccc3fdcc0bbea862ae7f7b017df774c/lib/python3.9/site-packages/_pytest/helpconfig.py", line 100, in pytest_cmdline_parse
    config: Config = outcome.get_result()
  File "/Users/szto/.cache/pants/named_caches/pex_root/venvs/6d4a9de78703d30bcbe4e7c4b80df143e68dc32c/91bd7b41fccc3fdcc0bbea862ae7f7b017df774c/lib/python3.9/site-packages/pluggy/_result.py", line 60, in get_result
    raise ex[1].with_traceback(ex[2])
  File "/Users/szto/.cache/pants/named_caches/pex_root/venvs/6d4a9de78703d30bcbe4e7c4b80df143e68dc32c/91bd7b41fccc3fdcc0bbea862ae7f7b017df774c/lib/python3.9/site-packages/pluggy/_callers.py", line 39, in _multicall
    res = hook_impl.function(*args)
  File "/Users/szto/.cache/pants/named_caches/pex_root/venvs/6d4a9de78703d30bcbe4e7c4b80df143e68dc32c/91bd7b41fccc3fdcc0bbea862ae7f7b017df774c/lib/python3.9/site-packages/_pytest/config/__init__.py", line 1003, in pytest_cmdline_parse
    self.parse(args)
  File "/Users/szto/.cache/pants/named_caches/pex_root/venvs/6d4a9de78703d30bcbe4e7c4b80df143e68dc32c/91bd7b41fccc3fdcc0bbea862ae7f7b017df774c/lib/python3.9/site-packages/_pytest/config/__init__.py", line 1283, in parse
    self._preparse(args, addopts=addopts)
  File "/Users/szto/.cache/pants/named_caches/pex_root/venvs/6d4a9de78703d30bcbe4e7c4b80df143e68dc32c/91bd7b41fccc3fdcc0bbea862ae7f7b017df774c/lib/python3.9/site-packages/_pytest/config/__init__.py", line 1191, in _preparse
    self.hook.pytest_load_initial_conftests(
  File "/Users/szto/.cache/pants/named_caches/pex_root/venvs/6d4a9de78703d30bcbe4e7c4b80df143e68dc32c/91bd7b41fccc3fdcc0bbea862ae7f7b017df774c/lib/python3.9/site-packages/pluggy/_hooks.py", line 265, in __call__
    return self._hookexec(self.name, self.get_hookimpls(), kwargs, firstresult)
  File "/Users/szto/.cache/pants/named_caches/pex_root/venvs/6d4a9de78703d30bcbe4e7c4b80df143e68dc32c/91bd7b41fccc3fdcc0bbea862ae7f7b017df774c/lib/python3.9/site-packages/pluggy/_manager.py", line 80, in _hookexec
    return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
  File "/Users/szto/.cache/pants/named_caches/pex_root/venvs/6d4a9de78703d30bcbe4e7c4b80df143e68dc32c/91bd7b41fccc3fdcc0bbea862ae7f7b017df774c/lib/python3.9/site-packages/pluggy/_callers.py", line 60, in _multicall
    return outcome.get_result()
  File "/Users/szto/.cache/pants/named_caches/pex_root/venvs/6d4a9de78703d30bcbe4e7c4b80df143e68dc32c/91bd7b41fccc3fdcc0bbea862ae7f7b017df774c/lib/python3.9/site-packages/pluggy/_result.py", line 60, in get_result
    raise ex[1].with_traceback(ex[2])
  File "/Users/szto/.cache/pants/named_caches/pex_root/venvs/6d4a9de78703d30bcbe4e7c4b80df143e68dc32c/91bd7b41fccc3fdcc0bbea862ae7f7b017df774c/lib/python3.9/site-packages/pluggy/_callers.py", line 39, in _multicall
    res = hook_impl.function(*args)
  File "/Users/szto/.cache/pants/named_caches/pex_root/venvs/6d4a9de78703d30bcbe4e7c4b80df143e68dc32c/91bd7b41fccc3fdcc0bbea862ae7f7b017df774c/lib/python3.9/site-packages/pytest_django/plugin.py", line 353, in pytest_load_initial_conftests
    _setup_django()
  File "/Users/szto/.cache/pants/named_caches/pex_root/venvs/6d4a9de78703d30bcbe4e7c4b80df143e68dc32c/91bd7b41fccc3fdcc0bbea862ae7f7b017df774c/lib/python3.9/site-packages/pytest_django/plugin.py", line 236, in _setup_django
    django.setup()
  File "/Users/szto/.cache/pants/named_caches/pex_root/venvs/6d4a9de78703d30bcbe4e7c4b80df143e68dc32c/91bd7b41fccc3fdcc0bbea862ae7f7b017df774c/lib/python3.9/site-packages/django/__init__.py", line 24, in setup
    apps.populate(settings.INSTALLED_APPS)
  File "/Users/szto/.cache/pants/named_caches/pex_root/venvs/6d4a9de78703d30bcbe4e7c4b80df143e68dc32c/91bd7b41fccc3fdcc0bbea862ae7f7b017df774c/lib/python3.9/site-packages/django/apps/registry.py", line 91, in populate
    app_config = AppConfig.create(entry)
  File "/Users/szto/.cache/pants/named_caches/pex_root/venvs/6d4a9de78703d30bcbe4e7c4b80df143e68dc32c/91bd7b41fccc3fdcc0bbea862ae7f7b017df774c/lib/python3.9/site-packages/django/apps/config.py", line 224, in create
    import_module(entry)
  File "/usr/local/Cellar/python@3.9/3.9.10/Frameworks/Python.framework/Versions/3.9/lib/python3.9/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1030, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1007, in _find_and_load
  File "<frozen importlib._bootstrap>", line 984, in _find_and_load_unlocked
ModuleNotFoundError: No module named 'jazzmin'
p
the
jazzmin
string that gets added to the
DJANGO_APPS
list doesn't have any dots in it, so pants dependency inference logic doesn't even try to infer it as a code dependency (I think). So what you will have to do to work around this issue is to add this dependency to the BUILD file where the settings.py is located. this will look something like:
Copy code
python_sources(
    dependencies=[
        "3rdparty/python#jazzmin",  # via DJANGO_APPS
        ],
)
the
3rdparty/python
path will depend on the location of your reqs file. you can figure it out by running something like
./pants filter :: | grep "#jazzmin
h
To follow up on what Asher mentioned - Pants infers deps from
import
statements, but Django, notoriously, does a lot of dynamic loading based on strings in settings.py.
You can use this option to tell Pants to also infer deps based on strings in a file
but it’s limited to strings that “look like modules”, i.e., have some number of dots in them (the exact number is controlled by the
string_imports_min_dots
option).
Which is why in this case the best solution may be to add an explicit dep from settings.py, as Asher demonstrated.
Also, if you want to be more precise and only add the dep to
settings.py
and not to other .py files in that directory, you can use
Copy code
python_sources(
    overrides={"settings.py": {"dependencies": ["3rdparty/python#jazzmin"]}},
)
c
Thanks a lot! That’s very clear. Do you think it is not recommended to include all deps for settings? @polite-garden-50641 @happy-kitchen-89482
Copy code
python_sources(
    dependencies=[
        "//:requirements",  # instead of //:requirements#jazzmin
        ],
)
h
That would add all deps to all sources in the directory!
It’s generally better to be precise, if it’s not too verbose to do so
at the very least, have
settings.py
depend on all the requirements, but not other files?
On the other hand, the files in that dir are probably all very high-level, so in practice what you have is probably fine!
They all probably genuinely depend on everything, at least transitively