Opened 20 months ago

Closed 20 months ago

Last modified 20 months ago

#21502 closed Uncategorized (duplicate)

Django 1.6 upgrade: "cannot import name BaseHandler"

Reported by: eevenson Owned by: nobody
Component: Uncategorized Version: 1.6
Severity: Normal Keywords:
Cc: bmispelon Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description (last modified by bmispelon)

I am trying to upgrade from Django 1.5.5 to Django 1.6. Everything tests fine, but when I try to run my django project, I get the following error:

    ValueError: Unable to configure handler 'mail_admins': Cannot resolve 'vbenergyzone.core.utils.log.StaffSuperuserEmailHandler': cannot import name BaseHandler

Also: http://stackoverflow.com/questions/20167580/django-1-6-upgrade-cannot-import-name-basehandler.

Here is what I have tried:

  • I have removed my custom logging handler code completely. The project runs fine without any errors.
  • I have replaced my custom logging handler code and replaced it with the default handler code. I get the same error.
  • I have tried Django 1.6c1 and get the same error.

Thanks!

Here is my stacktrace:

    20:29:03 web.1    | started with pid 1501
    20:29:03 worker.1 | started with pid 1504
    20:29:03 web.1    | 2013-11-23 20:29:03 [1503] [INFO] Starting gunicorn 18.0
    20:29:03 web.1    | 2013-11-23 20:29:03 [1503] [INFO] Listening at: http://192.168.50.4:5000 (1503)
    20:29:03 web.1    | 2013-11-23 20:29:03 [1503] [INFO] Using worker: sync
    20:29:03 web.1    | 2013-11-23 20:29:03 [1518] [INFO] Booting worker with pid: 1518
    20:29:04 web.1    | 2013-11-23 14:29:04 [1518] [ERROR] Exception in worker process:
    20:29:04 web.1    | Traceback (most recent call last):
    20:29:04 web.1    |   File "/home/vagrant/.virtualenvs/VBEZ/local/lib/python2.7/site-packages/gunicorn/arbiter.py", line 495, in spawn_worker
    20:29:04 web.1    |     worker.init_process()
    20:29:04 web.1    |   File "/home/vagrant/.virtualenvs/VBEZ/local/lib/python2.7/site-packages/gunicorn/workers/base.py", line 106, in init_process
    20:29:04 web.1    |     self.wsgi = self.app.wsgi()
    20:29:04 web.1    |   File "/home/vagrant/.virtualenvs/VBEZ/local/lib/python2.7/site-packages/gunicorn/app/base.py", line 114, in wsgi
    20:29:04 web.1    |     self.callable = self.load()
    20:29:04 web.1    |   File "/home/vagrant/.virtualenvs/VBEZ/local/lib/python2.7/site-packages/gunicorn/app/wsgiapp.py", line 62, in load
    20:29:04 web.1    |     return self.load_wsgiapp()
    20:29:04 web.1    |   File "/home/vagrant/.virtualenvs/VBEZ/local/lib/python2.7/site-packages/gunicorn/app/wsgiapp.py", line 49, in load_wsgiapp
    20:29:04 web.1    |     return util.import_app(self.app_uri)
    20:29:04 web.1    |   File "/home/vagrant/.virtualenvs/VBEZ/local/lib/python2.7/site-packages/gunicorn/util.py", line 354, in import_app
    20:29:04 web.1    |     __import__(module)
    20:29:04 web.1    |   File "/vagrant/vbenergyzone/wsgi.py", line 23, in <module>
    20:29:04 web.1    |     from django.core.wsgi import get_wsgi_application
    20:29:04 web.1    |   File "/home/vagrant/.virtualenvs/VBEZ/local/lib/python2.7/site-packages/django/core/wsgi.py", line 1, in <module>
    20:29:04 web.1    |     from django.core.handlers.wsgi import WSGIHandler
    20:29:04 web.1    |   File "/home/vagrant/.virtualenvs/VBEZ/local/lib/python2.7/site-packages/django/core/handlers/wsgi.py", line 11, in <module>
    20:29:04 web.1    |     from django.core.handlers import base
    20:29:04 web.1    |   File "/home/vagrant/.virtualenvs/VBEZ/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 12, in <module>
    20:29:04 web.1    |     from django.db import connections, transaction
    20:29:04 web.1    |   File "/home/vagrant/.virtualenvs/VBEZ/local/lib/python2.7/site-packages/django/db/__init__.py", line 83, in <module>
    20:29:04 web.1    |     signals.request_started.connect(reset_queries)
    20:29:04 web.1    |   File "/home/vagrant/.virtualenvs/VBEZ/local/lib/python2.7/site-packages/django/dispatch/dispatcher.py", line 88, in connect
    20:29:04 web.1    |     if settings.DEBUG:
    20:29:04 web.1    |   File "/home/vagrant/.virtualenvs/VBEZ/local/lib/python2.7/site-packages/django/conf/__init__.py", line 54, in __getattr__
    20:29:04 web.1    |     self._setup(name)
    20:29:04 web.1    |   File "/home/vagrant/.virtualenvs/VBEZ/local/lib/python2.7/site-packages/django/conf/__init__.py", line 50, in _setup
    20:29:04 web.1    |     self._configure_logging()
    20:29:04 web.1    |   File "/home/vagrant/.virtualenvs/VBEZ/local/lib/python2.7/site-packages/django/conf/__init__.py", line 80, in _configure_logging
    20:29:04 web.1    |     logging_config_func(self.LOGGING)
    20:29:04 web.1    |   File "/usr/lib/python2.7/logging/config.py", line 777, in dictConfig
    20:29:04 web.1    |     dictConfigClass(config).configure()
    20:29:04 web.1    |   File "/usr/lib/python2.7/logging/config.py", line 575, in configure
    20:29:04 web.1    |     '%r: %s' % (name, e))
    20:29:04 web.1    | ValueError: Unable to configure handler 'mail_admins': Cannot resolve 'vbenergyzone.core.utils.log.StaffSuperuserEmailHandler': cannot import name BaseHandler
    20:29:04 web.1    | Traceback (most recent call last):
    20:29:04 web.1    |   File "/home/vagrant/.virtualenvs/VBEZ/local/lib/python2.7/site-packages/gunicorn/arbiter.py", line 495, in spawn_worker
    20:29:04 web.1    |     worker.init_process()
    20:29:04 web.1    |   File "/home/vagrant/.virtualenvs/VBEZ/local/lib/python2.7/site-packages/gunicorn/workers/base.py", line 106, in init_process
    20:29:04 web.1    |     self.wsgi = self.app.wsgi()
    20:29:04 web.1    |   File "/home/vagrant/.virtualenvs/VBEZ/local/lib/python2.7/site-packages/gunicorn/app/base.py", line 114, in wsgi
    20:29:04 web.1    |     self.callable = self.load()
    20:29:04 web.1    |   File "/home/vagrant/.virtualenvs/VBEZ/local/lib/python2.7/site-packages/gunicorn/app/wsgiapp.py", line 62, in load
    20:29:04 web.1    |     return self.load_wsgiapp()
    20:29:04 web.1    |   File "/home/vagrant/.virtualenvs/VBEZ/local/lib/python2.7/site-packages/gunicorn/app/wsgiapp.py", line 49, in load_wsgiapp
    20:29:04 web.1    |     return util.import_app(self.app_uri)
    20:29:04 web.1    |   File "/home/vagrant/.virtualenvs/VBEZ/local/lib/python2.7/site-packages/gunicorn/util.py", line 354, in import_app
    20:29:04 web.1    |     __import__(module)
    20:29:04 web.1    |   File "/vagrant/vbenergyzone/wsgi.py", line 23, in <module>
    20:29:04 web.1    |     from django.core.wsgi import get_wsgi_application
    20:29:04 web.1    |   File "/home/vagrant/.virtualenvs/VBEZ/local/lib/python2.7/site-packages/django/core/wsgi.py", line 1, in <module>
    20:29:04 web.1    |     from django.core.handlers.wsgi import WSGIHandler
    20:29:04 web.1    |   File "/home/vagrant/.virtualenvs/VBEZ/local/lib/python2.7/site-packages/django/core/handlers/wsgi.py", line 11, in <module>
    20:29:04 web.1    |     from django.core.handlers import base
    20:29:04 web.1    |   File "/home/vagrant/.virtualenvs/VBEZ/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 12, in <module>
    20:29:04 web.1    |     from django.db import connections, transaction
    20:29:04 web.1    |   File "/home/vagrant/.virtualenvs/VBEZ/local/lib/python2.7/site-packages/django/db/__init__.py", line 83, in <module>
    20:29:04 web.1    |     signals.request_started.connect(reset_queries)
    20:29:04 web.1    |   File "/home/vagrant/.virtualenvs/VBEZ/local/lib/python2.7/site-packages/django/dispatch/dispatcher.py", line 88, in connect
    20:29:04 web.1    |     if settings.DEBUG:
    20:29:04 web.1    |   File "/home/vagrant/.virtualenvs/VBEZ/local/lib/python2.7/site-packages/django/conf/__init__.py", line 54, in __getattr__
    20:29:04 web.1    |     self._setup(name)
    20:29:04 web.1    |   File "/home/vagrant/.virtualenvs/VBEZ/local/lib/python2.7/site-packages/django/conf/__init__.py", line 50, in _setup
    20:29:04 web.1    |     self._configure_logging()
    20:29:04 web.1    |   File "/home/vagrant/.virtualenvs/VBEZ/local/lib/python2.7/site-packages/django/conf/__init__.py", line 80, in _configure_logging
    20:29:04 web.1    |     logging_config_func(self.LOGGING)
    20:29:04 web.1    |   File "/usr/lib/python2.7/logging/config.py", line 777, in dictConfig
    20:29:04 web.1    |     dictConfigClass(config).configure()
    20:29:04 web.1    |   File "/usr/lib/python2.7/logging/config.py", line 575, in configure
    20:29:04 web.1    |     '%r: %s' % (name, e))
    20:29:04 web.1    | ValueError: Unable to configure handler 'mail_admins': Cannot resolve 'vbenergyzone.core.utils.log.StaffSuperuserEmailHandler': cannot import name BaseHandler

Here is my logging configuration:

    LOGGING = {
        'version': 1,
        'disable_existing_loggers': True,
        'filters': {
             'require_debug_false': {
                 '()': 'django.utils.log.RequireDebugFalse'
             }
         },
        'formatters': {
            'verbose': {
                'format': '%(levelname)s %(asctime)s %(module)s %(process)d %(thread)d %(message)s'
            },
            'simple': {
                'format': '%(levelname)s %(message)s'
            },
        },
        'handlers': {
            'null': {
                'level': 'DEBUG',
                'class': 'django.utils.log.NullHandler',
            },
            'console':{
                'level': 'DEBUG',
                'class': 'logging.StreamHandler',
                'formatter': 'simple'
            },
            'mail_admins': {
                'level': 'ERROR',
                # 'class': 'django.utils.log.AdminEmailHandler',
                'class': 'vbenergyzone.core.utils.log.StaffSuperuserEmailHandler',
                'filters': [],
            }
        },
        'loggers': {
            'django': {
                'handlers': ['null'],
                'propagate': True,
                'level': 'INFO',
            },
            'django.request': {
                'handlers': ['mail_admins'],
                'level': 'ERROR',
                'propagate': True,
            },
            'vbenergyzone': {
                'handlers': ['console', 'mail_admins'],
                'level': 'INFO',
            }
        }
    }

Here is my custom logger:

    """
    Logging utilities
    """
    import logging
    import traceback
    
    from django.contrib.sites.models import Site
    
    from django.views.debug import get_exception_reporter_filter
    
    from vbenergyzone.core import send_message
    
    # ==============================================================================
    
    class StaffSuperuserEmailHandler(logging.Handler):
        def emit(self, record):
            try:
                request = record.request
                domain = Site.objects.get_current().domain
                
                subject = 'User %s experienced an error on %s: %s' % \
                    (request.user, domain, record.getMessage())
                
                filter = get_exception_reporter_filter(request)
                request_repr = filter.get_request_repr(request)
            except Exception:
                subject = '%s: %s' % (
                    record.levelname,
                    record.getMessage(),
                )
                
                request = None
                request_repr = "Request repr() unavailable."
    
            if record.exc_info:
                exc_info = record.exc_info
                stack_trace = \
                    '\n'.join(traceback.format_exception(*record.exc_info))
            else:
                exc_info = (None, record.getMessage(), None)
                stack_trace = 'No stack trace available'
            
            context_object = {
                'message':      record.getMessage(),
                'request':      request,
                'request_repr': request_repr,
                'stack_trace':  stack_trace,
            }
            
            send_message(
                context_object=context_object,
                html_template='core/email/staff_super_email_handler.html',
                send_to_staff_and_superusers=True,
                subject=self.format_subject(subject),
                text_template='core/email/staff_super_email_handler.txt',
            )
        
        def format_subject(self, subject):
            """
            Escape CR and LF characters, and limit length.
            RFC 2822's hard limit is 998 characters per line. So, minus "Subject: "
            the actual subject must be no longer than 989 characters.
            """
            formatted_subject = subject.replace('\n', '\\n').replace('\r', '\\r')
            return formatted_subject[:989]

Change History (10)

comment:1 Changed 20 months ago by bmispelon

  • Cc bmispelon added
  • Description modified (diff)
  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset

Hi,

I think you might have broken imports in your code, but the traceback is not helpful in finding out where.

Does import vbenergyzone.core.utils.log.StaffSuperuserEmailHandler work in a plain shell?

comment:2 Changed 20 months ago by eevenson

Yes, from vbenergyzone.core.utils.log import StaffSuperuserEmailHandler works in the Django shell for both 1.5.5 and 1.6.

comment:3 Changed 20 months ago by claudep

I think this might be a circular import issue, similar to #21486. Could you please test if applying the following patch fixes your issue?
https://github.com/django/django/commit/42fef2944640659b95679381a9c8f02b3be884b1

comment:4 Changed 20 months ago by eevenson

Ok, first of all, thanks for helping in such a timely fashion.

I added the commit you linked to my requirements. Unfortunately, the commit breaks a different requirement that I currently have: https://bitbucket.org/smileychris/django-countries/. This is a minor requirement, but would take some time for me to back out. It looks like it is failing on an import as well (from django.utils.encoding import force_unicode, StrAndUnicode).

The stacktrace I get when I try to use the commit you specified is:

Traceback (most recent call last):
  File "manage.py", line 10, in <module>
    execute_from_command_line(sys.argv)
  File "/home/vagrant/.virtualenvs/VBEZ/src/django/django/core/management/__init__.py", line 416, in execute_from_command_line
    utility.execute()
  File "/home/vagrant/.virtualenvs/VBEZ/src/django/django/core/management/__init__.py", line 408, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/home/vagrant/.virtualenvs/VBEZ/src/django/django/core/management/base.py", line 244, in run_from_argv
    self.execute(*args, **options.__dict__)
  File "/home/vagrant/.virtualenvs/VBEZ/src/django/django/core/management/base.py", line 290, in execute
    self.validate()
  File "/home/vagrant/.virtualenvs/VBEZ/src/django/django/core/management/base.py", line 316, in validate
    num_errors = get_validation_errors(s, app)
  File "/home/vagrant/.virtualenvs/VBEZ/src/django/django/core/management/validation.py", line 34, in get_validation_errors
    for (app_name, error) in get_app_errors().items():
  File "/home/vagrant/.virtualenvs/VBEZ/src/django/django/db/models/loading.py", line 246, in get_app_errors
    self._populate()
  File "/home/vagrant/.virtualenvs/VBEZ/src/django/django/db/models/loading.py", line 115, in _populate
    self.load_app(app_name)
  File "/home/vagrant/.virtualenvs/VBEZ/src/django/django/db/models/loading.py", line 136, in load_app
    models = import_module('%s.%s' % (app_name, MODELS_MODULE_NAME))
  File "/usr/lib/python2.7/importlib/__init__.py", line 37, in import_module
    __import__(name)
  File "/vagrant/vbenergyzone/eee_core/models/__init__.py", line 4, in <module>
    from vbenergyzone.eee_core.models.attachments import Attachment
  File "/vagrant/vbenergyzone/eee_core/models/__init__.py", line 6, in <module>
    from vbenergyzone.eee_core.models.locations import Location
  File "/vagrant/vbenergyzone/eee_core/models/locations.py", line 6, in <module>
    from django_countries import CountryField
  File "/home/vagrant/.virtualenvs/VBEZ/local/lib/python2.7/site-packages/django_countries/__init__.py", line 1, in <module>
    from django_countries.fields import CountryField
  File "/home/vagrant/.virtualenvs/VBEZ/local/lib/python2.7/site-packages/django_countries/fields.py", line 2, in <module>
    from django.utils.encoding import force_unicode, StrAndUnicode
ImportError: cannot import name StrAndUnicode
Traceback (most recent call last):
  File "manage.py", line 10, in <module>
    execute_from_command_line(sys.argv)
  File "/home/vagrant/.virtualenvs/VBEZ/src/django/django/core/management/__init__.py", line 416, in execute_from_command_line
    utility.execute()
  File "/home/vagrant/.virtualenvs/VBEZ/src/django/django/core/management/__init__.py", line 408, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/home/vagrant/.virtualenvs/VBEZ/src/django/django/core/management/__init__.py", line 288, in fetch_command
    klass = load_command_class(app_name, subcommand)
  File "/home/vagrant/.virtualenvs/VBEZ/src/django/django/core/management/__init__.py", line 78, in load_command_class
    module = import_module('%s.management.commands.%s' % (app_name, name))
  File "/usr/lib/python2.7/importlib/__init__.py", line 37, in import_module
    __import__(name)
  File "/vagrant/vbenergyzone/core/management/commands/recalculate_calculated_values.py", line 8, in <module>
    from vbenergyzone.core.models.trends_mixins import Trends_Mixin
  File "/vagrant/vbenergyzone/core/models/__init__.py", line 11, in <module>
    from vbenergyzone.core.models.contracts import Contract
  File "/vagrant/vbenergyzone/core/models/contracts.py", line 19, in <module>
    from .trends_mixins import Trends_Mixin
  File "/vagrant/vbenergyzone/core/models/trends_mixins.py", line 24, in <module>
    from ..workers import VBEZTask
  File "/vagrant/vbenergyzone/core/workers/__init__.py", line 10, in <module>
    from vbenergyzone.eee_core.models.tasks import Task
  File "/vagrant/vbenergyzone/eee_core/models/__init__.py", line 6, in <module>
    from vbenergyzone.eee_core.models.locations import Location
  File "/vagrant/vbenergyzone/eee_core/models/locations.py", line 6, in <module>
    from django_countries import CountryField
  File "/home/vagrant/.virtualenvs/VBEZ/local/lib/python2.7/site-packages/django_countries/__init__.py", line 1, in <module>
    from django_countries.fields import CountryField
  File "/home/vagrant/.virtualenvs/VBEZ/local/lib/python2.7/site-packages/django_countries/fields.py", line 2, in <module>
    from django.utils.encoding import force_unicode, StrAndUnicode
ImportError: cannot import name StrAndUnicode

comment:5 Changed 20 months ago by eevenson

I see now that StrAndUnicode was deprecated. So perhaps what is happening is that your patch fixes the original problem and I am now seeing the next thing I need to fix -- but I can't be sure until I fix this deprecation issue.

comment:6 Changed 20 months ago by bmispelon

What if you just apply that one commit on top of the 1.6 release?

To do so, install Django 1.6 as normal then go edit the file /home/vagrant/.virtualenvs/VBEZ/local/lib/python2.7/site-packages/django/dispatch/dispatcher.py to change line 88.

Instead of having if settings.DEBUG:, write if settings.configured and settings.DEBUG:.

Does that fix anything?

comment:7 Changed 20 months ago by claudep

Oh yes, sorry, the commit I gave you was on the master branch. I should have referenced https://github.com/django/django/commit/432de546113942be60089a879371073ad09fb4fe. But as Baptiste told you, you can also just change one line in dispatcher.py in a Django 1.6 installation.

comment:8 Changed 20 months ago by eevenson

I changed the one line as Baptiste suggested, and my project runs fine.

comment:9 Changed 20 months ago by claudep

  • Resolution set to duplicate
  • Status changed from new to closed

Thanks for checking, the Django 1.6.1 release will include the fix.

comment:10 Changed 20 months ago by eevenson

Excellent. I will use the commit you suggested in the meantime as it seems to work fine. Will move to 1.6.1 when it is available.

Thanks again for your help and the great tool!

Note: See TracTickets for help on using tickets.
Back to Top