+
    4jy                       a  0 t $ R t^ RIHt ^ RIt^ RIt^ RIt^ RIt^ RIt^ RI	t	^ RI
t
^ RIHt ^ RIHt ^ RIHt ^ RIHtHt ^ RIHtHtHt ^ RIHtHt ^ R	IHt ^R
IHt ^RIH t H!t! ^RI"H#t#H$t$H%t% ]'       d   ^ RI&H't' ^ RIH(t( ^ RI)H*t* ^RI"H+t+H,t, . R^Ot-]]].3,          t/R_t0R]1R&   ]2! ]	R4      t3 ! R R]$4      t4 ! R R]54      t6 ! R R]54      t7 ! R R]54      t8]Pr                  ! R]Pt                  4      t;]Pr                  ! R ]Px                  4      t=R`t>^t?]! R!R"7      R# R$ l4       t@]! R!R"7      R% R& l4       tAR' R( ltBR) R* ltCR+ R, ltDR- R. ltER/tFR0tGR1 R2 ltHR3 R4 ltIR5 R6 ltJ]! R7R7R87       ! R9 R4      4       tK]! R7R7R87       ! R: R4      4       tL ! R; R4      tMR<R/R= R> lltNR? R@ ltORA RB ltPRC RD ltQRE RF ltRRGtSRH RI ltTRJ RK ltURL RM ltVRN RO ltWRP RQ ltXRR RS ltYRT RU ltZRV RW lt[RX RY lt\RZ R[ lt]R\ R] lt^R# )aa[  PyPI Simple API client using PEP 691 JSON and PEP 658/714 metadata.

Fetches package listings and wheel/sdist metadata from PyPI. An index that
answers with the PEP 503 HTML serialization instead is read through
:mod:`nab_index._pep503`. Transport-agnostic: any async HTTP client
implementing the :class:`AsyncHttpTransport` protocol can be used.
)annotationsN)Mapping)	dataclass)	lru_cache)TYPE_CHECKINGAny)urljoinurlsplit
urlunsplit)canonicalize_nameparse_sdist_filename)Version)json_listing)SimpleSerializationsimple_accept_header)IDENTITY_HEADERS	HttpErrorraise_unless_ok)Path)NormalizedName)Self)AsyncHttpTransportHttpResponseACCEPTED_HASH_ALGORITHMSAsyncSimpleClientMalformedSimpleResponseErrorMetadataHashMismatchError	SdistFileSdistHashMismatchError	WheelFileWheelHashMismatchErrorztuple[str, ...]data_filterc                      ] tR t^DtRtRtR# )r   a"  The index served a 200 response that is not a usable Simple-API body.

Covers a listing that is neither valid JSON nor decodable HTML, and a
PEP 658 metadata sidecar that is not valid UTF-8. Subclasses
:class:`HttpError` so a broken body is caught alongside transport and
4xx/5xx failures.
 N__name__
__module____qualname____firstlineno____doc____static_attributes__r#       b/home/user/pdf2html-billing-ledger-validate/.venv/lib/python3.14/site-packages/nab_index/client.pyr   r   D   s    r+   c                      ] tR t^NtRtRtR# )r   z:Fetched PEP 658 metadata did not match its published hash.r#   Nr$   r#   r+   r,   r   r   N   s    Dr+   c                      ] tR t^RtRtRtR# )r   z9A fetched sdist archive did not match its published hash.r#   Nr$   r#   r+   r,   r   r   R   s    Cr+   c                      ] tR t^VtRtRtR# )r    zAA range-recovered wheel's bytes did not match its published hash.r#   Nr$   r#   r+   r,   r    r    V   s    Kr+   z	(\d+)(.*)z^[\w\d._]*$i   )maxsizec                    V ^8  d   QhRRRR/# )   versionstrreturnr#   )formats   "r,   __annotate__r7   d   s     ! ! ! !r+   c                *    \        \        V 4      4      # )z)Return a cached canonical version string.)r4   r   )r3   s   &r,   _canonical_versionr9   c   s     ww  r+   c                    V ^8  d   QhRRRR/# )r2   namer4   r5   r   r#   )r6   s   "r,   r7   r7   j   s     # #s #~ #r+   c                    \        V 4      # )zReturn a cached canonical name.)r   )r;   s   &r,   _intern_namer=   i   s     T""r+   c                    V ^8  d   QhRRRR/# r2   filenamer4   r5   z!tuple[NormalizedName, str] | Noner#   )r6   s   "r,   r7   r7   o   s     -. -.C -.,M -.r+   c                   V P                  R4      '       g   R# V RR pVP                  R4      pV\        9  d   R# VP                  RV^,
          4      pV^ ,          pRV9   g   \        P                  V4      f   R#  \        V^,          4      pT\        8H  ;'       d    \        P                  T^,          4      RJ p\        ;QJ d2    R TR	,          P                  R4       4       F  '       g   K   RM'	  RM#! R TR	,          P                  R4       4       4      pT'       g	   T'       d   R# \        T4      T3#   \         d     R# i ; i)
a  Parse a wheel filename per PEP 427.

Returns ``(canonical_name, version_string)`` or ``None`` for any
filename packaging rejects (wrong extension, malformed, etc.) and
for a version digit run past CPython's int-from-string limit.
Never raises.
The version string is the canonical form produced by
:class:`packaging.version.Version`, so trailing-zero handling
matches what packaging records on the file; e.g. a wheel
declaring ``2.0.0`` in its filename comes back as ``"2.0.0"``,
not ``"2"``.

This reproduces :func:`packaging.utils.parse_wheel_filename`'s
name/version validation and its rejection of empty tag components,
but discards the ``frozenset[Tag]`` that the tag parser builds and
nab does not use.
z.whlN-__c              3  J   "   T F  pR VP                  R4      9   x  K  	  R# 5i) .N)split).0	components   & r,   	<genexpr>(_parse_wheel_filename.<locals>.<genexpr>   s      U@T9B)//#..@Ts   !#TF)endswithcount_WHEEL_DASHESrG   _WHEEL_NAME_REmatchr9   
ValueError_WHEEL_DASHES_WITH_BUILD_BUILD_TAG_REanyr=   )r@   stemdashesparts	name_partr3   	bad_build	empty_tags   &       r,   _parse_wheel_filenamer]   o   s   $ V$$CR=DZZ_F]"JJsFQJ'EaIyN00;C$U1X. 	**TT}/B/B58/LPT/T  Ub	PS@TUUb	PS@TUUII#W--  s    E   EEc                    V ^8  d   QhRRRR/# r?   r#   )r6   s   "r,   r7   r7      s        C  ,M  r+   c                    V P                  R4      '       d   R#  \        V 4      w  rT\        T4      3#   \         d     R# i ; i)a$  Parse a ``.tar.gz`` sdist filename to ``(canonical_name, version)``.

Returns ``None`` for anything packaging rejects, for a version digit
run past CPython's int-from-string limit, and for ``.zip`` sdists,
which nab does not support (gzip-tar only, and not part of the PEP 625
standard).  Never raises.

Legacy filenames with embedded build tags (e.g. ``cffi-1.0.2-2.tar.gz``)
parse to a surprising ``(name="cffi-1-0-2", version="2")``, so callers
MUST drop files whose canonical name does not match the queried
package.  See :func:`_parse_files`.
z.zipN)rN   r   rS   r4   )r@   r;   r3   s   &  r,   _parse_sdist_filenamer`      sN       ,X6 #g,  s   5 AAc                    V ^8  d   QhRRRR/# )r2   dataobjectr5   boolr#   )r6   s   "r,   r7   r7      s      & T r+   c                r   \        V \        4      '       g   R# V P                  R4      p\        V\        4      '       g   R# V Fo  p\        V\        4      '       d   VP                  R4      '       d   K2  VP                  R4      p\        V\        4      '       g   K[  \        V4      '       d   Kn   R# 	  R# )zWhether a Simple-API body offers a file nab cannot read.

nab reads wheels and ``.tar.gz`` sdists, so a page of ``.zip`` sdists
or ``.exe`` installers parses to no files at all.  A body that is not
a list of file entries answers ``False``.
Ffilesyankedr@   T)
isinstancedictgetlistr4   is_readable_filename)rb   	raw_files	file_infor@   s   &   r,   holds_unreadable_formatro      s     dD!!!Ii&&	)T**immH.E.E==,h$$-A(-K-K  r+   c                    V ^8  d   QhRRRR/# )r2   r@   r4   r5   rd   r#   )r6   s   "r,   r7   r7      s      3 4 r+   c                F    \        V 4      RJ;'       g    \        V 4      RJ# )z:Whether ``filename`` names a wheel or a ``.tar.gz`` sdist.N)r]   r`   )r@   s   &r,   rl   rl      s-     	h't3 	7 	7 *$6r+   i  zhttps://pypi.org/simple/c               $    V ^8  d   QhRRRRRR/# )r2   responser   keyr4   r5   
str | Noner#   )r6   s   "r,   r7   r7      s!      l   r+   c                    V P                   pVP                  4       pVP                  4        F  w  rEVP                  4       V8X  g   K  Vu # 	  R# )zCase-insensitive header lookup.

The :class:`HttpResponse` Protocol only promises a plain
:class:`Mapping`. Both real transports (httpx, urllib3) return
case-insensitive header containers, but we don't rely on
that here so a plain-dict fake also works.
N)headersloweritems)rs   rt   rw   targetr;   values   &&    r,   _headerr|      sD     GYY[F}}::<6!L ' r+   c                    V ^8  d   QhRRRR/# )r2   content_typeru   r5   rd   r#   )r6   s   "r,   r7   r7      s     	E 	E: 	E$ 	Er+   c                    V f   R# V P                  R4      ^ ,          P                  4       P                  4       pVR8H  ;'       g    VP                  R4      # )zReturn True when a Content-Type names an HTML Simple-API serialization.

Covers :pep:`503`'s ``text/html`` and :pep:`691`'s
``application/vnd.pypi.simple.vN+html``.
F;z	text/htmlz+html)	partitionstriprx   rN   )r~   
media_types   & r,   _is_html_listingr      sR     '',Q/557==?J$DD
(;(;G(DDr+   c          
     ,    V ^8  d   QhRRRRRRRRRR	/# )
r2   rs   r   	index_urlr4   packageserializationr   r5   bytesr#   )r6   s   "r,   r7   r7      s:     ;9 ;9;9;9 ;9 '	;9
 ;9r+   c                z   V P                   p\        V R4      p\        V4      pV\        P                  Jd   VV\        P
                  J 8w  dk   Ve   RV: 2MRpV'       d    R\        P
                  P                  : R2MRpV RV: R	V R
VP                  : RV RVP                   R2p	\        V	4      hV'       g   V#  VP                  R4      p
 \        YP                  4      #   \         d   pT RT: R2p	\        T	4      ThRp?ii ; i  \         d   pT RT: RT 2p	\        T	4      ThRp?ii ; i)a  Return a listing response's body as PEP 691 JSON bytes.

The served Content-Type picks the decoder. An HTML page is re-serialized
so the parser and the cache only ever see one shape; any other body is
passed through untouched. A pinned index that answers in the other
serialization raises instead.

An HTML page's hrefs resolve against the URL that served the page, which
is not the requested one when the index redirected.
zcontent-typeNzContent-Type zno Content-Typez set serialization = ,rE   z served z with z., but this index is pinned to serialization = z.  Drop the pin,z' or set url to an endpoint that serves rF   utf-8, served a malformed Simple-API response for z: HTML body is not valid UTF-8z: )contentr|   r   r   	NEGOTIATEHTMLr{   r   decodeUnicodeDecodeErrorr   urlrS   )rs   r   r   r   bodyr~   is_htmlservedinsteadmsgtextexcs   &&&&        r,   _listing_bodyr      s     D8^4L|,G/999g,111?
 ' L+," 	  $$7$<$<$B$B#EQG 	 k'F6( ;**7*=*=)@ A%Y '##$A' 	 +3//9{{7#9D,,//  9kEk79 	 +3/S89  9kEg[PRSVRWX 	 +3/S8	9s0   C+ D +D6DDD:D55D:T)frozenslotsc                      ] tR tRt$ RtR]R&   R]R&   R]R&   R]R&   R	]R
&   R]R&   RtR]R&   RtR]R&   RtR]R&   Rt	R]R&   ]
R R l4       tRtR# )r   i4  a  Wheel file record returned by the Simple-API client.

``hashes`` is a tuple of ``(algorithm, hex_digest)`` pairs in the
order PEP 691 declared them (tuple form keeps the dataclass
hashable).  ``has_metadata`` says whether the index advertised a
PEP 658/714 sidecar; :attr:`metadata_url` derives the URL lazily.

``local_path`` is the on-disk path of a wheel served from a local
index, and ``None`` for one fetched from a remote index.  It lets
downstream code use the path directly instead of reversing the
``file:`` URL, which is lossy across platforms.

``metadata_hash`` is the published ``(algorithm, hex_digest)`` for
the PEP 658/714 sidecar, or ``None`` when the index advertised the
sidecar without a hash.  The fetcher verifies the sidecar bytes
against it.
r4   r@   r   r3   ru   requires_pythonrd   has_metadataupload_timetuple[tuple[str, str], ...]hashesN
int | NonesizePath | None
local_pathtuple[str, str] | Nonemetadata_hashc                   V ^8  d   QhRR/# )r2   r5   ru   r#   )r6   s   "r,   r7   WheelFile.__annotate__T  s     	V 	Vj 	Vr+   c                    V P                   '       g   R# \        V P                  4      p\        VP	                  VP
                  R,           RR7      4      # )zReturn the PEP 658/714 metadata URL, or None when unsupported.

The suffix goes on the path, so a PEP 503 hash fragment is dropped.
Nz	.metadatarE   )pathfragment)r   r	   r   r
   _replacer   )selfrY   s   & r,   metadata_urlWheelFile.metadata_urlS  sC        "%..ejj;.FQS.TUUr+   r#   )r%   r&   r'   r(   r)   __annotations__r   r   r   r   propertyr   r*   r#   r+   r,   r   r   4  sh    $ M	HL*,F',D*"J",0M)0	V 	Vr+   c                  x    ] tR tRt$ RtR]R&   R]R&   R]R&   R]R&   R]R	&   RtR
]R&   RtR]R&   RtR]R&   Rt	R# )r   i`  zA source distribution from the Simple API.

See :class:`WheelFile` for the meaning of ``hashes``, ``size`` and
``local_path``.
r4   r@   r   r3   ru   r   r   r   r   Nr   r   r   r   r#   )
r%   r&   r'   r(   r)   r   r   r   r   r*   r#   r+   r,   r   r   `  sC     M	HL*,F',D*"J"r+   c                  t    ] tR tRtRt]3R R lltR R ltR R ltR	 R
 lt	R R lt
R R ltR R ltRtR# )r   ir  zzAsync PyPI Simple API client.

Uses an :class:`AsyncHttpTransport` for HTTP, so any async HTTP
library can be plugged in.
c               $    V ^8  d   QhRRRRRR/# )r2   	transportr   r   r4   r5   Noner#   )r6   s   "r,   r7   AsyncSimpleClient.__annotate__y  s(     6 6%6 6 
	6r+   c                L    Wn         VP                  R4      R,           V n        R# )z4Create a client with the given async HTTP transport./N)
_transportrstrip
_index_url)r   r   r   s   &&&r,   __init__AsyncSimpleClient.__init__y  s      $#**3/#5r+   c                   V ^8  d   QhRR/# )r2   r5   r   r#   )r6   s   "r,   r7   r     s     ' 'd 'r+   c                V   "   V P                   P                  4       G Rj  xL
  R#  L5i)zClose the underlying transport.N)r   acloser   s   &r,   r   AsyncSimpleClient.aclose  s     oo$$&&&s   )')c                   V ^8  d   QhRR/# )r2   r5   r   r#   )r6   s   "r,   r7   r     s      $ r+   c                   "   V # 5i)z Enter the async context manager.r#   r   s   &r,   
__aenter__AsyncSimpleClient.__aenter__  s
     s   c                    V ^8  d   QhRRRR/# )r2   argsrc   r5   r   r#   )r6   s   "r,   r7   r     s      V  r+   c                B   "   V P                  4       G Rj  xL
  R#  L5i)z7Exit the async context manager and close the transport.N)r   )r   r   s   &*r,   	__aexit__AsyncSimpleClient.__aexit__  s     kkms   c                    V ^8  d   QhRRRR/# )r2   r   r4   r5   list[WheelFile | SdistFile]r#   )r6   s   "r,   r7   r     s     S Ss S/J Sr+   c                  "   V P                    V R2p\        \        P                  4      pV P                  P                  VRV/R7      G Rj  xL
 pVP                  \        8X  d   . # \        WB4       \        W@P                   V\        P                  4      p \        P                  ! V4      p\        Y`P                   YP                  R7      #  L  \         d%   pT P                    RT: R2p\        T4      ThRp?ii ; i5i)zFetch all distribution files for a package.

A body ``json.loads`` rejects becomes a
:class:`MalformedSimpleResponseError`, not a raw decode error.
r   Acceptrw   Nr   z: body is not valid JSON)page_url)r   r   r   r   r   rj   status_code_HTTP_NOT_FOUNDr   r   jsonloadsrS   r   _parse_filesr   )	r   r   r   acceptrs   r   rb   r   r   s	   &&       r,   	get_filesAsyncSimpleClient.get_files  s      !'!,%&9&C&CD,,S8V:L,MM?2I&oow0C0M0M
	=::d#D D//7\\RR! N  	=??##O+57  /s3<	=s7   ADCADC 2"DD C??DDc                    V ^8  d   QhRRRR/# )r2   r   r4   r5   r#   )r6   s   "r,   r7   r     s      C C r+   c                   "   V P                   P                  V4      G Rj  xL
 p\        W!4       VP                  #  L5i)z:Fetch metadata text from a known PEP 658/714 metadata URL.N)r   rj   r   r   )r   r   rs   s   && r,   get_metadata_text#AsyncSimpleClient.get_metadata_text  s3     ,,\::/}} ;s   ?=?c                    V ^8  d   QhRRRR/# )r2   r   r4   r5   r   r#   )r6   s   "r,   r7   r     s        #  %  r+   c                   "   V P                   P                  V\        R7      G Rj  xL
 p\        W!4       VP                  #  L5i)z<Fetch a distribution artefact (wheel or sdist) as raw bytes.r   N)r   rj   r   r   r   )r   r   rs   s   && r,   downloadAsyncSimpleClient.download  s<     ,,S:J,KK& Ls   %AAA)r   r   N)r%   r&   r'   r(   r)   DEFAULT_INDEXr   r   r   r   r   r   r   r*   r#   r+   r,   r   r   r  s5     '6'S4   r+   r   c          
     ,    V ^8  d   QhRRRRRRRRRR	/# )
r2   rb   rc   r   r4   r   r   ru   r5   r   r#   )r6   s   "r,   r7   r7     s4     < <
< <+.<=G< <r+   c                  \        V4      pVe   TMV V R2p. p\        V \        4      '       g+   V RV: R\        V 4      P                   R2p\        V4      hV P                  R4      p\        V\        4      '       g+   V RV: R\        V4      P                   R2p\        V4      hV F  p	\        V	\        4      '       g   K  V	P                  R4      '       d   K4  V	P                  R	4      p
V	P                  R
4      p\        V
\        4      '       d   \        V\        4      '       g   K  \        WWV4      pVf   K  VP                  V4       K  	  V# )a  Parse distribution files from a Simple API JSON response.

``package`` is the package the index was queried for; files whose
parsed canonical name does not match are dropped.  PyPI hosts a
handful of legacy sdists with embedded build tags
(``cffi-1.0.2-2.tar.gz`` and similar) that
:func:`packaging.utils.parse_sdist_filename` interprets as a
different project (``cffi-1-0-2`` at version ``2``).  Without the
name check those leak into the listing as a phantom version, and
show up in the resolved lockfile as ``cffi==2``.

``page_url`` is the URL the project page was retrieved from, the base a
relative entry resolves against. ``None`` falls back to the page URL
built from ``index_url`` and ``package``.

PEP 592 ``yanked`` files are dropped unconditionally.

A single malformed *entry* (non-dict, missing string ``filename`` /
``url``, or a ``url`` that does not parse) is skipped so the usable
entries in the same listing are kept.  A malformed *body* (not a JSON
object, or a ``files`` value that is not a list) is a broken response,
not an empty one, so it raises :class:`MalformedSimpleResponseError`
rather than returning no files: an empty result means "package absent"
to the multi-index router, which would otherwise fall through to a
lower-priority index and risk pinning a different version.
r   r   z
: body is z, expected a JSON objectrf   z: 'files' is z, expected a listrg   r@   r   )r   rh   ri   typer%   r   rj   rk   r4   _parse_file_entryappend)rb   r   r   r   expectedbase_urlrf   r   rm   rn   r@   raw_urlparseds   &&&$         r,   r   r     sO   : !)H#/x	{7)15MH)+EdD!!kEkDJ$7$7#88PR 	 +3//!Ii&&kEktI'?'?&@@QS 	 +3//	)T**==""==,--&(C((
7C0H0H"98TLL   Lr+   c               $    V ^8  d   QhRRRRRR/# )r2   r   r4   r   r5   ru   r#   )r6   s   "r,   r7   r7     s!      s c j r+   c                     V P                  R4      '       d   \        V 4       V # \        W4      #   \         d     R# i ; i)zReturn the entry's absolute URL, or None when it does not parse.

PEP 691 allows a relative ``url``, which resolves against the package
page.  ``urlsplit`` raises on a netloc it cannot parse, such as an
unbalanced bracket in an IPv6 host.
N)zhttps://zhttp://)
startswithr	   r   rS   )r   r   s   &&r,   _resolve_file_urlr     sE    	566 WNx)) s   #1 
1 A A c               0    V ^8  d   QhRRRRRRRRRRR	R
/# )r2   rn   
_FileEntryr@   r4   r   r   r   r   r5   zWheelFile | SdistFile | Noner#   )r6   s   "r,   r7   r7     sL     F FFF F 	F
 F "Fr+   c                @   \        W#4      pVf   R# \        V P                  R4      4      p\        V P                  R4      4      pV P                  R4      p\	        V\
        4      '       d   \        P                  ! V4      MRp	V P                  R4      p
\	        V
\
        4      '       d   T
MRp\        V4      pVe3   Vw  rW8w  d   R# \        VVVV	\        V 4      VVV\        V 4      R7	      # \        V4      pVf   R# Vw  rW8w  d   R# \        VVVV	VVVR7      # )a`  Build a file record from a validated PEP 691 entry, or None to drop it.

``filename`` and ``raw_url`` are the entry's already-validated string
fields.  ``expected`` is the queried package's canonical name; files
whose parsed name differs, whose filename packaging does not
recognise, or whose URL does not parse are dropped (see
:func:`_parse_files`).
Nr   r   zrequires-pythonzupload-time)	r@   r   r3   r   r   r   r   r   r   )r@   r   r3   r   r   r   r   )r   _parse_hashesrj   _parse_sizerh   r4   sysinternr]   r   _has_metadata_metadata_hashr`   r   )rn   r@   r   r   r   file_urlr   r   requires_python_rawr   upload_time_rawr   wheel_parsedparsed_namer3   sdist_parseds   &&&&&           r,   r   r     s4    !3H9==23Fy}}V,-D
 $--(9:
 )3// 	

&'   mmM2O%/%E%E/4K(2L+"+&y1#(3

 
	
 )2L'K' r+   c                    V ^8  d   QhRRRR/# )r2   r{   rc   r5   r   r#   )r6   s   "r,   r7   r7   P  s       $? r+   c                   \        V \        4      '       g   R# \        V 4      ^8X  d   V P                  4       w  w  r\        V\        4      '       dT   \        V\        4      '       d>   V'       d6   \
        P                  ! VP                  4       4      VP                  4       33# R# . pV P                  4        F  w  r\        V\        4      '       g   K  \        V\        4      '       g   K5  V'       g   K?  VP                  \
        P                  ! VP                  4       4      VP                  4       34       K  	  \        V4      # )   r#   )
rh   ri   lenry   r4   r   r   rx   r   tuple)r{   algodigestouts   &   r,   r   r   P  s     eT""	 5zQ!KKM$dC  Z%<%<ZZ

-v||~>@@	!#CdC  Z%<%<JJ

4::<0&,,.AB & :r+   c                    V ^8  d   QhRRRR/# )r2   r{   rc   r5   r   r#   )r6   s   "r,   r7   r7   i  s      v * r+   c                p    \        V \        4      '       d    \        V \        4      '       g
   V ^ 8  d   V # R# )    N)rh   intrd   )r{   s   &r,   r   r   i  s)    %j&=&=%1*r+   zdist-info-metadatac                    V ^8  d   QhRRRR/# )r2   rn   r   r5   rc   r#   )r6   s   "r,   r7   r7   s  s     / /z /f /r+   c                \    RV 9   d   V P                  R4      # V P                  \        4      # )a  Return the metadata field, applying PEP 714 key precedence.

When ``core-metadata`` is present it wins and the legacy
``dist-info-metadata`` key is ignored, so ``core-metadata: false``
means no sidecar even if a stale legacy entry lingers.  The legacy key
applies only when ``core-metadata`` is absent.  ``data-dist-info-metadata``
is the HTML attribute name and never appears in the JSON response.
zcore-metadata)rj   _LEGACY_METADATA_KEY)rn   s   &r,   _metadata_valuer  s  s+     )#}}_--==-..r+   c                    V ^8  d   QhRRRR/# )r2   rn   r   r5   rd   r#   )r6   s   "r,   r7   r7     s     4 4Z 4D 4r+   c                P    \        V 4      pVRJ ;'       g    \        V\        4      # )zReturn True when the file entry advertises a PEP 658/714 sidecar.

PEP 691 allows either a ``true`` boolean (sidecar exists but no
hashes published) or a mapping carrying the digest table.  Either
flavour means the index will serve ``<file>.metadata``.
T)r  rh   ri   )rn   r{   s   & r,   r   r     s'     I&ED=33Jud33r+   c                    V ^8  d   QhRRRR/# )r2   rn   r   r5   r   r#   )r6   s   "r,   r7   r7     s     , ,j ,-C ,r+   c                    \        V 4      p\        V\        4      '       g   R# \        ;QJ d"    . R VP	                  4        4       F  NK  	  5M! R VP	                  4        4       4      p\        V4      # )zReturn the sidecar's published ``(algo, hex)`` to verify, or None.

A bare ``true`` (sidecar exists, no hash), an empty digest, or a table with
no accepted algorithm yields None, so no check runs.
Nc              3     "   T F:  w  r\        V\        4      '       g   K  \        V\        4      '       g   K5  W3x  K<  	  R # 5i)N)rh   r4   )rH   r  r	  s   &  r,   rJ   !_metadata_hash.<locals>.<genexpr>  s6      )LDdC  	%/%< 	)s   AAA)r  rh   ri   r  ry   _select_artifact_hash)rn   r{   	publisheds   &  r,   r   r     sa     I&EeT"" !KKM !KKM I
 !++r+   c               $    V ^8  d   QhRRRRRR/# )r2   r   r   r   tuple[str, str]r5   r   r#   )r6   s   "r,   r7   r7     s!     - -5 - -T -r+   c                    Vw  r#\         P                  ! W 4      P                  4       pWC8w  d   RV RV RV 2p\        V4      hR# )zGRaise :class:`MetadataHashMismatchError` if ``content`` fails the hash.z	metadata  mismatch: expected , got N)hashlibnew	hexdigestr   )r   r   r  r   actualr   s   &&    r,   _verify_metadata_hashr$    sO    "ND[['113F$3H:VF8L',, r+   c                    V ^8  d   QhRRRR/# )r2   r   r   r5   r   r#   )r6   s   "r,   r7   r7     s      'r+   c                    V  UUu/ uF$  w  rVP                  4       VP                  4       bK&  	  ppp\         F!  pVP                  V4      pV'       g   K  W3u # 	  R# u uppi )a  Pick the preferred ``(algo, hex)`` to verify, or ``None`` if none qualify.

Walks :data:`ACCEPTED_HASH_ALGORITHMS` in order, so sha256 is preferred,
then sha384, then sha512. An empty set, an empty digest, or only unaccepted
algorithms (md5) yields ``None``.
N)rx   r   rj   )r   r  r	  by_algos   &   r,   r  r    s]     AGGtzz|V\\^+GG(T"6>! )  Hs   *A c               $    V ^8  d   QhRRRRRR/# )r2   r   r   
sdist_hashr  r5   r   r#   )r6   s   "r,   r7   r7     s!     * *u */ *d *r+   c                    Vw  r#\         P                  ! W 4      P                  4       pWC8w  d   RV RV RV 2p\        V4      hR# )zDRaise :class:`SdistHashMismatchError` if ``content`` fails the hash.zsdist r  r  N)r   r!  r"  r   )r   r)  r  r   r#  r   s   &&    r,   verify_sdist_hashr+    sO    ND[['113Ftf0
&I$S)) r+   c                    V ^8  d   QhRRRR/# r2   rb   r   r5   tuple[str | None, str | None]r#   )r6   s   "r,   r7   r7     s      u )F r+   c           	          \        V 4      #   \        P                  \        \        \
        \        \        P                  \        3 d    Ru # i ; i)a  Extract PKG-INFO and pyproject.toml from a .tar.gz sdist archive.

Returns ``(pkg_info, pyproject_toml)``. Either may be ``None`` if
the archive cannot be read or the file is absent. PEP 643 static
metadata detection requires both: PKG-INFO carries the ``Dynamic``
field that says which values are not authoritative, and
pyproject.toml's ``[project].dynamic`` is the static-metadata
fallback when PKG-INFO marks dependencies dynamic.

.zip sdists are intentionally unsupported.
NN)
_read_tar_sdist_filestarfileTarErrorOSErrorr   KeyErrorEOFErrorzliberrorRecursionError)rb   s   &r,   _extract_sdist_filesr:    sL    $T**

 	
  s   
 A AAc                    V ^8  d   QhRRRR/# r-  r#   )r6   s   "r,   r7   r7     s     5 5 5*G 5r+   c                   / p/ p\         P                  ! \        P                  ! V 4      R R7      ;_uu_ 4       pV F|  p\	        VP
                  4      w  rVpV^8w  d   K$  VR8X  d   TM
VR8X  d   TMRpVe   Wh9   d   KD  VP                  V4      p	V	f   K[  V	P                  4       P                  R4      W&   K~  	  RRR4       \        W4      #   + '       g   i     L; i)r:gzfileobjmodezPKG-INFOzpyproject.tomlNr   )
r2  openioBytesIO_sdist_member_top_levelr;   extractfilereadr   _select_sdist_root)
rb   	pkg_infos
pyprojectstarmemberdepthtop_dirbasenamerz   	extracteds
   &         r,   r1  r1    s     "I!#J	bjj.V	<	<F'>v{{'K$EHz z)  //    ~!2/I$"+.."2"9"9'"B  
=$ i44% 
=	<s   AC%CC	c               $    V ^8  d   QhRRRRRR/# )r2   rH  zdict[str, str]rI  r5   r.  r#   )r6   s   "r,   r7   r7     s$     , ,,+9,",r+   c                    \        V 4      ^8w  d   R# \        \        V P                  4       4      4      w  r#W1P	                  V4      3# )a  Pick PKG-INFO and pyproject.toml from one ``<name>-<version>/`` root.

A conformant sdist has a single top-level directory holding both
files.  PKG-INFO is the defining file, so its directory is the root;
pyproject.toml counts only when it shares that directory.  If several
top-level directories carry a PKG-INFO the root is ambiguous, so both
return ``None`` rather than risk pairing files from different roots.
r0  )r  nextiterry   rj   )rH  rI  rootpkg_infos   &&  r,   rG  rG    s@     9~$y012NDnnT*++r+   c                    V ^8  d   QhRRRR/# )r2   r;   r4   r5   ztuple[int, str, str]r#   )r6   s   "r,   r7   r7     s     0 0# 0*> 0r+   c                    V P                  R4      pV'       d   VP                  R4      '       d   R# VP                  R4      p\        V4      ^8  d
   V^ ,          MRp\        V4      ^,
          W2R,          3# )a2  Return ``(depth, top_dir, basename)`` for a tar member.

Strips a single leading ``./``.  Depth 0 means the file sits at the
archive root; depth 1 means it sits directly under a top-level
directory, whose name is ``top_dir`` (empty at depth 0).  Anything
deeper is reported as-is so callers can ignore it.
z./r   rE   rM   )rM   rE   rE   )removeprefixr   rG   r  )r;   strippedrY   rM  s   &   r,   rD  rD    sg       &Hx**3//NN3Ee*q.eAhbGJNG2Y//r+   c               $    V ^8  d   QhRRRRRR/# )r2   rb   r   
target_dirr   r5   r#   )r6   s   "r,   r7   r7     s$     / /
/!/	/r+   c                   \         '       g   Rp\        V4      hVP                  4       p \        P                  ! \
        P                  ! V 4      RR7      ;_uu_ 4       pVP                  VRR7       RRR4       \        TP!                  4       4      p\#        T4      ^8X  dD   T^ ,          P%                  4       '       d'   T^ ,          P'                  4       '       g
   T^ ,          # T#   + '       g   i     L~; i  \        P                   d   pRT 2p\        T4      ThRp?i\         d   pRT 2p\        T4      ThRp?i\        P                  \        \        \        P                  3 d   pR	T 2p\        T4      ThRp?ii ; i)
a  Extract a .tar.gz sdist into ``target_dir`` and return the source root.

Anything the extractor cannot read raises :class:`ValueError`: a corrupt or
truncated stream, a tar that will not open, and a member the tar ``data``
filter (:pep:`706`) refuses.  The filter refuses any member that would write
outside ``target_dir`` (absolute paths, ``..``, escaping links), is a special
file (device node, FIFO), or is a hard link whose target the archive does not
carry.  A lone top-level directory that wraps every member is the source
root; otherwise (top-level files, as in a flat sdist, or several top-level
directories) the root is ``target_dir``.

The data filter is required; a Python that lacks it (before 3.10.12 /
3.11.4 / 3.12) is unsupported and extraction raises.
zfextracting an sdist archive requires the tar data filter; upgrade to Python 3.10.12+ / 3.11.4+ / 3.12+r=  r>  rb   )filterNzunsafe sdist member: zbroken link in sdist member: zunreadable sdist archive: )_SUPPORTS_DATA_FILTERrS   resolver2  rA  rB  rC  
extractallFilterErrorr5  r3  r4  r6  r7  r8  rk   iterdirr  is_dir
is_symlink)rb   r[  r   rJ  r   entriess   &&    r,   extract_sdist_archiverf    sH   " ! < 	 o##%J'\\"**T"2@@CNN:fN5 A$ :%%'(G
7|qWQZ..009N9N9P9Pqz+ A@ '%cU+o3& '-cU3o3&gx< ' +3%0o3&'sY   4C< C)3C< )C9	4C< 9C< <F	D""F	/F	0E0F	2F	3FF	)r   r   r   r   r   r   r   r   r    rf  ro   rl   r+  )sha256sha384sha512)      )___conditional_annotations__r)   
__future__r   r   rB  r   rer   r2  r7  collections.abcr   dataclassesr   	functoolsr   typingr   r   urllib.parser   r	   r
   packaging.utilsr   r   packaging.versionr   _pep503r   r   r   r   r   r   r   r   pathlibr   r   typing_extensionsr   r   r   __all__rc   r   r   r   hasattrr^  r   	Exceptionr   r   r    compileASCIIrU   UNICODErQ   rP   rT   r9   r=   r]   r`   ro   rl   r   r   r|   r   r   r   r   r   r   r   r   r   r   r  r  r   r   r$  r  r+  r:  r1  rG  rD  rf  )rl  s   @r,   <module>r     s   #  	  	 
   # !  % 6 6 C % ! D C C.&;$ S&[!
 -K / J
  7 9 E	 EDY DLY L
 

<2NBJJ7  5! !
 5# #
-.` 0, * 	E;9| $d#(V (V $(VV $d## # $#"@  @ F<JN<~&FR2 , /4,$-"*852,"0*/r+   