+
    2jQ                      a  0 t $ R t^ RIHt ^ RIt^ RIHtHtHt ^ RI	H
t
Ht ^RIHtHtHtHtHtHt ^RIHt ^RIHt ^RIHtHtHtHt ^R	IHtHt ^R
IH t H!t!H"t"H#t#H$t$ ^RI%H&t& ^RI'H(t( ^RI)H*t* ]
'       d)   ^ RI+H,t,H-t- ^ RI.H.t. ^ RI/H0t0 ^RI1H2t2 ^RI3H4t4H5t5 ^RI6H7t7 . RNRNRNRNRNRNRNRNRNRNRNRNR NR!NR"NR#NR$NR%NR&NR'NR(NR)NR*NR+NR,NR-NR.NR/NR0NR1NR2NR3NR4NR5NR6Nt8]Pr                  ! ]:4      t;R7t<RNt=R8]>R&   R9 R: lt?]! R;R;R<7       ! R= R)4      4       t@]! R;R;R<7       ! R> R&4      4       tA]! R;R;R<7       ! R? R4      4       tB]! R;R;R<7       ! R@ R4      4       tC]! R;R;R<7       ! RA R(4      4       tD]! R;R;R<7       ! RB R4      4       tE]B]C,          ]D,          ]E,          tF]! R;R;R<7       ! RC R$4      4       tGRD RE ltH]! R;R;R<7       ! RF R'4      4       tI] ! RG R4      4       tJRH RI ltKRJ RK ltLRL RM ltMR# )Oa  PEP 751 lockfile (``pylock.toml``) emission for nab-python.

Public surface for producing lockfiles from a resolve. The three
emitters are :func:`write_lock` (PEP 751 ``pylock.toml``),
:func:`write_requirements_with_hashes`, and
:func:`write_requirements_without_hashes`. A resolve contributes one
:class:`TargetLock` per environment it ran against; the writer
collapses them into one ``Package`` per distinct ``(name, version,
source)`` with a marker disjoining the targets that chose it, and drops
the marker when every target agrees.
)annotationsN)	dataclassfieldreplace)TYPE_CHECKINGAny)MissingHashErrorMissingSdistErrorMissingVcsCommitErrorbuild_target_lockread_lockfile_anchorread_lockfile_packages)DisjointnessError)BASE_MEMBER)DivergentBaseDependencyErrorbuild_pylockrender_lock
write_lock)write_requirements_with_hashes!write_requirements_without_hashes)InvalidLockfileErrorLockDisqualificationLockfileSyntaxErrorRootRequirementcheck_locked)is_valid_pylock_pathcanonicalize_name)Version)MappingSequence)datetime)Path)Marker)ConflictSetPackageOverride)ResolveTargetACCEPTED_HASH_ALGORITHMSr   LOCK_VERSION
ArchivePinr   r   IndexPinr   LocalPinr   	LockInputr   r   r	   r
   PinShape
Provenancer   SdistArtifact
TargetLockVcsPinWheelArtifactr   r   r   drop_workspace_pinsr   !package_metadata_override_recordsr   r   r   summarize_lockr   r   r   z1.0tuple[str, ...]c                    V ^8  d   QhRRRR/# )   hashestuple[tuple[str, str], ...]returnztuple[str, str] | None )formats   "^/home/user/billing-ledger-validation/.venv/lib/python3.14/site-packages/nab_python/lockfile.py__annotate__r?   l   s      '    c                Z    \        V 4      p\         F  pW!9   g   K  W!V,          3u # 	  R # N)dictr'   )r9   by_algoalgos   &  r>   _select_primary_digestrF   l   s.     6lG(?&& ) r@   T)frozenslotsc                  z    ] tR t^vt$ RtR]R&   R]R&   R]R&   RtR]R	&   RtR
]R&   RtR]R&   ]	R R l4       t
RtR# )r2   a  A single wheel file to record in the lockfile.

``hashes`` is the set of (algorithm, digest) pairs the index
published.  PEP 751 mandates at least one hash per artefact;
nab requires at least one of ``sha256``, ``sha384``, ``sha512``
so the lockfile is consumable by pip's hash-checking mode.

``upload_time`` is the index's upload timestamp when available;
informational provenance per PEP 751 ``packages.wheels.upload-time``.

``local_path`` is the on-disk path of a wheel from a local
find-links directory; the lockfile writer emits it as a relative
``path`` instead of ``url`` so the lockfile is portable.  ``None``
for a wheel fetched from a remote index.
strfilenameurlr:   r9   N
int | Nonesizedatetime | Noneupload_timePath | None
local_pathc                   V ^8  d   QhRR/# r8   r;   ztuple[str, str]r<   )r=   s   "r>   r?   WheelArtifact.__annotate__          r@   c                l    \        V P                  4      pVf   V P                   R2p\        V4      hV# EReturn ``(algo, digest)`` for the first acceptable algorithm present.z has no acceptable hashrF   r9   rK   
ValueErrorselfchosenmsgs   &  r>   primary_digestWheelArtifact.primary_digest   7     (4>]]O#:;CS/!r@   r<   __name__
__module____qualname____firstlineno____doc____annotations__rN   rP   rR   propertyr`   __static_attributes__r<   r@   r>   r2   r2   v   sI      M	H''D*#'K'"J" r@   c                  z    ] tR t^t$ RtR]R&   R]R&   R]R&   RtR]R	&   RtR
]R&   RtR]R&   ]	R R l4       t
RtR# )r/   zAn sdist tarball to record in the lockfile.

See :class:`WheelArtifact` for the meaning of ``hashes``,
``upload_time`` and ``local_path``.
rJ   rK   rL   r:   r9   NrM   rN   rO   rP   rQ   rR   c                   V ^8  d   QhRR/# rT   r<   )r=   s   "r>   r?   SdistArtifact.__annotate__   rV   r@   c                l    \        V P                  4      pVf   V P                   R2p\        V4      hV# rX   rZ   r\   s   &  r>   r`   SdistArtifact.primary_digest   rb   r@   r<   rc   r<   r@   r>   r/   r/      sI     M	H''D*#'K'"J" r@   c                  d    ] tR t^t$ RtR]R&   R]R&   R]R&   RtR]R&   RtR	]R
&   RtR]R&   Rt	R# )r*   zA package resolved from a Simple-API index.

``index`` is the URL of the Simple-API root that served the
package, matching what PEP 751 expects for ``packages.index``.
rJ   nameversionindexNzSdistArtifact | Nonesdistztuple[WheelArtifact, ...]wheels
str | Nonerequires_pythonr<   )
rd   re   rf   rg   rh   ri   ru   rv   rx   rk   r<   r@   r>   r*   r*      s8     ILJ"&E&(*F%*"&OZ&r@   c                  V    ] tR t^t$ RtR]R&   R]R&   R]R&   RtR]R&   R	tR
]R&   RtR	# )r+   aW  A package resolved from a local checkout.

``path`` is the absolute filesystem path the resolver was pointed
at.  Lockfile consumers walk the same tree to install.

``editable`` records a PEP 660 editable install request;
``subdirectory`` is a path under ``path`` for monorepo layouts.
Both come from the ``[[tool.nab.local-sources]]`` entry.
rJ   rr   rs   pathFbooleditableNrw   subdirectoryr<   )	rd   re   rf   rg   rh   ri   r|   r}   rk   r<   r@   r>   r+   r+      s,     IL
IHd#L*#r@   c                  x    ] tR t^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# )r1   a+  A package resolved from a VCS clone.

``repo_url`` is the reproducible pip-style installable URL: the
``git+`` prefix, the bare repository URL, ``@<commit-id>``, and any
``#subdirectory=`` fragment.  The requirements.txt emitter writes it
verbatim, so a branch or tag pin installs the locked commit rather
than a moving ref.  ``bare_repo_url`` is the plain repository URL
with none of those parts, captured when the source URL is parsed and
written to PEP 751 ``packages.vcs.url``.

``requested_revision`` is the human-readable ref (tag or branch)
the user pinned, recorded only when it differs from ``commit_id``;
informational per PEP 751 ``packages.vcs.requested-revision``.

``vcs_type`` is the PEP 751 ``packages.vcs.type`` backend
(``git``/``hg``/``svn``/``bzr``), taken from the URL's ``<vcs>+``
scheme.
rJ   rr   rs   repo_urlbare_repo_url	commit_idNrw   r}   requested_revisiongitvcs_typer<   )
rd   re   rf   rg   rh   ri   r}   r   r   rk   r<   r@   r>   r1   r1      sB    & ILMN#L*#%)
)Hcr@   c                  h    ] tR t^t$ RtR]R&   R]R&   R]R&   R]R&   RtR	]R
&   ]R R l4       tRt	R# )r)   a  A package resolved from a direct-URL archive.

``url`` is the archive URL with the hash fragment stripped, written
to PEP 751 ``packages.archive.url``.  ``hashes`` are the verified
``(algorithm, digest)`` pairs; PEP 751 requires at least one, and
nab verifies the download against them before the archive is used.

Unlike a VCS or directory source, an archive is content-pinned by
its hash, so the pin carries a real ``version`` and the emitter
records it (see :func:`_pin_to_package`).
rJ   rr   rs   rL   r:   r9   Nrw   r}   c                   V ^8  d   QhRR/# rT   r<   )r=   s   "r>   r?   ArchivePin.__annotate__	  rV   r@   c                l    \        V P                  4      pVf   V P                   R2p\        V4      hV# )rY   z archive has no acceptable hash)rF   r9   rr   r[   r\   s   &  r>   r`   ArchivePin.primary_digest  s7     (4>YYK>?CS/!r@   r<   )
rd   re   rf   rg   rh   ri   r}   rj   r`   rk   r<   r@   r>   r)   r)      s:    
 IL	H''#L*# r@   c                      ] 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&   R R lt
RtR# )r.   i  a  Optional ``[tool.nab]`` provenance block written into the lock.

PEP 751 lets tools record any additional metadata under
``[tool.<name>]`` so long as it does not affect installation.
nab uses the slot to record the inputs that produced the lock:
a reader can audit a committed lockfile without re-running.

Every field is informational.  The lockfile reader MUST NOT
feed any of it into the install path.
rJ   nab_versionr!   
created_atr6   command_line
input_pathmodeNrw   python_specifier	platformsr:   cli_project_overrides'tuple[tuple[str, tuple[str, ...]], ...]package_metadata_overridesc                   V ^8  d   QhRR/# )r8   r;   zdict[str, Any]r<   )r=   s   "r>   r?   Provenance.__annotate__1  s      . r@   c           
     @   RV P                   RV P                  R\        V P                  4      RV P                  RV P
                  /pV P                  e   V P                  VR&   V P                  '       d   \        V P                  4      VR&   V P                  '       d)   V P                   UUu. uF  w  r#V RV 2NK  	  uppVR	&   V P                  '       d8   V P                   UUu. uF  w  rEV R
RP                  V4       2NK  	  uppVR&   V# u uppi u uppi )z>Render to the dict the TOML writer drops under ``[tool.nab]``.znab-versionz
created-atzcommand-linez
input-pathr   zpython-specifierr   =zcli-project-overrides: , zpackage-metadata-overrides)r   r   listr   r   r   r   r   r   r   join)r]   blockflagvaluerequirementfieldss   &     r>   to_blockProvenance.to_block1  s    4++$//D!2!23$//DII!
   ,(,(=(=E$%>>>!%dnn!5E+%%%595O5O.5Okd4&%!5O.E)* *** ,0+J+J3+J'K -r$))F"3!45+J3E./ .3s   0D*!Dr<   )rd   re   rf   rg   rh   ri   r   r   r   r   r   rk   r<   r@   r>   r.   r.     sb    	 !!O
I#'j'!#I# :<6; KM GL r@   c                    V ^8  d   QhRRRR/# )r8   	overrideszSequence[PackageOverride]r;   r   r<   )r=   s   "r>   r?   r?   J  s      (,r@   c                ^   . pV  F  p. pVP                   e   VP                  R4       VP                  e   VP                  R4       VP                  e   VP                  R4       V'       g   Kl  VP                  \	        VP
                  4      \        V4      34       K  	  \        V4      # )a  Summarise the configured per-package metadata overrides for provenance.

Each returned pair is a requirement string and the metadata fields the
entry set (``dependencies``, ``requires-python``, ``provides-extra``).
Entries that set no metadata field are skipped.  This records every
configured override as input provenance, including any scoped to a
version no candidate has (a documented no-op), so an entry here is not a
claim that it shaped the lock.  Strictly informational: the reader must
not feed it into the install path.
dependencieszrequires-pythonzprovides-extra)r   appendrx   provides_extrarJ   r   tuple)r   recordsoverrider   s   &   r>   r4   r4   J  s     24G  ,MM.)##/MM+,"".MM*+6NNC 4 45uV}EF  >r@   c                      ] tR tRt$ RtR]R&   R]R&   ]! ]R7      tR]R	&   ]! ]R7      t	R]R
&   ]! ]R7      t
R]R&   RtR# )r0   if  a_  What one target contributed to the lock.

``pins`` is keyed by canonical package name; each value is the pin
that target resolved to.  ``dependencies`` is the forward edge set
among those pins, keyed the same way, which the writer emits as
PEP 751 ``packages.dependencies``.  ``base_dependencies`` is its
unconditional subset: the edges from each package's own metadata,
before any activated extra folds its deps in.  The writer closes a
conflict environment's no-member base-name set over these edges only.

``target`` is the environment the pins hold for.  The writer reads
its markers and its
:attr:`~nab_python.target.ResolveTarget.selection` rather than being
handed a projection of them, so a lock entry and the environment it
was resolved for cannot drift apart.

``package_gates`` maps a package this target locked to every install
context that reaches it, as ``(kind, name)`` members: each selected
extra and group, including the conflict fork's own selection, and
:data:`BASE_MEMBER` for the project's own dependencies, which the
writer renames to ``[tool.nab].base-group``.  The writer disjoins
them into ``'name' in extras`` / ``'name' in dependency_groups``
clauses on that package's marker.  With no ``base-group`` set there
is no name to give the project's own dependencies, so the writer
drops the gate of every package they reach and it stays
unconditional.
r&   targetzMapping[str, PinShape]pinsdefault_factoryzMapping[str, tuple[str, ...]]r   base_dependenciesz)Mapping[str, tuple[tuple[str, str], ...]]package_gatesr<   N)rd   re   rf   rg   rh   ri   r   rC   r   r   r   rk   r<   r@   r>   r0   r0   f  sL    8 
  272ML/M7<T7R4R?D@M< r@   c                      ] tR tRt$ Rt]! ]R7      tR]R&   ]! ]R7      t	R]R&   ]! ]
R7      tR]R	&   R
tR]R&   RtR]R&   RtR]R&   RtR]R&   RtR]R&   R
tR]R&   RtR]R&    R
tR]R&    R
tR]R&    ]R R l4       t]R R l4       tRtR
# )r,   i  aG  Everything the writer needs to produce a Pylock.

``targets`` maps a target's label to what that target contributed.
A resolve always runs against at least one target, so there is
always at least one entry; a declared matrix (and each conflict
fork of it) adds more.  The writer collapses them into one
``[[packages]]`` entry per distinct ``(name, version, source)``,
with a marker disjoining the targets that chose it, and omits the
marker when the entry covers every target.

``env_base_names`` maps an environment signature
(``tuple(sorted(env.items()))``) to the canonical names that the
base (no-member) resolve produced for that environment.  A package
present in every conflict fork only counts as a base dependency
(and so drops its membership clause) when its name is listed here;
a dependency required by every member but not by the base keeps the
membership clause, so it does not install when no member is
selected.

The missing-key vs empty-frozenset distinction is load-bearing:
a missing signature means no base pass ran for that env (with no
forks: the no-conflict path; with forks: base status unknowable,
so the membership OR is kept).  An empty frozenset means the base
pass ran and produced zero pins, so every dep is member-only.
Empty when no conflict fork ran.

``environments`` is the lockfile-level set of permitted
environments (PEP 751 ``environments``): what each target declared
of the environment it resolved for.

``provenance`` is optional metadata about the inputs that
produced this lock.  When present, it lands in the ``[tool.nab]``
block of the emitted ``pylock.toml``.
r   zMapping[str, TargetLock]targetsz4Mapping[tuple[tuple[str, str], ...], frozenset[str]]env_base_nameszlist[Marker]environmentsNrw   rx   nabrJ   
created_byr6   extrasdependency_groupsdefault_groupszProvenance | None
provenanceztuple[ConflictSet, ...]	conflicts
base_groupbuild_groupc                   V ^8  d   QhRR/# )r8   r;   r6   r<   )r=   s   "r>   r?   LockInput.__annotate__  s       r@   c                    \         P                  . V P                  OV P                  O54      pV P                  V P
                  3 F  pVf   K	  RW&   K  	  \        V4      # )a@  Every group an install context can activate.

PEP 751 keeps the ``default-groups`` names out of
``dependency-groups``, and an installer that selects nothing
still activates the defaults, so the group axis of an install
context is the union of the two arrays, plus the name the lock
gives the project's own dependencies.
N)rC   fromkeysr   r   r   r   r   )r]   namesnameds   &  r>   active_groupsLockInput.active_groups  s[     M 6 6M9L9LMNoot'7'78E # 9 U|r@   c                   V ^8  d   QhRR/# )r8   r;   zdict[str, Mapping[str, str]]r<   )r=   s   "r>   r?   r     s     W W9 Wr@   c                    V P                   P                  4        UUu/ uF  w  rWP                  P                  bK  	  upp# u uppi )z:The PEP 508 marker environment each target resolved under.)r   itemsr   
marker_env)r]   labellocks   &  r>   marker_envsLockInput.marker_envs  s<     BFASASAUVAU+%{{---AUVVVs   !Ar<   )rd   re   rf   rg   rh   r   rC   r   ri   r   r   r   rx   r   r   r   r   r   r   r   r   rj   r   r   rk   r<   r@   r>   r,   r,     s    !F ).d(CG%CKPLNH  "'t!<L,<"&OZ&J FO )++&(NO($(J!()+I&+6 "J
!P"K"O   W Wr@   c               $    V ^8  d   QhRRRRRR/# )r8   
lock_inputr,   excludezfrozenset[str]r;   r<   )r=   s   "r>   r?   r?     s!      0  0I  0  09  0r@   c                  aa
 S'       g   V # R V3R llo
V P                   P                  4        UUUUUUu/ uEF  w  r#T\        TVP                  P                  4        UUu/ uF  w  rES
! V4      '       g   K  WEbK  	  uppVP                  P                  4        UUu/ uFS  w  rFS
! V4      '       g   K  \
        ;QJ d    . V
3R lV 4       F  NK  	  5M! V
3R lV 4       4      ;p'       g   KQ  WHbKU  	  uppVP                  P                  4        UUu/ uF  w  rGS
! V4      '       g   K  WGbK  	  uppR7      bEK	  	  p	pppppp\        W	R7      # u uppi u uppi u uppi u uppppppi )a/  Return a copy of ``lock_input`` with the ``exclude`` pins removed.

``exclude`` holds canonical workspace member names; pin keys are already
canonical.  An empty set returns ``lock_input`` unchanged.  Each target's
pins are filtered, and its forward dependency graph and membership gates
with them, so no emitted edge or gate names a dropped member with no
``[[packages]]`` entry.  ``base_dependencies`` carries through untouched:
it is never emitted, and cutting the member out of it would strip base
status from everything reached only through that member.
c                    V ^8  d   QhRRRR/# )r8   rr   rJ   r;   r{   r<   )r=   s   "r>   r?   )drop_workspace_pins.<locals>.__annotate__  s     6 63 64 6r@   c                    < \        V 4      S9  # rB   r   )rr   r   s   &r>   keep!drop_workspace_pins.<locals>.keep  s     &g55r@   c              3  H   <"   T F  pS! V4      '       g   K  Vx  K  	  R # 5irB   r<   ).0depr   s   & r>   	<genexpr>&drop_workspace_pins.<locals>.<genexpr>  s     0RS	s   "
")r   r   r   )r   )r   r   r   r   r   r   r   )r   r   r   r   rr   pindepsgatekeptr   r   s   &f        @r>   r3   r3     sH    6 6  &--335  6KE 	w-1YY__->M->	$t*)$)->M #'"3"3"9"9";";JD: +050R0R550R0R+R#R4#R 
"; .2-?-?-E-E-G-Gzt4PT:

-G
 	
 6   :// N
sM   ,E)#E:E  E) E 7
E ,E 3E 9 E)E#"0E#"6E)E)c               $    V ^8  d   QhRRRRRR/# )r8   r   r,   priorMapping[str, Version] | Noner;   rJ   r<   )r=   s   "r>   r?   r?     s(     D Dy D1M DRU Dr@   c           	        \        V P                  4      ^8  d   \        V P                  4       R2# V P                  P                  4        UUUu/ uF(  pVP                  P	                  4        F  w  r4W4bK	  	  K*  	  ppppVP	                  4        UUu/ uF9  w  r4\        V\        \        34      '       g   K#  V\        VP                  4      bK;  	  ppp\        V4       R\        W4       2# u upppi u uppi )a!  Summarise what was written: a package diff, or the tuple count.

A matrix pins a package once per tuple, and two tuples may disagree, so
there is no one version to diff against the prior lock; it reports the
tuples it covered instead.  ``prior`` comes from
:func:`read_lockfile_packages`.
z tuplesz	 packages)lenr   valuesr   r   
isinstancer*   r)   r   rs   _diff_summary)r   r   r   rr   r   r   	versioneds   &&     r>   r5   r5     s     :"j(()*'22 &&--//D*ID 		* 	/ 	  %IDcHj12 	#gckk""%  
 $i[	-"A!BCCs   .C1 C8;C8c               $    V ^8  d   QhRRRRRR/# )r8   r   r   currentzMapping[str, Version]r;   rJ   r<   )r=   s   "r>   r?   r?     s$      4  4' 42G 4 4r@   c                  a a S f   R# \        V 3R lS 4       4      p\        V3R lS  4       4      p^ ;rESP                  4        F<  w  rgS P                  V4      pVe   W8X  d   K"  Wx8  d   V^,          pK3  V^,          pK>  	  VR3VR3VR3VR33 U	U
u. uF  w  rV	'       g   K  V	 RV
 2NK  	  pp	p
V'       d   R	R
P                  V4       2# R# u up
p	i )zReturn a ``: A added, B upgraded, ...`` suffix for a re-lock.

``prior`` is the previous pylock's pins or ``None`` (first lock or an
unparseable prior file); both fall back to an empty suffix.  An unchanged
pin set also yields an empty suffix.
 c              3  ,   <"   T F	  qS9  x  K  	  R # 5irB   r<   )r   rr   r   s   & r>   r    _diff_summary.<locals>.<genexpr>(  s     6gdE!g   c              3  ,   <"   T F	  qS9  x  K  	  R # 5irB   r<   )r   rr   r   s   & r>   r   r   )  s     8%$g%%r   addedupgraded
downgradedremoved r   r   )sumr   getr   )r   r   r   r   r   r   rr   rs   oldcountr   partss   ff          r>   r   r     s     }6g66E8%88GH iio;#.=MH!OJ ) Gz"&i 	
	
LE  	5'5'
 
 	 ',R		% !"33	s   C(C)sha256sha384sha512)N__conditional_annotations__rh   
__future__r   loggingdataclassesr   r   r   typingr   r   _lockfile.builderr   r	   r
   r   r   r   _lockfile.disjointnessr   _lockfile.groupsr   _lockfile.pylockr   r   r   r   _lockfile.requirementsr   r   _lockfile.validater   r   r   r   r   _vendor.packaging.pylockr   _vendor.packaging.utilsr   _vendor.packaging.versionr   collections.abcr   r    r!   pathlibr"   _vendor.packaging.markersr#   configr$   r%   r   r&   __all__	getLoggerrd   loggerr(   r'   ri   rF   r2   r/   r*   r+   r1   r)   r-   r.   r4   r0   r,   r3   r5   r   )r  s   @r>   <module>r     sJ  
 #  1 1 %  6 )   ; 6 .1!14%$$$ $ 	$
 $ #$ $ $ $ $ $ $ $ $ $  !$" #$$ %$& '$( )$* +$, -$. /$0 1$2 3$4 5$6 7$8 (9$: ;$< =$> ?$@ A$B C$D %E$F (G$N 
		8	$ -K / J $d#  $D $d#  $0 $d#' ' $' $d#$ $ $$$ $d#  $< $d#  $: h'*4 $d#1 1 $1h8 $d## # $#L MW MW MW` 0FD8 4r@   