ó
¨œž[c           @` s  d  Z  d d l m Z m Z m Z d d l Z d d l m Z d d l m	 Z	 d d l
 m Z d d l m Z m Z m Z d d l m Z d d	 l m Z m Z m Z m Z y d d l Z Wn e k
 rÏ n Xd
 e	 j f d „  ƒ  YZ d e f d „  ƒ  YZ d e	 j f d „  ƒ  YZ d e	 j f d „  ƒ  YZ d e f d „  ƒ  YZ d e e f d „  ƒ  YZ  d e! f d „  ƒ  YZ" d e! f d „  ƒ  YZ# d e# f d „  ƒ  YZ$ d e# f d „  ƒ  YZ% d e# f d „  ƒ  YZ& d  e# f d! „  ƒ  YZ' d" e" f d# „  ƒ  YZ( d$ „  Z) d S(%   sq  Flexible routing implementation.

Tornado routes HTTP requests to appropriate handlers using `Router`
class implementations. The `tornado.web.Application` class is a
`Router` implementation and may be used directly, or the classes in
this module may be used for additional flexibility. The `RuleRouter`
class can match on more criteria than `.Application`, or the `Router`
interface can be subclassed for maximum customization.

`Router` interface extends `~.httputil.HTTPServerConnectionDelegate`
to provide additional routing capabilities. This also means that any
`Router` implementation can be used directly as a ``request_callback``
for `~.httpserver.HTTPServer` constructor.

`Router` subclass must implement a ``find_handler`` method to provide
a suitable `~.httputil.HTTPMessageDelegate` instance to handle the
request:

.. code-block:: python

    class CustomRouter(Router):
        def find_handler(self, request, **kwargs):
            # some routing logic providing a suitable HTTPMessageDelegate instance
            return MessageDelegate(request.connection)

    class MessageDelegate(HTTPMessageDelegate):
        def __init__(self, connection):
            self.connection = connection

        def finish(self):
            self.connection.write_headers(
                ResponseStartLine("HTTP/1.1", 200, "OK"),
                HTTPHeaders({"Content-Length": "2"}),
                b"OK")
            self.connection.finish()

    router = CustomRouter()
    server = HTTPServer(router)

The main responsibility of `Router` implementation is to provide a
mapping from a request to `~.httputil.HTTPMessageDelegate` instance
that will handle this request. In the example above we can see that
routing is possible even without instantiating an `~.web.Application`.

For routing to `~.web.RequestHandler` implementations we need an
`~.web.Application` instance. `~.web.Application.get_handler_delegate`
provides a convenient way to create `~.httputil.HTTPMessageDelegate`
for a given request and `~.web.RequestHandler`.

Here is a simple example of how we can we route to
`~.web.RequestHandler` subclasses by HTTP method:

.. code-block:: python

    resources = {}

    class GetResource(RequestHandler):
        def get(self, path):
            if path not in resources:
                raise HTTPError(404)

            self.finish(resources[path])

    class PostResource(RequestHandler):
        def post(self, path):
            resources[path] = self.request.body

    class HTTPMethodRouter(Router):
        def __init__(self, app):
            self.app = app

        def find_handler(self, request, **kwargs):
            handler = GetResource if request.method == "GET" else PostResource
            return self.app.get_handler_delegate(request, handler, path_args=[request.path])

    router = HTTPMethodRouter(Application())
    server = HTTPServer(router)

`ReversibleRouter` interface adds the ability to distinguish between
the routes and reverse them to the original urls using route's name
and additional arguments. `~.web.Application` is itself an
implementation of `ReversibleRouter` class.

`RuleRouter` and `ReversibleRuleRouter` are implementations of
`Router` and `ReversibleRouter` interfaces and can be used for
creating rule-based routing configurations.

Rules are instances of `Rule` class. They contain a `Matcher`, which
provides the logic for determining whether the rule is a match for a
particular request and a target, which can be one of the following.

1) An instance of `~.httputil.HTTPServerConnectionDelegate`:

.. code-block:: python

    router = RuleRouter([
        Rule(PathMatches("/handler"), ConnectionDelegate()),
        # ... more rules
    ])

    class ConnectionDelegate(HTTPServerConnectionDelegate):
        def start_request(self, server_conn, request_conn):
            return MessageDelegate(request_conn)

2) A callable accepting a single argument of `~.httputil.HTTPServerRequest` type:

.. code-block:: python

    router = RuleRouter([
        Rule(PathMatches("/callable"), request_callable)
    ])

    def request_callable(request):
        request.write(b"HTTP/1.1 200 OK\r\nContent-Length: 2\r\n\r\nOK")
        request.finish()

3) Another `Router` instance:

.. code-block:: python

    router = RuleRouter([
        Rule(PathMatches("/router.*"), CustomRouter())
    ])

Of course a nested `RuleRouter` or a `~.web.Application` is allowed:

.. code-block:: python

    router = RuleRouter([
        Rule(HostMatches("example.com"), RuleRouter([
            Rule(PathMatches("/app1/.*"), Application([(r"/app1/handler", Handler)]))),
        ]))
    ])

    server = HTTPServer(router)

In the example below `RuleRouter` is used to route between applications:

.. code-block:: python

    app1 = Application([
        (r"/app1/handler", Handler1),
        # other handlers ...
    ])

    app2 = Application([
        (r"/app2/handler", Handler2),
        # other handlers ...
    ])

    router = RuleRouter([
        Rule(PathMatches("/app1.*"), app1),
        Rule(PathMatches("/app2.*"), app2)
    ])

    server = HTTPServer(router)

For more information on application-level routing see docs for `~.web.Application`.

.. versionadded:: 4.5

i    (   t   absolute_importt   divisiont   print_functionN(   t   partial(   t   httputil(   t   _CallableAdapter(   t
   url_escapet   url_unescapet   utf8(   t   app_log(   t   basestring_typet   import_objectt   re_unescapet   unicode_typet   Routerc           B` s    e  Z d  Z d „  Z d „  Z RS(   s   Abstract router interface.c         K` s   t  ƒ  ‚ d S(   sò  Must be implemented to return an appropriate instance of `~.httputil.HTTPMessageDelegate`
        that can serve the request.
        Routing implementations may pass additional kwargs to extend the routing logic.

        :arg httputil.HTTPServerRequest request: current HTTP request.
        :arg kwargs: additional keyword arguments passed by routing implementation.
        :returns: an instance of `~.httputil.HTTPMessageDelegate` that will be used to
            process the request.
        N(   t   NotImplementedError(   t   selft   requestt   kwargs(    (    s.   lib/python2.7/site-packages/tornado/routing.pyt   find_handlerÆ   s    c         C` s   t  |  | | ƒ S(   N(   t   _RoutingDelegate(   R   t   server_connt   request_conn(    (    s.   lib/python2.7/site-packages/tornado/routing.pyt   start_requestÓ   s    (   t   __name__t
   __module__t   __doc__R   R   (    (    (    s.   lib/python2.7/site-packages/tornado/routing.pyR   Ã   s   	t   ReversibleRouterc           B` s   e  Z d  Z d „  Z RS(   sx   Abstract router interface for routers that can handle named routes
    and support reversing them to original urls.
    c         G` s   t  ƒ  ‚ d S(   s  Returns url string for a given route name and arguments
        or ``None`` if no match is found.

        :arg str name: route name.
        :arg args: url parameters.
        :returns: parametrized url string for a given route name (or ``None``).
        N(   R   (   R   t   namet   args(    (    s.   lib/python2.7/site-packages/tornado/routing.pyt   reverse_urlÜ   s    (   R   R   R   R   (    (    (    s.   lib/python2.7/site-packages/tornado/routing.pyR   ×   s   R   c           B` s5   e  Z d  „  Z d „  Z d „  Z d „  Z d „  Z RS(   c         C` s(   | |  _  | |  _ d  |  _ | |  _ d  S(   N(   R   R   t   Nonet   delegatet   router(   R   R!   R   R   (    (    s.   lib/python2.7/site-packages/tornado/routing.pyt   __init__è   s    			c      	   C` s   t  j d |  j d |  j d | d | ƒ } |  j j | ƒ |  _ |  j d  k r| t j	 d | j
 | j ƒ t |  j ƒ |  _ n  |  j j | | ƒ S(   Nt
   connectiont   server_connectiont
   start_linet   headerss$   Delegate for %s %s request not found(   R   t   HTTPServerRequestR   R   R!   R   R    R   R	   t   debugt   methodt   patht   _DefaultMessageDelegatet   headers_received(   R   R%   R&   R   (    (    s.   lib/python2.7/site-packages/tornado/routing.pyR,   î   s    				c         C` s   |  j  j | ƒ S(   N(   R    t   data_received(   R   t   chunk(    (    s.   lib/python2.7/site-packages/tornado/routing.pyR-   ü   s    c         C` s   |  j  j ƒ  d  S(   N(   R    t   finish(   R   (    (    s.   lib/python2.7/site-packages/tornado/routing.pyR/   ÿ   s    c         C` s   |  j  j ƒ  d  S(   N(   R    t   on_connection_close(   R   (    (    s.   lib/python2.7/site-packages/tornado/routing.pyR0     s    (   R   R   R"   R,   R-   R/   R0   (    (    (    s.   lib/python2.7/site-packages/tornado/routing.pyR   ç   s
   				R+   c           B` s   e  Z d  „  Z d „  Z RS(   c         C` s   | |  _  d  S(   N(   R#   (   R   R#   (    (    s.   lib/python2.7/site-packages/tornado/routing.pyR"     s    c         C` s9   |  j  j t j d d d ƒ t j ƒ  ƒ |  j  j ƒ  d  S(   Ns   HTTP/1.1i”  s	   Not Found(   R#   t   write_headersR   t   ResponseStartLinet   HTTPHeadersR/   (   R   (    (    s.   lib/python2.7/site-packages/tornado/routing.pyR/   
  s    	(   R   R   R"   R/   (    (    (    s.   lib/python2.7/site-packages/tornado/routing.pyR+     s   	t
   RuleRouterc           B` s>   e  Z d  Z d d „ Z d „  Z d „  Z d „  Z d „  Z RS(   s!   Rule-based router implementation.c         C` s#   g  |  _  | r |  j | ƒ n  d S(   sI  Constructs a router from an ordered list of rules::

            RuleRouter([
                Rule(PathMatches("/handler"), Target),
                # ... more rules
            ])

        You can also omit explicit `Rule` constructor and use tuples of arguments::

            RuleRouter([
                (PathMatches("/handler"), Target),
            ])

        `PathMatches` is a default matcher, so the example above can be simplified::

            RuleRouter([
                ("/handler", Target),
            ])

        In the examples above, ``Target`` can be a nested `Router` instance, an instance of
        `~.httputil.HTTPServerConnectionDelegate` or an old-style callable,
        accepting a request argument.

        :arg rules: a list of `Rule` instances or tuples of `Rule`
            constructor arguments.
        N(   t   rulest	   add_rules(   R   R5   (    (    s.   lib/python2.7/site-packages/tornado/routing.pyR"     s    	c         C` s   x– | D]Ž } t  | t t f ƒ r| t | ƒ d k s: t ‚ t  | d t ƒ rm t t | d ƒ | d Œ } q| t | Œ  } n  |  j j	 |  j
 | ƒ ƒ q Wd S(   s£   Appends new rules to the router.

        :arg rules: a list of Rule instances (or tuples of arguments, which are
            passed to Rule constructor).
        i   i   i   i    i   N(   i   i   i   (   t
   isinstancet   tuplet   listt   lent   AssertionErrorR
   t   Rulet   PathMatchesR5   t   appendt   process_rule(   R   R5   t   rule(    (    s.   lib/python2.7/site-packages/tornado/routing.pyR6   2  s     c         C` s   | S(   s¯   Override this method for additional preprocessing of each rule.

        :arg Rule rule: a rule to be processed.
        :returns: the same or modified Rule instance.
        (    (   R   R@   (    (    s.   lib/python2.7/site-packages/tornado/routing.pyR?   B  s    c         K` sz   xs |  j  D]h } | j j | ƒ } | d  k	 r
 | j rG | j | d <n  |  j | j | |  } | d  k	 rr | Sq
 q
 Wd  S(   Nt   target_kwargs(   R5   t   matchert   matchR   RA   t   get_target_delegatet   target(   R   R   R   R@   t   target_paramsR    (    (    s.   lib/python2.7/site-packages/tornado/routing.pyR   J  s    	c         K` sp   t  | t ƒ r | j | |  St  | t j ƒ rG | j | j | j ƒ St | ƒ rl t	 t
 | |  | j ƒ Sd S(   s°  Returns an instance of `~.httputil.HTTPMessageDelegate` for a
        Rule's target. This method is called by `~.find_handler` and can be
        extended to provide additional target types.

        :arg target: a Rule's target.
        :arg httputil.HTTPServerRequest request: current request.
        :arg target_params: additional parameters that can be useful
            for `~.httputil.HTTPMessageDelegate` creation.
        N(   R7   R   R   R   t   HTTPServerConnectionDelegateR   R$   R#   t   callableR   R   R   (   R   RE   R   RF   (    (    s.   lib/python2.7/site-packages/tornado/routing.pyRD   Y  s    
N(	   R   R   R   R   R"   R6   R?   R   RD   (    (    (    s.   lib/python2.7/site-packages/tornado/routing.pyR4     s   			t   ReversibleRuleRouterc           B` s,   e  Z d  Z d d „ Z d „  Z d „  Z RS(   s  A rule-based router that implements ``reverse_url`` method.

    Each rule added to this router may have a ``name`` attribute that can be
    used to reconstruct an original uri. The actual reconstruction takes place
    in a rule's matcher (see `Matcher.reverse`).
    c         C` s#   i  |  _  t t |  ƒ j | ƒ d  S(   N(   t   named_rulest   superRI   R"   (   R   R5   (    (    s.   lib/python2.7/site-packages/tornado/routing.pyR"   y  s    	c         C` s`   t  t |  ƒ j | ƒ } | j r\ | j |  j k rI t j d | j ƒ n  | |  j | j <n  | S(   Ns4   Multiple handlers named %s; replacing previous value(   RK   RI   R?   R   RJ   R	   t   warning(   R   R@   (    (    s.   lib/python2.7/site-packages/tornado/routing.pyR?   }  s    	c         G` sx   | |  j  k r& |  j  | j j | Œ  SxK |  j D]@ } t | j t ƒ r0 | j j | | Œ } | d  k	 rp | Sq0 q0 Wd  S(   N(	   RJ   RB   t   reverseR5   R7   RE   R   R   R   (   R   R   R   R@   t   reversed_url(    (    s.   lib/python2.7/site-packages/tornado/routing.pyR   ‰  s    N(   R   R   R   R   R"   R?   R   (    (    (    s.   lib/python2.7/site-packages/tornado/routing.pyRI   q  s   	R<   c           B` s/   e  Z d  Z d d d „ Z d „  Z d „  Z RS(   s   A routing rule.c         C` sR   t  | t ƒ r t | ƒ } n  | |  _ | |  _ | r< | n i  |  _ | |  _ d S(   sd  Constructs a Rule instance.

        :arg Matcher matcher: a `Matcher` instance used for determining
            whether the rule should be considered a match for a specific
            request.
        :arg target: a Rule's target (typically a ``RequestHandler`` or
            `~.httputil.HTTPServerConnectionDelegate` subclass or even a nested `Router`,
            depending on routing implementation).
        :arg dict target_kwargs: a dict of parameters that can be useful
            at the moment of target instantiation (for example, ``status_code``
            for a ``RequestHandler`` subclass). They end up in
            ``target_params['target_kwargs']`` of `RuleRouter.get_target_delegate`
            method.
        :arg str name: the name of the rule that can be used to find it
            in `ReversibleRouter.reverse_url` implementation.
        N(   R7   t   strR   RB   RE   RA   R   (   R   RB   RE   RA   R   (    (    s.   lib/python2.7/site-packages/tornado/routing.pyR"   ™  s    		c         G` s   |  j  j | Œ  S(   N(   RB   RM   (   R   R   (    (    s.   lib/python2.7/site-packages/tornado/routing.pyRM   ´  s    c         C` s)   d |  j  j |  j |  j |  j |  j f S(   Ns   %s(%r, %s, kwargs=%r, name=%r)(   t	   __class__R   RB   RE   RA   R   (   R   (    (    s.   lib/python2.7/site-packages/tornado/routing.pyt   __repr__·  s    N(   R   R   R   R   R"   RM   RQ   (    (    (    s.   lib/python2.7/site-packages/tornado/routing.pyR<   –  s   	t   Matcherc           B` s    e  Z d  Z d „  Z d „  Z RS(   s*   Represents a matcher for request features.c         C` s   t  ƒ  ‚ d S(   s1  Matches current instance against the request.

        :arg httputil.HTTPServerRequest request: current HTTP request
        :returns: a dict of parameters to be passed to the target handler
            (for example, ``handler_kwargs``, ``path_args``, ``path_kwargs``
            can be passed for proper `~.web.RequestHandler` instantiation).
            An empty dict is a valid (and common) return value to indicate a match
            when the argument-passing features are not used.
            ``None`` must be returned to indicate that there is no match.N(   R   (   R   R   (    (    s.   lib/python2.7/site-packages/tornado/routing.pyRC   À  s    
c         G` s   d S(   sE   Reconstructs full url from matcher instance and additional arguments.N(   R   (   R   R   (    (    s.   lib/python2.7/site-packages/tornado/routing.pyRM   Ì  s    (   R   R   R   RC   RM   (    (    (    s.   lib/python2.7/site-packages/tornado/routing.pyRR   ½  s   	t
   AnyMatchesc           B` s   e  Z d  Z d „  Z RS(   s   Matches any request.c         C` s   i  S(   N(    (   R   R   (    (    s.   lib/python2.7/site-packages/tornado/routing.pyRC   Ô  s    (   R   R   R   RC   (    (    (    s.   lib/python2.7/site-packages/tornado/routing.pyRS   Ñ  s   t   HostMatchesc           B` s    e  Z d  Z d „  Z d „  Z RS(   s@   Matches requests from hosts specified by ``host_pattern`` regex.c         C` sM   t  | t ƒ r@ | j d ƒ s+ | d 7} n  t j | ƒ |  _ n	 | |  _ d  S(   Nt   $(   R7   R
   t   endswitht   ret   compilet   host_pattern(   R   RY   (    (    s.   lib/python2.7/site-packages/tornado/routing.pyR"   Û  s
    c         C` s   |  j  j | j ƒ r i  Sd  S(   N(   RY   RC   t	   host_nameR   (   R   R   (    (    s.   lib/python2.7/site-packages/tornado/routing.pyRC   ã  s    (   R   R   R   R"   RC   (    (    (    s.   lib/python2.7/site-packages/tornado/routing.pyRT   Ø  s   	t   DefaultHostMatchesc           B` s    e  Z d  Z d „  Z d „  Z RS(   sŒ   Matches requests from host that is equal to application's default_host.
    Always returns no match if ``X-Real-Ip`` header is present.
    c         C` s   | |  _  | |  _ d  S(   N(   t   applicationRY   (   R   R\   RY   (    (    s.   lib/python2.7/site-packages/tornado/routing.pyR"   ï  s    	c         C` s2   d | j  k r. |  j j |  j j ƒ r. i  Sn  d  S(   Ns	   X-Real-Ip(   R&   RY   RC   R\   t   default_hostR   (   R   R   (    (    s.   lib/python2.7/site-packages/tornado/routing.pyRC   ó  s    (   R   R   R   R"   RC   (    (    (    s.   lib/python2.7/site-packages/tornado/routing.pyR[   ê  s   	R=   c           B` s2   e  Z d  Z d „  Z d „  Z d „  Z d „  Z RS(   s@   Matches requests with paths specified by ``path_pattern`` regex.c         C` sŸ   t  | t ƒ r@ | j d ƒ s+ | d 7} n  t j | ƒ |  _ n	 | |  _ t |  j j ƒ d |  j j f k sƒ t	 d |  j j
 ƒ ‚ |  j ƒ  \ |  _ |  _ d  S(   NRU   i    sD   groups in url regexes must either be all named or all positional: %r(   R7   R
   RV   RW   RX   t   regexR:   t
   groupindext   groupsR;   t   patternt   _find_groupst   _patht   _group_count(   R   t   path_pattern(    (    s.   lib/python2.7/site-packages/tornado/routing.pyR"   þ  s    	'c         C` s«   |  j  j | j ƒ } | d  k r% d  S|  j  j s5 i  Sg  i  } } |  j  j rs t d „  | j ƒ  j ƒ  Dƒ ƒ } n% g  | j ƒ  D] } t	 | ƒ ^ q€ } t d | d | ƒ S(   Nc         s` s-   |  ]# \ } } t  | ƒ t | ƒ f Vq d  S(   N(   RO   t   _unquote_or_none(   t   .0t   kt   v(    (    s.   lib/python2.7/site-packages/tornado/routing.pys	   <genexpr>  s   t	   path_argst   path_kwargs(
   R^   RC   R*   R   R`   R_   t   dictt	   groupdictt   itemsRf   (   R   R   RC   Rj   Rk   t   s(    (    s.   lib/python2.7/site-packages/tornado/routing.pyRC     s    %c         G` sÇ   |  j  d  k r( t d |  j j ƒ ‚ n  t | ƒ |  j k sI t d ƒ ‚ t | ƒ s\ |  j  Sg  } xQ | D]I } t | t	 t
 f ƒ s“ t | ƒ } n  | j t t | ƒ d t ƒƒ qi W|  j  t | ƒ S(   Ns   Cannot reverse url regex s&   required number of arguments not foundt   plus(   Rc   R   t
   ValueErrorR^   Ra   R:   Rd   R;   R7   R   t   bytesRO   R>   R   R   t   FalseR8   (   R   R   t   converted_argst   a(    (    s.   lib/python2.7/site-packages/tornado/routing.pyRM   "  s    !#c         C` s  |  j  j } | j d ƒ r( | d } n  | j d ƒ rD | d  } n  |  j  j | j d ƒ k rc d Sg  } x | j d ƒ D]~ } d | k rÅ | j d ƒ } | d k r÷ | j	 d | | d ƒ q÷ qy y t
 | ƒ } Wn t k
 ré d SX| j	 | ƒ qy Wd	 j | ƒ |  j  j f S(   s¶   Returns a tuple (reverse string, group count) for a url.

        For example: Given the url pattern /([0-9]{4})/([a-z-]+)/, this method
        would return ('/%s/%s/', 2).
        t   ^i   RU   iÿÿÿÿt   (t   )i    s   %st    N(   NN(   NN(   R^   Ra   t
   startswithRV   R`   t   countR   t   splitt   indexR>   R   Rq   t   join(   R   Ra   t   piecest   fragmentt	   paren_loct   unescaped_fragment(    (    s.   lib/python2.7/site-packages/tornado/routing.pyRb   0  s&    (   R   R   R   R"   RC   RM   Rb   (    (    (    s.   lib/python2.7/site-packages/tornado/routing.pyR=   û  s
   			t   URLSpecc           B` s&   e  Z d  Z d d d „ Z d „  Z RS(   sÍ   Specifies mappings between URLs and handlers.

    .. versionchanged: 4.5
       `URLSpec` is now a subclass of a `Rule` with `PathMatches` matcher and is preserved for
       backwards compatibility.
    c         C` sM   t  t |  ƒ j t | ƒ | | | ƒ |  j j |  _ |  j |  _ | |  _ d S(   sƒ  Parameters:

        * ``pattern``: Regular expression to be matched. Any capturing
          groups in the regex will be passed in to the handler's
          get/post/etc methods as arguments (by keyword if named, by
          position if unnamed. Named and unnamed capturing groups
          may not be mixed in the same rule).

        * ``handler``: `~.web.RequestHandler` subclass to be invoked.

        * ``kwargs`` (optional): A dictionary of additional arguments
          to be passed to the handler's constructor.

        * ``name`` (optional): A name for this handler.  Used by
          `~.web.Application.reverse_url`.

        N(	   RK   Rƒ   R"   R=   RB   R^   RE   t   handler_classR   (   R   Ra   t   handlerR   R   (    (    s.   lib/python2.7/site-packages/tornado/routing.pyR"   Z  s    %c         C` s,   d |  j  j |  j j |  j |  j |  j f S(   Ns   %s(%r, %s, kwargs=%r, name=%r)(   RP   R   R^   Ra   R„   R   R   (   R   (    (    s.   lib/python2.7/site-packages/tornado/routing.pyRQ   r  s    N(   R   R   R   R   R"   RQ   (    (    (    s.   lib/python2.7/site-packages/tornado/routing.pyRƒ   S  s   c         C` s&   |  d k r |  St |  d d d t ƒS(   s¹   None-safe wrapper around url_unescape to handle unmatched optional
    groups correctly.

    Note that args are passed as bytes so the handler can decide what
    encoding to use.
    t   encodingRp   N(   R   R   Rs   (   Ro   (    (    s.   lib/python2.7/site-packages/tornado/routing.pyRf   x  s    (*   R   t
   __future__R    R   R   RW   t	   functoolsR   t   tornadoR   t   tornado.httpserverR   t   tornado.escapeR   R   R   t   tornado.logR	   t   tornado.utilR
   R   R   R   t   typingt   ImportErrorRG   R   R   t   HTTPMessageDelegateR   R+   R4   RI   t   objectR<   RR   RS   RT   R[   R=   Rƒ   Rf   (    (    (    s.   lib/python2.7/site-packages/tornado/routing.pyt   <module>°   s4   "
a%'X%