1

Upgrading Django 2.0.13 -> 2.1.0 (or greater) causes the following error when calling runserver, migrate etc.

On Django 2.0.13 (and any lower) does not throw this error.

Traceback (most recent call last):
  File "/usr/lib/python3.6/logging/config.py", line 390, in resolve
     found = getattr(found, frag)
AttributeError: module 'mysite' has no attribute 'mymodule'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/usr/lib/python3.6/logging/config.py", line 565, in configure
    handler = self.configure_handler(handlers[name])
File "/usr/lib/python3.6/logging/config.py", line 715, in configure_handler
    klass = self.resolve(cname)
File "/usr/lib/python3.6/logging/config.py", line 393, in resolve
    found = getattr(found, frag)
AttributeError: module 'mysite' has no attribute 'mymodule'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/home/me/mysite/manage.py", line 20, in <module>
    execute_from_command_line(sys.argv)
File "/home/me/venv/lib/python3.6/site-packages/django/core/management/__init__.py", line 381, in execute_from_command_line
    utility.execute()
File "/home/me/venv/lib/python3.6/site-packages/django/core/management/__init__.py", line 357, in execute
    django.setup()
File "/home/me/venv/lib/python3.6/site-packages/django/__init__.py", line 19, in setup
    configure_logging(settings.LOGGING_CONFIG, settings.LOGGING)
File "/home/me/venv/lib/python3.6/site-packages/django/utils/log.py", line 76, in configure_logging
    logging_config_func(logging_settings)
File "/usr/lib/python3.6/logging/config.py", line 802, in dictConfig
    dictConfigClass(config).configure()
File "/usr/lib/python3.6/logging/config.py", line 573, in configure
    '%r: %s' % (name, e))
ValueError: Unable to configure handler 'console': module 'mysite' has no attribute 'mymodule'

This error is thrown in class BaseConfigurator(object):

The same issue is also with python3.8

Tracing the error to settings.py -> LOGGING

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'verbose': {
            'format': '%(levelname)s %(asctime)s %(module)s %(process)d %(thread)d %(message)s',
        },
        'simple': {
            'format': '%(levelname)s %(message)s',
        },
    },
    'filters': {
        'require_debug_false': {
            '()': 'django.utils.log.RequireDebugFalse'
        },
    },
    'handlers': {
        'console': {
            'level': 'DEBUG',
            'class': 'mysite.mymodule.log.TheConsoleHandler',
            'formatter': 'simple',
        },
        ...
    },
    'loggers': {
        ...
    },
}

If I comment this out all the handlers (and loggers) this error won't be thrown.

Looking at https://docs.djangoproject.com/en/3.0/releases/2.1/ I have hard time understanding what change is causing this or how to debug it.

Project structure (related items)

mysite/
  __init__.py #called twice after upgrade to 2.1
  manage.py
  settings.py
  urls.py
  wsgi.py
  local_settings.py
  mymodule/ #this module is not found from mysite
     __init__.py #empty
     log.py 
     ...
  othermodule/ #moving log.py to this or any other module just causes fail there
  ...

One important note is that for whatever reason, after upgrade to 2.1 mysite/__init__.py is called twice! (--noreload flag is applied). Not sure if this is related to the problem though.

mysite/__init__.py

from uwsgi_tasks import set_uwsgi_callbacks, django_setup

set_uwsgi_callbacks()
django_setup()

mysite/manage.py

import os
import sys

if __name__ == "__main__":
    package_dir = os.path.dirname(os.path.abspath(__file__))
    sys.path.remove(package_dir)
    sys.path.insert(0, os.path.normpath(os.path.join(package_dir, '..')))
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings")
    from django.core.management import execute_from_command_line

    execute_from_command_line(sys.argv)

mysite/mymodule/log.py (content reduced which is irrelevant)

# encoding=utf-8
import logging
import sys


class TheConsoleHandler(logging.Handler):

    def __init__(self):
        logging.Handler.__init__(self)

    def emit(self, record):
        # irrelevant if has content or not, error is thrown anyway
        pass
Levi
  • 141
  • 1
  • 9
  • `mysite.mymodule.log.TheConsoleHandler` might have a circular import which is preventing Django from loading it. It's hard to offer any more specific help because you haven't shown the code. – Alasdair Jun 16 '20 at 10:20
  • @Alasdair I added the class from file as extra info. However if it had a circular import, it should presumably fail already with any previous Django. – Levi Jun 16 '20 at 10:34
  • I don't see any issues with the `log.py` itself, so perhaps the issue is in `mysite` or `mysite.mymodule`. I would try moving `log.py` to the project base, and setting `'class': 'log.TheConsoleHandler',` – Alasdair Jun 16 '20 at 10:48
  • *it should presumably fail already with any previous Django*. Not necessarily. Perhaps there's some change to how Django loads the settings, so it's only an issue now that you've upgraded. I'm not familiar with the Django changes from 2.0.13 to 2.1.0, but I certainly remember seeing users hit errors from circular imports after upgrading around Django 1.7, when the app loading changed. – Alasdair Jun 16 '20 at 10:50
  • I have tried taking log to the project base but then it fails finding log instead of mymodule. – Levi Jun 16 '20 at 12:10
  • Also, it's important to notice that after upgrade mysite/__init__.py is called twice. – Levi Jun 16 '20 at 12:11
  • *then it fails finding log instead of mymodule* - I can't help debug this without seeing your project layout and the traceback of that error. – Alasdair Jun 16 '20 at 12:48
  • 1
    You haven't shown `mysite/__init__.py` either - putting code in there seems fragile. – Alasdair Jun 16 '20 at 12:49
  • 1
    You're right, the problem was because the code was in `mysite/__init__.py`. I moved it to `mysite/manage.py` instead and the issue resolved. Thank you! – Levi Jun 16 '20 at 13:34

1 Answers1

0

The code in mysite/__init__.py needs to be moved to mysite/manage.py.

Credits to Alasdair for helping me debug.

Levi
  • 141
  • 1
  • 9