On Oct 13, 3:10 am, Benjamin Slavin <benjamin.sla...@gmail.com> wrote: > There really is no such thing as "INSTALLED_APPS loading". I think > you mean "model loading"... if so, it's not quite so simple. Maybe > there's a way to make this approach work, but it's at least not as > easy as "let's just add these two settings".
I'm referring to the following code in Settings.__init__(): # Expand entries in INSTALLED_APPS like "django.contrib.*" to a list # of all those apps. new_installed_apps = [] for app in self.INSTALLED_APPS: if app.endswith('.*'): app_mod = importlib.import_module(app[:-2]) appdir = os.path.dirname(app_mod.__file__) app_subdirs = os.listdir(appdir) app_subdirs.sort() name_pattern = re.compile(r'[a-zA-Z]\w*') for d in app_subdirs: if name_pattern.match(d) and os.path.isdir(os.path.join (appdir, d)): new_installed_apps.append('%s.%s' % (app[:-2], d)) else: new_installed_apps.append(app) self.INSTALLED_APPS = new_installed_apps I know it was sloppy of me to call it "INSTALLED_APPS loading" as that happens in db/models/loading.py - I thought it would be clear from my saying I was talking about calling from Settings.__init__(). > The big offender here is that __import__ (and thus "import ..." and > "from ... import ...") has consequences. Models are initialized the > first time the Python interpreter sees them. I'll illustrate why this > is a problem through an example: > > Lets say you have myapp/bootstrap.py and bootstrap.py does an import > (from myapp.views import some_signal_i_care_about) and myapp.views > imports myapp.models. Right there... with two seemingly innocuous > imports, we've broken the contract that the environment is pristine. Yes, but that's also true if you just try to import models or some other django modules in settings.py. I thought I covered this by saying "Obviously the callables would be restricted in what they could do, but it need be no worse than the restrictions on e.g. what you can import in settings.py". Aren't we talking about the same thing - having to work with how model loading is done? Certainly for the logging configuration and other configuration which isn't model-dependent, where is the problem? I agree this limitation would need to be well documented and perhaps have better error reporting. > Now, if we register a listener for class_prepared, it will never* get > called for anything in myapp.models, or anything imported there. (* > From memory... this is true unless there's a deferred processing of a > model relationship, in which case it's even harder to predict the > outcome) > > So, given the current state of affairs it goes beyond just "what they > could do" to "what could be imported". Even a stray import in an > __init__.py could create a series of problems. That is why I specifically appended "but it need be no worse than the restrictions on e.g. what you can import in settings.py" to "what they could do". Perhaps I should have specifically referred to "imports made from code imported and called from settings.py", but I thought that would be evident. > If we're building a bootstrapping system, it's likely possible to > introduce some additional logic into the metaclass approach that > models use, and work around this case.... but it's non-trivial. I'm not quite sure what you're suggesting here - work around what? Importing problems in settings.py? Before I knew better, I once did from django.db.backends.utils import CursorDebugWrapper in settings.py, which seems innocuous and appears not to be model- dependent in any way, and yet it gave an error: "Error: Can't find the file 'settings.py' in the directory containing './manage.py'. It appears you've customized things. You'll have to run django-admin.py, passing it your settings module. (If the file settings.py does indeed exist, it's causing an ImportError somehow.)" We could certainly do with better error messages in such cases. I'm not saying the approach I suggested was a complete fix for all the problems people might have. But it seems to cover at least the use case Simon started this thread with (logging configuration) in a way that gives the user control over if and when and how logging gets configured, early-ish in the game. It might apply to other types of site-wide configuration, too. Regards, Vinay Sajip --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Django developers" group. To post to this group, send email to django-developers@googlegroups.com To unsubscribe from this group, send email to django-developers+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/django-developers?hl=en -~----------~----~----~----~------~----~------~--~---