
    .Ph4                        d Z ddlZddlZddlmZ ddlmZmZmZm	Z	m
Z
mZ ddlmZmZmZmZmZmZ ddlmZ ddlmZ 	 	 dd	ed
ee         dededeeef         f
dZde
eef         defdZdedefdZde
eef         defdZd	eded
ee         defdZd
ededefdZd	ed
ee         dede	e         fdZd
edefdZ d
edefdZ!d
edefdZ"dedefdZ#dS )aW  Compute the content hash of a lock specification.

The content hash is used with `conda-lock --check-content-hash` to avoid unnecessary
relocking when the lock specification is unchanged.

Note that the content hash depends not only on the LockSpecification object but
also the virtual package specification.

WARNING: The fundamental concept of a content hash is seriously flawed:
<https://github.com/conda/conda-lock/issues/432#issuecomment-1637071282>

It is important to maintain the content hash for backwards compatibility,
but we should stop using it in the future.

Note that anything that modifies the content hash is a breaking change,
since it will invalidate all existing lockspecs.

The content hash is computed by JSON-serializing the lock specification and
the virtual package specification, and then hashing the serialized
representation.
    Ndeepcopy)DictOptionalSequenceSetUnioncast)	EmptyDict$HashableVirtualPackageRepresentationPlatformSubdirStrSerializedDependencySerializedLockspecSubdirMetadata)LockSpecification)FakeRepoDataT	lock_specvirtual_package_reporeinsert_spurious_build_numberremove_new_nullsreturnc                     i }|r|t          |          }| j        D ]6}t          | ||          }|rt          |          }t	          |          ||<   7|S )a  Compute the content hashes for the given lock specification.

    Args:
        lock_spec: The lock specification to compute the content hashes for.

        virtual_package_repo: The virtual package repository to use.
            If None, the content hash is computed without the VPR.

        reinsert_spurious_build_number: Whether to reinsert the spurious build
            number in the build string of the VPR. This prevents the content hash
            from changing when upgrading from v2 to v3.0.3.

        remove_new_nulls: Whether to remove newly added fields from the package
            specs when they are null. This prevents the content hash from changing
            when upgrading from v2 to v3.0.3.

    Returns:
        A dictionary of platform-specific content hashes.
    )_reinsert_spurious_build_number	platforms_content_for_platform_remove_new_nulls_dict_to_hash)r   r   r   r   resultplatformcontents          W/var/www/html/test/jupyter/venv/lib/python3.11/site-packages/conda_lock/content_hash.pycompute_content_hashesr"   )   s|    2 ,.F & U*>*J>?STT' 2 2'	8=QRR 	1'00G(11xM    dc                 .    t          j        | d          S )z:Produce a canonical JSON representation of the given dict.T)	sort_keys)jsondumpsr$   s    r!   _dict_to_jsonr*   Q   s     :a4((((r#   sc                 t    t          j        |                     d                                                    S )zHash the given JSON string.zutf-8)hashlibsha256encode	hexdigest)r+   s    r!   _json_to_hashr1   X   s*    >!((7++,,66888r#   c                 :    t          t          |                     S )zHash the given dict.)r1   r*   r)   s    r!   r   r   ]   s     q))***r#   r   c                     d | j         D             d t          | j        |         d           D             d}| j        rd | j        D             |d<   |t	          ||          |d<   |S )	Nc                 6    g | ]}|                                 S  model_dump_json).0cs     r!   
<listcomp>z)_content_for_platform.<locals>.<listcomp>j   s$    EEEQQ&&((EEEr#   c                 \    g | ])}t          t          |                                          *S r5   )r
   r   
model_dump)r8   ps     r!   r:   z)_content_for_platform.<locals>.<listcomp>k   s;     
 
 
 %q||~~66
 
 
r#   c                     | j         | j        fS )N)managername)r=   s    r!   <lambda>z'_content_for_platform.<locals>.<lambda>n   s    AF@S r#   )key)channelsspecsc                 6    g | ]}|                                 S r5   r6   )r8   repos     r!   r:   z)_content_for_platform.<locals>.<listcomp>s   s1     3
 3
 3
'+D  ""3
 3
 3
r#   pip_repositoriesvirtual_package_hash)rC   sorteddependenciesrG   %_virtual_package_content_for_platform)r   r   r   serialized_lockspecs       r!   r   r   d   s     FE)2DEEE
 
&x06S6S  
 
 
/ / ! 
3
 3
/8/I3
 3
 3
./ '12FQQ 	23 r#   c                     | j         }ddii d}d|ii d}i }i }d|                    d|          ||                    ||          i}|S )zSerialize the virtual package content into a dict for hashing.

    This is used in the computation of the content hash, and goes
    into the "virtual_package_hash" field of the serialized lockspec.
    subdirnoarch)infopackages)all_repodataget)r   r   vpr_datafallback_noarchfallback_platformr   s         r!   rK   rK   }   s     $0H 8$9 9O
 8$; ; O 	(,,x99(,,x):;;4F Mr#   c           	      \   g }||g}|                                 D ]9}|dk    r1t          |          r"|                    t          |                     :|                                 D ]$}|                    t	          |                     %|t          |          dk    sJ dg}nt          |          dk    sJ |}t                      }|D ]Z}|                    t          | |dd          |                    |                    t          | |dd          |                    [|S )a  Compute a set of content hashes for equivalent lock specifications.

    Computing multiple content hashes allows us to support previous versions of
    the content hash computation for backwards compatibility.

    We could have adopted a more targeted strategy for producing specific variants
    of the VPR, but the VPR can also be customized, so it's hard to know exactly
    how it's constructed. Therefore we just enumerate all possible variants to be safe.

    Note that VPR=None is only used for old tests, and it corresponds to the case where
    VPR is unspecified rather than default. (TODO: replace those tests and eliminate
    this special case?)
    Nosx-64r   F)r   r   r   r   T)	copy_contains_osx_11_0_0_tar_bz2append!add_or_remove_osx_10_15_0_tar_bz2r   lensetaddr"   )r   r   r   virtual_package_repo_variantsvprvprsallowed_hashesvpr_or_nones           r!   #backwards_compatible_content_hashesre      s   $ 9;!' *>(>% -1133 Y Yx$@$E$E)001RSV1W1WXXX -1133 S S%,,-LS-Q-QRRRR #011Q6666v011A5555,  #uuN 
 

 	"#%0/4!&	  
 	
 	
 	
 	"#%0/4!%	  
 	
 	
 	
 	
 r#   c                     |                      d          }t          t          |j        d                   }|d         }d|v r|d= ndddd	dg d
dddd
|d<   |S )aC  Add or remove the __osx 10.15 virtual package.

    Adds __osx 10.15 if it is not present, and removes it if it is present.
    This way, whichever convention we start with, the opposite convention will be
    produced.

    Rationale:
    In 6f69901 we started generating the default repodata based on
    default-virtual-packages.yaml instead of programmatically. But there was a bug
    in which we added both __osx 10.15 and 11.0. The extra 10.15 is ignored by conda
    and mamba, and 11.0 takes precedence. We added an option to readd the 10.15 package
    in 777dfbf.
    TdeeprX   rQ   z__osx-10.15-0.tar.bz2__osxz10.15 r      >virtual_system0
r@   versionbuild_stringbuild_numberrO   depends	timestamppackage_typebuildrN   )
model_copyr
   r   rR   )r   r   rdrQ   s       r!   r\   r\      s      ",,$,77F nf.A(.KLLB*~H(**,-- &,-
 -
() Mr#   c                     | j                             di           }d|vrdS t          t          |          }|d                             d          dddddg d	d
ddd
k    S )NrX   rQ   Fz__osx-11.0-0.tar.bz2ri   z11.0rj   r   rk   rl   rm   rn   )rR   rS   r
   r   )r   rw   s     r!   rZ   rZ     s    		*	.	.x	<	<Bu	nb	!	!Bj>455"(: :  r#   c           
         |                      d          }|j        D ]}|j        |         }d|v rt          t          |          }|d                                                                         D ]d\  }}|d         }|d         }|d         }|d         }	t          |          dk    r,| d	|	 |d
<   | d| d| d	|	 d}
||d         |
<   |d         |= e|S )a  Reinsert the spurious build number in the build string.

    This was introduced in v3.0.3 to reproduce the content hash of the v2 lockfiles.
    <https://github.com/conda/conda-lock/pull/776>

    Without the spurious build number:

    ```json
    "__archspec-1-x86_64.tar.bz2": {
        "build": "x86_64",
        "build_number": 0,
        "build_string": "x86_64",
        "depends": [],
        "name": "__archspec",
        "noarch": "",
        "package_type": "virtual_system",
        "subdir": "linux-64",
        "timestamp": 1577854800000,
        "version": "1"
    }
    ```

    With the spurious build number:
    ```json
    "__archspec-1-x86_64_0.tar.bz2": {
        "build": "x86_64_0",
        "build_number": 0,
        "build_string": "x86_64",
        "depends": [],
        "name": "__archspec",
        "noarch": "",
        "package_type": "virtual_system",
        "subdir": "linux-64",
        "timestamp": 1577854800000,
        "version": "1"
    }
    ```
    Trg   rQ   r@   ro   rp   rq   r   _ru   -z.tar.bz2)rv   rR   r
   r   rY   itemsr]   )r   r   r   rw   package_namepackage_datar@   ro   rp   rq   new_names              r!   r   r   #  s   N ",,$,77F' 5 5 *nb))B.0n.A.A.C.C.I.I.K.K 	5 	5*l#F+&y1+N;+N;|$$q((/;,L,Ll,L,LL)"&XXXX<XX,XXXH/;BzN8,:|4Mr#   r    c                 v    t          |           }|d         D ] }d|v r|d         |d= d|v r|d         |d= !|S )zRemove newly added fields from the VPR when they are null.

    New fields added in v3.0.0 that are usually None but were absent in v2
    would alter the content hash, so we remove them for backwards compatibility.
    rD   markersNsubdirectoryr   )r    r   specs      r!   r   r   \  sb     gFw % %i!8YT!!d>&:&B^$Mr#   )TT)$__doc__r-   r'   rY   r   typingr   r   r   r   r	   r
   conda_lock.content_hash_typesr   r   r   r   r   r   conda_lock.models.lock_specr   conda_lock.virtual_packager   boolstrr"   r*   r1   r   r   rK   re   r\   rZ   r   r   r5   r#   r!   <module>r      s   ,         = = = = = = = = = = = = = = = =                : 9 9 9 9 9 3 3 3 3 3 3 ,0!	% % %"<0% %)% 	%
 

S
 !% % % %P)!EEF)) ) ) )9S 9S 9 9 9 9
+!EEF++ + + +  #<0 	   2!&!! *! ! ! !HD D"<0D  D 	X	D D D DN%&%% % % %P|     &6, 6< 6 6 6 6r1 6H      r#   