
    R?ga                        S r SSKrSSKJr  SSKJr  SSKJr  SSKJ	r	J
r
Jr  SSKJr  SSKJrJrJrJr  SS	KJrJrJrJrJrJrJrJrJr   " S
 S\R:                  5      r " S S\5      r " S S\R@                  5      r! " S S\R@                  5      r"\\S\\   \\\#S4   \4   \\\#S4   \\\#\4   4   \\\#S4   \\\#\4   \#4   4      r$ " S S\5      r% " S S\\%5      r& " S S\'5      r( " S S\'5      r) " S S\)5      r* " S S\)5      r+ " S S\)5      r, " S  S!\)5      r- " S" S#\(5      r.\S$\#S%\/4S& j5       r0\S)S' j5       r0S$\\#   S%\\/   4S( jr0g)*ap  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

    N)partial)httputil)_CallableAdapter)
url_escapeurl_unescapeutf8)app_log)basestring_typeimport_objectre_unescapeunicode_type)	AnyUnionOptional	AwaitableListDictPatternTupleoverloadc                       \ rS rSrSrS\R                  S\S\\R                     4S jr
S\S\R                  S\R                  4S	 jrS
rg)Router   zAbstract router interface.requestkwargsreturnc                     [        5       e)a  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.
NotImplementedError)selfr   r   s      1/usr/lib/python3/dist-packages/tornado/routing.pyfind_handlerRouter.find_handler   s     "##    server_connrequest_connc                     [        XU5      $ N)_RoutingDelegate)r    r%   r&   s      r!   start_requestRouter.start_request   s      <@@r$    N)__name__
__module____qualname____firstlineno____doc__r   HTTPServerRequestr   r   HTTPMessageDelegater"   objectHTTPConnectionr*   __static_attributes__r,   r$   r!   r   r      s`    $$11$=@$	(..	/$A!A191H1HA		%	%Ar$   r   c                   4    \ rS rSrSrS\S\S\\   4S jrSr	g)	ReversibleRouter   zpAbstract router interface for routers that can handle named routes
and support reversing them to original urls.
nameargsr   c                     [        5       e)zReturns 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``).
r   )r    r:   r;   s      r!   reverse_urlReversibleRouter.reverse_url   s     "##r$   r,   N)
r-   r.   r/   r0   r1   strr   r   r=   r6   r,   r$   r!   r8   r8      s%    $ $C $HSM $r$   r8   c                       \ rS rSrS\S\S\R                  SS4S jrS\	\R                  \R                  4   S	\R                  S\\S      4S
 jrS\S\\S      4S jrSS jrSS jrSrg)r)      routerr%   r&   r   Nc                 6    X l         X0l        S U l        Xl        g r(   )r%   r&   delegaterB   )r    rB   r%   r&   s       r!   __init___RoutingDelegate.__init__   s     '(r$   
start_lineheadersc                    [        U[        R                  5      (       d   e[        R                  " U R                  U R
                  UUS9nU R                  R                  U5      U l        U R                  cF  [        R                  " SUR                  UR                  5        [        U R                  5      U l        U R                  R                  X5      $ )N)
connectionserver_connectionrG   rH   z$Delegate for %s %s request not found)
isinstancer   RequestStartLiner2   r&   r%   rB   r"   rD   r	   debugmethodpath_DefaultMessageDelegateheaders_received)r    rG   rH   r   s       r!   rR   !_RoutingDelegate.headers_received   s    
 *h&?&?@@@@,,(("..!	
 009== MM6!!
 4D4E4EFDM}}--jBBr$   chunkc                 V    U R                   c   eU R                   R                  U5      $ r(   )rD   data_received)r    rT   s     r!   rV   _RoutingDelegate.data_received  s'    }}(((}}**511r$   c                 V    U R                   c   eU R                   R                  5         g r(   )rD   finishr    s    r!   rY   _RoutingDelegate.finish
  s"    }}(((r$   c                 V    U R                   c   eU R                   R                  5         g r(   )rD   on_connection_closerZ   s    r!   r]   $_RoutingDelegate.on_connection_close  s"    }}((())+r$   )rD   r&   rB   r%   r   N)r-   r.   r/   r0   r   r4   r   r5   rE   r   rM   ResponseStartLineHTTPHeadersr   r   rR   bytesrV   rY   r]   r6   r,   r$   r!   r)   r)      s    +1AIAXAX	C(33X5O5OOPC %%C 
)D/	"	C025 2Xio-F 2,r$   r)   c                   D    \ rS rSrS\R
                  SS4S jrSS jrSrg)	rQ   i  rJ   r   Nc                     Xl         g r(   rJ   )r    rJ   s     r!   rE    _DefaultMessageDelegate.__init__  s    $r$   c                     U R                   R                  [        R                  " SSS5      [        R                  " 5       5        U R                   R                  5         g )NzHTTP/1.1  z	Not Found)rJ   write_headersr   r`   ra   rY   rZ   s    r!   rY   _DefaultMessageDelegate.finish  sD    %%&&z3D  "	
 	 r$   re   r_   )	r-   r.   r/   r0   r   r5   rE   rY   r6   r,   r$   r!   rQ   rQ     s     %8#:#: %t %!r$   rQ   RuleMatcherc            	           \ rS rSrSrSS\\   SS4S jjrS\SS4S jrSS jr	S	\
R                  S
\S\\
R                     4S jrS\S	\
R                  S\S\\
R                     4S jrSrg)
RuleRouteri,  z!Rule-based router implementation.Nrulesr   c                 D    / U l         U(       a  U R                  U5        gg)a  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)ro   	add_rules)r    ro   s     r!   rE   RuleRouter.__init__/  s    6 
NN5! r$   c                 :   U H  n[        U[        [        45      (       aM  [        U5      S;   d   e[        US   [        5      (       a  [        [        US   5      /USS Q76 nO[        U6 nU R                  R                  U R                  U5      5        M     g)zAppends new rules to the router.

:arg rules: a list of Rule instances (or tuples of arguments, which are
    passed to Rule constructor).
)         r      N)
rL   tuplelistlenr
   rk   PathMatchesro   appendprocess_rule)r    ro   rules      r!   rq   RuleRouter.add_rulesN  s     D$..4yI---d1g77DG 4@tABx@D;DJJd//56 r$   c                     U$ )zOverride 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    r~   s     r!   r}   RuleRouter.process_rule^  s	     r$   r   r   c                     U R                    Hh  nUR                  R                  U5      nUc  M#  UR                  (       a  UR                  US'   U R                  " UR
                  U40 UD6nUc  Mf  Us  $    g )Ntarget_kwargs)ro   matchermatchr   get_target_delegatetarget)r    r   r   r~   target_paramsrD   s         r!   r"   RuleRouter.find_handlerf  sx     JJD LL..w7M(%%595G5GM/233KK,9 '#O  r$   r   r   c                 z   [        U[        5      (       a  UR                  " U40 UD6$ [        U[        R                  5      (       a5  UR
                  c   eUR                  UR                  UR
                  5      $ [        U5      (       a/  UR
                  c   e[        [        U40 UD6UR
                  5      $ g)ax  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)rL   r   r"   r   HTTPServerConnectionDelegaterJ   r*   rK   callabler   r   )r    r   r   r   s       r!   r   RuleRouter.get_target_delegatex  s     ff%%&&w@-@@ E EFF%%111''(A(A7CUCUVVf%%111#0-0'2D2D  r$   )ro   r(   r~   rk   r   rk   )r-   r.   r/   r0   r1   r   	_RuleListrE   rq   r}   r   r2   r   r3   r"   r   r6   r,   r$   r!   rn   rn   ,  s    +"hy1 "T ">7y 7T 7 11=@	(..	/$$,$>$>QT	(..	/r$   rn   c                   n   ^  \ rS rSrSrSS\\   SS4U 4S jjjrSU 4S jjrS\	S	\
S\\	   4S
 jrSrU =r$ )ReversibleRuleRouterrh   zA 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`).
Nro   r   c                 2   > 0 U l         [        TU ]	  U5        g r(   )named_rulessuperrE   )r    ro   	__class__s     r!   rE   ReversibleRuleRouter.__init__  s    r$   c                    > [         TU ]  U5      nUR                  (       aS  UR                  U R                  ;   a!  [        R
                  " SUR                  5        XR                  UR                  '   U$ )Nz4Multiple handlers named %s; replacing previous value)r   r}   r:   r   r	   warning)r    r~   r   s     r!   r}   !ReversibleRuleRouter.process_rule  sY    w#D)99yyD,,,JDII +/TYY'r$   r:   r;   c                    XR                   ;   a&  U R                   U   R                  R                  " U6 $ U R                   HH  n[	        UR
                  [        5      (       d  M$  UR
                  R                  " U/UQ76 nUc  MF  Us  $    g r(   )r   r   reversero   rL   r   r8   r=   )r    r:   r;   r~   reversed_urls        r!   r=    ReversibleRuleRouter.reverse_url  sz    #####D)11994@@JJD$++'788#{{66tCdC+''	  r$   )r   r(   r   )r-   r.   r/   r0   r1   r   r   rE   r}   r?   r   r=   r6   __classcell__r   s   @r!   r   r     sM     hy1  T    

 
C 
HSM 
 
r$   r   c                   z    \ rS rSrSr  SSSS\S\\\\4      S\\   S	S4
S
 jjr	S\S	\\   4S jr
S	\4S jrSrg)rk   i  zA routing rule.Nr   rl   r   r   r:   r   c                     [        U[        5      (       a  [        U5      nXl        X l        U(       a  UO0 U l        X@l        g)a  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)rL   r?   r   r   r   r   r:   )r    r   r   r   r:   s        r!   rE   Rule.__init__  s8    . fc"" #6*F.;]	r$   r;   c                 4    U R                   R                  " U6 $ r(   )r   r   r    r;   s     r!   r   Rule.reverse  s    ||##T**r$   c           
          U R                   R                  < SU R                  < SU R                  < SU R                  < SU R
                  < S3
$ N(z, z	, kwargs=z, name=))r   r-   r   r   r   r:   rZ   s    r!   __repr__Rule.__repr__  s7    NN##LLKKII
 	
r$   )r   r:   r   r   NN)r-   r.   r/   r0   r1   r   r   r   r?   rE   r   r   r6   r,   r$   r!   rk   rk     sw     37"   S#X/	
 sm 
B+S +Xc] +
# 
r$   c                   f    \ rS rSrSrS\R                  S\\\	\
4      4S jrS\
S\\	   4S jrSrg	)
rl   i  z*Represents a matcher for request features.r   r   c                     [        5       e)a  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.r   r    r   s     r!   r   Matcher.match  s     "##r$   r;   c                     g)zEReconstructs full url from matcher instance and additional arguments.Nr,   r   s     r!   r   Matcher.reverse  s    r$   r,   N)r-   r.   r/   r0   r1   r   r2   r   r   r?   r   r   r   r6   r,   r$   r!   rl   rl     sB    4
$X77 
$HT#s(^<T 
$S Xc] r$   c                   N    \ rS rSrSrS\R                  S\\\	\
4      4S jrSrg)
AnyMatchesi  zMatches any request.r   r   c                     0 $ r(   r,   r   s     r!   r   AnyMatches.match  s    	r$   r,   N)r-   r.   r/   r0   r1   r   r2   r   r   r?   r   r   r6   r,   r$   r!   r   r     s+    X77 HT#s(^<T r$   r   c                   j    \ rS rSrSrS\\\4   SS4S jrS\	R                  S\\\\4      4S jrS	rg)
HostMatchesi  z@Matches requests from hosts specified by ``host_pattern`` regex.host_patternr   Nc                     [        U[        5      (       a7  UR                  S5      (       d  US-  n[        R                  " U5      U l        g Xl        g )N$)rL   r
   endswithrecompiler   )r    r   s     r!   rE   HostMatches.__init__  sA    lO44((--# "

< 8D ,r$   r   c                 \    U R                   R                  UR                  5      (       a  0 $ g r(   )r   r   	host_namer   s     r!   r   HostMatches.match  s'    ""7#4#455Ir$   )r   )r-   r.   r/   r0   r1   r   r?   r   rE   r   r2   r   r   r   r   r6   r,   r$   r!   r   r     sG    J-U3<%8 -T -X77 HT#s(^<T r$   r   c                   d    \ rS rSrSrS\S\SS4S jrS\R                  S\
\\\4      4S	 jrS
rg)DefaultHostMatchesi  zMatches requests from host that is equal to application's default_host.
Always returns no match if ``X-Real-Ip`` header is present.
applicationr   r   Nc                     Xl         X l        g r(   r   r   )r    r   r   s      r!   rE   DefaultHostMatches.__init__  s    &(r$   r   c                     SUR                   ;  a6  U R                  R                  U R                  R                  5      (       a  0 $ g )Nz	X-Real-Ip)rH   r   r   r   default_hostr   s     r!   r   DefaultHostMatches.match   s9    goo-  &&t'7'7'D'DEE	r$   r   )r-   r.   r/   r0   r1   r   r   rE   r   r2   r   r   r?   r   r6   r,   r$   r!   r   r     sG    )C )w )4 )X77 HT#s(^<T r$   r   c                       \ rS rSrSrS\\\4   SS4S jrS\	R                  S\\\\4      4S jrS	\S\\   4S
 jrS\\\   \\   4   4S jrSrg)r{   i(  z@Matches requests with paths specified by ``path_pattern`` regex.path_patternr   Nc                    [        U[        5      (       a7  UR                  S5      (       d  US-  n[        R                  " U5      U l        OXl        [        U R
                  R                  5      SU R
                  R                  4;   d   SU R
                  R                  -  5       eU R                  5       u  U l        U l        g )Nr   r   zDgroups in url regexes must either be all named or all positional: %r)rL   r
   r   r   r   regexrz   
groupindexgroupspattern_find_groups_path_group_count)r    r   s     r!   rE   PathMatches.__init__+  s    lO44((--#L1DJ%J4::(()a1B1B-CC 	
#zz112	
C
 )-(9(9(;%
D%r$   r   c                    U R                   R                  UR                  5      nUc  g U R                   R                  (       d  0 $ / n0 nU R                   R                  (       a/  [        S UR                  5       R                  5        5       5      nO)UR                  5        Vs/ s H  n[        U5      PM     nn[        X4S9$ s  snf )Nc              3   R   #    U  H  u  p[        U5      [        U5      4v   M     g 7fr(   )r?   _unquote_or_none).0kvs      r!   	<genexpr>$PathMatches.match.<locals>.<genexpr>I  s%      <U&1Q)!,-<Us   %')	path_argspath_kwargs)	r   r   rP   r   r   dict	groupdictitemsr   )r    r   r   r   r   ss         r!   r   PathMatches.match:  s    

  .=zz  I	 ::   <AOO<M<S<S<U K 7<llnEn)!,nIEiAA Fs   'Cr;   c                    U R                   c"  [        SU R                  R                  -   5      e[	        U5      U R
                  :X  d   S5       e[	        U5      (       d  U R                   $ / nU HK  n[        U[        [        45      (       d  [        U5      nUR                  [        [        U5      SS95        MM     U R                   [        U5      -  $ )NzCannot reverse url regex z&required number of arguments not foundF)plus)r   
ValueErrorr   r   rz   r   rL   r   rb   r?   r|   r   r   rx   )r    r;   converted_argsas       r!   r   PathMatches.reverseQ  s    ::84::;M;MMNN4yD--- 	
7	
- 4yy::Aa,!677F!!*T!W5"AB  zzE.111r$   c                 z   U R                   R                  nUR                  S5      (       a  USS nUR                  S5      (       a  USS nU R                   R                  UR                  S5      :w  a  g/ nUR                  S5       Hf  nSU;   a@  UR                  S5      nUS	:  a'   [        X4S-   S 5      nUR                  S
U-   5        MG  MI   [        U5      nUR                  U5        Mh     SR                  U5      U R                   R                  4$ ! [         a       gf = f! [         a       gf = f)zReturns 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).
^rw   Nr   r   r   r   r   z%s )r   r   
startswithr   r   countsplitindexr   r   r|   join)r    r   piecesfragment	paren_locunescaped_fragments         r!   r   PathMatches._find_groups`  s:    **$$c""abkGC  crlG::c 22 c*Hh$NN3/	>,-8a-/9R-S*
 MM$);";< "()4X)>&
 01% +( wwv

 1 111 & ,  ,, " ( ((s$   +DD,
D)(D),
D:9D:)r   r   r   )r-   r.   r/   r0   r1   r   r?   r   rE   r   r2   r   r   r   r   r   r   intr   r6   r,   r$   r!   r{   r{   (  s    J<U3<%8 <T <BX77 BHT#s(^<T B.2S 2Xc] 2&2eHSM8C=$@A &2r$   r{   c                   z   ^  \ rS rSrSr  SS\\\4   S\S\	\
\\4      S\	\   SS4
U 4S	 jjjrS\4S
 jrSrU =r$ )URLSpeci  zSpecifies 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.
Nr   handlerr   r:   r   c                    > [        U5      n[        TU ]	  XRX45        UR                  U l        U R                  U l        X0l        g)a+  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)r{   r   rE   r   r   handler_classr   )r    r   r   r   r:   r   r   s         r!   rE   URLSpec.__init__  s:    0 g&68]]
![[r$   c           
          U R                   R                  < SU R                  R                  < SU R                  < SU R
                  < SU R                  < S3
$ r   )r   r-   r   r   r   r   r:   rZ   s    r!   r   URLSpec.__repr__  s=    NN##JJKKII
 	
r$   )r   r   r   r   )r-   r.   r/   r0   r1   r   r?   r   r   r   r   rE   r   r6   r   r   s   @r!   r   r     su     ,0"sG|$  c3h(	
 sm 
 >
# 
 
r$   r   r   r   c                     g r(   r,   r   s    r!   r   r         r$   c                     g r(   r,   r  s    r!   r   r     r  r$   c                 "    U c  U $ [        U SSS9$ )zNone-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.
NF)encodingr   )r   r  s    r!   r   r     s     	yDu55r$   )r   Nr   N)1r1   r   	functoolsr   tornador   tornado.httpserverr   tornado.escaper   r   r   tornado.logr	   tornado.utilr
   r   r   r   typingr   r   r   r   r   r   r   r   r   r   r   r8   r3   r)   rQ   r?   r   rn   r   r4   rk   rl   r   r   r   r{   r   rb   r   r,   r$   r!   <module>r     s  aF 
   / 9 9  R R X X XAX22 A.$v $ +,x33 +,\	!h:: 	! 	S	eCN#S()eCN#S$sCx.89eCN#S$sCx.#=>		@	e eP"+Z "J.
6 .
bf ( ' $ "^2' ^2B.
d .
b 
	 	 	 
	 
	 
		6 	6(5/ 	6r$   