__init__.py000064400000000232150043323140006645 0ustar00from ._url import URL, cache_clear, cache_configure, cache_info __version__ = "1.9.2" __all__ = ("URL", "cache_clear", "cache_configure", "cache_info") __init__.pyi000064400000007531150043323140007027 0ustar00import sys from functools import _CacheInfo from typing import Any, Mapping, Optional, Sequence, Tuple, Type, Union, overload import multidict if sys.version_info >= (3, 8): from typing import Final, TypedDict, final else: from typing_extensions import Final, TypedDict, final _SimpleQuery = Union[str, int, float] _QueryVariable = Union[_SimpleQuery, Sequence[_SimpleQuery]] _Query = Union[ None, str, Mapping[str, _QueryVariable], Sequence[Tuple[str, _QueryVariable]] ] @final class URL: scheme: Final[str] raw_user: Final[str] user: Final[Optional[str]] raw_password: Final[Optional[str]] password: Final[Optional[str]] raw_host: Final[Optional[str]] host: Final[Optional[str]] port: Final[Optional[int]] raw_authority: Final[str] authority: Final[str] raw_path: Final[str] path: Final[str] raw_query_string: Final[str] query_string: Final[str] path_qs: Final[str] raw_path_qs: Final[str] raw_fragment: Final[str] fragment: Final[str] query: Final[multidict.MultiDict[str]] raw_name: Final[str] name: Final[str] raw_suffix: Final[str] suffix: Final[str] raw_suffixes: Final[Tuple[str, ...]] suffixes: Final[Tuple[str, ...]] raw_parts: Final[Tuple[str, ...]] parts: Final[Tuple[str, ...]] parent: Final[URL] def __init__( self, val: Union[str, "URL"] = ..., *, encoded: bool = ... ) -> None: ... @classmethod def build( cls, *, scheme: str = ..., authority: str = ..., user: Optional[str] = ..., password: Optional[str] = ..., host: str = ..., port: Optional[int] = ..., path: str = ..., query: Optional[_Query] = ..., query_string: str = ..., fragment: str = ..., encoded: bool = ... ) -> URL: ... def __str__(self) -> str: ... def __repr__(self) -> str: ... def __eq__(self, other: Any) -> bool: ... def __le__(self, other: Any) -> bool: ... def __lt__(self, other: Any) -> bool: ... def __ge__(self, other: Any) -> bool: ... def __gt__(self, other: Any) -> bool: ... def __hash__(self) -> int: ... def __truediv__(self, name: str) -> URL: ... def __mod__(self, query: _Query) -> URL: ... def is_absolute(self) -> bool: ... def is_default_port(self) -> bool: ... def origin(self) -> URL: ... def relative(self) -> URL: ... def with_scheme(self, scheme: str) -> URL: ... def with_user(self, user: Optional[str]) -> URL: ... def with_password(self, password: Optional[str]) -> URL: ... def with_host(self, host: str) -> URL: ... def with_port(self, port: Optional[int]) -> URL: ... def with_path(self, path: str, *, encoded: bool = ...) -> URL: ... @overload def with_query(self, query: _Query) -> URL: ... @overload def with_query(self, **kwargs: _QueryVariable) -> URL: ... @overload def update_query(self, query: _Query) -> URL: ... @overload def update_query(self, **kwargs: _QueryVariable) -> URL: ... def with_fragment(self, fragment: Optional[str]) -> URL: ... def with_name(self, name: str) -> URL: ... def with_suffix(self, suffix: str) -> URL: ... def join(self, url: URL) -> URL: ... def joinpath(self, *url: str) -> URL: ... def human_repr(self) -> str: ... # private API @classmethod def _normalize_path(cls, path: str) -> str: ... @final class cached_property: def __init__(self, wrapped: Any) -> None: ... def __get__(self, inst: URL, owner: Type[URL]) -> Any: ... def __set__(self, inst: URL, value: Any) -> None: ... class CacheInfo(TypedDict): idna_encode: _CacheInfo idna_decode: _CacheInfo def cache_clear() -> None: ... def cache_info() -> CacheInfo: ... def cache_configure( *, idna_encode_size: Optional[int] = ..., idna_decode_size: Optional[int] = ... ) -> None: ... __pycache__/__init__.cpython-311.pyc000064400000000543150043323140013212 0ustar00 bg&ddlmZmZmZmZdZdZdS))URL cache_clearcache_configure cache_infoz1.9.2N)_urlrrrr __version____all__D/opt/cloudlinux/venv/lib64/python3.11/site-packages/yarl/__init__.pyr s7???????????? Ar __pycache__/_quoting.cpython-311.pyc000064400000001425150043323140013300 0ustar00 bgddlZddlZdZeejdZejjdkrdZes ddl m Z m Z dS#e $r ddl m Z m Z YdSwxYwddl m Z m Z dS)N)_Quoter _UnquoterYARL_NO_EXTENSIONScpythonT)ossys__all__boolenvironget NO_EXTENSIONSimplementationname _quoting_crr ImportError _quoting_pyD/opt/cloudlinux/venv/lib64/python3.11/site-packages/yarl/_quoting.pyrs "RZ^^$899:: i''M042222222222 4443333333333340/////////sA AA__pycache__/_quoting_py.cpython-311.pyc000064400000022641150043323140014013 0ustar00 bgNddlZddlZddlmZmZmZddlmZmZej dZ de dDZ dZ dZed zZe ezZeezd zZeezZejd Zejd Zejd ZGddZGddZdS)N) ascii_lettersascii_lowercasedigits)Optionalcastasciic@h|]}d|ddS)%02Xr)encode).0is c/builddir/build/BUILD/cloudlinux-venv-1.0.7/venv/lib64/python3.11/site-packages/yarl/_quoting_py.py rs.@@@ A ""7++@@@z:/?#[]@z!$'()*,+&=;z-._~s[A-Z0-9][A-Z0-9]z[A-Fa-f0-9][A-Fa-f0-9]zutf-8c ^eZdZddddddedededed d f d Zd eed eefd Zd S)_QuoterFT)safe protectedqsrequoterrrrreturnNc>||_||_||_||_dS)N)_safe _protected_qs_requote)selfrrrrs r__init__z_Quoter.__init__s$ # rvalc|dSt|tstd|sdStt|dd}t }t }|j}|tz }|js|dz }||j z }|d}d}|t|kr||}|d z }|r|tvr|d z }| |t|d kr=|d d} t| s/|d ||d z} t#t%|d ddd} n?#t($r2|d ||d z}Y$wxYw| |j vr||n<| |vr#| t+| n|||nTt|d krA|t|kr.|d ||d z}|t+dkrZ|jrS|| ||t|kr|d [|jr7|t+dkr$| t+d||vr| ||d|dd|t|k|d} | |kr|S| S)NArgument should be strrutf8ignore)errorsrrr s%25baser  +r ) isinstancestr TypeErrorrr bytearrayrALLOWEDrrlenBASCII_LOWERCASEappend_IS_HEXmatchextendclearchrintdecode ValueErrorordr ) r!r#bvalretpctrbsafeidxchbufunquotedret2s r__call__z_Quoter.__call__$s ;4#s## 6455 5 2C~~$$VH$==kkkkz x  FND  G$$CIIoocB 1HC+ )))bB 2s88q==abb'C"==--! 6*** q !#&s3qrr7>>'+B+B'L'L'L#M#M%!!! 6*** q  !  4?22 3!T)) 3x==1111 3IIKKKKXX]]sc$ii'7'7JJv&&&IIKKK1HCs3xxDM  2#d))##JJv&&&x S>>JJs3xx(((U{{ 2 JJ B ,,W55 6 6 6sCIIoovzz'"" 3;;J s 9F8GG__name__ __module__ __qualname__r3boolr"rrLrrrrs                  OHSMOhsmOOOOOOrrcReZdZddddededdfdZd eedeefd ZdS) _UnquoterrF)unsaferrUrrNcr||_||_t|_td|_dS)NT)r)_unsaferr_quoter _qs_quoter)r!rUrs rr"z_Unquoter.__init__ws1 yy !T***rr#c|dSt|tstd|sdSttjt }g}d}|t|kr||}|dz }|dkr|t|dz kr|||dz}t |rtt|dg}|dz } | |}n#t$r|d z t|jd zz } ||| |d z | | |}n2#t$r%|||d z |YYBwxYwYnwxYw|sP|jr@|d vr<||} | t'd || nZ||jvr<||} | t'd || n|||jrQ|dz t|jd zz } ||| |dz ||d kr=|jr ||jvr|d n|d ||jvrg|dt-t/|dd} | D]}|||||t|k|jr3||t|j d zdd|} | |kr|S| S)Nr%rrr)r r,r-r.r+z+=&;zCannot quote Noner1r0)r2r3r4rcodecsBufferedIncrementalDecoder utf8_decoderr7 _IS_HEX_STR fullmatchbytesr?r@UnicodeDecodeErrorbufferr9resetrrY RuntimeErrorrWrXhexrBupperjoin) r!r#decoderrDrGrHrEbrJ start_pctto_addhrKs rrLz_Unquoter.__call__}s ;4#s## 6455 5 2v8,..IICHHnnSB 1HCSyySCHHqL00#a-(((--s3R000122A1HC %#*>>!#4#4-%%%$'!Gc'..A.AA.E$E  3y37':#;<<< %'.~~a'8'8HH1%%%JJs37S='9:::$HH%%H %$! x -H$6$6!%!:!:!>"./B"C"CC 6****!T\11!%h!7!7!>"./B"C"CC 6**** 8,,,~ !Gc'.&9&9A&==  3y3723444 Syyx$2#5#5JJsOOOOJJsOOOT\!! 3BLL&&((,##BJJrNNNN JJrNNNmCHHnnp > 8 JJsC///!3556 7 7 7wws|| 3;;J s7#C99AF E+*F +*FF FF F rMrRrrrTrTvs~(*u+++#++++++ HHSMHhsmHHHHHHrrT)r[restringrrrtypingrrr r8range BPCT_ALLOWED GEN_DELIMSSUB_DELIMS_WITHOUT_QS SUB_DELIMSRESERVED UNRESERVEDr6compiler:r^getincrementaldecoderr]rrTrRrrrysY 9999999999!!!!!!!!)?)'22@@UU3ZZ@@@  ! "V +  " V #f , , , "*( ) )bj122 +v+G44 ]]]]]]]]@OOOOOOOOOOr__pycache__/_url.cpython-311.pyc000064400000142701150043323140012417 0ustar00 bg/ddlZddlZddlZddlmZmZddlmZddlm Z ddl m Z m Z m Z mZmZmZddlZddlmZmZddlmZmZd d d d d ZeZd ed efdZGddZdZeGddZdZdZ ej!e da"ej!e da#edZ$edZ%ee e ddZ&dS)N)MappingSequence)suppress) ip_address) SplitResult parse_qslquoteurljoinurlsplit urlunsplit) MultiDictMultiDictProxy)_Quoter _UnquoterPi)httphttpswswssobjreturncd|_|S)Nyarl) __module__)rs @/opt/cloudlinux/venv/lib64/python3.11/site-packages/yarl/_url.pyrewrite_modulersCN Jc(eZdZdZdZefdZdZdS)cached_propertyaRUse as a class method decorator. It operates almost exactly like the Python `@property` decorator, but it puts the result of the method it decorates into the instance dict after the first call, effectively replacing the function it decorates with an instance variable. It is, in Python parlance, a data descriptor. cv||_ |j|_n#t$r d|_YnwxYw|j|_dS)N)wrapped__doc__AttributeError__name__name)selfr#s r__init__zcached_property.__init__!sM  "?DLL   DLLL $ s **c||S|j|j|}||ur|S||}||j|j<|SN)_cachegetr'r#)r(instowner _sentinelvals r__get__zcached_property.__get__)sW <Kkoodi33 i  Jll4  !$ DI rc td)Nzcached property is read-only)r%)r(r.values r__set__zcached_property.__set__3s;<<Ze,dAZ?e,dBZ@e,dCZAe,dDZBe,dEZCe,dFZDe,dGZEe,dHZFe,dIZGeHdJZIdbdKZJedLZKedbdMZLe dcdNZMdOZNdPZOdQZPdRZQdSZRddTdUZSedVZTeHdWZUdXZVdYZWdZZXd[ZYd\ZZd]Z[d^Z\ddTd_Z]d`Z^dS)dURL)r,_valF)requotez@:z/+)safe protectedrH)rIrJz?/:@z=+&;T)rIrJqsrH)rIrJrK)rIrKrH)rIrH)rI+)unsafe)rKr"N)encodedstrictc|tjdt||ur|St|turt |}nit|t ur|st dnAt|trt t|}ntd|s |dsd}d}nh|j }|t d |j }n"#t $r}t d|d}~wwxYw| |j |j ||dd }||d }|r||}||| ||d } ||d } t |d||| | }t&|} || _i| _| S)Nzstrict parameter is ignoredz$Cannot apply decoding to SplitResultz#Constructor parameter should be strrr"z/Invalid URL: host is required for absolute urlsz/Invalid URL: port can't be converted to integerT)encoderHhostpathr)warningswarntypestrr r ValueError isinstance TypeErrorhostnameport _make_netlocusernamepassword_PATH_REQUOTER_normalize_path _validate_authority_uri_abs_path_QUERY_REQUOTER_FRAGMENT_REQUOTERobject__new__rGr,) clsr1rNrOnetlocrTr`erUqueryfragmentr(s rrjz URL.__new__s   M7 8 8 8 99  J 99  3--CC #YY+ % % I !GHHH I S ! ! C3s88$$CCABB B Eq6 |<$%VWWW8DD!$I ))L#,d4QU*%%c!f--D 1**400  0 0d 0 F F F''A//E--c!f55Hc!ffdE8DDC~~c""   s"C** D 4DD ) scheme authorityuserrcrTr`rUrn query_stringrorNc |r|s|s|s|rtd|r|std|r| rtd| |||| | td|rG| r|} njtd|ddd} || j| j| j| jd} n(|s |s|s|sd} n|||||| | } | sm||}| r| |}| || | | } | | } |t|| || | d }|r| |S|S) zCreates and returns a new URLz@Can't mix "authority" with "user", "password", "host" or "port".z/Can't build URL with "port" but without "host".z6Only one of "query" or "query_string" should be passedNz}NoneType is illegal for "scheme", "authority", "host", "path", "query_string", and "fragment" args, use empty string instead.r"T)rQ)rQ encode_hostrSrN)r\r^rrarbrcr_r` _PATH_QUOTERrerf _QUERY_QUOTER_FRAGMENT_QUOTER with_query)rkrprqrrrcrTr`rUrnrsrorNrltmpurls rbuildz URL.builds*$  $ ( d d S   Q QOPP P  W\ WUVV V N ||#Q    "!"iR<<))L#, cht* h t D FF%%hdw;PWK&F 6##D))D 1**400  0 0d 0 F F F,,\::L++H55Hc lH E Et     >>%(( (Jrc(td|d)NzInheriting a class z from URL is forbidden)r^)rks r__init_subclass__zURL.__init_subclass__sKcKKKLLLrc|j}|js8|r$|js|jr|d}t |SN/rU)rGrU is_absoluternro_replacer r(r1s r__str__z URL.__str__ sWix )D,,.. )CI ) ),,C,((C#rc@|jjdt|dS)Nz('z')) __class__r&r[r(s r__repr__z URL.__repr__&s$.)::SYY::::rcFt|dS)Nascii)r[rQrs r __bytes__z URL.__bytes__)s4yy(((rc(t|turtS|j}|js*|r|d}|j}|js*|r|d}||kSr)rZrFNotImplementedrGrUrr)r(otherval1val2s r__eq__z URL.__eq__,sE{{c!!! !yy +T--// +==c=**Dzy +U..00 +==c=**Dt|rc|jd}|Q|j}|js*|r|d}t |x}|jd<|S)Nhashrr)r,r-rGrUrrr)r(retr1s r__hash__z URL.__hash__:smkoof%% ;)C8 - 0 0 2 2 -lll,,(,S 1C$+f% rc\t|turtS|j|jkSr+rZrFrrGr(rs r__le__z URL.__le__C(E{{c!!! !yEJ&&rc\t|turtS|j|jkSr+rrs r__lt__z URL.__lt__H(E{{c!!! !y5:%%rc\t|turtS|j|jkSr+rrs r__ge__z URL.__ge__Mrrc\t|turtS|j|jkSr+rrs r__gt__z URL.__gt__Rrrcht|turtS||fSr+)rZr[r _make_childr(r's r __truediv__zURL.__truediv__Ws/DzzS  ! !(((rc,||Sr+) update_query)r(rns r__mod__z URL.__mod__\s  '''rrc|t|jjp#|jjp|jjp |jjSr+)boolrGrlrUrnrors r__bool__z URL.__bool___s8 I  W  W$)/ WTYEW   rc|jfSr+)rGrs r __getstate__zURL.__getstate__ds  |rc|d/t|dtr|dd|_n |^|_}i|_dS)NrrrG)r]dictrGr,)r(stateunuseds r __setstate__zURL.__setstate__gsH 8  58T : : a(DII!& DI rc|jduS)zA check for absolute URLs. Return True for absolute ones (having scheme or starting with //), False otherwise. N)raw_hostrs rrzURL.is_absoluteos}D((rcp|jdSt|j}|dS|j|kS)zA check for default port. Return True if port is default for specified scheme, e.g. 'http://python.org' or 'http://python.org:80', False otherwise. NF)r` DEFAULT_PORTSr-rp)r(defaults ris_default_portzURL.is_default_portxs= 9 5##DK00 ?5yG##rc$|std|jjstd|j}|dd|j|j}||ddd}t|dS)z}Return an URL with scheme, host and port parts only. user, password, path, query and fragment are removed. URL should be absolutezURL should have schemeNr")rlrUrnroTrv) rr\rGrprar_r`rrF)r(vrlr1s roriginz URL.origins!! 7566 6y 7566 6 I""4qz16BBjjRrBjGG3%%%%rc|std|jdd}t |dS)zhReturn a relative part of the URL. scheme, user, password, host and port are removed. rr")rprlTrv)rr\rGrrFrs rrelativez URL.relativesT !! 7566 6i  2 663%%%%rc|jjS)zdScheme for absolute URLs. Empty string for relative URLs or URLs starting with // )rGrprs rrpz URL.schemeyrc|jjS)zQEncoded authority part of URL. Empty string for relative URLs. )rGrlrs r raw_authorityzURL.raw_authorityrrc^||j|j|j|jdS)zQDecoded authority part of URL. Empty string for relative URLs. Fru)rarrrcrTr`rs rrqz URL.authoritys4  It}di!   rc&|jj}|sdS|S)zEEncoded user part of URL. None if user is missing. N)rGrbr(rs rraw_userz URL.raw_users i  4 rc6||jS)zEDecoded user part of URL. None if user is missing. ) _UNQUOTERrrs rrrzURL.users~~dm,,,rc|jjS)zMEncoded password part of URL. None if password is missing. )rGrcrs r raw_passwordzURL.raw_passwordy!!rc6||jS)zMDecoded password part of URL. None if password is missing. )rrrs rrcz URL.password~~d/000rc|jjS)zDEncoded host part of URL. None for relative URLs. )rGr_rs rrz URL.raw_hostsy!!rcB|j}|dSd|vr|St|S)zDDecoded host part of URL. None for relative URLs. N%)r _idna_decode)r(raws rrTzURL.hosts3m ;4 #::JC   rcb|jjp#t|jjS)zPort part of URL, with scheme-based fallback. None for relative URLs or URLs without explicit port and scheme without default port substitution. )rGr`rr-rprs rr`zURL.ports&y~D!2!2493C!D!DDrc|jjS)zyPort part of URL, without scheme-based fallback. None for relative URLs or URLs without explicit port. )rGr`rs r explicit_portzURL.explicit_port sy~rcN|jj}|s|rd}|S)zNEncoded path of URL. / for absolute URLs without path part. r)rGrUrrs rraw_pathz URL.raw_paths2in t'')) C rc6||jS)zNDecoded path of URL. / for absolute URLs without path part. )_PATH_UNQUOTERrrs rrUzURL.path"s""4=111rcftt|jd}t|S)zA MultiDictProxy representing parsed query parameters in decoded representation. Empty value if URL has no query part. Tkeep_blank_values)r rraw_query_stringrrs rrnz URL.query+s/ $"74PPPQQc"""rc|jjS)zOEncoded query part of URL. Empty string if query is missing. )rGrnrs rrzURL.raw_query_string6syrc6||jS)zODecoded query part of URL. Empty string if query is missing. ) _QS_UNQUOTERrrs rrszURL.query_string?s  !6777rc@|js|jS|jd|jS)zDecoded path of URL with query.?)rsrUrs rpath_qsz URL.path_qsHs0  9 )11d/111rc@|js|jS|jd|jS)zEncoded path of URL with query.r)rrrs r raw_path_qszURL.raw_path_qsOs0$ != -99$"7999rc|jjS)zUEncoded fragment part of URL. Empty string if fragment is missing. )rGrors r raw_fragmentzURL.raw_fragmentVrrc6||jS)zUDecoded fragment part of URL. Empty string if fragment is missing. )rrrs rroz URL.fragment_rrcH|jj}|r(|sdg}nndg|dddz}nL|dr"dg|dddz}n|d}t |S)zjA tuple containing encoded *path* parts. ('/',) for absolute URLs if *path* is missing. rrN)rGrUrsplit startswithtuple)r(rUpartss r raw_partsz URL.raw_partshsy~      ( 4QRRs 3 33s## (QRRs 3 33 3U||rcDtfdjDS)zjA tuple containing decoded *path* parts. ('/',) for absolute URLs if *path* is missing. c3BK|]}|VdSr+r).0partr(s r zURL.parts..s/EEdT^^D))EEEEEEr)rrrs`rrz URL.parts|s*EEEEdnEEEEEErcR|j}|r|dkr;|js|jr+t|jdddS|S|d}|jd|dddd}t|dS) z]A new URL with last part of path removed and cleaned up query and fragment. rr")rnroTrvNr<rUrnro)rrrrFrGrrjoin)r(rUrr1s rparentz URL.parents } ts{{  TD$9 T49--B-DDdSSSSK 3i  chhuSbSz&:&:"r RR3%%%%rct|j}|r|dd}|sdS|dS|dS)zThe last part of raw_parts.rNr"r<)rr)r(rs rraw_namez URL.raw_namesM      !""IE !rRy 9 rc6||jS)zThe last part of parts.)rrrs rr'zURL.names~~dm,,,rc|j}|d}d|cxkrt|dz kr nn ||dSdS)Nr;rrr")rrfindlen)r(r'is r raw_suffixzURL.raw_suffixsV} JJsOO q 3t99q= 8O2rc6||jSr+)rrrs rsuffixz URL.suffixs~~do...rc|j}|drdS|d}td|dddDS)Nr;r8c3 K|] }d|zV dSr;Nr8)rrs rrz#URL.raw_suffixes..s&DDfS6\DDDDDDrr)rendswithlstriprrrs r raw_suffixeszURL.raw_suffixessc} ==   2{{3DD 30CDDDDDDrcDtfdjDS)Nc3BK|]}|VdSr+r)rrr(s rrzURL.suffixes..s/LLT^^F++LLLLLLr)rr rs`rsuffixesz URL.suffixess)LLLL$:KLLLLLLrct|dkr7t|dkr&|dstddSdSdS)znEnsure that path in URL with authority starts with a leading slash. Raise ValueError if not. rrzCPath in a URL with authority should start with a slash ('/') if setN)rrr\rSs rrfz$URL._validate_authority_uri_abs_pathsU t99q==SYY]]4??33G3G]U  =]]]]rcg}t|D]}|s|ddkrtd|d|r|n||}d|vr0|dt|dDz }q|dkr||||jj}|r,g|dd|}| r"t|}|r|ddkrdg|}d |}t|j |ddd S) zIadd segments to self._val.path, accounting for absolute vs relative pathsrrzAppending path z! starting from slash is forbiddenc3*K|]}|r |dk |VdSr r8)rsubs rrz"URL._make_child..s7sGJczzCzzzzrr;r"rTrv)reversedr\rwrr@reverserGrUrstriprrDrrFr)r(rArNparsedrCold_pathnew_paths rrzURL._make_childsH%% # #C 1v}} NcNNN!<##d&7&7&<&  A@xs++11#66@@F      '-f55F '&)r//v88F## I  HB  D Dd    rcd}|dr d}|dd}|d}|dt|zS)Nr"rr)rrrrD)rkrUprefixrAs rrezURL._normalize_paths` ??3   F8D::c??!9(!C!CDDDDrc< |d\}}}t|}|j}|r|d|zz }|jdkrd|zdz}nM#t$r@|}|s|r|cYSt|}YnwxYw|S)Nr[]) partitionr compressedversionr\lowerisascii _idna_encode)rkrThumanipsepzones r _encode_hostzURL._encode_hosts ( NN3//MBTBB=D #d "zQTzC' & & &::<||}|r||}t|dkr|ddkrd|z}t |j|dddS)z$Return a new URL with path replaced.rrr"rTrv)rwrrerrFrGr)r(rUrNs r with_pathz URL.with_paths 2$$T**D!! 2++D11 t99q==T!W^^:D49%%4rB%GGQUVVVVrc#K|D]\}}t|ttfr5|D]1}||dz|||zV2V||dz|||zVdS)N=)r]listr _query_var)rkr0pairskeyr1rs r_query_seq_pairszURL._query_seq_pairss F FHC#e}-- FHHA &+++ffS^^A5F5F.G.GGGGGGHfSkkC'&&1D1D*E*EEEEEE  F Frct|}t|tr|St|trbt j|rt dt j|rt dtt|St|tr%|turtt|Std ||)Nzfloat('inf') is not supportedzfloat('nan') is not supportedzMInvalid variable type: value should be str, int or float, got {!r} of type {}) rZ issubclassr[floatmathisinfr\isnanr;rr^format)rrks rrBzURL._query_vars1gg c3   H c5 ! ! !z!}} B !@AAAz!}} B !@AAAuQxx== c3   CtOOs1vv;;  3   rc|r%t|dkrtd|}n+t|dkr |d}ntd|d}nt|trCjd|}nt|tr |}nt|tttfrtdt|tr*jdfd|D}ntd|S)Nrz7Either kwargs or single query parameter must be presentr&zAInvalid query type: bytes, bytearray and memoryview are forbiddenc3xK|]4\}}|dz|zV5dS)r@N)rB)rkrr0r(s rrz%URL._get_str_query..s_AEAq C&&););"<"<<rzRInvalid query type: only str, mapping or sequence of (key, value) pairs is allowed)rr\r]r_QUERY_PART_QUOTERrrEitemsr[rxbytes bytearray memoryviewr^r)r(argskwargsrnr0s` @r_get_str_queryzURL._get_str_querys  X4yy1}} MEE YY!^^GEEVWW W =EE w ' ' ,FHHT2265;;==IIJJEE s # # &&u--EE y*= > > S x ( ( ,F HHINEE<   rc|j|i|pd}t|j|jj|dS)a[Return a new URL with query part replaced. Accepts any Mapping (e.g. dict, multidict.MultiDict instances) or str, autoencode the argument if needed. A sequence of (key, value) pairs is supported as well. It also can take an arbitrary number of keyword arguments. Clear query if None is passed. r")rUrnTrv)rXrFrGrrU)r(rVrW new_querys rrzzURL.with_querysU(D'888>B  I  DIN)  D Dd    rc0|j|i|}d}|Gtt|d}t|j}||t |j||pddS)z)Return a new URL with query part updated.NTrr")rnrv)rXr rrnupdaterFrGr)r(rVrWsrnrZs rrzURL.update_querys D  0 0 0 =!)A"F"F"FGGIdj))E LL # # # I  T%8%8%?%?%E2  F FPT    rc|d}n9t|tstd||}|j|kr|St |j|dS)zReturn a new URL with fragment replaced. Autoencode fragment if needed. Clear fragment to default if None is passed. Nr"zInvalid fragment type)roTrv)r]r[r^ryrrFrGr)r(rors r with_fragmentzURL.with_fragments~  LLHc** ;344 400::L   , ,K49%%|%<>>>rc0|||S)zAReturn a new URL with the elements in other appended to the path.rv)r)r(rNrs rjoinpathz URL.joinpathZsw777rc t|jd}t|jd}|j}|r||jd}t|jd}dd|jD}t|j d}tt|j | ||||jjd |||S) z.fs\  1 NN<733\!W5M5M N N      rr"Fr)rjrrrcrTr*rUrrnrRror rrprarGr`)r(rrrcrTrUrsros r human_reprzURL.human_repr^sDIw// w77y  <$$TYd$;;DDIt,,xx   ((**       r22  !!IN % "     r)r")F)FTF)_r&rr6 __slots__rr/r.rwrdrxrgrQryrhrrrrrj classmethodr}rrrrrrrrrrrrrrrrrrrrpropertyrprr rqrrrrrcrrTr`rrrUrnrrsrrrrorrrrr'rrr r staticmethodrfrrer*rar2r5r7r9r<r>rErBrXrzrr_rardrrgrkr8rrrFrFOsN#Ige$$$G I7eDDDLW$$777NG6dERRRMg6VEEEO fuEEEwFE::: f--- IYc***N9%%%L.d.....`    DDDD[DLMMM ;;;)))   ''' &&& ''' &&& ))) ((( $    ))) $ $ $&&& & & &  X   X   _   X --_-""X"11_1""X"!!_! EEXEX  X 22_2##_#X88_822_2 ::_: ""X"11_1_&FF_F & &_ &  _ --_-_//_/EE_EMM_M\    @ E E[ E[*QV[2LLL   4   2   0   ,*/WWWWWFF[F  \ $&&&P   (    LLL&   @$$$*???"(-88888     rrFc|s|Sd|zD]-}||vr'||dt|d}.|r|Sdd|DS)Nr02Xr"c3`K|])}|r|nt|V*dSr+) isprintabler )rcs rrz_human_quote..s9AA! 511U1XXAAAAAAr)replaceordrsr)r]rMrts rrjrj|s  6\// 66 !-Q---..A}} 77AAqAAA A AArc tj|dS#t$r+|ddcYSwxYw)Nridna)rydecoderQ UnicodeError)rs rrrsd2{3::g../// 222zz'""))&111112s&)2AAc tj|ddS#t$r+|ddcYSwxYw)NT)uts46rry)ryrQrzr{)rTs rr%r%sk3{4t,,,33G<<< 333{{6""))'222223s(+2A A cjttdSr+)r cache_clearr%r8rrrrs,rchttdS)N) idna_encode idna_decode)r% cache_inforr8rrrrs1$..00#..00  ridna_encode_sizeidna_decode_sizectj|tjatj|tjadSr+) functools lru_cacher% __wrapped__rrs rcache_configurersD99&'7889QRRL89&'7889QRRLLLr)'rrIrXcollections.abcrr contextlibr ipaddressr urllib.parserrr r r r ry multidictr r_quotingrrrrir7rr rDrFrj _MAXCACHErrr%rrrr8rrrsV -------- UUUUUUUUUUUUUUUU ////////((((((((cC@@ 6886 ========>0i i i i i i i i X!BBB  Y22 2Y33 3 (1ISSSSSSSr_quoting.py000064400000001031150043323140006731 0ustar00import os import sys __all__ = ("_Quoter", "_Unquoter") NO_EXTENSIONS = bool(os.environ.get("YARL_NO_EXTENSIONS")) # type: bool if sys.implementation.name != "cpython": NO_EXTENSIONS = True if not NO_EXTENSIONS: # pragma: no branch try: from ._quoting_c import _Quoter, _Unquoter # type: ignore[assignment] except ImportError: # pragma: no cover from ._quoting_py import _Quoter, _Unquoter # type: ignore[assignment] else: from ._quoting_py import _Quoter, _Unquoter # type: ignore[assignment] _quoting_c.cpython-311-x86_64-linux-gnu.so000075500000363310150043323140014107 0ustar00ELF>F@@8 @66@@@  PPP##0}00:H}HH888$$PtdcccQtdRtd0}00GNUձ0D11wS0@Ye51Mz ^^ lf ,:\lJI > [rY$ : r6*Z -aj w) oJl pi%[C FG:4^\8 )R"Lu;L  g }@ @ J__gmon_start___init_fini_ITM_deregisterTMCloneTable_ITM_registerTMCloneTable__cxa_finalize_Py_NoneStructPyBaseObject_TypePyObject_GetAttrPyObject_GC_IsFinalizedPyObject_CallFinalizerFromDeallocPyExc_DeprecationWarningPyErr_WarnFormatPyExc_TypeErrorPyErr_Format_Py_DeallocPyLong_AsUnsignedLongPyExc_OverflowErrorPyErr_SetStringPyErr_OccurredPyLong_TypePyObject_GC_UnTrackPyErr_FetchPyErr_NormalizeExceptionPyException_SetTracebackPyErr_SetExcInfoPyErr_ClearPyObject_RichCompareBoolPyCapsule_NewPyDict_SetItemPyObject_GetAttrStringPyDict_SetItemStringPyExc_AttributeErrorPyErr_ExceptionMatchesPyThreadState_GetPyInterpreterState_GetIDPyExc_ImportErrorPyModule_NewObjectPyModule_GetDictPyObject_GenericGetAttr_PyObject_GenericGetAttrWithDict_PyType_LookupPyDict_DelItemPyType_ModifiedPyExc_RuntimeErrorPyErr_GetExcInfoPyErr_RestorePyDict_NewPyImport_ImportModuleLevelObjectPyList_NewPyDict_NextPyUnicode_ComparePyTuple_NewPyObject_CallPyErr_SetObjectPyErr_PrintExPyUnicode_FromStringPyErr_WriteUnraisablePyLong_FromLongPyUnicode_AsUTF8AndSizePyCode_NewEmptyPyExc_NameErrorPy_EnterRecursiveCallPy_LeaveRecursiveCallPyExc_SystemErrorPyCFunction_TypePyType_IsSubtypePyLong_AsLongPyMem_ReallocPyMem_MallocmemcpyPyErr_NoMemory_PyDict_GetItem_KnownHash_PyObject_GetDictPtr_Py_FalseStruct_Py_TrueStructPyObject_NotPyFrame_NewPyTraceBack_HerePyUnicode_FromFormatPyUnicode_AsUTF8PyObject_SetAttrPy_GetVersionPyOS_snprintfPyErr_WarnExPyBytes_FromStringAndSizePyUnicode_FromStringAndSizePyImport_AddModulePyObject_SetAttrStringPyUnicode_InternFromStringPyUnicode_DecodePyObject_Hash__pyx_module_is_main_yarl___quoting_cPyImport_GetModuleDictPyDict_GetItemStringPyTuple_PackPySlice_NewPyType_ReadyPyImport_ImportModulePyExc_ValueErrorPyNumber_AddPyUnicode_ConcatPyUnicode_TypePyUnicode_ContainsPyCMethod_NewPyObject_IsTruePyDict_Size_PyUnicode_ReadyPyMem_FreePyMethod_TypePyLong_FromSsize_tPyObject_GetItemPyTuple_TypePySequence_ContainsPyUnicode_FormatPyNumber_InPlaceAddPyBytes_FromStringPyObject_SizePyList_TypePyExc_StopIterationPyObject_GetIterPyErr_GivenExceptionMatchesPyExc_IndexErrorPyUnicode_DecodeASCIIPyUnicode_FromOrdinalPy_OptimizeFlagPyUnicode_DecodeUTF8StatefulPyUnicode_FromKindAndDataPyUnicode_JoinPyList_AppendPyExc_AssertionErrorPyErr_SetNonePyInit__quoting_cPyModuleDef_Initlibpthread.so.0libc.so.6GLIBC_2.2.5GLIBC_2.14 ui   0h8h@@Ȥ@ГȤ@`xh `(x0h@Hbhp``_^ha _0x8`Xp`(ahXb`aЕXؕ``Pa H(XaH@Pbp8xb0b(Ȗb bb8@b`hbb`ؗb@`(0bPإXKbxХaȥaȘИbb @b@Hbhpbb3ba`0x8aXp`Haha`aКXؚ `P_ H(8aH@Pbp8xfb0(b(ț` xab8@yb`ha`b؜apb(0bPؤXbxФ`bȤbȝН`H\` hG_Q]]`l`h0mȟ iw]] ]j`ȡ iw]]` ]Х%]  ( 0 8!@'H(P)X:`;h=p?xJMQTW[]ceȏfЏh؏orv{ (08@HP X `hpxȐАؐ "#$%& *(+0,8-@.H/P0X1`2h3p4x56789;<>@AȑBБCؑDEFGHIKLN O(P0R8S@UHVPXXY`Zh\p^x_`abdgijklȒmВnؒpqstuwxyz {(|0}8~@HPHHUOHt+H5O%O@%Oh%Oh%Oh%Oh%Oh%Oh%Oh%Ohp%Oh`%Oh P%Oh @%Oh 0%Oh %zOh %rOh%jOh%bOh%ZOh%ROh%JOh%BOh%:Oh%2Oh%*Ohp%"Oh`%OhP%Oh@% Oh0%Oh %Nh%Nh%Nh%Nh %Nh!%Nh"%Nh#%Nh$%Nh%%Nh&%Nh'p%Nh(`%Nh)P%Nh*@%Nh+0%Nh, %zNh-%rNh.%jNh/%bNh0%ZNh1%RNh2%JNh3%BNh4%:Nh5%2Nh6%*Nh7p%"Nh8`%Nh9P%Nh:@% Nh;0%Nh< %Mh=%Mh>%Mh?%Mh@%MhA%MhB%MhC%MhD%MhE%MhF%MhGp%MhH`%MhIP%MhJ@%MhK0%MhL %zMhM%rMhN%jMhO%bMhP%ZMhQ%RMhR%JMhS%BMhT%:MhU%2MhV%*MhWp%"MhX`%MhYP%MhZ@% Mh[0%Mh\ %Lh]%Lh^%Lh_%Lh`%Lha%Lhb%Lhc%Lhd%Lhe%Lhf%LhgpATIUQH5^#HHuPE1Ht'LH&AąxHMuHDZ]A\ATI1HU1Q6HtGH5"^HLHHExHAHEuH-HHEuHADZ]A\AVIAUIHATUSDHt5H;GHuE1tHLLAHMu)HHGAH8t?E1[D]A\A]A^AVAUIATUQ`Hx7HPKHuHCKHt#H9tHGH5H8E1L%rMt I$H5VLIHtHIHuLHtH(IHAH HLH xkAH LLHxHAH LLHix%E1H LLHIxIHMHP1HMHtH9H=0NHH HMHtH MHM1H5MHMHsH MHM1H5M_HhMHBH `NL aN1LcNHTNH55N HHH=UpH5VpAQWIIH5M5MH HH ML M1LMHMH5MHHH=oH5oAPWIIH5M5MH H\HbLH HHoHfHnH=HfHnH1oflHoHoHoHnHnHn)KyA L5A H5 oH=eIxH5MH=&oH?HxH=/HxHHH=FHnHjKHnH HUKeH5nH=FHECH5/MH=nHp%H]H=HnIH H5HIHH@u+H5H HH5eH81IE(MM Ht HHLLH=w.HZ5AH ~HRH57H81UILt$P1H #AQL?LAHiT1L1ZYIMuLI $ LA L5AH=#mtBH=mtLDH=D#H=lHt7HHlu' HuH4H5H81H=l I $uL]HH9 HJHSHHHHJH=IHHBiIHH uHH5qJLHH H5VJH=lHH uHH5 JLHHK H5IH=kH9_H uHtIuLgH JH=)kHHHkuEHIH=jHHHju#H=jL-3H5IL9tL9uXH H=jHjHuH=jH5jL9tL9u:H H=[jHTjHuHjH GH9Hu"L5FMtI7H=HIH=HHFH5F IMp HgjH FH9Hu"HFHtH7H=bHHH=QHHZFH5[F& HHHLOIHIuLH uHH5JHLHHIuLHCH;1t@L9t;HHH41HSH5TA L5AH81IH=hHhHuH=hH5hL9tL9uXHAH=hHhHuHpGH=ihHHH\huWE1)(H)HLHHH5FH=hH'H uHbHhH DH9Hu"HDHtH7H=nFHH=]FHvDH5wDRHHH=_GHwIHH uHH=gL9u'H/H5dAI!AGH8@7LCAąIuLHgAH@_H;Cu"L=CMtI7H=EIH=}EHCH5CrIMLIHtIu%LAHtAY!AHwDLHH PFHfH BH9Hu"L=BMtI7H=D<IH=DHBH5BIM#LIHtIu%LSHtAf!AIDLHH EHIfH :BH9Hu"L=%BMtI7H=$DIH=DHAH5AIMH=EL-HHIuLH=-eH;=-u.HM-H5A!L5AJH8HAąH uH6AH^eH ?AH9Hu"H*AHtH7H=9CHH=(CHAH5AHHH9IHtH u,H"HtA!L5?AKDLHH CIIHA11H=?HH8H5BH=hdHrH uHHLA11H=a?lHHH5AH=dH9H uHHHH5AH=cHNH HA AIL5yL\l1A L5A LA A L5LA A L5LA AL5~A8!L5AFi1AD!L5pAGRA!L5[AJ=A!L5ZA(A!L5EAA!L5AH uSHdIA A A A A ALL5HM;H.Hu$AK!AGAH L5AAL L5~AAM L5fAAN L5NAAr L56AAt L5AAv L5AkAx L5ASA L5A;A L5A#A L5A A L5AA L5vAA L5^AA !L5FAA6!L5.AFAB!L5AG{AW!L5AHcAd!L5AIKAz!L5AJ3A!L5AKA!L5AA!L5AA!L5nAAz L5VAA|!AJ!H[]A\A]A^A_H=6H= ;H;H9tH&Ht H=:H5:H)HH?HHHtHu'HtfD=:u/UH=^'Ht H=$hq:]{f.ATIUHSHH(Ht HՅu!H{01Ht[LH]A\f.[]A\ff.HuC10Ht'HG&H 8^HfHnHHflHP@(Hf.H1&H5"^18Hu#10Ht H]HPHfDH%H5]18HGHHtfDHGHu@f.HtH@tH|$cH|$uH|$puH|$HGH@HHÐUHGHL@t3H$LHeH81AHEu&]fDH$HHH5H81Hmt 1]H1ff.ATUHHGHGE1HtHt&Hxi|AHuAHD]A\fDGAĩtH $H5H8ADHu5HtfDH#H52AH8\f.H@`HtfHHtZHHtPH#H9Eu'@HHmA9Hr,HH5NHHuDH6H #H5WAH8fUHGHHH}HtHEH/t\H}(HtHE(H/t5H}0HtHE0H/tHEH]H@DffHgZHJ]USHHH-H"H(HEHk(HHEHt H/tAHEH{0HHk0HEHtH/tH1[]fH1[]ffAWAVAUATIUHSHH(L|$Lt$Ll$LLL LLLHulHT$HtH|$H}xQHT$HtHH|$HtHHt$HtHI<$HuHH(1[]A\A]A^A_fDH|$I$HEHHtH/t9H|$HtH/tAH|$HtH/t!H([]A\A]A^A_DffH(H|$HT$HD$HD$Ht$HD$MH|$Ht)H;=T tHT$Ht$[H(fDH/tBH|$HtH/tJH|$HtH/tRHH5,H8H(H|$HuH|$Hu말AVAUIATUHHt}H=WIIHHHLE1LHL-IHmtHL]A\A]A^@H8HL]A\A]A^f1IHtpH=JWEIHtMHHt@E1LLHLI,$ItLHmhvfDI,$uLHE1]LA\A]A^ff.@AWAVAUATIUHSHHHHT$L|$0Lt$(LD$Ll$8HD$(HD$0HD$8@LLLH_+H Ht$(HqHHfDHPHHtH92uHT$0H|$L)HHF;H!f.HFH9Gt.HJHHtYH9H9uHD$0HL$L)HKHT$^HT$ HJHHt$(HufI9ufDHFH9GtgIL9twI$H8H9uHT$HH5RHH81HH[]A\A]A^A_DHuHt$(HT$xcHt$(tIL9uHHT$H5GHFDHMHT$H5H81wHH[]A\A]A^A_HTHt$(HHL$0L)H|$H HHt$(@AUATUHHH@uvt@tv1IHtO1HHImItpMt3IL$@tmLHfI,$u]LA\A]@]A\A]fH]A\A]H9]H5A\A]H8DLHfDH HH5H815UH H|$HT$Ht$wH|$HtHHt$HtHHT$HtHH=^BHT$Ht$H|$HHt&HHmtH ]ÐHH ]fH=H ]ff.AUIATLHH={RHGHHtIMtHLA\A]DIMuHdLH5[H81HLA\A]ff.AUIATHHGHHtIMt#HLA\A]IMuHH8tHLH5H81zATIUSHHtHHHXID$HHtsH=_uH1LHIMt$Hmt L[]A\DHL[]A\IHt-E1fDE1[]LA\DL1HkIH7H5 H8 ff.ATIH5UHSHH9t AtMHUBtBHZ ujHmH=zuCLHIMt!L[]A\f[LH]A\;IHtE1[]LA\1HmH5VH8V@AUIATIUSHHsHIEHLhHHX ID$I$HHH=uq1HLIMtMHmtI,$t&HL[]A\A]fHI,$uL HL[]A\A]3IHt8E1fDHE1[L]A\A]1HL{InHDH5-H8-SUHHGt~HGHtr 螽藽fH5!HL$HVHL$H9IHH@H0Ht$H<$LAHHHCDxHCL(IEMcIIHHH IHD$LD$ԼLD$HD$FI8M(H/谼L Hu Hqff.AWAVAUATUSHH(H-!L=9 LnHl$L|$H MML-? HEL9t H;w H{HEH/NL% HkM9M9u M9:k H-AH5> H}H9t 訿@HUB1Lj UHmH=պk1HAHHDH{(H/Hk(mHHH5 LHL%AL5IAID$LMtH=uHLHLAIlM3HmH{0H/Lc01H([]A\A]A^A_DLXŃؼHMkHEL5@LM}H=虹u31HLAH¼HfkHWH H=H([]A\A]A^A_ÐfDHعH{0H/軹fD諹@fDLHLRIHfDiHmSHt$ _t$ 91fMwHI,HH~RHL5s KLH0HVpHt JDHIIAHuHfHl$Lt$fH"H3H5H8HH5H8J1HT$LLH5 ufH H=5ZHHHHH5H81 =@H1L蛻HH[f.HHHH5oAUL E1H H81蚻XZ>fDhff.AWfAVAUATUSHH(H-lLn)D$fHnfl)$HML5IAHUHQH9t L9IT$H9t M9@fAnfAnfbfCfoEEufo(C L9M HE2LE  HUHM>1H{ A(EʃHHADL9 vL%yL-ID$HHlH=f9q1LLI_M.LA AI,$HmtH JDDH=H([]A\A]A^A_HU0HuH@HD@HmfHk0C0M9PAL$ I$MD$ IT$HM1H /f.AHHADD\L9s vH-L-HEHHH=ų1HLHHHJHmLA AH0NBHs *fAHHAD L9 fvHHLBHHH5H81ɷH([]A\A]A^A_DLBHHHH耳&It$0IT$H@HEPfIHs #fAHHADI9 yL\MHIHH~DL5 HKLH0HV@HtJHIIHH|$H,$Ld$HH;=L5AH;=XDL9AŃ*H|$HEH;=]AH;=DuRL9tMشAǃWH4 H H=nYEH|$EmfHH5AA H8.L1LLIHA AH0@M I,$t.1f.kH' L 1vIH &fDHH@<@|L9t yHA LA議A AHHH5H8J!u5HLIHuif.I! ffDIT$BtLj Md$H=LuHLAIJMaHmvIFLLIH&IELHHEHH~H L[]A\A]A^fDH`H5 LHHV躪HHD$HCHLmHHHH5߻AUL AH 8H81XZH H=E1H L[]A\A]A^DHEIHPHU@IFHLIHpHEHIM I:HFHHD$YH\Hl$fDH8}E1=L%i L- ID$HH9H=^1>1LLIWM5LI,$I#'fDH FH=`MME1M$<f蛨I! HuHH5÷T$ H8迦T$ fI$<fLI'#LHT$LLLKH5+V~L1LwIHI##ԧI##H0fAWAVAUATUSHHcH92H~IIIHnHEH;-IH;-u H9DHmxI|$Eu Il$ HEH9I}0H/'I|$Im0Il$(HEH9I}(H/I|$Im(FIl$0HEHEH9t H;I}H/ID$ImHUHOHHH[]A\A]A^A_fHئAƃ WHAH5YHFIELHHHHH/IEH5LHHIMIEH5LHHHIEHIEHH<I|$Md$8I$H}H;=uLuMhL}IIHmLLL3I.II,$M_I/ImnL赢a諢fD蛢fDH舢{{fDHt;ADH H=:H1[]A\A]A^A_fL(fDHH5AH8蔢 D1QIHt!HL莢I.HHA XH5H9t$uLHI-IDHUBtLj aLuH=Ʋ虠1LLAIMI$IHI$PL:DfIHt!HL裡I.HHA mDH&HH}H9HXH)HqH~1H;THH9uHEHJH5AHWH81ffDHm H8 fD~IHt!HL軠I.H>H8A D۟fDH%HH}H9HXHHqH~1H;THH9uHEHJH5AHWH81f覠IHtHLI.HtzHA LA LL؞;HL踞L訞yHHHeHH5AH81臢"HHH9sHuH;taH82L(=LBHH5:AH8脞 f.KI=A `[gfDH9IHt"LH3ImIM6AHmHT$ JT$ |HuHH5H8豝I,$A%DE1HH5dAH8tHpH5CAH8SnL趜HHLl$H|$@IFHF(HHD$ HF HD$HFHD$軓HfDAAHmuH蕔H GDDH=Ql17DLhfHX軘HL8H(LLNL%E1u H H=IEHP1LA\AHF HHD$HFHD$膒HUfDAA袕HuHH5פH8דI.I7FLt$"t$1fHIH8Imt*H H=1fDLfD#HE1A$D&L}MDLmIIEHmtLLLI/I?L>2H@`HLHH<HH.H@H3H9f.,LeID$HH1HcHDeHmH詑@HmHE1芑uDDeAMcHmfDeEII IDDeEII yHH5IHHH@!HYI뎾HT$LLLtH5\rHHH H5yjL AH'H81衔Y^-DHHHEH5lHH81mtxHLH5H81H:HHAH5jL )H BH8H1 _AXHH=HH5H8L"H@`HHHHHHH9Xu{HGLgID$HHԫHcHDgAMcH/6DgGII IDgGII DgH5HHmHmPHݎCH|$H|$ItH|$OH|$I]ݐHuHaH5H8H 2H=8S1Lt$Pt$H H= $H NH=1H H=ã1AWAVAUATUSHHG L%I$~HHHC0H5LeHHE HC(HHE(HCHHE0HFHCHHHIM-L=>M9DIHWIEHHLhsIHgI.HmLHH H9HWL%MGI$xIHHCHIFHHM~(IF I?IHfInfInfl@HEHPHUIo(HEHMt ImHL[]A\A]A^A_fHIH8 蔍L=ILk0M9M@L%I$I,$ aI.ALT$ I脋T$ Mt I,$0H "H=`KHHEE1HHEHH2DL L9{(/LkM9%H2H@H9L%MI$蚌IHHCHIFHHIF HEIn(`IHfInfInfl@Hm8(fHȎI IﻄLT$ 4T$ HL9LE1I,$uE1LT$ ݉MT$ -IXH hH=E1HEHR I.I@H=9HjH5kIHH TH=2H=H H5 FIH:H=L5HGLHHIMHLH5H81誌V fH=L52HGLHHIMHLH5H812DI,$H H=SH H=e"IdIa ff.AWAVAUATUSHH0H薉HHjSL- CIEL%II$H{ SIHwL$وL$HI!fHnfInfInH5Cfl@fInfl@(HFHCHHHHHHH$H9JIH~HEHLHhʅIHvIm3I/Hj H H9HaLMIILD$·LD$HIHCHIEHHIE H$IE(H茇LD$HII$fInfInMflHJ@I $L`(IH:LMLIiH+Hm HML-QCIEL%I$HIH8蔆HHH$H H H9HML%M]I$~IHHCHIEHHIE IM}(EIHAfInfInH,$fl@IHPIHHmHL[]A\A]A^A_LLHhHOE1AAH DDH=MUI.tE1G15fAHmImthE1AE11I,$t3MtI(txMtImxLD $LD $cLLD$D $/LD$D $@LL$L$fDHL$L$dLD $D $sA3DH=L-HGLHHIMHLH5ݜMAQH81聆A fDH=L-*HGLHH\IMuH~LH5uMAH81H,$Af.MAA@MAAa@H=HH5MAQݽA IHyfDH=QHJH5K覽IHMH,$AAbfASMA @MH,$E1AADA^MAA WIAJIMH,$E1AA=AWAVIAUATUSHXHt$H|$8HT$HHD$8Ht$@HD$@HD$H[LH9H|$8IHt H/HD$8H|$@Ht H/HD$@H|$HHt H/HD$H1IH5IvH=L1HHH(AHtHmtHHXD[]A\A]A^A_fDI.HAH5ܕuLrfH5ɕ~@HXfDK>fD;fD+fDH=i$uH=A111~HT$HHt$@H|$8mIFH;Jt H;yIE1H$E11A4Cũ@HD$MMBl(HH<$IFH I9NSI9IFJIHHt HmMoIHCHCHtbHXHHHIHCHH5AH8I~H#1fH}YLD$H$LLD$HH'L$L$Ht HH2H9L$~L$IMhHIIpHL}I9}K\IHf|"fDHH5H8J}D]yH XH=A}HݾWI.uLT$4$f|4$T$DH@`HHHHIHH@H-OH9fD;IBH>HABũI*AL{4LLIHH@HH$HI}H}HH4H5H8{LH5d1IH|H@@HLLT$B~LT$H$HHH5gLT$H8j{LT$I*LzfDI*1E1HLzHwH5؉LT$H8{LT$HP@HVHP@CHXHt.HJH~1H;tHH9uTuHH9HuH;5@H@`HhHHXLT$LLT$HI=H@H9uPIC1HtHuXACũI+sLLT$AyLT$\LH5KLT$HIBH@HLLT$L\$&|L\$LT$HtHHL\$H5@LT$H8CyL\$LT$LT1TH @AH=]`zLT$Hc~LT$zLT$HfHH5OH8xLT$FL\$HH5`LT$H8xLT$L\$LVM1H;DHI9u1HLHQtA@t8H9VLXMMYM~1I;L0HI9uHI9uVHL$wL$9HT$HHt$@AH|$8{PH ͑H=VL\$LT$/yLT$L\$HzH@`H7HH'LT$ LL\$L\$LT$ HHD$H9huvHT$HBIHB1HtHBũHT$HHD$HHHL\$ LT$!vLT$L\$ H5)HL\$ LT$LT$L\$ HHD$YL\$ LT$HxzH|$xLT$L\$ H^Ht4HL\$ H5 LT$H8vL\$ LT$$wLT$L\$ HtH<H5H8uLT$L\$ H@`HHHL\$ H|$LT$LT$L\$ HHH9hL\$(LT$ H|$GH|$LT$ L\$(H/_L\$ LT$tLT$L\$ AL\$LT$vLT$L\$HH5H5VH5p=LT$L\$ HH\L\$ LT$cvLT$L\$ HHH5$HHH9HuH; uAWAVAUATUSH(HH9rH~IIHnHELl$HLoD$AD$0Hmt]IbIo HEH;-jH;- uAH9tHHLl$H|$@IFHF(HHD$ HF HD$HFHD${cHfDAWAHmuHUdH DDH={,17DL(dfHd{hHLcHcLcLcNLc%E1 H H~H={sIEHP1LAAHF HHD$HFHD$FbHUfDAhAbeHuHH5tH8cI.IFLt$bt$1fH H8cImt*H d}kH=z腟1fDLbfDfHE1AyD{L}MDLmIIEHmtLLLSI/I?La2H@`HLHH<HH.H@HH9f.,LeID$HH-~HcHDeHmHia@HmHE1JauDDeAMcHmfDeEII IDDeEII yHH5 z։HHH@!HcI뎾,HT$LLLM|H5!"rHHOH {H59tjL {AH|H81adY^-DHHHH5,{H{H81-dxHDLH5tzH81d:HHAH5sjL zH {H8Hf{1c_AXH_aH=H[H5xH8 `"H@`HHHHHHH9Xu{HGLgID$HH{HcHDgAMcH/^DgGII IDgGII DgH5w謇HHmHmPH^CH|$`H|$ItH|$H|$I]`HuH!H5lwH8^H xUH=u1Lt$^t$H xH=yuH xH=Wuš1H }xcH=3u螚1AWAVAUATUSHHH;5HFHH$HӅMIE1} McC HEEILHI9U щ@D @HMHF$AE}A%tOAVt A  DAAA$(=EAN4$ND9McׄI<EIIH9U щ@ @nHMHDAAuHc H HHIH9U A@AAEH}H<EKA AKEKɃAKEK ACt. HSHCH;H9u6L HH9L6\HH"H;HSLkD$EHCD9,$CHEH %HID]H+ EHwHH;HHD$HCH;Cu@L H@HL$H9GLz[HL$HHnH;HCLk%HCKHHCH;H;Cu@L HHL$H9L[HL$HHH;HCLkFHCKHHCDL$H;A0H;CuKL H|DL$HL$H9LZHL$DL$HH*H;HCLkD HCKHHCIH;I H;CuJL H HL$H9tLLL$BZLL$HL$HH<H;HCLK%HCKHPHSD< a7DH;H;SuTHDT$L HL$H9 LLL$YLL$HL$HDT$H[H;HSLKDHCKHHCAA A0EH;H;CuJL HHL$H9LLL$9YLL$HL$HHH;HCLKD,HCKHHCHH;IH;Cu@H HH9{HHL$XHL$HHH;HCHK%HCKHPHSD< 0H;H;SuHH&L$L H9LLL$UXLL$L$HH|H;HSLK HCKHHCAA A0EH;H;Cu@H HH9HHL$WHL$HHrH;HCHKD,HCKDH߃?@΀诐H|$(HT$8HD$(HD$0Ht$0HD$8aUH|$(H+H;=dHT$8Ht$0gUBLZHH@3VHjEDOЃ vOOAAA ADE˿IC|0C| tfHCH;H;Cu@L H#DL$H9L]VDL$HHH;HCLcD HCKIELHI9 U щ@@HMHB  a zHHHHH9oM ȉ mHEHGaE1A) Hu0HMH@HEE@OOS@@ HMHF$! fHRH nH=kӐ1HH[]A\A]A^A_f@HMHF$afHCH;H;Cu@L H5DL$H9gLoTDL$HHH;HCLc%HCKHHCDH;Dy0H9Cu@L HθDL$H97LTDL$HHH;HCLcD<HCKHHCAA J A0EH;H9Cu6L H[H9LSHH`H;HCLcD<HCK^@HMHAuDyHcJHD\$Ht$LT$QLT$Ht$D\$0 HE HCH;H;Cu6L HH9hLRHHH;HCLc+EHCKHu0HMH@HE@IHCH;I H;CuJL H&HL$H9LLL$[RLL$HL$HHH;HCLK%HCKHHCH;H;CuJL HHL$H90LLL$QLL$HL$HH"H;HCLKEHCKHHCI  A0EH;H9CuJL HFDL$HL$H9L{QHL$DL$HHH;HCLkD HCKHHCHH;IH;Cu@H HصH9HHL$QHL$HHH;HCHK%HCKHPHSD<  0DH;H9SuJHgDL$H H9|HHL$PHL$DL$HHsH;HSHKD HCKHHCAA b A0EH;H;Cu@H HH9HHL$PHL$HHwH;HCHKD,HCKHHCH;H;Cu6L HH9CLOHHH;HCLk%HCKHPHSD<  0DH;H9SKD@s HMHB HaHZHH$HHk fDH|$0Ht H/h H|$8Ht H/J HH52^H8NHHCH;IH;Cu@H HsH9 HHL$NHL$HH4 H;HCHK%HCKHHCDH; J7H;CuIL H L$H9 LLL$@NLL$L$HHH;HCLK HCKHHCAA NA0EH;H;Cu@H HH9^ HHL$MHL$HHH;HCHKD,HCKHHCH;H;Cu6L H2H9A LqMHH]H;HCLk%HCKHPHSD< 0DH;H;Su@H˱H H9s HHL$LHL$HHH;HSHKD,HCKHHCAA wdA0EH;H;Cu6L HUH9|LLHHH;HCLkD$EHCKUA7EfDHyH5gH8KEDAHCH;H;Cu@L HDL$H9LKDL$HHH;HCL{%HCD cHHCDA0DH;H9CuJH HKDL$H9=HHL$KHL$DL$HH=H;HCHKD<HCD cHHCAA wyA0EH;H9Cu@H HүH9!HHL$ KHL$HH!H;HCHKD<HCD cfD7D@A7EfDHu0HMH@HE@@HMHD9ufH9H %HCKHHCDH;0H9Cu?L HL$H9L+JL$HHH;HCLk HCKHHC)LM0H}H@IE"@E_H}H<fHLT$GLT$x0HEEI<IIH9f7D-@A7E7ODA7EX7D5@Hu0HMH@HE9@HHL$;FHL$HHrH3HSHL$yCHL$Ho@A7E?LM0H}H@IE!H]H5\H8A)HHL$EHL$HHH3HSHL$BHL$H0@LLL$kELL$L$HH]H3HSL$LL$BLL$L$HTfDHHL$EHL$HH2H3HSHL$YBHL$H@LDHHH3HS(BHLDDL$HH'H3HSDL$ADL$H{LDDL$HHkH3HSDL$ADL$HLJDHH`H3HSAHHEH0L DH>H3HSHUAHHDL$Ht$ >Ht$DL$HEYHEHp&?HL$HXHL$qHCHL$H}0HMH@HEHL$>HL$HHL$qHCHL$@HL$>HL$HHL$VqHCHL$2>HL$HHL$+qHCHL$@DS>HqHS*7>HnpHCHL$>HL$HHHL$pHSHL$=HL$HHL$pHCHL$O=HrpHCf=HL$HHL$CpHCHL$HL$k=HL$HHL$pHCHL$HL$;=HL$HmHL$oHCHL$D =HBoHS$HHL$HHHL$@HL$HHH3HSHL$=HL$HLLL$t@LL$HL$HHH3HSLL$HL$=HL$LL$HLLL$)@LL$HL$HHH3HSLL$HL$]=HL$LL$HL?HL$HH'H3HSHL$!=HL$HL?HL$DL$HHuH3HSDL$HL$HL$DL$HHH3HSHL$DL$;DL$HL$H\LLL$~>LL$HL$HHH3HSLL$HL$;HL$LL$HdL8>HL$DL$HHH3HSDL$HL$l;HL$DL$HHHL$=HL$HHH3HSHL$+;HL$HHHL$=HL$HHH3HSHL$:HL$HLLL$u=LL$L$HHH3HSLL$L$:L$LL$HJL2=HHH3HSz:HLLL$=LL$HL$HH*H3HSLL$HL$9:HL$LL$HH(H!HH$HHu H8H|$0Ht H/H|$8Ht H/HH5GH8R8I7HePL3H;Fu2H HH9 H43HHt$H;HCHk+1HCKD32H H[]A\A]A^A_fDHCH;IH;Cu6L HqH9L2HHH;HCLk%HCKHHCDH; Dr7H9Cu6L HH9xLP2HHDH;HCLkD4HCKHHCAA wA0EH;H9Cu6L HH9?L1HHH;HCLkD$HCKHHCH;H;Cu6L HUH9 L1HH(H;HCLc%HCKHPHS< 0DH;H9Su6HL H9L'1HHH;HSLkD$HCKHHC@ wk0DH;H9Cu6H HH9H0HHH;HCHkD$1HCKH[]A\A]A^A_7DHSHCL @HLH9u9HL I9LLC0HHwH HsLc1%HCKHHCH;Dj0H9Cu6L HH9L/HH[H;HCLcD,HCKHHC7DU@A7EMHCH;I H;C%HCKHHCH;H9Cu6L HH9dLH Ll$pHs0HCH@@HEL@HCHD(@LL$f LL$9@L AZAn1/@HLL$ # LL$ fLL$ LL$@LL$ LL$@HLL$(LD$ HSLL$(LD$ ]HCH pHLL$0LD$(L$ R vHSLL$0LD$(L$ @4HCHDhfHHH9 8+uHW0HGH@HEL CHLD$  HSLD$ E1[HRHWH5"AAiH81 LD$PHD$pPATA]HW0HGH@HEHWH5%A1A7H8 BLD$PAXAnHIWH5$A1A7H8 LD$PAAiH=2nLL$8LD$0 LD$0LL$8l>gH= LL$8H Q#LD$0EHT$xHt$pH|$P4LL$8LD$0JI)HD$({ ID$ D$DHCHy H¹HHMsL9IOH9{ H)@ :HsH@LD$ @@HHH LD$ HH$H IV IFHHH9H9IVHH4HIFH$H/H$H$LD$ H$HDŽ$RL1ҾLH$HHHt$HtHHD$ HHH$HDŽ$Ht H/qH$HDŽ$Ht H/XH$HDŽ$Ht H/H|$PHDŽ$Ht H/HD$PH|$pHt H/HD$pH|$xHt H/HT$hHt$`HD$xH|$X Hl$ARhHuHSH5H8HD$P/HSH5A1AaH8kA IIAAimHK0HCH@@HEl1uHD$PH|$pAAi1Hs0HCH@@HEHD$PHK0HCH@@HEAA71Hs0HCH@@HEL|$ AA71Ll$pI}H5ISH9t+u"HLh9HHl$xIUBtHR MmH=HT$ HT$ <HLHHH|$PHl$xHtH/HD$PH|$pMIV IFHHH9H9IVHEE1LD$(H,HIFLHt$PHH|$pIsLHl$xL9L$HHQAAO1H8{E1LHD$pHH.H@HHL|$ IH5CHH$LMA%Aj1HLZAAR1Hl$xuLl$pI}H5$QH9tLuCHLC7HLD$ LD$ LHt$PHtH|$pIUBtHR MmH=HT$ HT$ HLHHH|$PHl$xHtH/t=HD$PH|$pH5HHt$pHK0HsH@@HEHl$x6#HwOH5@A1ASH8LD$PAAi'AAQ1WHuHNH5H8HD$xH|$PHtH/cHD$PH|$pAAR1HLLD$ LD$ 4AADHT$hHt$`H|$XF /zAAS1]ATA]1HD$xAM5xHHNH5H8dHK0HsH@HE LVAvAq1HMA9A:1H8HHT$ ~HT$ LD$0FAADHDŽ$H=dLD$ FH=LLD$ H 3HG%@HFH@t}HXHt(HJH1H;tHH9uHH9HuH;5GM1AAjAA@tuLF1H;|YHI91I9~_HDHHt:@t1H9%LXMtVMQ1I;DHI9HMAAjAAi1HHH9HuH;FuM1AAjAAHAAFHLD$ GLD$ ZAAJH@`HHHLLL$(LL$(HHL9xu3HG*LIGHH5HcHH5 LL$(HHuI)LzDGAMcH/LL$(LL$(LL$(LL$(HuHDEH5H8LL$(HHEH5dH8DDGGII MIiDGGIMI SLL$0H|$(AH|$(LL$0I2LL$0H|$(p/LL$0H|$(IHH__int__ returned non-int (type %.200s). The ability to return an instance of a strict subclass of int is deprecated, and may be removed in a future version of Python.__%.4s__ returned non-%.4s (type %.200s)can't convert negative value to uint8_tvalue too large to convert to uint8_tInterpreter change detected - this module can only be loaded into one interpreter per process.Unable to initialize pickling for %sNo active exception to reraise%s() got multiple values for keyword argument '%U'%.200s() keywords must be strings%s() got an unexpected keyword argument '%U'calling %R should have returned an instance of BaseException, not %Rraise: exception class must be a subclass of BaseException while calling a Python objectNULL result without error in PyObject_Callcan't convert negative value to uint64_tModule '_quoting_c' has already been imported. Re-initialisation is not supported.compiletime version %s of module '%.100s' does not match runtime version %s%.200s.%.200s is not a type object%.200s.%.200s size changed, may indicate binary incompatibility. Expected %zd from C header, got %zd from PyObject%s.%s size changed, may indicate binary incompatibility. Expected %zd from C header, got %zd from PyObject'NoneType' object is not iterable%.200s() takes %.8s %zd positional argument%.1s (%zd given)yarl._quoting_c._Unquoter.__init__Argument '%.200s' has incorrect type (expected %.200s, got %.200s)yarl._quoting_c._Quoter.__init__yarl._quoting_c._Quoter.__call__yarl._quoting_c._Unquoter.__call__'NoneType' object is not subscriptableCannot convert %.200s to %.200shasattr(): attribute name must be stringyarl._quoting_c.__pyx_unpickle__Unquoter__set_stateyarl._quoting_c._Unquoter.__setstate_cython__yarl._quoting_c.__pyx_unpickle__Unquoteryarl._quoting_c._Unquoter.__reduce_cython__yarl._quoting_c._Quoter.__reduce_cython__too many values found during array assignment, expected %zdnot enough values found during array assignment, expected %zd, got %zdcarray.from_py.__Pyx_carray_from_py_uint8_tyarl._quoting_c.__pyx_unpickle__Quoter__set_stateyarl._quoting_c._Quoter.__setstate_cython__yarl._quoting_c.__pyx_unpickle__Quoterobject of type 'NoneType' has no len()yarl._quoting_c._Quoter._do_quoteyarl._quoting_c._Unquoter._do_unquoteargument of type 'NoneType' is not iterable'%.200s' object is unsliceableonly single character unicode strings can be converted to Py_UCS4, got length %zdcannot convert negative value to Py_UCS4value too large to convert to Py_UCS4intan integer is requiredname__loader__loader__file__origin__package__parent__path__submodule_search_locationsyarl._quoting_c._write_charco_argcountco_posonlyargcountco_kwonlyargcountco_nlocalsco_stacksizeco_flagsco_codeco_constsco_namesco_varnamesco_freevarsco_cellvarsco_linetablereplacename '%U' is not definedcannot import name %Syarl/_quoting_c.c%s (%s:%d)yarl/_quoting_c.pyxstringsource%d.%dbuiltinscython_runtime__builtins__typeunicodeExpected %.16s, got %.200sinit yarl._quoting_c__init__exactlysafeprotected'NoneType' is not iterable__call__Missing type objecttuple__pyx_unpickle__Unquoter__pyx_unpickle__Quoterstring index out of rangestrictyarl._quoting_c._Unquoter__reduce_cython____setstate_cython__yarl._quoting_c._QuoterK4LHKH8RRQQPRST5T?TvTfT|8|x{x<܁TW9CzjG[:DrU_Incompatible checksums (0x%x vs (0x276577d, 0x4dde2d1, 0x5358bd6) = (_qs, _qs_quoter, _quoter, _unsafe))Only safe symbols with ORD < 128 are allowedIncompatible checksums (0x%x vs (0xe91bd35, 0x60b2b56, 0x7e82961) = (_protected_table, _qs, _requote, _safe_table))__pyx_unpickle__UnquoterArgument should be str__pyx_unpickle__Quotercline_in_tracebackUnicodeDecodeErroryarl._quoting_c__setstate_cython____pyx_PickleError__reduce_cython__ascii_lettersOverflowErrorstringsource__pyx_checksumPickleError__pyx_vtable____pyx_resultValueErrorIndexError__reduce_ex____pyx_stateprotectedenumerateTypeError__setstate____pyx_type__getstate___Unquoterrequoteupdateunsafestring__reduce__pickle__import__digits_Quoterupperrange__test__safe__name____main____dict__val__new__hexchr+&=;-._~+?=;!$'()*,:/?#[]@qs% ++=&;i@ ;3b(@ds@O@  <Xl`P   8   P`P 4|pH`! '< / 4 9x B B P V ]D j Pr sЀzRx $HFJ w?;*3$"4DEBDD a GBL AAB|hDA K <HDe G p|on z B D A@ G h H ( 8^BAD | DBG 8lAi N T4\wAAG I CAJ I CAC ``7BBB B(D0D8G` 8C0A(B BBBG K 8F0A(B BBBF $WBDA LAB$ +kBIC YAB8Hn~BEH A(A0b(D BBB8`BBE A(A0J(D BBBMbjHBBE B(A0A8DP8D0A(B BBB ( D0U G @ H \L!BBE A(D0S (D BBBE L (D BBBJ (D EBBdlBBB B(D0D8H 8A0A(B BBBF u 8F0A(B BBBA P BBA s EBI A BBC D BBH H IBM 0h< AD0 AB L AC PAH+BBE B(A0A8G8D0A(B BBB0| tBEG e EBF lEB( xBED ^ EBH DH BIA [ ABF L ABA \ AEF D BKD R ABJ A GBF Q AEI \, (BEI A(G0u (D ABBJ [ (D ABBD \ (D DBBH <8 /AD h AJ F AA J AM G AH (xXBD T EA I EB P >BBB D(C0" (A BBBJ W (F BBBE 8 BEA G(G0s (D ABBF d4BBE E(D0A8F 8A0A(B BBBH d 8A0A(B BBBJ BBB B(A0D8GAOFITAOFIBKnA 8A0A(B BBBp$ BBB B(A0A8G` 8A0A(B BBBF  8F0A(B BBBB 4hWp\hF`pBFB B(A0A8G` 8A0A(B BBBH  8F0A(B BBBF EhWp\hF`\ $ BBE B(D0A8DW_F_ 8D0A(B BBBD dl )GBEB A(D0DP4 0D(A BBBG |XW`_XFP_ 0D(A BBBF d - BBB B(A0A8DP 8D0A(B BBBJ  8C0A(B BBBJ < (6At K p H ` 6 BFB B(A0D8Dp 8A0A(B BBBI |xW_xFp^ 8A0A(B BBBH n 8A0A(B BBBH xW_xAp`xV`xGpH CRBBB B(A0A8GP 8D0A(B BBBC HT IBBB B(A0A8KP: 8D0A(B BBBD H tP BBE B(A0A8D 8D0A(B BBBG d ]BBB B(A0A8D` 8D0A(B BBBD j 8C0A(B BBBJ T PdAt K p H x d BFB B(A0D8Dp 8A0A(B BBBI |xW_xFp^ 8A0A(B BBBH n 8A0A(B BBBH xW_xAp`xV`xGpL r&BBB B(A0A8D 8A0A(B BBBC |p 8BBB B(A0C8G@ 8A0A(B BBBA  8F0A(B BBBG F 8A0A(B BBBH H D,BBB B(A0A8G 8D0A(B BBBF < hh@o  @ J08o`@  ,  ooooH6@F@V@f@v@@@@@@@@@AA&A6AFAVAfAvAAAAAAAAABB&B6BFBVBfBvBBBBBBBBBCC&C6CFCVCfCvCCCCCCCCCDD&D6DFDVDfDvDDDDDDDDDEE&E6EFEVEfEvEEEEEEEEEFF&F6FFFVFfFvFFFFȤ@Ȥ@`xh`xhb``_t^iha  _-x`p(a hXb`a X``Pa HXa @b8b0b(b bbbbb`b@`b إKbХa ȥa bb@b b b b3ba `xapHa ha `a X `P_H8a@b8fb0(b (` xabyba `ba pb bؤbФ`bȤb`\ G_Q]]8`lDh0m iw]] ]@j iw]]` ]Х%]GCC: (GNU) 10.2.1 20210130 (Red Hat 10.2.1-11) hE0 ihZ iH i jo. pjV k^m `l 0mw m7 FW GkH* rG~D G`W`mu PIM Iȥ 0( & n= o!V ql~ ps `t L ut ux v w8 w(Q x/i zX {>   } p~P,HFcpt _Q@   4HW8guHئ`ЦXȦ-?xWsХxp!0h?`Ohcpxx`XP P<  &j  8  P H @8 8\ 0 (   h  `# @M  , P X  إ  @ 8 0" 8 S i  (       أ7 УM ȣh ~       K  @ (2 aȤo GГ  ؤ% a Х p   RH^yx ph`&X@ i  `  @ TbФr h b ` `_tC ^in ha  _- ` (a  Xb a  `` a ! Xa 4 b@ bL bX bd bp b{ b b b ` b @` b  Kb a  a  b$ b.? @b N b [ b h bt 3b a  ` a Ha  a  a  ` _4 8aG bR fb` (b o ` xa b yb a  ` b a  pb  b b, `b: bF `^  l0`` h @h h  84 h@0_sm@zHc 8`@ , @ @ F J Pcd08@H` !-FT p}#=^u J&4P`s,:Kmz  2FUhx g !6@\jy " 3 K a m         !!4!H!V!e!s!!!!!!!!" "3"D"U"f"w"""""" @"""" ##3#__pyx_tp_traverse_4yarl_10_quoting_c__Unquoter__pyx_tp_new_4yarl_10_quoting_c__Unquoter__pyx_vtabptr_4yarl_10_quoting_c__Unquoter__pyx_empty_tuple__pyx_tp_new_4yarl_10_quoting_c__Quoter__pyx_vtabptr_4yarl_10_quoting_c__Quoter__Pyx_PyObject_GetAttrStr__pyx_tp_dealloc_4yarl_10_quoting_c__Quoter__Pyx_PyNumber_IntOrLongWrongResultType__Pyx_PyInt_As_uint8_t__pyx_tp_dealloc_4yarl_10_quoting_c__Unquoter__pyx_tp_clear_4yarl_10_quoting_c__Unquoter__Pyx_GetException__Pyx_setup_reduce_is_named__pyx_n_s_name__Pyx_SetVtable__pyx_n_s_pyx_vtable__Pyx_copy_spec_to_module__pyx_pymod_createmain_interpreter_id.0__pyx_m__Pyx_PyObject_GetAttrStrNoError__Pyx_setup_reduce__pyx_n_s_getstate__pyx_n_s_reduce_ex__pyx_n_s_reduce__pyx_n_s_reduce_cython__pyx_n_s_setstate__pyx_n_s_setstate_cython__Pyx_ReraiseException__Pyx_Import.constprop.0__Pyx_ParseOptionalKeywords.constprop.0__Pyx_Raise.constprop.0__Pyx_WriteUnraisable.constprop.0__Pyx_PyCode_New.constprop.0__Pyx_GetBuiltinName__pyx_b__Pyx_ImportFrom__Pyx__PyObject_CallOneArg__Pyx_PyObject_CallOneArg__Pyx_PyObject_Call2Args__Pyx_PyInt_As_uint64_t__Pyx_PyInt_As_long.part.0__pyx_f_4yarl_10_quoting_c__write_pct__pyx_v_4yarl_10_quoting_c_BUFFER__Pyx__GetModuleGlobalName__pyx_d__Pyx_AddTraceback__pyx_cython_runtime__pyx_dict_version.2__pyx_dict_cached_value.1__pyx_n_s_cline_in_traceback__pyx_code_cache__pyx_pymod_exec__quoting_c__pyx_empty_bytes__pyx_empty_unicode__pyx_string_tab__pyx_int_2__pyx_int_41310077__pyx_int_81650385__pyx_int_87395286__pyx_int_101395286__pyx_int_132655457__pyx_int_244432181__pyx_n_s_main__pyx_n_s_range__pyx_n_s_chr__pyx_builtin_chr__pyx_n_s_ValueError__pyx_builtin_ValueError__pyx_n_s_TypeError__pyx_builtin_TypeError__pyx_n_s_UnicodeDecodeError__pyx_builtin_UnicodeDecodeError__pyx_n_s_hex__pyx_builtin_hex__pyx_n_s_OverflowError__pyx_builtin_OverflowError__pyx_n_s_enumerate__pyx_n_s_IndexError__pyx_builtin_IndexError__pyx_kp_u_Only_safe_symbols_with_ORD_128_a__pyx_tuple__2__pyx_kp_u_Argument_should_be_str__pyx_tuple__3__pyx_slice__8__pyx_tuple__9__pyx_tuple__10__pyx_n_s_pyx_state__pyx_n_s_pyx_result__pyx_n_s_pyx_PickleError__pyx_n_s_pyx_checksum__pyx_n_s_pyx_type__pyx_n_s_pyx_unpickle__Quoter__pyx_kp_s_stringsource__pyx_n_s_pyx_unpickle__Unquoter__pyx_vtable_4yarl_10_quoting_c__Quoter__pyx_f_4yarl_10_quoting_c_7_Quoter__do_quote__pyx_f_4yarl_10_quoting_c_7_Quoter__write__pyx_type_4yarl_10_quoting_c__Quoter__pyx_v_4yarl_10_quoting_c_GEN_DELIMS__pyx_v_4yarl_10_quoting_c_SUB_DELIMS_WITHOUT_QS__pyx_v_4yarl_10_quoting_c_SUB_DELIMS__pyx_v_4yarl_10_quoting_c_RESERVED__pyx_v_4yarl_10_quoting_c_UNRESERVED__pyx_v_4yarl_10_quoting_c_ALLOWED__pyx_v_4yarl_10_quoting_c_QS__pyx_n_s_Quoter__pyx_type_4yarl_10_quoting_c__Unquoter__pyx_ptype_4yarl_10_quoting_c__Quoter__pyx_vtable_4yarl_10_quoting_c__Unquoter__pyx_f_4yarl_10_quoting_c_9_Unquoter__do_unquote__pyx_n_s_Unquoter__pyx_ptype_4yarl_10_quoting_c__Unquoter__pyx_n_s_ascii_letters__pyx_n_s_digits__pyx_n_s_string__pyx_kp_u__11__pyx_kp_u__12__pyx_kp_u__13__pyx_dict_version.30__pyx_dict_cached_value.29__pyx_dict_version.28__pyx_dict_cached_value.27__pyx_kp_u__14__pyx_kp_u__15__pyx_v_4yarl_10_quoting_c_ALLOWED_TABLE__pyx_v_4yarl_10_quoting_c_ALLOWED_NOTQS_TABLE__pyx_n_s_i__pyx_dict_version.26__pyx_dict_cached_value.25__pyx_dict_version.24__pyx_dict_cached_value.23__pyx_dict_version.22__pyx_dict_cached_value.21__pyx_dict_version.20__pyx_dict_cached_value.19__pyx_dict_version.18__pyx_dict_cached_value.17__pyx_n_s_yarl__quoting_c__pyx_mdef_4yarl_10_quoting_c_1__pyx_unpickle__Quoter__pyx_mdef_4yarl_10_quoting_c_3__pyx_unpickle__Unquoter__pyx_n_s_test__pyx_pw_4yarl_10_quoting_c_9_Unquoter_1__init____pyx_kp_u___pyx_n_s_qs__pyx_pyargnames.14__pyx_pw_4yarl_10_quoting_c_7_Quoter_1__init____pyx_pyargnames.8__pyx_pw_4yarl_10_quoting_c_7_Quoter_3__call____pyx_n_s_val__pyx_pyargnames.3__pyx_pw_4yarl_10_quoting_c_9_Unquoter_3__call____pyx_pyargnames.9__pyx_f_4yarl_10_quoting_c___pyx_unpickle__Unquoter__set_state__pyx_n_s_dict__pyx_n_s_update__pyx_pw_4yarl_10_quoting_c_9_Unquoter_7__setstate_cython____pyx_pw_4yarl_10_quoting_c_3__pyx_unpickle__Unquoter__pyx_n_s_new__pyx_n_s_PickleError__pyx_n_s_pickle__pyx_kp_s_Incompatible_checksums_0x_x_vs_0_2__pyx_pyargnames.16__pyx_pw_4yarl_10_quoting_c_9_Unquoter_5__reduce_cython____pyx_dict_version.13__pyx_dict_cached_value.12__pyx_dict_version.11__pyx_dict_cached_value.10__pyx_pw_4yarl_10_quoting_c_7_Quoter_5__reduce_cython____pyx_dict_version.7__pyx_dict_cached_value.6__pyx_dict_version.5__pyx_dict_cached_value.4__Pyx_carray_from_py_uint8_t.constprop.0__pyx_f_4yarl_10_quoting_c___pyx_unpickle__Quoter__set_state__pyx_pw_4yarl_10_quoting_c_7_Quoter_7__setstate_cython____pyx_pw_4yarl_10_quoting_c_1__pyx_unpickle__Quoter__pyx_kp_s_Incompatible_checksums_0x_x_vs_0__pyx_pyargnames.15__pyx_kp_u__7__pyx_n_s_upper__pyx_kp_u__4__pyx_kp_u__5__pyx_kp_u__6__pyx_moduledef__pyx_n_s_safe__pyx_n_s_protected__pyx_n_s_requote__pyx_n_s_unsafe__pyx_k___pyx_k_Argument_should_be_str__pyx_k_Incompatible_checksums_0x_x_vs_0__pyx_k_Incompatible_checksums_0x_x_vs_0_2__pyx_k_IndexError__pyx_k_Only_safe_symbols_with_ORD_128_a__pyx_k_OverflowError__pyx_k_PickleError__pyx_k_Quoter__pyx_k_TypeError__pyx_k_UnicodeDecodeError__pyx_k_Unquoter__pyx_k_ValueError__pyx_k__11__pyx_k__12__pyx_k__13__pyx_k__14__pyx_k__15__pyx_k__4__pyx_k__5__pyx_k__6__pyx_k__7__pyx_k_ascii_letters__pyx_k_chr__pyx_k_cline_in_traceback__pyx_k_dict__pyx_k_digits__pyx_k_enumerate__pyx_k_getstate__pyx_k_hex__pyx_k_i__pyx_n_s_import__pyx_k_import__pyx_k_main__pyx_k_name__pyx_k_new__pyx_k_pickle__pyx_k_protected__pyx_k_pyx_PickleError__pyx_k_pyx_checksum__pyx_k_pyx_result__pyx_k_pyx_state__pyx_k_pyx_type__pyx_k_pyx_unpickle__Quoter__pyx_k_pyx_unpickle__Unquoter__pyx_k_pyx_vtable__pyx_k_qs__pyx_k_range__pyx_k_reduce__pyx_k_reduce_cython__pyx_k_reduce_ex__pyx_k_requote__pyx_k_safe__pyx_k_setstate__pyx_k_setstate_cython__pyx_k_string__pyx_k_stringsource__pyx_k_test__pyx_k_unsafe__pyx_k_update__pyx_k_upper__pyx_k_val__pyx_k_yarl__quoting_c__pyx_methods__pyx_moduledef_slots__pyx_methods_4yarl_10_quoting_c__Unquoter__pyx_methods_4yarl_10_quoting_c__Quoterderegister_tm_clones__do_global_dtors_auxcompleted.0__do_global_dtors_aux_fini_array_entryframe_dummy__frame_dummy_init_array_entry__FRAME_END____dso_handle_DYNAMIC__GNU_EH_FRAME_HDR__TMC_END___GLOBAL_OFFSET_TABLE_PyUnicode_FromFormatPyList_New_PyUnicode_ReadyPyExc_SystemErrorPyDict_SetItemStringPyErr_GetExcInfoPyDict_SizePyException_SetTracebackPyMethod_Type_ITM_deregisterTMCloneTablePyTuple_TypePyErr_RestorePyModuleDef_InitPy_EnterRecursiveCallPyFrame_NewPyMem_FreePyNumber_InPlaceAddPyNumber_AddPyObject_GetAttrStringPyUnicode_JoinPyImport_AddModulePyBytes_FromStringAndSize_PyObject_GenericGetAttrWithDictPyObject_SetAttrStringPyErr_WarnEx_Py_DeallocPyModule_NewObjectPyErr_NoMemoryPyErr_SetObjectPyErr_NormalizeException_finiPyImport_GetModuleDictPyUnicode_DecodeUTF8StatefulPyExc_RuntimeErrorPyCMethod_NewPyErr_GivenExceptionMatchesPyErr_SetStringPyUnicode_ContainsPyObject_GetItemPyExc_ValueErrorPyExc_DeprecationWarningPyExc_TypeErrorPyInterpreterState_GetIDPySequence_ContainsPyErr_PrintExPyMem_ReallocPyErr_SetNonePyErr_ExceptionMatchesPyOS_snprintfPyTraceBack_HerePyObject_CallFinalizerFromDeallocPyObject_NotPyLong_FromSsize_tPyType_ReadyPyLong_FromLongPyObject_RichCompareBoolPyErr_ClearPyList_Append_Py_FalseStruct__gmon_start__PyTuple_NewPyObject_GenericGetAttrPyThreadState_GetPyExc_OverflowErrorPyDict_DelItemmemcpy@@GLIBC_2.14PyType_ModifiedPyObject_SetAttrPyBytes_FromStringPyErr_OccurredPyLong_AsLongPyInit__quoting_cPyImport_ImportModule_PyDict_GetItem_KnownHashPy_LeaveRecursiveCallPy_OptimizeFlagPyDict_GetItemString__pyx_module_is_main_yarl___quoting_cPyObject_Size_Py_NoneStructPyObject_IsTrue_PyType_LookupPyImport_ImportModuleLevelObjectPyExc_AssertionErrorPyObject_HashPyUnicode_Compare_Py_TrueStructPyUnicode_FromKindAndDataPyDict_NewPyExc_IndexErrorPyObject_GC_IsFinalizedPyLong_AsUnsignedLongPyDict_NextPyBaseObject_TypePyUnicode_AsUTF8PyLong_Type_PyObject_GetDictPtrPyErr_FetchPyUnicode_FromStringPyObject_GetIterPyUnicode_InternFromStringPyExc_ImportErrorPyDict_SetItemPyExc_AttributeErrorPyExc_StopIterationPyObject_CallPyUnicode_TypePyCapsule_NewPyType_IsSubtypePyUnicode_AsUTF8AndSizePyUnicode_DecodePyErr_FormatPySlice_NewPyExc_NameErrorPyUnicode_FromStringAndSizePyModule_GetDict_ITM_registerTMCloneTablePyUnicode_FromOrdinalPyUnicode_ConcatPyObject_GetAttrPyCFunction_TypePyUnicode_FormatPyErr_SetExcInfoPyMem_MallocPyErr_WarnFormat__cxa_finalize@@GLIBC_2.2.5_initPyTuple_PackPyUnicode_DecodeASCIIPy_GetVersionPyCode_NewEmptyPyObject_GC_UnTrackPyErr_WriteUnraisablePyList_Type.symtab.strtab.shstrtab.note.gnu.build-id.gnu.hash.dynsym.dynstr.gnu.version.gnu.version_r.rela.dyn.rela.plt.init.text.fini.rodata.eh_frame_hdr.eh_frame.init_array.fini_array.data.rel.ro.dynamic.got.got.plt.data.bss.comment88$.o``48  @@@ HoUo0d  nB,, x@@s @ @~FFJJ PP ccddP00}88}@@}HH}X``   $ 0 /P8(' ?#_quoting_c.pyi000064400000000677150043323140007423 0ustar00from typing import Optional class _Quoter: def __init__( self, *, safe: str = ..., protected: str = ..., qs: bool = ..., requote: bool = ... ) -> None: ... def __call__(self, val: Optional[str] = ...) -> Optional[str]: ... class _Unquoter: def __init__(self, *, unsafe: str = ..., qs: bool = ...) -> None: ... def __call__(self, val: Optional[str] = ...) -> Optional[str]: ... _quoting_c.pyx000064400000026352150043323140007440 0ustar00# cython: language_level=3 from cpython.exc cimport PyErr_NoMemory from cpython.mem cimport PyMem_Free, PyMem_Malloc, PyMem_Realloc from cpython.unicode cimport PyUnicode_DecodeASCII, PyUnicode_DecodeUTF8Stateful from libc.stdint cimport uint8_t, uint64_t from libc.string cimport memcpy, memset from string import ascii_letters, digits cdef str GEN_DELIMS = ":/?#[]@" cdef str SUB_DELIMS_WITHOUT_QS = "!$'()*," cdef str SUB_DELIMS = SUB_DELIMS_WITHOUT_QS + '+?=;' cdef str RESERVED = GEN_DELIMS + SUB_DELIMS cdef str UNRESERVED = ascii_letters + digits + '-._~' cdef str ALLOWED = UNRESERVED + SUB_DELIMS_WITHOUT_QS cdef str QS = '+&=;' DEF BUF_SIZE = 8 * 1024 # 8KiB cdef char BUFFER[BUF_SIZE] cdef inline Py_UCS4 _to_hex(uint8_t v): if v < 10: return (v+0x30) # ord('0') == 0x30 else: return (v+0x41-10) # ord('A') == 0x41 cdef inline int _from_hex(Py_UCS4 v): if '0' <= v <= '9': return (v) - 0x30 # ord('0') == 0x30 elif 'A' <= v <= 'F': return (v) - 0x41 + 10 # ord('A') == 0x41 elif 'a' <= v <= 'f': return (v) - 0x61 + 10 # ord('a') == 0x61 else: return -1 cdef inline int _is_lower_hex(Py_UCS4 v): return 'a' <= v <= 'f' cdef inline Py_UCS4 _restore_ch(Py_UCS4 d1, Py_UCS4 d2): cdef int digit1 = _from_hex(d1) if digit1 < 0: return -1 cdef int digit2 = _from_hex(d2) if digit2 < 0: return -1 return (digit1 << 4 | digit2) cdef uint8_t ALLOWED_TABLE[16] cdef uint8_t ALLOWED_NOTQS_TABLE[16] cdef inline bint bit_at(uint8_t array[], uint64_t ch): return array[ch >> 3] & (1 << (ch & 7)) cdef inline void set_bit(uint8_t array[], uint64_t ch): array[ch >> 3] |= (1 << (ch & 7)) memset(ALLOWED_TABLE, 0, sizeof(ALLOWED_TABLE)) memset(ALLOWED_NOTQS_TABLE, 0, sizeof(ALLOWED_NOTQS_TABLE)) for i in range(128): if chr(i) in ALLOWED: set_bit(ALLOWED_TABLE, i) set_bit(ALLOWED_NOTQS_TABLE, i) if chr(i) in QS: set_bit(ALLOWED_NOTQS_TABLE, i) # ----------------- writer --------------------------- cdef struct Writer: char *buf Py_ssize_t size Py_ssize_t pos bint changed cdef inline void _init_writer(Writer* writer): writer.buf = &BUFFER[0] writer.size = BUF_SIZE writer.pos = 0 writer.changed = 0 cdef inline void _release_writer(Writer* writer): if writer.buf != BUFFER: PyMem_Free(writer.buf) cdef inline int _write_char(Writer* writer, Py_UCS4 ch, bint changed): cdef char * buf cdef Py_ssize_t size if writer.pos == writer.size: # reallocate size = writer.size + BUF_SIZE if writer.buf == BUFFER: buf = PyMem_Malloc(size) if buf == NULL: PyErr_NoMemory() return -1 memcpy(buf, writer.buf, writer.size) else: buf = PyMem_Realloc(writer.buf, size) if buf == NULL: PyErr_NoMemory() return -1 writer.buf = buf writer.size = size writer.buf[writer.pos] = ch writer.pos += 1 writer.changed |= changed return 0 cdef inline int _write_pct(Writer* writer, uint8_t ch, bint changed): if _write_char(writer, '%', changed) < 0: return -1 if _write_char(writer, _to_hex(ch >> 4), changed) < 0: return -1 return _write_char(writer, _to_hex(ch & 0x0f), changed) cdef inline int _write_utf8(Writer* writer, Py_UCS4 symbol): cdef uint64_t utf = symbol if utf < 0x80: return _write_pct(writer, utf, True) elif utf < 0x800: if _write_pct(writer, (0xc0 | (utf >> 6)), True) < 0: return -1 return _write_pct(writer, (0x80 | (utf & 0x3f)), True) elif 0xD800 <= utf <= 0xDFFF: # surogate pair, ignored return 0 elif utf < 0x10000: if _write_pct(writer, (0xe0 | (utf >> 12)), True) < 0: return -1 if _write_pct(writer, (0x80 | ((utf >> 6) & 0x3f)), True) < 0: return -1 return _write_pct(writer, (0x80 | (utf & 0x3f)), True) elif utf > 0x10FFFF: # symbol is too large return 0 else: if _write_pct(writer, (0xf0 | (utf >> 18)), True) < 0: return -1 if _write_pct(writer, (0x80 | ((utf >> 12) & 0x3f)), True) < 0: return -1 if _write_pct(writer, (0x80 | ((utf >> 6) & 0x3f)), True) < 0: return -1 return _write_pct(writer, (0x80 | (utf & 0x3f)), True) # --------------------- end writer -------------------------- cdef class _Quoter: cdef bint _qs cdef bint _requote cdef uint8_t _safe_table[16] cdef uint8_t _protected_table[16] def __init__( self, *, str safe='', str protected='', bint qs=False, bint requote=True, ): cdef Py_UCS4 ch self._qs = qs self._requote = requote if not self._qs: memcpy(self._safe_table, ALLOWED_NOTQS_TABLE, sizeof(self._safe_table)) else: memcpy(self._safe_table, ALLOWED_TABLE, sizeof(self._safe_table)) for ch in safe: if ord(ch) > 127: raise ValueError("Only safe symbols with ORD < 128 are allowed") set_bit(self._safe_table, ch) memset(self._protected_table, 0, sizeof(self._protected_table)) for ch in protected: if ord(ch) > 127: raise ValueError("Only safe symbols with ORD < 128 are allowed") set_bit(self._safe_table, ch) set_bit(self._protected_table, ch) def __call__(self, val): cdef Writer writer if val is None: return None if type(val) is not str: if isinstance(val, str): # derived from str val = str(val) else: raise TypeError("Argument should be str") _init_writer(&writer) try: return self._do_quote(val, &writer) finally: _release_writer(&writer) cdef str _do_quote(self, str val, Writer *writer): cdef Py_UCS4 ch cdef int changed cdef int idx = 0 cdef int length = len(val) while idx < length: ch = val[idx] idx += 1 if ch == '%' and self._requote and idx <= length - 2: ch = _restore_ch(val[idx], val[idx + 1]) if ch != -1: idx += 2 if ch < 128: if bit_at(self._protected_table, ch): if _write_pct(writer, ch, True) < 0: raise continue if bit_at(self._safe_table, ch): if _write_char(writer, ch, True) < 0: raise continue changed = (_is_lower_hex(val[idx - 2]) or _is_lower_hex(val[idx - 1])) if _write_pct(writer, ch, changed) < 0: raise continue else: ch = '%' if self._write(writer, ch) < 0: raise if not writer.changed: return val else: return PyUnicode_DecodeASCII(writer.buf, writer.pos, "strict") cdef inline int _write(self, Writer *writer, Py_UCS4 ch): if self._qs: if ch == ' ': return _write_char(writer, '+', True) if ch < 128 and bit_at(self._safe_table, ch): return _write_char(writer, ch, False) return _write_utf8(writer, ch) cdef class _Unquoter: cdef str _unsafe cdef bint _qs cdef _Quoter _quoter cdef _Quoter _qs_quoter def __init__(self, *, unsafe='', qs=False): self._unsafe = unsafe self._qs = qs self._quoter = _Quoter() self._qs_quoter = _Quoter(qs=True) def __call__(self, val): if val is None: return None if type(val) is not str: if isinstance(val, str): # derived from str val = str(val) else: raise TypeError("Argument should be str") return self._do_unquote(val) cdef str _do_unquote(self, str val): if len(val) == 0: return val cdef list ret = [] cdef char buffer[4] cdef Py_ssize_t buflen = 0 cdef Py_ssize_t consumed cdef str unquoted cdef Py_UCS4 ch = 0 cdef Py_ssize_t idx = 0 cdef Py_ssize_t length = len(val) cdef Py_ssize_t start_pct while idx < length: ch = val[idx] idx += 1 if ch == '%' and idx <= length - 2: ch = _restore_ch(val[idx], val[idx + 1]) if ch != -1: idx += 2 assert buflen < 4 buffer[buflen] = ch buflen += 1 try: unquoted = PyUnicode_DecodeUTF8Stateful(buffer, buflen, NULL, &consumed) except UnicodeDecodeError: start_pct = idx - buflen * 3 buffer[0] = ch buflen = 1 ret.append(val[start_pct : idx - 3]) try: unquoted = PyUnicode_DecodeUTF8Stateful(buffer, buflen, NULL, &consumed) except UnicodeDecodeError: buflen = 0 ret.append(val[idx - 3 : idx]) continue if not unquoted: assert consumed == 0 continue assert consumed == buflen buflen = 0 if self._qs and unquoted in '+=&;': ret.append(self._qs_quoter(unquoted)) elif unquoted in self._unsafe: ret.append(self._quoter(unquoted)) else: ret.append(unquoted) continue else: ch = '%' if buflen: start_pct = idx - 1 - buflen * 3 ret.append(val[start_pct : idx - 1]) buflen = 0 if ch == '+': if not self._qs or ch in self._unsafe: ret.append('+') else: ret.append(' ') continue if ch in self._unsafe: ret.append('%') h = hex(ord(ch)).upper()[2:] for ch in h: ret.append(ch) continue ret.append(ch) if buflen: ret.append(val[length - buflen * 3 : length]) return ''.join(ret) _quoting_py.py000064400000014342150043323140007452 0ustar00import codecs import re from string import ascii_letters, ascii_lowercase, digits from typing import Optional, cast BASCII_LOWERCASE = ascii_lowercase.encode("ascii") BPCT_ALLOWED = {f"%{i:02X}".encode("ascii") for i in range(256)} GEN_DELIMS = ":/?#[]@" SUB_DELIMS_WITHOUT_QS = "!$'()*," SUB_DELIMS = SUB_DELIMS_WITHOUT_QS + "+&=;" RESERVED = GEN_DELIMS + SUB_DELIMS UNRESERVED = ascii_letters + digits + "-._~" ALLOWED = UNRESERVED + SUB_DELIMS_WITHOUT_QS _IS_HEX = re.compile(b"[A-Z0-9][A-Z0-9]") _IS_HEX_STR = re.compile("[A-Fa-f0-9][A-Fa-f0-9]") utf8_decoder = codecs.getincrementaldecoder("utf-8") class _Quoter: def __init__( self, *, safe: str = "", protected: str = "", qs: bool = False, requote: bool = True, ) -> None: self._safe = safe self._protected = protected self._qs = qs self._requote = requote def __call__(self, val: Optional[str]) -> Optional[str]: if val is None: return None if not isinstance(val, str): raise TypeError("Argument should be str") if not val: return "" bval = cast(str, val).encode("utf8", errors="ignore") ret = bytearray() pct = bytearray() safe = self._safe safe += ALLOWED if not self._qs: safe += "+&=;" safe += self._protected bsafe = safe.encode("ascii") idx = 0 while idx < len(bval): ch = bval[idx] idx += 1 if pct: if ch in BASCII_LOWERCASE: ch = ch - 32 # convert to uppercase pct.append(ch) if len(pct) == 3: # pragma: no branch # peephole optimizer buf = pct[1:] if not _IS_HEX.match(buf): ret.extend(b"%25") pct.clear() idx -= 2 continue try: unquoted = chr(int(pct[1:].decode("ascii"), base=16)) except ValueError: ret.extend(b"%25") pct.clear() idx -= 2 continue if unquoted in self._protected: ret.extend(pct) elif unquoted in safe: ret.append(ord(unquoted)) else: ret.extend(pct) pct.clear() # special case, if we have only one char after "%" elif len(pct) == 2 and idx == len(bval): ret.extend(b"%25") pct.clear() idx -= 1 continue elif ch == ord("%") and self._requote: pct.clear() pct.append(ch) # special case if "%" is last char if idx == len(bval): ret.extend(b"%25") continue if self._qs: if ch == ord(" "): ret.append(ord("+")) continue if ch in bsafe: ret.append(ch) continue ret.extend((f"%{ch:02X}").encode("ascii")) ret2 = ret.decode("ascii") if ret2 == val: return val return ret2 class _Unquoter: def __init__(self, *, unsafe: str = "", qs: bool = False) -> None: self._unsafe = unsafe self._qs = qs self._quoter = _Quoter() self._qs_quoter = _Quoter(qs=True) def __call__(self, val: Optional[str]) -> Optional[str]: if val is None: return None if not isinstance(val, str): raise TypeError("Argument should be str") if not val: return "" decoder = cast(codecs.BufferedIncrementalDecoder, utf8_decoder()) ret = [] idx = 0 while idx < len(val): ch = val[idx] idx += 1 if ch == "%" and idx <= len(val) - 2: pct = val[idx : idx + 2] if _IS_HEX_STR.fullmatch(pct): b = bytes([int(pct, base=16)]) idx += 2 try: unquoted = decoder.decode(b) except UnicodeDecodeError: start_pct = idx - 3 - len(decoder.buffer) * 3 ret.append(val[start_pct : idx - 3]) decoder.reset() try: unquoted = decoder.decode(b) except UnicodeDecodeError: ret.append(val[idx - 3 : idx]) continue if not unquoted: continue if self._qs and unquoted in "+=&;": to_add = self._qs_quoter(unquoted) if to_add is None: # pragma: no cover raise RuntimeError("Cannot quote None") ret.append(to_add) elif unquoted in self._unsafe: to_add = self._quoter(unquoted) if to_add is None: # pragma: no cover raise RuntimeError("Cannot quote None") ret.append(to_add) else: ret.append(unquoted) continue if decoder.buffer: start_pct = idx - 1 - len(decoder.buffer) * 3 ret.append(val[start_pct : idx - 1]) decoder.reset() if ch == "+": if not self._qs or ch in self._unsafe: ret.append("+") else: ret.append(" ") continue if ch in self._unsafe: ret.append("%") h = hex(ord(ch)).upper()[2:] for ch in h: ret.append(ch) continue ret.append(ch) if decoder.buffer: ret.append(val[-len(decoder.buffer) * 3 :]) ret2 = "".join(ret) if ret2 == val: return val return ret2 _url.py000064400000112057150043323140006060 0ustar00import functools import math import warnings from collections.abc import Mapping, Sequence from contextlib import suppress from ipaddress import ip_address from urllib.parse import SplitResult, parse_qsl, quote, urljoin, urlsplit, urlunsplit import idna from multidict import MultiDict, MultiDictProxy from ._quoting import _Quoter, _Unquoter DEFAULT_PORTS = {"http": 80, "https": 443, "ws": 80, "wss": 443} sentinel = object() def rewrite_module(obj: object) -> object: obj.__module__ = "yarl" return obj class cached_property: """Use as a class method decorator. It operates almost exactly like the Python `@property` decorator, but it puts the result of the method it decorates into the instance dict after the first call, effectively replacing the function it decorates with an instance variable. It is, in Python parlance, a data descriptor. """ def __init__(self, wrapped): self.wrapped = wrapped try: self.__doc__ = wrapped.__doc__ except AttributeError: # pragma: no cover self.__doc__ = "" self.name = wrapped.__name__ def __get__(self, inst, owner, _sentinel=sentinel): if inst is None: return self val = inst._cache.get(self.name, _sentinel) if val is not _sentinel: return val val = self.wrapped(inst) inst._cache[self.name] = val return val def __set__(self, inst, value): raise AttributeError("cached property is read-only") def _normalize_path_segments(segments): """Drop '.' and '..' from a sequence of str segments""" resolved_path = [] for seg in segments: if seg == "..": # ignore any .. segments that would otherwise cause an # IndexError when popped from resolved_path if # resolving for rfc3986 with suppress(IndexError): resolved_path.pop() elif seg != ".": resolved_path.append(seg) if segments and segments[-1] in (".", ".."): # do some post-processing here. # if the last segment was a relative dir, # then we need to append the trailing '/' resolved_path.append("") return resolved_path @rewrite_module class URL: # Don't derive from str # follow pathlib.Path design # probably URL will not suffer from pathlib problems: # it's intended for libraries like aiohttp, # not to be passed into standard library functions like os.open etc. # URL grammar (RFC 3986) # pct-encoded = "%" HEXDIG HEXDIG # reserved = gen-delims / sub-delims # gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@" # sub-delims = "!" / "$" / "&" / "'" / "(" / ")" # / "*" / "+" / "," / ";" / "=" # unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" # URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ] # hier-part = "//" authority path-abempty # / path-absolute # / path-rootless # / path-empty # scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) # authority = [ userinfo "@" ] host [ ":" port ] # userinfo = *( unreserved / pct-encoded / sub-delims / ":" ) # host = IP-literal / IPv4address / reg-name # IP-literal = "[" ( IPv6address / IPvFuture ) "]" # IPvFuture = "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" ) # IPv6address = 6( h16 ":" ) ls32 # / "::" 5( h16 ":" ) ls32 # / [ h16 ] "::" 4( h16 ":" ) ls32 # / [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32 # / [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32 # / [ *3( h16 ":" ) h16 ] "::" h16 ":" ls32 # / [ *4( h16 ":" ) h16 ] "::" ls32 # / [ *5( h16 ":" ) h16 ] "::" h16 # / [ *6( h16 ":" ) h16 ] "::" # ls32 = ( h16 ":" h16 ) / IPv4address # ; least-significant 32 bits of address # h16 = 1*4HEXDIG # ; 16 bits of address represented in hexadecimal # IPv4address = dec-octet "." dec-octet "." dec-octet "." dec-octet # dec-octet = DIGIT ; 0-9 # / %x31-39 DIGIT ; 10-99 # / "1" 2DIGIT ; 100-199 # / "2" %x30-34 DIGIT ; 200-249 # / "25" %x30-35 ; 250-255 # reg-name = *( unreserved / pct-encoded / sub-delims ) # port = *DIGIT # path = path-abempty ; begins with "/" or is empty # / path-absolute ; begins with "/" but not "//" # / path-noscheme ; begins with a non-colon segment # / path-rootless ; begins with a segment # / path-empty ; zero characters # path-abempty = *( "/" segment ) # path-absolute = "/" [ segment-nz *( "/" segment ) ] # path-noscheme = segment-nz-nc *( "/" segment ) # path-rootless = segment-nz *( "/" segment ) # path-empty = 0 # segment = *pchar # segment-nz = 1*pchar # segment-nz-nc = 1*( unreserved / pct-encoded / sub-delims / "@" ) # ; non-zero-length segment without any colon ":" # pchar = unreserved / pct-encoded / sub-delims / ":" / "@" # query = *( pchar / "/" / "?" ) # fragment = *( pchar / "/" / "?" ) # URI-reference = URI / relative-ref # relative-ref = relative-part [ "?" query ] [ "#" fragment ] # relative-part = "//" authority path-abempty # / path-absolute # / path-noscheme # / path-empty # absolute-URI = scheme ":" hier-part [ "?" query ] __slots__ = ("_cache", "_val") _QUOTER = _Quoter(requote=False) _REQUOTER = _Quoter() _PATH_QUOTER = _Quoter(safe="@:", protected="/+", requote=False) _PATH_REQUOTER = _Quoter(safe="@:", protected="/+") _QUERY_QUOTER = _Quoter(safe="?/:@", protected="=+&;", qs=True, requote=False) _QUERY_REQUOTER = _Quoter(safe="?/:@", protected="=+&;", qs=True) _QUERY_PART_QUOTER = _Quoter(safe="?/:@", qs=True, requote=False) _FRAGMENT_QUOTER = _Quoter(safe="?/:@", requote=False) _FRAGMENT_REQUOTER = _Quoter(safe="?/:@") _UNQUOTER = _Unquoter() _PATH_UNQUOTER = _Unquoter(unsafe="+") _QS_UNQUOTER = _Unquoter(qs=True) def __new__(cls, val="", *, encoded=False, strict=None): if strict is not None: # pragma: no cover warnings.warn("strict parameter is ignored") if type(val) is cls: return val if type(val) is str: val = urlsplit(val) elif type(val) is SplitResult: if not encoded: raise ValueError("Cannot apply decoding to SplitResult") elif isinstance(val, str): val = urlsplit(str(val)) else: raise TypeError("Constructor parameter should be str") if not encoded: if not val[1]: # netloc netloc = "" host = "" else: host = val.hostname if host is None: raise ValueError("Invalid URL: host is required for absolute urls") try: port = val.port except ValueError as e: raise ValueError( "Invalid URL: port can't be converted to integer" ) from e netloc = cls._make_netloc( val.username, val.password, host, port, encode=True, requote=True ) path = cls._PATH_REQUOTER(val[2]) if netloc: path = cls._normalize_path(path) cls._validate_authority_uri_abs_path(host=host, path=path) query = cls._QUERY_REQUOTER(val[3]) fragment = cls._FRAGMENT_REQUOTER(val[4]) val = SplitResult(val[0], netloc, path, query, fragment) self = object.__new__(cls) self._val = val self._cache = {} return self @classmethod def build( cls, *, scheme="", authority="", user=None, password=None, host="", port=None, path="", query=None, query_string="", fragment="", encoded=False, ): """Creates and returns a new URL""" if authority and (user or password or host or port): raise ValueError( 'Can\'t mix "authority" with "user", "password", "host" or "port".' ) if port and not host: raise ValueError('Can\'t build URL with "port" but without "host".') if query and query_string: raise ValueError('Only one of "query" or "query_string" should be passed') if ( scheme is None or authority is None or host is None or path is None or query_string is None or fragment is None ): raise TypeError( 'NoneType is illegal for "scheme", "authority", "host", "path", ' '"query_string", and "fragment" args, use empty string instead.' ) if authority: if encoded: netloc = authority else: tmp = SplitResult("", authority, "", "", "") netloc = cls._make_netloc( tmp.username, tmp.password, tmp.hostname, tmp.port, encode=True ) elif not user and not password and not host and not port: netloc = "" else: netloc = cls._make_netloc( user, password, host, port, encode=not encoded, encode_host=not encoded ) if not encoded: path = cls._PATH_QUOTER(path) if netloc: path = cls._normalize_path(path) cls._validate_authority_uri_abs_path(host=host, path=path) query_string = cls._QUERY_QUOTER(query_string) fragment = cls._FRAGMENT_QUOTER(fragment) url = cls( SplitResult(scheme, netloc, path, query_string, fragment), encoded=True ) if query: return url.with_query(query) else: return url def __init_subclass__(cls): raise TypeError(f"Inheriting a class {cls!r} from URL is forbidden") def __str__(self): val = self._val if not val.path and self.is_absolute() and (val.query or val.fragment): val = val._replace(path="/") return urlunsplit(val) def __repr__(self): return f"{self.__class__.__name__}('{str(self)}')" def __bytes__(self): return str(self).encode("ascii") def __eq__(self, other): if not type(other) is URL: return NotImplemented val1 = self._val if not val1.path and self.is_absolute(): val1 = val1._replace(path="/") val2 = other._val if not val2.path and other.is_absolute(): val2 = val2._replace(path="/") return val1 == val2 def __hash__(self): ret = self._cache.get("hash") if ret is None: val = self._val if not val.path and self.is_absolute(): val = val._replace(path="/") ret = self._cache["hash"] = hash(val) return ret def __le__(self, other): if not type(other) is URL: return NotImplemented return self._val <= other._val def __lt__(self, other): if not type(other) is URL: return NotImplemented return self._val < other._val def __ge__(self, other): if not type(other) is URL: return NotImplemented return self._val >= other._val def __gt__(self, other): if not type(other) is URL: return NotImplemented return self._val > other._val def __truediv__(self, name): if not type(name) is str: return NotImplemented return self._make_child((name,)) def __mod__(self, query): return self.update_query(query) def __bool__(self) -> bool: return bool( self._val.netloc or self._val.path or self._val.query or self._val.fragment ) def __getstate__(self): return (self._val,) def __setstate__(self, state): if state[0] is None and isinstance(state[1], dict): # default style pickle self._val = state[1]["_val"] else: self._val, *unused = state self._cache = {} def is_absolute(self): """A check for absolute URLs. Return True for absolute ones (having scheme or starting with //), False otherwise. """ return self.raw_host is not None def is_default_port(self): """A check for default port. Return True if port is default for specified scheme, e.g. 'http://python.org' or 'http://python.org:80', False otherwise. """ if self.port is None: return False default = DEFAULT_PORTS.get(self.scheme) if default is None: return False return self.port == default def origin(self): """Return an URL with scheme, host and port parts only. user, password, path, query and fragment are removed. """ # TODO: add a keyword-only option for keeping user/pass maybe? if not self.is_absolute(): raise ValueError("URL should be absolute") if not self._val.scheme: raise ValueError("URL should have scheme") v = self._val netloc = self._make_netloc(None, None, v.hostname, v.port) val = v._replace(netloc=netloc, path="", query="", fragment="") return URL(val, encoded=True) def relative(self): """Return a relative part of the URL. scheme, user, password, host and port are removed. """ if not self.is_absolute(): raise ValueError("URL should be absolute") val = self._val._replace(scheme="", netloc="") return URL(val, encoded=True) @property def scheme(self): """Scheme for absolute URLs. Empty string for relative URLs or URLs starting with // """ return self._val.scheme @property def raw_authority(self): """Encoded authority part of URL. Empty string for relative URLs. """ return self._val.netloc @cached_property def authority(self): """Decoded authority part of URL. Empty string for relative URLs. """ return self._make_netloc( self.user, self.password, self.host, self.port, encode_host=False ) @property def raw_user(self): """Encoded user part of URL. None if user is missing. """ # not .username ret = self._val.username if not ret: return None return ret @cached_property def user(self): """Decoded user part of URL. None if user is missing. """ return self._UNQUOTER(self.raw_user) @property def raw_password(self): """Encoded password part of URL. None if password is missing. """ return self._val.password @cached_property def password(self): """Decoded password part of URL. None if password is missing. """ return self._UNQUOTER(self.raw_password) @property def raw_host(self): """Encoded host part of URL. None for relative URLs. """ # Use host instead of hostname for sake of shortness # May add .hostname prop later return self._val.hostname @cached_property def host(self): """Decoded host part of URL. None for relative URLs. """ raw = self.raw_host if raw is None: return None if "%" in raw: # Hack for scoped IPv6 addresses like # fe80::2%Проверка # presence of '%' sign means only IPv6 address, so idna is useless. return raw return _idna_decode(raw) @property def port(self): """Port part of URL, with scheme-based fallback. None for relative URLs or URLs without explicit port and scheme without default port substitution. """ return self._val.port or DEFAULT_PORTS.get(self._val.scheme) @property def explicit_port(self): """Port part of URL, without scheme-based fallback. None for relative URLs or URLs without explicit port. """ return self._val.port @property def raw_path(self): """Encoded path of URL. / for absolute URLs without path part. """ ret = self._val.path if not ret and self.is_absolute(): ret = "/" return ret @cached_property def path(self): """Decoded path of URL. / for absolute URLs without path part. """ return self._PATH_UNQUOTER(self.raw_path) @cached_property def query(self): """A MultiDictProxy representing parsed query parameters in decoded representation. Empty value if URL has no query part. """ ret = MultiDict(parse_qsl(self.raw_query_string, keep_blank_values=True)) return MultiDictProxy(ret) @property def raw_query_string(self): """Encoded query part of URL. Empty string if query is missing. """ return self._val.query @cached_property def query_string(self): """Decoded query part of URL. Empty string if query is missing. """ return self._QS_UNQUOTER(self.raw_query_string) @cached_property def path_qs(self): """Decoded path of URL with query.""" if not self.query_string: return self.path return f"{self.path}?{self.query_string}" @cached_property def raw_path_qs(self): """Encoded path of URL with query.""" if not self.raw_query_string: return self.raw_path return f"{self.raw_path}?{self.raw_query_string}" @property def raw_fragment(self): """Encoded fragment part of URL. Empty string if fragment is missing. """ return self._val.fragment @cached_property def fragment(self): """Decoded fragment part of URL. Empty string if fragment is missing. """ return self._UNQUOTER(self.raw_fragment) @cached_property def raw_parts(self): """A tuple containing encoded *path* parts. ('/',) for absolute URLs if *path* is missing. """ path = self._val.path if self.is_absolute(): if not path: parts = ["/"] else: parts = ["/"] + path[1:].split("/") else: if path.startswith("/"): parts = ["/"] + path[1:].split("/") else: parts = path.split("/") return tuple(parts) @cached_property def parts(self): """A tuple containing decoded *path* parts. ('/',) for absolute URLs if *path* is missing. """ return tuple(self._UNQUOTER(part) for part in self.raw_parts) @cached_property def parent(self): """A new URL with last part of path removed and cleaned up query and fragment. """ path = self.raw_path if not path or path == "/": if self.raw_fragment or self.raw_query_string: return URL(self._val._replace(query="", fragment=""), encoded=True) return self parts = path.split("/") val = self._val._replace(path="/".join(parts[:-1]), query="", fragment="") return URL(val, encoded=True) @cached_property def raw_name(self): """The last part of raw_parts.""" parts = self.raw_parts if self.is_absolute(): parts = parts[1:] if not parts: return "" else: return parts[-1] else: return parts[-1] @cached_property def name(self): """The last part of parts.""" return self._UNQUOTER(self.raw_name) @cached_property def raw_suffix(self): name = self.raw_name i = name.rfind(".") if 0 < i < len(name) - 1: return name[i:] else: return "" @cached_property def suffix(self): return self._UNQUOTER(self.raw_suffix) @cached_property def raw_suffixes(self): name = self.raw_name if name.endswith("."): return () name = name.lstrip(".") return tuple("." + suffix for suffix in name.split(".")[1:]) @cached_property def suffixes(self): return tuple(self._UNQUOTER(suffix) for suffix in self.raw_suffixes) @staticmethod def _validate_authority_uri_abs_path(host, path): """Ensure that path in URL with authority starts with a leading slash. Raise ValueError if not. """ if len(host) > 0 and len(path) > 0 and not path.startswith("/"): raise ValueError( "Path in a URL with authority should start with a slash ('/') if set" ) def _make_child(self, segments, encoded=False): """add segments to self._val.path, accounting for absolute vs relative paths""" parsed = [] for seg in reversed(segments): if not seg: continue if seg[0] == "/": raise ValueError( f"Appending path {seg!r} starting from slash is forbidden" ) seg = seg if encoded else self._PATH_QUOTER(seg) if "/" in seg: parsed += ( sub for sub in reversed(seg.split("/")) if sub and sub != "." ) elif seg != ".": parsed.append(seg) parsed.reverse() old_path = self._val.path if old_path: parsed = [*old_path.rstrip("/").split("/"), *parsed] if self.is_absolute(): parsed = _normalize_path_segments(parsed) if parsed and parsed[0] != "": # inject a leading slash when adding a path to an absolute URL # where there was none before parsed = ["", *parsed] new_path = "/".join(parsed) return URL( self._val._replace(path=new_path, query="", fragment=""), encoded=True ) @classmethod def _normalize_path(cls, path): # Drop '.' and '..' from str path prefix = "" if path.startswith("/"): # preserve the "/" root element of absolute paths, copying it to the # normalised output as per sections 5.2.4 and 6.2.2.3 of rfc3986. prefix = "/" path = path[1:] segments = path.split("/") return prefix + "/".join(_normalize_path_segments(segments)) @classmethod def _encode_host(cls, host, human=False): try: ip, sep, zone = host.partition("%") ip = ip_address(ip) except ValueError: host = host.lower() # IDNA encoding is slow, # skip it for ASCII-only strings # Don't move the check into _idna_encode() helper # to reduce the cache size if human or host.isascii(): return host host = _idna_encode(host) else: host = ip.compressed if sep: host += "%" + zone if ip.version == 6: host = "[" + host + "]" return host @classmethod def _make_netloc( cls, user, password, host, port, encode=False, encode_host=True, requote=False ): quoter = cls._REQUOTER if requote else cls._QUOTER if encode_host: ret = cls._encode_host(host) else: ret = host if port is not None: ret = ret + ":" + str(port) if password is not None: if not user: user = "" else: if encode: user = quoter(user) if encode: password = quoter(password) user = user + ":" + password elif user and encode: user = quoter(user) if user: ret = user + "@" + ret return ret def with_scheme(self, scheme): """Return a new URL with scheme replaced.""" # N.B. doesn't cleanup query/fragment if not isinstance(scheme, str): raise TypeError("Invalid scheme type") if not self.is_absolute(): raise ValueError("scheme replacement is not allowed for relative URLs") return URL(self._val._replace(scheme=scheme.lower()), encoded=True) def with_user(self, user): """Return a new URL with user replaced. Autoencode user if needed. Clear user/password if user is None. """ # N.B. doesn't cleanup query/fragment val = self._val if user is None: password = None elif isinstance(user, str): user = self._QUOTER(user) password = val.password else: raise TypeError("Invalid user type") if not self.is_absolute(): raise ValueError("user replacement is not allowed for relative URLs") return URL( self._val._replace( netloc=self._make_netloc(user, password, val.hostname, val.port) ), encoded=True, ) def with_password(self, password): """Return a new URL with password replaced. Autoencode password if needed. Clear password if argument is None. """ # N.B. doesn't cleanup query/fragment if password is None: pass elif isinstance(password, str): password = self._QUOTER(password) else: raise TypeError("Invalid password type") if not self.is_absolute(): raise ValueError("password replacement is not allowed for relative URLs") val = self._val return URL( self._val._replace( netloc=self._make_netloc(val.username, password, val.hostname, val.port) ), encoded=True, ) def with_host(self, host): """Return a new URL with host replaced. Autoencode host if needed. Changing host for relative URLs is not allowed, use .join() instead. """ # N.B. doesn't cleanup query/fragment if not isinstance(host, str): raise TypeError("Invalid host type") if not self.is_absolute(): raise ValueError("host replacement is not allowed for relative URLs") if not host: raise ValueError("host removing is not allowed") val = self._val return URL( self._val._replace( netloc=self._make_netloc(val.username, val.password, host, val.port) ), encoded=True, ) def with_port(self, port): """Return a new URL with port replaced. Clear port to default if None is passed. """ # N.B. doesn't cleanup query/fragment if port is not None: if isinstance(port, bool) or not isinstance(port, int): raise TypeError(f"port should be int or None, got {type(port)}") if port < 0 or port > 65535: raise ValueError(f"port must be between 0 and 65535, got {port}") if not self.is_absolute(): raise ValueError("port replacement is not allowed for relative URLs") val = self._val return URL( self._val._replace( netloc=self._make_netloc(val.username, val.password, val.hostname, port) ), encoded=True, ) def with_path(self, path, *, encoded=False): """Return a new URL with path replaced.""" if not encoded: path = self._PATH_QUOTER(path) if self.is_absolute(): path = self._normalize_path(path) if len(path) > 0 and path[0] != "/": path = "/" + path return URL(self._val._replace(path=path, query="", fragment=""), encoded=True) @classmethod def _query_seq_pairs(cls, quoter, pairs): for key, val in pairs: if isinstance(val, (list, tuple)): for v in val: yield quoter(key) + "=" + quoter(cls._query_var(v)) else: yield quoter(key) + "=" + quoter(cls._query_var(val)) @staticmethod def _query_var(v): cls = type(v) if issubclass(cls, str): return v if issubclass(cls, float): if math.isinf(v): raise ValueError("float('inf') is not supported") if math.isnan(v): raise ValueError("float('nan') is not supported") return str(float(v)) if issubclass(cls, int) and cls is not bool: return str(int(v)) raise TypeError( "Invalid variable type: value " "should be str, int or float, got {!r} " "of type {}".format(v, cls) ) def _get_str_query(self, *args, **kwargs): if kwargs: if len(args) > 0: raise ValueError( "Either kwargs or single query parameter must be present" ) query = kwargs elif len(args) == 1: query = args[0] else: raise ValueError("Either kwargs or single query parameter must be present") if query is None: query = None elif isinstance(query, Mapping): quoter = self._QUERY_PART_QUOTER query = "&".join(self._query_seq_pairs(quoter, query.items())) elif isinstance(query, str): query = self._QUERY_QUOTER(query) elif isinstance(query, (bytes, bytearray, memoryview)): raise TypeError( "Invalid query type: bytes, bytearray and memoryview are forbidden" ) elif isinstance(query, Sequence): quoter = self._QUERY_PART_QUOTER # We don't expect sequence values if we're given a list of pairs # already; only mappings like builtin `dict` which can't have the # same key pointing to multiple values are allowed to use # `_query_seq_pairs`. query = "&".join( quoter(k) + "=" + quoter(self._query_var(v)) for k, v in query ) else: raise TypeError( "Invalid query type: only str, mapping or " "sequence of (key, value) pairs is allowed" ) return query def with_query(self, *args, **kwargs): """Return a new URL with query part replaced. Accepts any Mapping (e.g. dict, multidict.MultiDict instances) or str, autoencode the argument if needed. A sequence of (key, value) pairs is supported as well. It also can take an arbitrary number of keyword arguments. Clear query if None is passed. """ # N.B. doesn't cleanup query/fragment new_query = self._get_str_query(*args, **kwargs) or "" return URL( self._val._replace(path=self._val.path, query=new_query), encoded=True ) def update_query(self, *args, **kwargs): """Return a new URL with query part updated.""" s = self._get_str_query(*args, **kwargs) query = None if s is not None: new_query = MultiDict(parse_qsl(s, keep_blank_values=True)) query = MultiDict(self.query) query.update(new_query) return URL( self._val._replace(query=self._get_str_query(query) or ""), encoded=True ) def with_fragment(self, fragment): """Return a new URL with fragment replaced. Autoencode fragment if needed. Clear fragment to default if None is passed. """ # N.B. doesn't cleanup query/fragment if fragment is None: raw_fragment = "" elif not isinstance(fragment, str): raise TypeError("Invalid fragment type") else: raw_fragment = self._FRAGMENT_QUOTER(fragment) if self.raw_fragment == raw_fragment: return self return URL(self._val._replace(fragment=raw_fragment), encoded=True) def with_name(self, name): """Return a new URL with name (last part of path) replaced. Query and fragment parts are cleaned up. Name is encoded if needed. """ # N.B. DOES cleanup query/fragment if not isinstance(name, str): raise TypeError("Invalid name type") if "/" in name: raise ValueError("Slash in name is not allowed") name = self._PATH_QUOTER(name) if name in (".", ".."): raise ValueError(". and .. values are forbidden") parts = list(self.raw_parts) if self.is_absolute(): if len(parts) == 1: parts.append(name) else: parts[-1] = name parts[0] = "" # replace leading '/' else: parts[-1] = name if parts[0] == "/": parts[0] = "" # replace leading '/' return URL( self._val._replace(path="/".join(parts), query="", fragment=""), encoded=True, ) def with_suffix(self, suffix): """Return a new URL with suffix (file extension of name) replaced. Query and fragment parts are cleaned up. suffix is encoded if needed. """ if not isinstance(suffix, str): raise TypeError("Invalid suffix type") if suffix and not suffix.startswith(".") or suffix == ".": raise ValueError(f"Invalid suffix {suffix!r}") name = self.raw_name if not name: raise ValueError(f"{self!r} has an empty name") old_suffix = self.raw_suffix if not old_suffix: name = name + suffix else: name = name[: -len(old_suffix)] + suffix return self.with_name(name) def join(self, url): """Join URLs Construct a full (“absolute”) URL by combining a “base URL” (self) with another URL (url). Informally, this uses components of the base URL, in particular the addressing scheme, the network location and (part of) the path, to provide missing components in the relative URL. """ # See docs for urllib.parse.urljoin if not isinstance(url, URL): raise TypeError("url should be URL") return URL(urljoin(str(self), str(url)), encoded=True) def joinpath(self, *other, encoded=False): """Return a new URL with the elements in other appended to the path.""" return self._make_child(other, encoded=encoded) def human_repr(self): """Return decoded human readable string for URL representation.""" user = _human_quote(self.user, "#/:?@") password = _human_quote(self.password, "#/:?@") host = self.host if host: host = self._encode_host(self.host, human=True) path = _human_quote(self.path, "#?") query_string = "&".join( "{}={}".format(_human_quote(k, "#&+;="), _human_quote(v, "#&+;=")) for k, v in self.query.items() ) fragment = _human_quote(self.fragment, "") return urlunsplit( SplitResult( self.scheme, self._make_netloc( user, password, host, self._val.port, encode_host=False, ), path, query_string, fragment, ) ) def _human_quote(s, unsafe): if not s: return s for c in "%" + unsafe: if c in s: s = s.replace(c, f"%{ord(c):02X}") if s.isprintable(): return s return "".join(c if c.isprintable() else quote(c) for c in s) _MAXCACHE = 256 @functools.lru_cache(_MAXCACHE) def _idna_decode(raw): try: return idna.decode(raw.encode("ascii")) except UnicodeError: # e.g. '::1' return raw.encode("ascii").decode("idna") @functools.lru_cache(_MAXCACHE) def _idna_encode(host): try: return idna.encode(host, uts46=True).decode("ascii") except UnicodeError: return host.encode("idna").decode("ascii") @rewrite_module def cache_clear(): _idna_decode.cache_clear() _idna_encode.cache_clear() @rewrite_module def cache_info(): return { "idna_encode": _idna_encode.cache_info(), "idna_decode": _idna_decode.cache_info(), } @rewrite_module def cache_configure(*, idna_encode_size=_MAXCACHE, idna_decode_size=_MAXCACHE): global _idna_decode, _idna_encode _idna_encode = functools.lru_cache(idna_encode_size)(_idna_encode.__wrapped__) _idna_decode = functools.lru_cache(idna_decode_size)(_idna_decode.__wrapped__) py.typed000064400000000016150043323140006233 0ustar00# Placeholder