diff options
Diffstat (limited to 'docs/designdefense.rst')
| -rw-r--r-- | docs/designdefense.rst | 77 |
1 files changed, 55 insertions, 22 deletions
diff --git a/docs/designdefense.rst b/docs/designdefense.rst index ce3c507c5..4975ae2a0 100644 --- a/docs/designdefense.rst +++ b/docs/designdefense.rst @@ -711,9 +711,9 @@ Pyramid Has Too Many Dependencies This is true. At the time of this writing, the total number of Python package distributions that :app:`Pyramid` depends upon transitively is 18 if -you use Python 2.6 or 2.7, or 16 if you use Python 2.4 or 2.5. This is a lot -more than zero package distribution dependencies: a metric which various -Python microframeworks and Django boast. +you use Python 2.6 or 2.7, or 16 if you use Python 2.5. This is a lot more +than zero package distribution dependencies: a metric which various Python +microframeworks and Django boast. The :mod:`zope.component` and :mod:`zope.configuration` packages on which :app:`Pyramid` depends have transitive dependencies on several other packages @@ -1125,10 +1125,11 @@ Self-described "microframeworks" exist: `Bottle <http://bottle.paws.de>`_ and <http://bobo.digicool.com/>`_ doesn't describe itself as a microframework, but its intended userbase is much the same. Many others exist. We've actually even (only as a teaching tool, not as any sort of official project) -`created one using BFG <http://bfg.repoze.org/videos#groundhog1>`_ (the -precursor to Pyramid). Microframeworks are small frameworks with one common -feature: each allows its users to create a fully functional application that -lives in a single Python file. +`created one using Pyramid <http://bfg.repoze.org/videos#groundhog1>`_ (the +videos use BFG, a precursor to Pyramid, but the resulting code is `available +for Pyramid too <http://github.com/Pylons/groundhog>`_). Microframeworks are +small frameworks with one common feature: each allows its users to create a +fully functional application that lives in a single Python file. Some developers and microframework authors point out that Pyramid's "hello world" single-file program is longer (by about five lines) than the @@ -1394,8 +1395,8 @@ predictability. a registry in another module. This has the effect that double-registrations will never be performed. -Routes (Usually) Need Relative Ordering -+++++++++++++++++++++++++++++++++++++++ +Routes Need Relative Ordering ++++++++++++++++++++++++++++++ Consider the following simple `Groundhog <https://github.com/Pylons/groundhog>`_ application: @@ -1470,20 +1471,52 @@ the view associated with the ``/:action`` routing pattern will be invoked: it matches first. A 404 error is raised. This is not what we wanted; it just happened due to the order in which we defined our view functions. -You may be willing to maintain an ordering of your view functions which -reifies your routing policy. Your application may be small enough where this -will never cause an issue. If it becomes large enough to matter, however, I -don't envy you. Maintaining that ordering as your application grows larger -will be difficult. At some point, you will also need to start controlling -*import* ordering as well as function definition ordering. When your -application grows beyond the size of a single file, and when decorators are -used to register views, the non-``__main__`` modules which contain -configuration decorators must be imported somehow for their configuration to -be executed. - -Does that make you a little uncomfortable? It should, because +This is because "Groundhog" routes are added to the routing map in import +order, and matched in the same order when a request comes in. Bottle, like +Groundhog, as of this writing, matches routes in the order in which they're +defined at Python execution time. Flask, on the other hand, does not order +route matching based on import order; it reorders the routes you add to your +application based on their "complexity". Other microframeworks have varying +strategies to do route ordering. + +Your application may be small enough where route ordering will never cause an +issue. If your application becomes large enough, however, being able to +specify or predict that ordering as your application grows larger will be +difficult. At some point, you will likely need to more explicitly start +controlling route ordering, especially in applications that require +extensibility. + +If your microframework orders route matching based on "complexity", you'll +need to understand what that "complexity" ordering is and attempt to inject a +"less complex" route to have it get matched before any "more complex" one to +ensure that it's tried first. + +If your microframework orders its route matching based on relative +import/execution of function decorator definitions, you will need to ensure +you execute all of these statements in the "right" order, and you'll need to +be cognizant of this import/execution ordering as you grow your application +or try to extend it. This is a difficult invariant to maintain for all but +the smallest applications. + +In either case, your application must import the non-``__main__`` modules +which contain configuration decorations somehow for their configuration to be +executed. Does that make you a little uncomfortable? It should, because :ref:`you_dont_own_modulescope`. +Pyramid uses neither decorator import time ordering nor does it attempt to +divine the relative "complexity" of one route to another in order to define a +route match ordering. In Pyramid, you have to maintain relative route +ordering imperatively via the chronology of multiple executions of the +:meth:`pyramid.config.Configurator.add_route` method. The order in which you +repeatedly call ``add_route`` becomes the order of route matching. + +If needing to maintain this imperative ordering truly bugs you, you can use +:term:`traversal` instead of route matching, which is a completely +declarative (and completely predictable) mechanism to map code to URLs. +While URL dispatch is easier to understand for small non-extensible +applications, traversal is a great fit for very large applications and +applications that need to be arbitrarily extensible. + "Stacked Object Proxies" Are Too Clever / Thread Locals Are A Nuisance ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @@ -1728,7 +1761,7 @@ If you can understand this hello world program, you can use Pyramid: Pyramid has ~ 650 pages of documentation (printed), covering topics from the very basic to the most advanced. *Nothing* is left undocumented, quite literally. It also has an *awesome*, very helpful community. Visit the -#repoze and/or #pylons IRC channels on freenode.net and see. +#pyramid and/or #pylons IRC channels on freenode.net and see. Hate Zope +++++++++ |
