Code

Opened 2 years ago

Closed 22 months ago

#18545 closed Cleanup/optimization (fixed)

Improve the error message when the implicit settings configuration fails

Reported by: ncoghlan Owned by: carljm
Component: Core (Other) Version: 1.4
Severity: Normal Keywords:
Cc: Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

Currently, the fairly generic ImportError message received when the implicit settings configuration fails has a couple of problems:

  • it doesn't mention the possibility of using django.conf.settings.configure(). The current error message suggests that an environment variable pointing to a module is the only configuration mechanism Django supports.
  • it doesn't mention *which setting* was being looked up when the implicit load failed

These combine to prevent someone that wants to use Django as a library from *incrementally* working out the minimum configuration they need to provide. Instead, they just get told "you need to provide some settings, but we're not going to give you any hints as to what settings are needed for the operations you're trying to use".

Adjusting the way the lazy initialisation is performed would go a long towards making django usable as a library - I could just start importing things, see what settings get accessed, look up those individual settings and provide appropriate values in a django.conf.settings.configure() call. With the current unhelpful error message, I have no idea where to even start.

Attachments (0)

Change History (4)

comment:1 Changed 2 years ago by lukeplant

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset
  • Triage Stage changed from Unreviewed to Accepted

This is definitely an area we could improve a lot. I don't know exactly what the solution should look like, or what solutions are feasible, but I'm accepting it on principle.

comment:2 follow-up: Changed 23 months ago by anonymous

Russell Keith-Magee and I were able to discuss this briefly at PyConAU. For the second part, it may be worth pursuing that as a general improvement to LazyObject. The trick is to avoid losing existing debugging data in the Python 2 case - in Python 3, it would be possible to just do "raise X from Y" when the init call fails to add the extra info about which attribute was being looked up without losing the original traceback, but in Python 2, raising a new exception means losing the original traceback. Perhaps it would be enough to just preserve the original error message? Is gaining the attribute name worth losing the inner part of the traceback?

The first part should be relatively straightforward, though - that's just a matter of mentioning the direct API in the error message.

(I ended up keeping busy with CPython at the sprints though, so I unfortunately never followed it up at the sprints).

comment:3 in reply to: ↑ 2 Changed 22 months ago by carljm

  • Component changed from Uncategorized to Core (Other)
  • Owner changed from nobody to carljm
  • Type changed from Uncategorized to Cleanup/optimization

Replying to anonymous:

Russell Keith-Magee and I were able to discuss this briefly at PyConAU. For the second part, it may be worth pursuing that as a general improvement to LazyObject. The trick is to avoid losing existing debugging data in the Python 2 case - in Python 3, it would be possible to just do "raise X from Y" when the init call fails to add the extra info about which attribute was being looked up without losing the original traceback, but in Python 2, raising a new exception means losing the original traceback. Perhaps it would be enough to just preserve the original error message? Is gaining the attribute name worth losing the inner part of the traceback?

I don't understand the necessity for raise X from Y in this case, or any of the associated Python 2 difficulty. All that's necessary is for LazySettings to override __getattr__ to pass the requested attribute name into _setup. I have this implemented at https://github.com/carljm/django/compare/ticket_18545

Worth noting this doesn't really help with *incrementally* figuring out the settings you need, it only helps with the very first one, since you only see this error if you've done nothing at all settings-related. Once you've called settings.configure(), if there's an additional setting you haven't set, you'll get a setting-specific error message from some other part of Django (e.g. the ORM will complain if you don't have DATABASES, the URL-resolver will complain if you have no ROOT_URLCONF, etc). But it's still marginally useful that initial time, and there's little cost, so going ahead and adding it.

Mentioning settings.configure() is of course a great idea, thanks for suggesting it.

comment:4 Changed 22 months ago by Carl Meyer <carl@…>

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

In [307706d082d20ac868654ccbaee18879db5197db]:

Fixed #18545 -- Make the 'no DJANGO_SETTINGS_MODULE' error message more useful.Thanks Nick Coghlan for the report, and Malcolm Tredinnick for review.

Add Comment

Modify Ticket

Change Properties
<Author field>
Action
as closed
as The resolution will be set. Next status will be 'closed'
The resolution will be deleted. Next status will be 'new'
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.