On Thu, Jan 29, 2015 at 9:55 AM, Jonathan Vanasco <
jona...@findmeon.com> wrote:
> They don't actually differ at all. There is really only one "Predicate"
> object with a specified behavior. As the docs say "You can use the same
> predicate factory as both a view predicate and as a route predicate." So
> they're really the same thing - a PredicateFactory - just invoked in a
> different context. The Predicate factories work identical and can be used in
> either context.
This actually isn't true. I'm having trouble finding the docs you've
referenced. They solve different problems but have a very similar api
and semantics.
Pyramid matches a url in 3 steps.
1) Find a matching route.
2) Find a context.
3) Find a view.
When matching a route, the first one that matches wins and if it
doesn't match then we continue in order to the next route in the list,
and see if it matches. Predicates, and the pattern, control whether
this is the route we will use. This predicate receives "info" and
"request" objects. It is "info" because the route is not matched yet,
so you cannot inspect request.matchdict. You can only inspect
info['match'].
http://docs.pylonsproject.org/docs/pyramid/en/latest/narr/urldispatch.html#custom-route-predicates
We aren't really talking about matching a context here so don't worry about it.
When finding a view we now know the route and the context. So the
predicate receives a "context" and "request". They follow basically
the same api because most of the default predicates do not need the
first argument and only bother inspecting the request.
There may even be some bugs here in Pyramid but this is how it works.
Feel free to open any issues.
The route predicates are useful if you have potentially conflicting
routes like '/{catchall:.*}' and '/foo'. You can either re-order the
routes so foo is tested first, or you can add a predicate to the
catchall route requiring the info['match']['catchall'] != 'foo'.
Things escalate in complexity from there.
Most of the time, however, you are thinking about multiple views
attached to a route. Such as request_method='GET' vs
request_method='POST'. Your first instinct may be to attach these to
different routes but then the route name must be different per route.
So instead you have the route match and then add the predicates to the
view.