
    8CfY                        d dl Z d dlZd dlZd dlmZmZ d dlm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mZmZ dd	lmZ dd
lmZmZ ddlmZ ddlmZmZ ddl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*m+Z+  G d de      Z,y)    N)ABCabstractmethod)SimpleNamespace)warn)
RouteGroup)	ParamInfo   )	BadMethodFinalizationErrorInvalidUsageNoMethodNotFound)Line)REGEX_TYPESREGEX_TYPES_ANNOTATION)Route)NodeTree)parts_to_pathpath_to_parts)datetime)unquote)UUID)
parse_datealphaslugnonemptystrc                      e Zd ZU dZ e       Zej                  edf   e	d<   de
eeeddfdedej                  e
   dej                  e   d	ej                  e   d
ej                  e   dededdfdZed        Zdddddedej&                  e   dej&                  e   dej&                  ej(                  eef      dej                  eej*                  dej,                  f   ej(                  eej,                  f   f   f
dZ	 	 	 	 	 	 	 d7dddedej*                  dej&                  ej0                  ej2                  e   ej4                  e   ef      dej&                  e   dej&                  ej(                  eej,                  f      dededed ed!edefd"Zefd#ed$ej*                  egej,                  f   d%ej0                  ej<                  ef   d&ej                  e   fd'Zd8d(ed)efd*Z d+ Z!d,edejD                  e   fd-Z#d9d.Z$	 d8d(ed)eddfd/Z%e&d0        Z'e&d1        Z(e&d2        Z)e&d3        Z*d9d4Z+e,d5        Z-defd6Z.y):
BaseRouterBASE.ALLOWED_METHODS/F	delimiter	exceptionmethod_handler_exceptionroute_classgroup_classstackingcascade_not_foundreturnNc                 ~   d | _         d | _        i | _        i | _        i | _        i | _        || _        || _        || _        || _	        || _
        t        |       | _        d| _        || _        t               | _        || _        i | _        t'        j(                         D ]  \  }\  }	}
}| j+                  ||	|
|        y )NrouterF)_find_route	_matchersstatic_routesdynamic_routesregex_routes
name_indexr#   r$   r%   r&   r'   r   tree	finalizedr(   r   ctxr)   regex_typesr   itemsregister_pattern)selfr#   r$   r%   r&   r'   r(   r)   labelcastpatternparam_info_classs               T/var/www/highfloat_scraper/venv/lib/python3.12/site-packages/sanic_routing/router.py__init__zBaseRouter.__init__'   s      DFEGCE.0""(@%&&%	 "$!2358C8I8I8K 	J4E4D'#3!!%w8HI	J    c                      y N )r:   kwargss     r?   getzBaseRouter.getG   s    rA   )methodorigextrapathrG   rH   rI   c                   	 | j                  ||| i i d|      \  }}t        |t              r	 |j                  |   }|d   }|r|d	   r|j                  j                         D ]l  \  }	}
	 |d	   |	   }t        |t               r|
j#                  ||       2|j$                  r |j$                  sK|
j&                  t        us^|||
j(                  <   n |j*                  r*|r(|d   |j,                  d   k7  r| j/                  d
|      ||j                  vr$| j                  d| d| ||j                        ||j0                  |fS # t        t        f$ rY}|j                  | j                        r| j                  |d d |||      cY d }~S |j                  t        |      |      d }~ww xY w# t        $ r% | j                  d| d| ||j                        w xY w# t        $ r Y w xY w)N)
__params____matches__)rJ   rG   rH   rI   )rJ   zMethod 'z' not found on )rG   allowed_methodsrL   rM   zPath not found)
find_router   r   endswithr#   resolve	__class__str
isinstancer   methods_indexKeyErrorr%   methodsparamsr8   tupleprocessregexr<   namestrictrJ   r$   handler)r:   rJ   rG   rH   rI   routeparam_basketerY   idxparamvalues               r?   rR   zBaseRouter.resolveK   s   	1"&//!"5#E<& eZ(++F3 l+m4 $ll002 /
U(7<E
 eU+MM&%0KKEJJc$9).F5::&/$ <<DT"XB%?..!1.==&//6(/%9 % 0   emmV++q (# 
	1 }}T^^,||cr!	 $   ++c!f4+00
	1  33vhoeW=!$)MM 4  $   s@   E	 F4 *G%	F12F,
F1F,,F14.G"%	G21G2r   )priorityr_   rX   r]   requirementsr^   r   	overwriteappendrf   c
                    |r|	rt        d      |
r|	st        d      |s j                  g}t        |d      rt        |t              st	        |      }nt        |t
              rt	        |g      } j                  rLt         fd|D              r8|D cg c]  }| j                  vr| }}t        d| d j                          j                  rt        d      d|vxr |d u } j                  |      }|r j                  }n|r j                  }n j                  }t        t        | j                          j                         }|r|j"                  n|j$                  } | j                         } j'                   ||xs d	||||||||

      } j)                  |      }|r$|j*                   j                  v r j                  }|sQ|j*                   j                  v r9 j                  j-                  |j*                        }|j/                  |||	       n?|j*                  |v r"||j*                     }|j/                  |||	       |||j*                  <   |r| j0                  |<   |j3                          |S c c}w )Nz?Cannot add a route with both overwrite and append equal to Truez3Cannot add a route with priority if append is False__iter__c              3   :   K   | ]  }|j                   v  y wrC   )r!   ).0rG   r:   s     r?   	<genexpr>z!BaseRouter.add.<locals>.<genexpr>   s!      (
39F$...(
s   zBad method: z. Must be one of: &Cannot finalize router more than once.< )r_   rX   rg   r^   r   staticr\   rf   )r   DEFAULT_METHODhasattrrU   	frozensetrT   r!   anyr
   r5   	_is_regexr2   r0   r1   r   r   r#   lstripstripr&   r'   segmentspopmerger3   finalize)r:   rJ   r_   rX   r]   rg   r^   r   rh   ri   rf   rG   badrr   r\   routesry   r`   groupexisting_groups   `                   r?   addzBaseRouter.add   s   & #  F#E  **+G7J'
7I0N(G%	*GC (
=D(
 %

 &!5!55 C 
 se#5d6J6J5KL  >>#$LMMD9\T%9t$ &&F''F((F $/
  &4::T^^$  JB% ! 
   ' enn(;(;;((F %..D,>,>>!//33ENNCNKK	6: ~~'!'!7NIv>%*F5>>"$)DOOD!Ss   J	r;   r<   r=   r>   c                    t        |t              st        d|       t        |      st        d|       t        |t              s4t        |t        j
                        st        d| dt        |             t        |t              rt        j                  |      }|t               |j                  <   |||f| j                  |<   y)a"  
        Add a custom parameter type to the router. The cast should raise a
        ValueError if it is an incorrect type. The order of registration is
        important if it is possible that a single value could pass multiple
        pattern types. Therefore, patterns are tried in the REVERSE order of
        registration. All custom patterns will be evaluated before any built-in
        patterns.

        :param label: The parts that is used to signify the type: example

        :type label: str
        :param cast: The callable that casts the value to the desired type, or
            fails trying
        :type cast: t.Callable[[str], t.Any]
        :param pattern: A regular expression that could also match the path
            segment
        :type pattern: Union[t.Pattern, str]
        z>When registering a pattern, label must be a string, not label=z>When registering a pattern, cast must be a callable, not cast=zOWhen registering a pattern, pattern must be a string or a Pattern, not pattern=z, type=N)rU   rT   r   callabletPatterntyperecompileglobals__name__r7   )r:   r;   r<   r=   r>   s        r?   r9   zBaseRouter.register_pattern  s    2 %%%%*G-  ~&&*V-  '3'
7AII0N44;9 =W(  gs#jj)G#'	$-- #'2B"CrA   
do_compiledo_optimizec                    | j                   rt        d      | j                  st        d      d| _         t        | j                  j                               t        | j                  j                               z   t        | j                  j                               z   D ]C  }|j                          |j                  D ]  }|j                           |j                          E | j                          | j                  ||       y)a]  
        After all routes are added, we can put everything into a final state
        and build the routing dource

        :param do_compile: Whether to compile the source, mainly a debugging
            tool, defaults to True
        :type do_compile: bool, optional
        :param do_optimize: Experimental feature that uses AST module to make
            some optimizations, defaults to False
        :type do_optimize: bool, optional
        :raises FinalizationError: Cannot finalize if there are no routes, or
            the router has already been finalized (can call reset() to undo it)
        ro   z'Cannot finalize with no routes defined.TN)r5   r   r   listr0   valuesr1   r2   r}   prioritize_routes_generate_tree_render)r:   r   r   r   r`   s        r?   r}   zBaseRouter.finalize7  s     >>#$LMM{{#$MNN ##**,-4&&--/014$$++-./	&E
 NN ! !##%	& 	 	Z-rA   c                    d| _         t        |       | _        d | _        t	        | j
                  j                               t	        | j                  j                               z   t	        | j                  j                               z   D ]3  }|j                          |j                  D ]  }|j                           5 y )NFr,   )r5   r   r4   r.   r   r0   r   r1   r2   resetr   r:   r   r`   s      r?   r   zBaseRouter.reset\  s    %	 ##**,-4&&--/014$$++-./	E
 KKM 	rA   has_dynamic_pathc                     t        t        | j                  j                               t        | j                  j                               z   D cg c]  }|j
                  |u r| c}d d      S c c}w )a  
        Paths that have some matching params (includes dynamic and regex),
        but excludes any routes with a <path:path> or delimiter in its regex.
        This is because those special cases need to be evaluated seperately.
        Anything else can be evaluated in the node tree.

        :param has_dynamic_path: Whether the path catches a path, or path-like
        type
        :type has_dynamic_path: bool
        :return: list of routes that have no path, but do need matching
        :rtype: List[RouteGroup]
        c                     | j                   S rC   )depthxs    r?   <lambda>z<BaseRouter._get_non_static_non_path_groups.<locals>.<lambda>  s
    !'' rA   Tkeyreverse)sortedr   r1   r   r2   dynamic_path)r:   r   r   s      r?   _get_non_static_non_path_groupsz*BaseRouter._get_non_static_non_path_groupsj  su      "$"5"5"<"<">?t((//123%%)99  "	
 		
s   A1c                     | j                   j                  | j                  d             | j                   j                          y )NF)r4   generater   r}   r:   s    r?   r   zBaseRouter._generate_tree  s/    		4??FG		rA   c                 ,   t        dd      t        dd      g}g }| j                  rG|t        dd      t        dd      t        dd      t        d	d      t        d
d      t        dd      gz  }| j                  rt        | j                  j	                         d d      }|j                  t        dd             t        |      D ]5  \  }}||_        |j                  t        d|j                   dd             7 |j                  t        dd             | j                  s| j                  r-|t        dd      gz  }|| j                  j                         z  }| j                  d      D ]  }|j                  rdnd}d}	g }
|j                  rd}	t               j!                  |
d|       |	dk(  r1t#        |j$                        dkD  rd}	t        j&                  |
d|       |j)                  t        d|j                   dd      t        dd      g|
t        dd      t        d| d|j*                   d|	 dd              |j                  t        dd             |j)                  |       d j-                  t/        t0        t3        d! |                  | _        |r	 t7        j8                  | j4                        }|r| j;                  |j<                  d          t>        j@                  jB                  d"k(  r=t>        j@                  jD                  d#k\  r tG        | d$t7        jH                  |             t7        jJ                  |       tM        |d d%      }i }t_        |d |       |d,   | _0        |jc                  d-      | _2        y y # tN        $ ru}d&|jP                   d'|jR                   d(|jT                   d)tW        dtY        |jZ                  xs d      dz
        z  d*z    }t]        d+| j4                   d(|       d }~ww xY w).Nz4def find_route(path, method, router, basket, extra):r   z/parts = tuple(path[1:].split(router.delimiter))r	   ztry:z#group = router.static_routes[parts]   zbasket['__raw_path__'] = pathzreturn group, basketzexcept KeyError:passc                 ,    t        | j                        S rC   )lenparts)r`   s    r?   r   z$BaseRouter._render.<locals>.<lambda>  s    #ekk"2 rA   Tr   zmatchers = [zre.compile(r'^z$'),]znum = len(parts)r2   r1   	route_idxzmatch = router.matchers[z].match(path)z	if match:z(basket['__params__'] = match.groupdict()zreturn router.[z][z	], basketzraise NotFoundrq   c                     | j                   S rC   )renderr   s    r?   r   z$BaseRouter._render.<locals>.<lambda>  s
    ahh rA      	   find_route_src_compiledexeczLine z: 
 ^zCannot compile route AST:
rP   matchers)3r   r0   r2   r   r   ri   	enumeratepattern_idxr=   r1   r4   r   r   r\   rg   r   _inject_requirementsr   r   _inject_method_checkextendrz   joinmaprT   filterfind_route_srcastparse	_optimizebodysysversion_infomajorminorsetattrunparsefix_missing_locationsr   SyntaxErrorlinenomsgtextmaxintoffsetr   r   r.   rF   r/   )r:   r   r   srcdelayedr   rc   r   route_containerr   holdersyntax_treecompiled_srcsesyntax_errorr6   s                   r?   r   zBaseRouter._render  s$   
 GKBAF
  
 VQ9 4a8+Q/'+VQ
 
C4 !!((*2F
 NN423'/ N
U$'!tnU]]O4$H!LMN NN4Q<( $"3"3D+Q/00C499##%%C 99$? #	E"'++3C  ,-I#%F!!'	++FAu=A~#ell"3a"7'	))&!U;JJ  % 1 12-A  a(  CQG ,_,=/r)IG #	J 	

4(!,-

7 ggV.45
 "!ii(;(;<NN;#3#3A#67##))Q.33C3C3I3IQ3N
 1K0 ))+6&  )+CtS)"<0D WWZ0DNO 6  BII;b277)3qRYY^!!4Q!677#=>@  (1$2E2E1F( s   )B;N 	PA0PPc                     | j                   S rC   )r.   r   s    r?   rP   zBaseRouter.find_route  s    rA   c                     | j                   S rC   )r/   r   s    r?   r   zBaseRouter.matchers  s    ~~rA   c                 N    i | j                   | j                  | j                  S rC   )r0   r1   r2   r   s    r?   groupszBaseRouter.groups   s8    
  
!!
 
 	
rA   c                     t        | j                  j                         D cg c]  }|D ]  }|  c}}      S c c}}w rC   )rZ   r   r   r   s      r?   r   zBaseRouter.routes(  s9     $ 2 2 4Hu%HUHUH
 	
Hs   ;
c                 F   t        d       t        |d      r|j                  D ]  }| j                  |        | j	                  |      r0| j	                  |j                  d         r|j                  d   }|j                  d   j                  d   }g }|j
                  |j
                  fD ]  }t        |t        j                        r|j                  |       /t        |t        j                        r@t        |j                  t        j                        r|j                  |j                          t        j                  t        j                         |      }||_        |j                  |_        t        d |j                  D              rZt!        |j                        dkD  rB|j                  ^}}	|	D ]'  }
|j                  j                  |
j                         ) |g|_        t        |d      r#|j"                  D ]  }| j                  |        y y )Nz`Router AST optimization is an experimental only feature. Results may vary from unoptimized code.r   r   )opr   c              3   P   K   | ]  }t        |t        j                           y wrC   )rU   r   If)rm   childs     r?   rn   z'BaseRouter._optimize.<locals>.<genexpr>]  s     E%Jucff-Es   $&r	   orelse)r   rt   r   r   _is_lone_iftestrU   r   Compareri   BoolOpr   Andr   r   allr   r   )r:   noder   currentnestedr   r   combinedfirstremitems              r?   r   zBaseRouter._optimize.  s   6	
 4  &u%& %$*:*:499Q<*H))A,1**1-(*$\\6;;7 D!$4d+#D#**5*; dkk2 ::6B'%{{ E499EE 		NQ&"ii 1DJJ%%dii01 #G	4" &u%& #rA   c                     t        | j                        dk(  xr' t        | j                  d   t        j                        S )Nr	   r   )r   r   rU   r   r   )r   s    r?   r   zBaseRouter._is_lone_ifl  s-    499~"Gz$))A,'GGrA   c                 d     t        | j                        } fdt        fd|D              S )Nc                     | j                  d      rd| vry| dd j                  d      ^}}}| j                  d      xs j                  | v xs |j                  vS )Nrp   :Fr	   rN   z:path>)
startswithsplitrQ   r#   r7   )part_pattern_type__r:   s       r?   requiresz&BaseRouter._is_regex.<locals>.requiress  sl    ??3'3d?#'":#3#3C#8 A|b h' 8>>T)8t'7'77rA   c              3   .   K   | ]  } |        y wrC   rD   )rm   r   r   s     r?   rn   z'BaseRouter._is_regex.<locals>.<genexpr>  s     4d8D>4s   )r   r#   rv   )r:   rJ   r   r   s   `  @r?   rw   zBaseRouter._is_regexp  s+    dDNN3
	 4e444rA   )NNNFFFF)TF)r*   N)/r   
__module____qualname__rs   rZ   r!   r   TuplerT   __annotations__r   r   r   r   Typeboolr@   r   rF   OptionalDictCallableAnyrR   UnionSequence	FrozenSetr   r   r   r   r9   r}   r   Listr   r   r   propertyrP   r   r   r   r   staticmethodr   rw   rD   rA   r?   r   r   #   s   N).OQWWS#X&0 &.5=%**4"'JJ 66(#J #$&&"2	J
 VVE]J VVJ'J J  J 
J@   #' $.2H,H, 

3	H,
 jjoH, zz!&&c*+H, 


3:.sAEEz0BB	CH,`  $7;p pp p GGAJJsOQ[[%5s:;
	p jjop jjQUU
!34p p p p p p 
pn /8.D.D jj#&.D C(	.D
 &&+.D`#.4 #.T #.J
 $
	

	
4
 <AN1N148N1	N1`       
 
 
 

<&| H H5c 5rA   r   )-r   r   typingr   abcr   r   typesr   warningsr   sanic_routing.groupr   sanic_routing.patternsr   
exceptionsr
   r   r   r   r   liner   patternsr   r   r`   r   r4   r   r   utilsr   r   r   r   urllib.parser   uuidr   r   r   r   r   r   rD   rA   r?   <module>r     sZ    
 
  # !  * ,   9   /
 
     : :\	5 \	5rA   