
    !hii;                       d Z ddlmZ ddlZddlZddlZddlZddlmZm	Z	 ddl
mZ ddlmZ ddlmZ  ej"                  ej$                        Zedz  Zg Zej,                  D ]?  Z ej"                  e      Z	 ej1                  ej3                  ej$                               A ej7                  d	 d
        G d d      Zej:                  Zej>                  Z  G d de      ZdddZ!d Z"dddZ#dd dZ$ejJ                  r ejL                  dd      Z'n ejL                  d      Z'd!d"dZ(d#dZ)d Z* e*       Z+d Z, e,       Z-y# e$ r Y w xY w)$a  
Additional helper methods for working specifically with Anaconda distributions are found at
:mod:`PyInstaller.utils.hooks.conda_support<PyInstaller.utils.hooks.conda>`
which is designed to mimic (albeit loosely) the `importlib.metadata`_ package. These functions find and parse the
distribution metadata from json files located in the ``conda-meta`` directory.

.. versionadded:: 4.2.0

This module is available only if run inside a Conda environment. Usage of this module should therefore be wrapped in
a conditional clause::

    from PyInstaller.compat import is_pure_conda

    if is_pure_conda:
        from PyInstaller.utils.hooks import conda_support

        # Code goes here. e.g.
        binaries = conda_support.collect_dynamic_libs("numpy")
        ...

Packages are all referenced by the *distribution name* you use to install it, rather than the *package name* you import
it with. I.e., use ``distribution("pillow")`` instead of ``distribution("PIL")`` or use ``package_distribution("PIL")``.
    )annotationsN)IterableList)PackagePath)compat)loggerz
conda-metac                ,    t        | j                        S N)lenparts)ps    IC:\des-py\Monitor\venv\Lib\site-packages\PyInstaller/utils/hooks/conda.py<lambda>r   >   s    s177|     T)keyreversec                  N    e Zd ZdZd	dZd Zd Zd Zed
d       Z	ed
d       Z
y)Distributiona  
    A bucket class representation of a Conda distribution.

    This bucket exports the following attributes:

    :ivar name: The distribution's name.
    :ivar version: Its version.
    :ivar files: All filenames as :meth:`PackagePath`\ s included with this distribution.
    :ivar dependencies: Names of other distributions that this distribution depends on (with version constraints
                        removed).
    :ivar packages: Names of importable packages included in this distribution.

    This class is not intended to be constructed directly by users. Rather use :meth:`distribution` or
    :meth:`package_distribution` to provide one for you.
    c                H   	 t        j                  |      | _        | j                  j                         sJ 	 t        j                  | j                  j                               | _        | j                  d   | _        | j                  d   | _        | j                  d   D cg c]  }t        |       c}| _        | j!                         | _        | j%                         | _        y # t        t
        f$ r$ t	        dj                  t        |                  w xY wc c}w )Nz_Distribution requires a path to a conda-meta json. Perhaps you want `distribution({})` instead?nameversionfiles)pathlibPath
_json_pathexists	TypeErrorAssertionErrorformatreprjsonloads	read_textrawr   r   r   r   _init_dependenciesdependencies_init_package_namespackages)self	json_pathis      r   __init__zDistribution.__init__Q   s    	%ll95DO??))+++ DOO$=$=$?@ &)	 HHY/.2hhw.?@k!n@
 335002 >* 	..4fT)_.E 	 As   6C) $D)3Dc                v    dj                  t        |       j                  | j                  | j                        S )Nz{}(name="{}", packages={}))r   type__name__r   r(   r)   s    r   __repr__zDistribution.__repr__e   s,    -44T$Z5H5H$))UYUbUbccr   c                |    g }| j                   d   D ]'  }|j                  d      ^}}|j                  |       ) |S )z
        Read dependencies from ``self.raw["depends"]``.

        :return: Dependent distribution names.
        :rtype: list

        The names in ``self.raw["depends"]`` come with extra version constraint information which must be stripped.
        depends   )maxsplit)r$   splitappend)r)   r&   
dependencyr   version_constraintss        r   r%   zDistribution._init_dependenciesh   sP     ((9- 	&J)3)9)91)9)E&D&%	& r   c                j    g }| j                   D ]!  }t        |      }||j                  |       # |S )z
        Search ``self.files`` for package names shipped by this distribution.

        :return: Package names.
        :rtype: list

        These are names you would ``import`` rather than names you would install.
        )r   _get_package_namer7   )r)   r(   filepackages       r   r'   z Distribution._init_package_namesy   s?     JJ 	)D'-G"(	) r   c                X    |t         v r	t         |   S t        dj                  |            )z
        Get distribution information for a given distribution **name** (i.e., something you would ``conda install``).

        :rtype: :class:`Distribution`
        zIDistribution {} is either not installed or was not installed using Conda.)distributionsModuleNotFoundErrorr   clsr   s     r   	from_namezDistribution.from_name   s3     =  &&!W^^_cd
 	
r   c                X    |t         v r	t         |   S t        dj                  |            )a  
        Get distribution information for a **package** (i.e., something you would import).

        :rtype: :class:`Distribution`

        For example, the package ``pkg_resources`` belongs to the distribution ``setuptools``, which contains three
        packages.

        >>> package_distribution("pkg_resources")
        Distribution(name="setuptools",
                     packages=['easy_install', 'pkg_resources', 'setuptools'])
        zDPackage {} is either not installed or was not installed using Conda.)distributions_by_packager@   r   rA   s     r   from_package_namezDistribution.from_package_name   s0     +++D11!"h"o"opt"uvvr   N)r*   str)r   rG   )r/   
__module____qualname____doc__r,   r1   r%   r'   classmethodrC   rF    r   r   r   r   A   sF    3(d"  

 

 w wr   r   c                      e Zd ZdZd Zy)r   z
    A filename relative to Conda's root (``sys.prefix``).

    This class inherits from :class:`pathlib.PurePosixPath` even on non-Posix OSs. To convert to a :class:`pathlib.Path`
    pointing to the real file, use the :meth:`locate` method.
    c                N    t        j                  t        j                        | z  S )z_
        Return a path-like object for this path pointing to the file's true location.
        )r   r   sysprefixr0   s    r   locatezPackagePath.locate   s     ||CJJ'$..r   N)r/   rH   rI   rJ   rQ   rL   r   r   r   r      s    /r   r   c                   |t        |      }ddlm} i } || g      }|ry|j                         }	 t        j                  |      x||<   }t        j                  d||        |j                  D ]%  }||v r||k(  r|||v r|j                  |       ' |ry|S # t        $ r t        j                  d||        Y w xY w)a  
    Collect a :class:`Distribution` and all direct and indirect dependencies of that distribution.

    Arguments:
        initial:
            Distribution name to collect from.
        excludes:
            Distributions to exclude.
    Returns:
        A ``{name: distribution}`` mapping where ``distribution`` is the output of
        :func:`conda_support.distribution(name) <distribution>`.
    r   )dequez8Collected Conda distribution '%s', a dependency of '%s'.zConda distribution '%s', dependency of '%s', was not found. If you installed this distribution with pip then you may ignore this warning.)setcollectionsrS   popr   rC   r   debugr@   warningr&   r7   )initialexcludesrS   donenames_to_dor   distribution_names           r   walk_dependency_treer_      s     x= "D	"K
 		(4(>(>t(DDDJLLSUY[bc ".. 	&E}} #(9u%	& 4 K' # 	NN`aegn 	s   1B  B?>B?c                f    |rt        | |      j                         S t        j                  |       gS r
   )r_   valuesr   rC   )r   r&   rZ   s      r   _iter_distributionsrb      s/    #D(3::<<&&t,--r   c                `    |rt        |       j                  S t        |       j                  d   S )a  
    List requirements of a distribution.

    Arguments:
        name:
            The name of the distribution.
        strip_versions:
            List only their names, not their version constraints.
    Returns:
        A list of distribution names.
    r3   )r]   r&   r$   )r   strip_versionss     r   requiresre      s.     D!...!!),,r   c                j    t        | ||      D cg c]  }|j                  D ]  }|  c}}S c c}}w )a  
    List all files belonging to a distribution.

    Arguments:
        name:
            The name of the distribution.
        dependencies:
            Recursively collect files of dependencies too.
        excludes:
            Distributions to ignore if **dependencies** is true.
    Returns:
        All filenames belonging to the given distribution.

    With ``dependencies=False``, this is just a shortcut for::

        conda_support.distribution(name).files
    )rb   r   )r   r&   rZ   distr<   s        r   r   r     s5    $ 1|XNfT[_[e[efSWDfDfffs   /Librarybinlibc           	     V   d}g }t        | ||      D ]  }t        j                  |      j                  t        k7  r*|j                         }|j                         sKt        |D cg c]  }|j                  |       c}      st|j                  t        |      |f        |S c c}w )a  
    Collect DLLs for distribution **name**.

    Arguments:
        name:
            The distribution's project-name.
        dest:
            Target destination, defaults to ``'.'``.
        dependencies:
            Recursively collect libs for dependent distributions (recommended).
        excludes:
            Dependent distributions to skip, defaults to ``None``.
    Returns:
        List of DLLs in PyInstaller's ``(source, dest)`` format.

    This collects libraries only from Conda's shared ``lib`` (Unix) or ``Library/bin`` (Windows) folders. To collect
    from inside a distribution's installation use the regular :func:`PyInstaller.utils.hooks.collect_dynamic_libs`.
    )z*.dllz*.dylibz*.soz*.so.*)r   r   PurePathparentlib_dirrQ   is_fileanymatchr7   rG   )	r   destr&   rZ   DLL_SUFFIXES_filesr<   resolved_filesuffixs	            r   collect_dynamic_libsrw      s    & :LFdL(3 2 D!((G3$$&lKFM''/KLs=)401%2& M	 Ls   &B&
c                   t        j                  |       } | j                  dk(  r)| j                  t        j
                  v r| j                  } n| j                  t        j
                  vryt        D ]q  }t        | j                        t        |j                        dz   k7  r2t        j                  t        | j                        t        |            se| j                  c S  y)au  
    Determine the package name of a Python file in :data:`sys.path`.

    Arguments:
        file:
            A Python filename relative to Conda root (sys.prefix).
    Returns:
        Package name or None.

    This function only considers single file packages e.g. ``foo.py`` or top level ``foo/__init__.py``\ s.
    Anything else is ignored (returning ``None``).
    r,   Nr4   )r   r   stemrv   r   ALL_SUFFIXESrm   PYTHONPATH_PREFIXESr   r   fnmatchrG   )r<   rP   s     r   r;   r;   N  s     <<D
 yyJ4;;&2E2E#E{{	F//	/
 & tzz?c&,,/!33 ??3t{{+S[999r   c                 r    i } t         j                  d      D ]  }t        |      }|| |j                  <    | S )Nz*.json)CONDA_META_DIRglobr   r   )r?   pathrg   s      r   _init_distributionsr   ~  sA    M##H- (D!#'dii ( r   c                 h    i } t         j                         D ]  }|j                  D ]  }|| |<   	  | S r
   )r?   ra   r(   )rE   r]   r=   s      r   _init_packagesr     sH    !%,,. =#,, 	=G0<$W-	== $#r   r
   )rY   rG   rZ   Iterable[str] | None)F)r   rG   rd   boolreturnz	List[str])FN)r   rG   r&   r   rZ   zlist | Noner   zList[PackagePath]).TN)r   rG   rr   rG   r&   r   rZ   r   )r<   r   ).rJ   
__future__r   r|   r!   r   rO   typingr   r   importlib.metadatar   _PackagePathPyInstallerr   PyInstaller.logr   r   rP   
CONDA_ROOTr~   r{   r   _pathr7   relative_to
ValueErrorsortr   rC   r]   rF   package_distributionr_   rb   re   r   is_winrl   rn   rw   r;   r   r?   r   rE   rL   r   r   <module>r      sc  . #    
 ! :  " W\\#**%
l*  XX EGLLE""5#4#4SZZ#@A   3T  Bew ewP %%#55 /, //d.-"g* 
==gy%0Ggu%G(\"` $%$ *+ m
  s   8*EEE