1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
U
X±dÃ9ã    @s²dZddlmZddlZddlZddlZddlmZddlm    Z    m
Z
ddl m Z ddl mZe jrpddlmZn ddlmZeejƒZed    ZgZejD]8ZeeƒZze e ej¡¡Wq˜ek
rÎYq˜Xq˜ejd
d „d d Gdd„dƒZejZ ej!Z"Gdd„deƒZd2dddœdd„Z#dd„Z$d3ddddœdd„Z%d4dddd d!œd"d#„Z&e j'rfed$d%ƒZ(ned&ƒZ(d5ddddd(œd)d*„Z)dd+œd,d-„Z*d.d/„Z+e+ƒZ,d0d1„Z-e-ƒZ.dS)6að
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)ÚPath)ÚIterableÚList)Úcompat)Úlogger©Ú PackagePathz
conda-metacCs
t|jƒS©N)ÚlenÚparts)Úp©rúTd:\z\workplace\vscode\pyvenv\venv\Lib\site-packages\PyInstaller/utils/hooks/conda.pyÚ<lambda>BórT)ÚkeyÚreversec@sZeZdZdZddœdd„Zdd„Zdd    „Zd
d „Zedd œd d„ƒZ    edd œdd„ƒZ
dS)Ú 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.
    Ústr)Ú    json_pathc    Cs zt|ƒ|_|j ¡st‚Wn*ttfk
rFtd t|ƒ¡ƒ‚YnXt |j     ¡¡|_
|j
d|_ |j
d|_ dd„|j
dDƒ|_ | ¡|_| ¡|_dS)Nz_Distribution requires a path to a conda-meta json. Perhaps you want `distribution({})` instead?ÚnameÚversioncSsg|] }t|ƒ‘qSrr)Ú.0ÚirrrÚ
<listcomp>esz)Distribution.__init__.<locals>.<listcomp>Úfiles)rZ
_json_pathÚexistsÚAssertionErrorÚ    TypeErrorÚformatÚreprÚjsonÚloadsÚ    read_textÚrawrrrÚ_init_dependenciesÚ dependenciesÚ_init_package_namesÚpackages)ÚselfrrrrÚ__init__Us
ÿÿ
 
zDistribution.__init__cCsd t|ƒj|j|j¡S)Nz{}(name="{}", packages={}))r ÚtypeÚ__name__rr)©r*rrrÚ__repr__iszDistribution.__repr__cCs2g}|jdD]}|jdd^}}| |¡q|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'Ú
dependencyrZversion_constraintsrrrr&ls
     zDistribution._init_dependenciescCs.g}|jD]}t|ƒ}|dk    r
| |¡q
|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.
        N)rÚ_get_package_namer4)r*r)ÚfileÚpackagerrrr(}s     
 z Distribution._init_package_names)rcCs"|tkrt|Std |¡ƒ‚dS)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.N)Ú distributionsÚModuleNotFoundErrorr ©ÚclsrrrrÚ    from_names
ÿzDistribution.from_namecCs"|tkrt|Std |¡ƒ‚dS)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.N)Údistributions_by_packager:r r;rrrÚfrom_package_namešszDistribution.from_package_nameN) r-Ú
__module__Ú __qualname__Ú__doc__r+r/r&r(Ú classmethodr=r?rrrrrEs rc@seZdZdZdd„ZdS)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.
    cCsttjƒ|S)z_
        Return a path-like object for this path pointing to the file's true location.
        )rÚsysÚprefixr.rrrÚlocate¸szPackagePath.locateN)r-r@rArBrFrrrrr    ±sr    rzIterable[str] | None)ÚinitialÚexcludescCsÄ|dk    rt|ƒ}ddlm}i}||gƒ}|rÀ| ¡}z$t |¡||<}t d||¡Wn&tk
r€t     d||¡Yq*YnX|j
D]4}||kr–qˆ||kr qˆ|dk    r²||kr²qˆ|  |¡qˆq*|S)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>`.
    Nr)Údequez8Collected Conda distribution '%s', a dependency of '%s'.z‰Conda distribution '%s', dependency of '%s', was not found. If you installed this distribution with pip then you may ignore this warning.) ÚsetÚ collectionsrIÚpoprr=rÚdebugr:Úwarningr'r4)rGrHrIÚdoneZ names_to_dorÚ distributionÚ_namerrrÚwalk_dependency_tree¿s4  
þ
 
rRcCs"|rt||ƒ ¡St |¡gSdSr
)rRÚvaluesrr=©rr'rHrrrÚ_iter_distributionsñsrUFÚboolz    List[str])rÚstrip_versionsÚreturncCs|rt|ƒjSt|ƒjdS)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.
    r0)rPr'r%)rrWrrrÚrequiresøs 
rYz list | NonezList[PackagePath])rr'rHrXcCsdd„t|||ƒDƒS)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
    cSsg|]}|jD]}|‘qqSr)r)rÚdistr7rrrrszfiles.<locals>.<listcomp>)rUrTrrrr    srÚLibraryÚbinÚlibÚ.)rÚdestr'rHcsfd}g}t|||ƒD]L}|jtkr$q| ¡‰ˆ ¡s6qt‡fdd„|DƒƒsNq| tˆƒ|f¡q|S)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.*csg|]}ˆ |¡‘qSr)Úmatch)rÚsuffix©Z resolved_filerrrCsz(collect_dynamic_libs.<locals>.<listcomp>)rÚparentÚlib_dirrFÚis_fileÚanyr4r)rr_r'rHZ DLL_SUFFIXESÚ_filesr7rrbrÚcollect_dynamic_libs$s
rh)r7cCs~t|ƒ}|jdkr&|jtjkr&|j}n|jtjkr6dStD]>}t|jƒt|jƒdkrXq:t         t
|jƒt
|ƒ¡r:|jSq:dS)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+Nr1) rÚstemrarZ ALL_SUFFIXESrcÚPYTHONPATH_PREFIXESr r Úfnmatchr)r7rErrrr6Ms  r6cCs*i}t d¡D]}t|ƒ}|||j<q|S)Nz*.json)ÚCONDA_META_DIRÚglobrr)r9ÚpathrZrrrÚ_init_distributions}s
 rocCs*i}t ¡D]}|jD] }|||<qq |Sr
)r9rSr))r>rPr8rrrÚ_init_packagesˆs
 
 rp)N)F)FN)r^TN)/rBÚ
__future__rrkr"rDÚpathlibrÚtypingrrZ PyInstallerrZPyInstaller.logrZis_py38Úimportlib.metadatar    Z _PackagePathZimportlib_metadatarEZ
CONDA_ROOTrlrjrnÚ_pathr4Ú relative_toÚ
ValueErrorÚsortrr=rPr?Zpackage_distributionrRrUrYrZis_winrdrhr6ror9rpr>rrrrÚ<module> sL     
 
h2 )0