Monday, February 23, 2009

Django Contrib

Jacob Kaplan-Moss wrote very good post on the purpose of django.contrib. For those unfamiliar with the Django project, django.contrib is a tightly managed, highly used collection of modules (packages in Python). Contrib is not quite Django core, but much more part of Django than the free-for-all of shared re-usable applications.

The reason why I find this interesting is that many open source projects struggle with the balance between the benefits and risks of maintaining a low bar to contribution. The generally adopted policy is to keep core development within a small trusted group of "committers" (who can commit their own and patches by others that they have reviewed) and then open up module development to rest of the world. What usually happens is that modules can be highly redundant and inconsistent on quality. Add-on modules are typically the greatest cause for system instability and insecurity and the most difficult to upgrade. But they are still great because they are code that you don't need to write. Drupal, with its explosive community growth, struggles with this balance. Drupal developers often find that it is easier to write a module than to find one that is well written and does what you need it to do. Yes, there are Drupal modules that rise to the top and eventually get included into the core (Views, CCK, etc.), but they are rare. Sometimes there are random reversals - remember when CCK overtook flexinode?. The rest churn in the rough and tumble Contributed Modules library. Other projects have these issue, Drupal's growth and scale just make it more visible. Typo3 had a rating system ("no cigar" through "Cohiba") but the initiative fizzled.

Back to Jacob and django.contrib... Contrib is a very important resource for the Django community. The packages there are widely used and considered (by many) as good as core Django code. If a developer finds a module he needs in contrib, he will use it rather than any other comparable module he finds elsewhere. Contrib modules are actively maintained and are tested against new versions of the core. They are "sanctioned" not just for what they do but how they are built. In his post, Jacob recognizes the impact of incorporating a package into contrib and tries to clarify what incorporation means. Jacob proposes three tests to determine whether a package gets into contrib: the functionality should be optional (that is Django won't break if you delete contrib from your system), it solves a common problem, and it exemplifies generally accepted best practices.

Jacob also writes that contrib packages should conform to the same standards and guidelines for the general module population. For example, they shouldn't access Django's "brittle internals" (that is, functionality not wrapped in an API that may change without warning). The rest of the post goes through examples of packages that should or not be in contrib according to his tests.

I think more projects should have a system like django.contrib or at least have an open discussion around what makes a preferred module. As Typo3 found, it is hard to instate one after the catalog of modules (and community of developers) has grown beyond a certain size. Putting the best modules into core carries the risk of bloating the core application with functionality that not everyone needs. The various Linux distributions that have package managers are able to put preferred modules in their package library (accessible through tools like port and yum). The last resort, which is where most big projects are, is to have a good network of developers and do your research from word of mouth.