Wednesday, March 31, 2010

Ways Django Can Import Things

How many ways can django import a module?

Grep is hard for this.

In .py files

"import (.*)\..*"
"from (.*)\..* import .*"
"patterns\(['"](.*)['"]"
"url(r?['"].*, ['"](.*)"


In INSTALLED_APPS and other settings.

Am I missing any? Better question: Why do I have to wonder if I'm missing any?

5 comments:

Doug Napoleone said...

You forgot about the magic __path__ hack done to the templatetags 'package' directory. It turns out that app.templatetags.app and django.templtatetags.app are two DIFFERENT imports of the same code and are independent modules with their own globals and locals...

Think about that for a while...

James Bennett said...

You did actually miss one: django.utils.importlib, which is simply a copy of the available-in-future-Python importlib module that Brett Cannon helpfully backported for us to handle all the things in Django (think pluggable backend modules) which require dynamic imports. Previously we used Python's raw __import__ for that, and importlib makes it ever so much simpler, and generally they have to in order to support the sort of dynamic-but-still-concise stuff people like to do in Python.

Anyway, two of the things you've listed are just standard Python import statements, and the other two are just URL-pattern functions which -- if it bugs you that much -- will happily accept the actual callable (or an iterable of patterns, in the case of include()) instead of strings. The string option is mostly just a convenience.

So I'm not sure I really understand the "why do I have to wonder if I'm missing any"; lots of frameworks/libraries have ways to specify something as a string and get it dynamically imported later through some mechanism other than a direct "import whatever" statement.

Oh, and for Doug: the __path__ hacking for templatetags is finally gone in trunk, which means it won't be in 1.2. The last bit of "magic" from magic-removal is finally out, hallelujah.

Graham Dumpleton said...

Not sure if it is what you were intent on capturing, but there is the import of the Django settings file as a special sort of case. I recently posted some stuff about that at http://blog.dscpl.com.au/2010/03/improved-wsgi-script-for-use-with.html.

James said...

__import__( ... )

Robert said...

Wouldn't it be nice to standardize these 'import later module strings'* that various python frameworks have as some sort of generic-ized deferredimport('some.python.path.etc') object?

*: which are sometimes necessary due to definition order and cyclic dependencies etc.

I write here about programming, how to program better, things I think are neat and are related to programming. I might write other things at my personal website.

I am happily employed by the excellent Caktus Group, located in beautiful and friendly Carrboro, NC, where I work with Python, Django, and Javascript.