+
    2jgK                    n   R t ^ RIHt ^ RIt^ RIt^ RIHt ^ RIHt ^ RI	H
t
 ^ RIHt ^ RIHtHtHt ^ RIHtHt ^R	IHt ]
'       d   ^R
IHt ^RIHt ^RIHtHtHtHt RtRt R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 R 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# )*a  Local-source, VCS-source, and archive-source materialisation.

A ``LocalSource`` becomes the only candidate for a package: PyPI is
not consulted.  A ``VcsSource`` clones the repo and an ``ArchiveSource``
downloads and hash-verifies a ``.tar.gz`` and extracts it; both reuse the
``LocalSource`` extraction path.  Each produces a single synthetic
``SdistFile`` whose version is read from ``[project].version``.
)annotationsN)suppress)Path)TYPE_CHECKING)ArchiveRequest)	SdistFileextract_sdist_archiveverify_sdist_hash)VcsCloneError
VcsRequest)canonicalize_name)Version)WheelMetadata)ArchiveSourceLocalSourceProvider	VcsSourcetreez.nab-completez.nab-hashesc               $    V ^8  d   QhRRRRRR/# )   providerr   sourceszlist[LocalSource]returnzdict[str, LocalSource] )formats   "g/home/user/billing-ledger-validation/.venv/lib/python3.14/site-packages/nab_python/_provider/sources.py__annotate__r   $   s&           c                    V'       g   / # / pV F=  p\        VP                  4      pWB9   d   RVP                  : 2p\        V4      hW2V&   K?  	  V# )a  Validate ``LocalSource`` entries and return a canonical-name map.

Admitted at every :class:`~nab_python.provider.BuildPolicy` level; the
policy only governs whether the backend may run when the static
pyproject read returns nothing usable (see
:func:`extract_source_metadata`).
zduplicate local source for )r   name
ValueError)r   r   outsrc	canonicalmsgs   &&    r   index_local_sourcesr%   $   sW     	"$C%chh/	/|<CS/!I  Jr   c               (    V ^8  d   QhRRRRRRRR/# )	r   r   r   
normalizedstrsourcer   r   list[tuple[Version, SdistFile]]r   )r   s   "r   r   r   ;   s6     T TTT T %	Tr   c                    \        VP                  4      pVP                  '       d   W2P                  ,          pRVP                  : 2p\	        V VV\        VP                  4      RR7      p\        WW5V4      # )a  Read metadata from ``source`` and seed caches with one synthetic version.

Static path: ``extract_static_metadata`` reads ``pyproject.toml``
directly.  Backend path: requires :attr:`BuildPolicy.BUILD_LOCAL`
or looser; raises :class:`UnsupportedSdistError` otherwise.
zlocal source local
descriptorpackagekind)r   pathsubdirectoryr   extract_source_metadatar   seed_synthetic_listing)r   r'   r)   r1   r.   metadatas   &&&   r   materialize_local_sourcer6   ;   so     D))) 0J&!&++.H "(
SSr   c               0    V ^8  d   QhRRRRRRRRRRR	R
/# )r   r   r   r1   r   r.   r(   r/   r0   r   r   r   )r   s   "r   r   r   T   sD     92 9292
92 	92
 92 92 92r   c                  ^RI Hp ^RIHpHp ^RIHpHp	  V! V4      p
T
e   T
# T P                  T4      pTR8X  d&   TP                  TP                  0pTP                  pMTP                  0pTP                  pY9  dN   T P                  ;P                  ^,          un        T RT RTP                   R	TP                   R
2pT	! T4      h TP                  TT P                  T P                  P                   R7      #   T d   pT RT 2pT	! T4      ThRp?ii ; i  T d   pT RT 2pT	! T4      ThRp?ii ; i)a3  Read metadata from a directory; gates the backend path on policy.

``kind`` is ``"local"`` for :class:`LocalSource` directories
(admitted at :attr:`BuildPolicy.BUILD_LOCAL` and above); ``"vcs"``
for :class:`VcsSource` clones and ``"archive"`` for extracted
:class:`ArchiveSource` trees both build only at
:attr:`BuildPolicy.BUILD_REMOTE`, like a remote sdist.

An unreadable ``pyproject.toml`` is reported as a read failure at
every policy level: the build path cannot read it either, so calling
it dynamic metadata would blame the policy for a permission error.
)build_backend)BuildBackendErrorextract_static_metadata)BuildPolicyUnsupportedSdistError: Nr,   z at z7 has dynamic metadata; building requires build-policy 'z' but the effective policy is '')configoffline) r9   r:   r;   r   r<   r=   !effective_build_policy_for_sourceBUILD_LOCALBUILD_REMOTEstatsexcluded_by_build_policyvalueextract_metadatabuild_configcoordinatorrA   )r   r1   r.   r/   r0   r9   r:   r;   r<   r=   r5   excr$   	effectiveallowedminimums   &&$$$           r   r3   r3   T   sk   * !J=2*40
 ::7CIw**K,D,DE))++,**//14/l$tf %%mm_ -!$ 	
 $C((2--((((00 . 
 	
/  2Bse$#C(c128  2Bse$#C(c12s/   D 1D! D	DD!D=(D88D=c               0    V ^8  d   QhRRRRRRRRR	RR
R/# )r   r   r   r'   r(   r1   r   r5   r   r.   r   r*   r   )r   s   "r   r   r      sD     $' $'$'$' $' 	$'
 $' %$'r   c           	     |   \        VP                  4      pWQ8w  d   ^RIHp V RV: RV: RV R2pV! V4      h\	        V RVP
                   R2VP                  4       \        VP
                  4      VP                  e   \        VP                  4      MRRVR	7      pVP
                  p	W0P                  W3&   W3.# )
z8Produce a one-version listing for a materialised source.)SourceNameMismatchErrorz declares package z but its [project].name is z (at zF); a source declared for one name must not provide a different project-z.tar.gzN)filenameurlversionrequires_pythonupload_time
local_path)
r   r   r   rR   r   rV   as_urir(   rW   metadata_cache)
r   r'   r1   r5   r.   actualrR   r$   synthetic_filerV   s
   &&&&&     r   r4   r4      s     x}}-F6 l,ZN ;""(5 7=> 	
 &c**<q!1!1 2':KKMH$$% ''3 (()N G5=Z12%&&r   c               $    V ^8  d   QhRRRRRR/# )r   r   r   r   zlist[VcsSource]r   zdict[str, VcsSource]r   )r   s   "r   r   r      s&     ' ''' 'r   c                   ^RI Hp ^RIHp V'       g   / # V P                  P
                  VP                  J d0   RV P                  P
                  P                   R2p\        V4      h/ pV Fj  pV! VP                  V P                  4       \        VP                  4      pWu9   g   WpP                  9   d   RVP                  : 2p\        V4      hWeV&   Kl  	  V# )a&  Validate VCS sources and return a canonical-name map.

Admitted at every :class:`~nab_python.provider.BuildPolicy` level; the
policy only governs whether the backend may run on the clone (see
:func:`extract_source_metadata`).  ``VcsPolicy.BLOCK`` still refuses
any declaration up-front because that is an independent decision
about whether VCS fetching is permitted at all.

Each URL is passed through :func:`admit_vcs_url` so the scheme,
repo, and pin allowlists apply to ``[[tool.nab.vcs-sources]]``
just like project-root direct-URL requirements.
)admit_vcs_url)	VcsPolicyz7vcs_sources require VcsPolicy.ALLOW; current policy is zE.  Set vcs_config to a permissive VcsConfig before declaring sources.duplicate source declared for )_vcs_admissionr`   r   ra   
vcs_configpolicyBLOCKrH   r    rU   r   r   local_sources)r   r   r`   ra   r$   r!   r"   r#   s   &&      r   index_vcs_sourcesrh      s    " /$	!!Y__4##**001 2@@ 	
 o "Ccggx223%chh/	y,B,BB2388,?CS/!I  Jr   c               (    V ^8  d   QhRRRRRRRR/# )	r   r   r   r'   r(   r)   r   r   r*   r   )r   s   "r   r   r      s6     )T )T)T)T )T %	)Tr   c                   ^ RI Hp ^RIHp V P                  f   RVP
                  : R2pV! V4      h \        P                  ! VP                  4      pVP                  V P                  VV P                  P                  V P                  P                  R7      pTP                  T P                   \#        TP
                  4      &   TP$                  P'                  4       p	TP(                  '       d   YP(                  ,          MT	p
RTP
                  : 2p\+        T T
T\#        TP
                  4      RR	7      p\-        YYT4      #   \         d"   pRTP
                  : RT 2pT! T4      ThRp?ii ; i)
zGClone ``source`` and materialise it via the same path as a LocalSource.)vcsr=   Nzvcs source z7 declared but no vcs_cache_dir was supplied to Provider)require_pinrA   r>   rk   r-   )	nab_indexrk   r   r=   vcs_cache_dirr   r   parserU   prepare_clonerd   rm   rK   rA   r
   
commit_shavcs_pinsr   r1   resolver2   r3   r4   )r   r'   r)   _vcsr=   r$   requestclonerL   rootr1   r.   r5   s   &&&          r   materialize_vcs_sourcery      s^    &0%&++ )6 7 	 $C((
2""6::."""" ++77((00	 # 
 9>8H8HH'45 ::D(-(:(:(:4$$$Dv{{o.J&!&++.H "(
SS!  2FKK?"SE2#C(c12s   A'E E4E//E4c               $    V ^8  d   QhRRRRRR/# )r   r   r   r   zlist[ArchiveSource]r   zdict[str, ArchiveSource]r   )r   s   "r   r   r     s&             r   c                   V'       g   / # / pV F  p\         P                  ! VP                  4      P                  '       g*   RVP                  : RVP                  : 2p\        V4      h\        VP                  4      pWR9   g!   WPP                  9   g   WPP                  9   d   RVP                  : 2p\        V4      hW2V&   K  	  V# )av  Validate archive sources and return a canonical-name map.

Admitted at every :class:`~nab_python.provider.BuildPolicy` level; the
policy only governs whether the backend may run on the extracted tree
(see :func:`extract_source_metadata`).  There is no ``VcsPolicy``-style
gate: the download is hash-verified, and which archive URLs are
permitted is decided at config parse.
archive source z has no hash in its URL: rb   )	r   rp   rU   has_usable_hashr   r    r   rg   vcs_sources)r   r   r!   r"   r$   r#   s   &&    r   index_archive_sourcesr     s     	$&C ##CGG,<<<#CHH</HTCS/!%chh/	2220002388,?CS/!I! " Jr   c               (    V ^8  d   QhRRRRRRRR/# )	r   r   r   r)   r   rv   r   r   bytesr   )r   s   "r   r   r   0  s0     ! !!! ! 	!r   c                   ^RI Hp \        VP                  4      pVP                  ^ ,          ^,          pV P
                  P                  pV P
                  P                  WEVP                  4      pVP                  4        VP                  WE4      pVe   RVP                  : RV 2p	V! V	4      VhVP                  WE4      p
V
f'   RVP                  : RVP                   R2p	V! V	4      hVP                   F  p\        W4       K  	  V
# )a	  Return the hash-verified bytes of ``source``'s archive.

Raises before returning if the fetch recorded a failure, produced no
bytes, or the bytes fail their hash.  The coordinator reads the declared
URL without verifying it, so every declared hash is checked here.
rl   r|   r>   z: download from z failed)r   r=   r   r   hashesrK   indexrequest_direct_archiverU   waitget_sdist_archive_errorget_sdist_archiver	   )r   r)   rv   r=   r#   digestr   eventfailurer$   datapinned_hashs   &&&         r   _fetch_archive_bytesr   0  s     1!&++.I^^Aq!F  &&E  77	7;;WE	JJL++I>Gb	:#C(g5""95D|.>w{{m7S#C((~~$, & Kr   c               $    V ^8  d   QhRRRRRR/# )r   r   r   r)   r   r   ztuple[Path, ArchiveRequest]r   )r   s   "r   r   r   T  s+     "N "N"N"N !"Nr   c                   ^RI Hp V P                  pVf   RVP                  : R2pV! V4      h\        P
                  ! VP                  4      pVP                  ^ ,          ^,          pW6,          p\        VP                  4      pV\        ,          P                  4       '       d   V\        V4      8:  d   \        V4      V3# \        WV4      p	\        W6WP                  4      V3# )af  Return the extracted tree's root and the parsed request for ``source``.

The cached tree is used with no download, offline runs included, only when
the record left at extraction covers every hash this resolve declares.
Otherwise the archive is downloaded and checked against the whole
declaration, so adding a hash re-verifies rather than trusting the tree.
rl   r|   z; declared but no archive_cache_dir was supplied to Provider)r   r=   archive_cache_dirr   r   rp   rU   r   set_COMPLETE_MARKERis_file_verified_hashes_extracted_rootr   _extract_archive)
r   r)   r=   	cache_dirr$   rv   r   targetdeclaredr   s
   &&        r   _prepare_archive_treer   T  s     1**Ifkk_ -: ; 	 $C((""6::.G
 ^^Aq!FF7>>"H!!**,,=Mf=U1Uv&//':DIt^^DgMMr   c                    V ^8  d   QhRRRR/# )r   r   r   r   zset[tuple[str, str]]r   )r   s   "r   r   r   y  s      T &: r   c                    V \         ,          pVP                  4       '       g   \        4       # VP                  RR7      P	                  4       pR V 4        UUUu0 uF	  w  r4pW53kK  	  uppp# u upppi )zReturn the hashes the tree at ``target`` was verified against.

The record is written with the completion marker, so a tree with no record
covers nothing and is refetched rather than trusted.
utf-8encodingc              3  B   "   T F  qP                  R 4      x  K  	  R# 5i=N)	partition).0lines   & r   	<genexpr>#_verified_hashes.<locals>.<genexpr>  s     (O)<)<s   )_HASHES_MARKERr   r   	read_text
splitlines)r   recordlines	algorithm_
hex_digests   &     r   r   r   y  ss     n$F>>ug.99;E )P(O(O$I* 
(O  s   A/c               (    V ^8  d   QhRRRRRRRR/# )	r   r   r   r'   r(   r)   r   r   r*   r   )r   s   "r   r   r     s6     T TTT T %	Tr   c                    \        W4      w  r4VP                  '       d   W4P                  ,          MTpRVP                  : 2p\        V VV\	        VP                  4      RR7      p\        WWWV4      # )a  Materialise ``source`` from its extracted tree, downloading if needed.

Every hash ``source`` declares is checked: against the downloaded bytes in
:func:`_fetch_archive_bytes`, or against the record the extraction left when
the cached tree is reused.  A tampered archive therefore fails the resolve
loudly rather than being used and pinned unverified.  The extracted tree
then takes the same path as a LocalSource.
r|   archiver-   )r   r2   r   r3   r   r4   )r   r'   r)   rx   rv   r1   r.   r5   s   &&&     r   materialize_archive_sourcer     sp     *(;MD +2*>*>*>4&&&DD"6;;/2J&!&++.H "(
SSr   c          
     ,    V ^8  d   QhRRRRRRRRR	R/# )
r   r   r   r   r(   r   r   verifiedztuple[tuple[str, str], ...]r   r   )r   s   "r   r   r     sA     F# F#F#F# F# *	F#
 
F#r   c                   ^RI Hp W,          pV\        ,          pVP                  4       '       Eg%   V P	                  RRR7       \        \        P                  ! W R2RR7      4      p VR,          pVP	                  4         \        W(4      p	T	P                  T\        ,          4       \        \        4      ;_uu_ 4        TP                  4        R	R	R	4       R
P                  R T 4       4      pT\         ,          P#                  TRR7       T\        ,          P%                  4         TP'                  T4       \*        P,                  ! TRR7       \/        V4      #   \         d   p
RT
 2pT! T4      T
hR	p
?
ii ; i  + '       g   i     L; i  \(         d   p
TP                  4       '       g^   \*        P,                  ! TRR7       \        \(        4      ;_uu_ 4        TP'                  T4       R	R	R	4       M  + '       g   i     M; iTP                  4       '       g   RT
 2pT! T4      T
h R	p
?
LR	p
?
ii ; i  \*        P,                  ! TRR7       i ; i)a  Extract ``data`` under ``cache_dir`` keyed by ``digest``; return the root.

The archive's root is published at ``_TREE_DIR`` inside the entry, so no
name the archive chose reaches the entry's top level.

``verified`` names the hashes the caller checked ``data`` against, recorded
beside the completion marker so a later resolve reuses the tree only for a
declaration those hashes cover.

Idempotent, like :func:`prepare_clone`: a tree another run published
between the caller's cache check and this call is reused rather than
re-extracted.  A fresh extraction lands in a temporary sibling and is
renamed into place once its completion marker is written, so the cache
path never holds a partial tree.
rl   T)parentsexist_ok.z.tmp)dirprefixsuffixunpackedz archive could not be extracted: N
c              3  4   "   T F  w  rV R V 2x  K  	  R# 5ir   r   )r   r   r   s   &  r   r   #_extract_archive.<locals>.<genexpr>  s!      IQ0E	9+Qzl+s   r   r   )ignore_errorsz1extracted archive could not be moved into place: )r   r=   r   r   mkdirr   tempfilemkdtempr   r    replace	_TREE_DIRr   FileNotFoundErrorrmdirjoinr   
write_texttouchrenameOSErrorshutilrmtreer   )r   r   r   r   r=   r   markertmpr   rx   rL   r$   r   s   &&&&         r   r   r     s   * 1F&&F>>t48##	HA,vVW&	3Z'HNN:,T< LLy)+,,  - YY IQ F >!--fw-G##**,>

6" MM#T26""E  :8>+C0c9: -,  
> ~~''MM&=!'**

6* +***~~''McUSC/4#= (
> MM#T2s   +I E" 3I FAI .F "F -E;;F  I F	I I!AH=&H8	H=HH=*H=8I =II Ic                    V ^8  d   QhRRRR/# )r   r   r   r   r   )r   s   "r   r   r     s     * *D *T *r   c                8    V \         ,          P                  4       # )z?Return the source root inside the extracted tree at ``target``.)r   rt   )r   s   &r   r   r     s     Y''))r   )/__doc__
__future__r   r   r   
contextlibr   pathlibr   typingr   nab_index.archiver   nab_index.clientr   r   r	   nab_index.vcsr
   r   _vendor.packaging.utilsr   _vendor.packaging.versionr   r5   r   r   r   r   r   r   r   r   r   r%   r6   r3   r4   rh   ry   r   r   r   r   r   r   r   r   r   r   <module>r      s    #       , P P 3 73(JJ 	" .T292x$'N'T)TX F!H"NJ8T8F#R*r   