diff options
| author | Chris McDonough <chrism@agendaless.com> | 2009-11-19 12:45:42 +0000 |
|---|---|---|
| committer | Chris McDonough <chrism@agendaless.com> | 2009-11-19 12:45:42 +0000 |
| commit | b8270351f72ad3d348dafb7a289d1500f1c9c03e (patch) | |
| tree | 6e203eda6ee1c39b5e127ffd577d55d64cf6845f /docs/designdefense.rst | |
| parent | 6d3878066c21a710274b25ed4ce16ddce44ed686 (diff) | |
| download | pyramid-b8270351f72ad3d348dafb7a289d1500f1c9c03e.tar.gz pyramid-b8270351f72ad3d348dafb7a289d1500f1c9c03e.tar.bz2 pyramid-b8270351f72ad3d348dafb7a289d1500f1c9c03e.zip | |
Namespace packaging.
Diffstat (limited to 'docs/designdefense.rst')
| -rw-r--r-- | docs/designdefense.rst | 59 |
1 files changed, 58 insertions, 1 deletions
diff --git a/docs/designdefense.rst b/docs/designdefense.rst index 61cde6888..b51b96438 100644 --- a/docs/designdefense.rst +++ b/docs/designdefense.rst @@ -1014,7 +1014,64 @@ an application written using any other web framework. The Name BFG Is Not Safe For Work --------------------------------- -"Big Friendly Giant" is not safe for your work? Where do you work? +"Big Friendly Giant" is not safe for your work? Where do you work? ;-) + +The BFG API Isn't "Flat" +------------------------ + +The :mod:`repoze.bfg` API is organized in such a way that API imports +must come from submodules of the ``repoze.bfg`` namespace. For +instance: + +.. code-block:: python + :linenos: + + from repoze.bfg.settings import get_settings + from repoze.bfg.url import model_url + +Some folks understandably don't want to think about the submodule +organization, and would rather be able to do: + +.. code-block:: python + :linenos: + + from repoze.bfg import get_settings + from repoze.bfg import model_url + +This would indeed be nice. However, the ``repoze.bfg`` Python package +is a `namespace package <http://www.python.org/dev/peps/pep-0382/>`_. +The ``__init__.py`` of a namespace package cannot contain any +meaningful code such as imports from submodules which would let us +form a flatter API. Sorry. + +Though it makes the API slightly "thinkier", making the ``repoze.bfg`` +package into a namespace package was an early design decision, which +we believe has paid off. The primary goal is to make it possible to +move features *out* of the core ``repoze.bfg`` distribution and into +add-on distributions without breaking existing imports. The +``repoze.bfg.lxml`` distribution is an example of such a package: this +functionality used to live in the core distribution, but we later +decided that a core dependency on ``lxml`` was unacceptable. Because +``repoze.bfg`` is a namespace package, we were able to remove the +``repoze.bfg.lxml`` module from the core and create a distribution +named ``repoze.bfg.lxml`` which contains an eponymous package. We +were then able, via our changelog, to inform people that might have +been depending on the feature that although it no longer shipped in +the core distribution, they could get it back *without changing any +code* by adding an ``install_requires`` line to their application +package's ``setup.py``. + +Often new :mod:`repoze.bfg` features are released as add-on packages +in the ``repoze.bfg`` namespace. Because ``repoze.bfg`` is a +namespace package, if we want to move one of these features *in* to +the core distribition at some point, we can do so without breaking +code which imports from the older package namespace. This is +currently less useful than the ability to move features *out* of the +core distribution, as :mod:`setuptools` does not yet have any concept +of "obsoletes" metadata which we could add to the core distribution. +This means it's not yet possible to declaratively deprecate the older +non-core package in the eyes of tools like ``easy_install``, ``pip`` +and ``buildout``. Other Challenges ---------------- |
