zmc
2023-08-08 e792e9a60d958b93aef96050644f369feb25d61b
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
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
U
W±dâ´ã@s8dZddlZddlZddlZddlZddlZddlmZddlm    Z    ddl
m Z m Z ddl
m ZddlmZddlmZmZmZmZmZmZmZmZdd    lmZdd
lmZmZdd lm Z m!Z!dd l"m#Z#dd l$m%Z%m&Z&m'Z'ddl(m)Z)m*Z*m+Z+ddl,m-Z-m.Z.e /e0¡Z1Gdd„de%ƒZ2da3ddd„Z4dd„Z5dS)at
Define a modified ModuleGraph that can return its contents as a TOC and in other ways act like the old ImpTracker.
TODO: This class, along with TOC and Tree, should be in a separate module.
 
For reference, the ModuleGraph node types and their contents:
 
 nodetype         identifier        filename
 
 Script           full path to .py  full path to .py
 SourceModule     basename          full path to .py
 BuiltinModule    basename          None
 CompiledModule   basename          full path to .pyc
 Extension        basename          full path to .so
 MissingModule    basename          None
 Package          basename          full path to __init__.py
        packagepath is ['path to package']
        globalnames is set of global names __init__.py defines
 ExtensionPackage basename          full path to __init__.{so,dll}
        packagepath is ['path to package']
 
The main extension here over ModuleGraph is a method to extract nodes from the flattened graph and return them as a
TOC, or added to a TOC. Other added methods look up nodes by identifier and return facts about them, replacing what
the old ImpTracker list could do.
éN)Ú defaultdict)Údeepcopy)ÚHOMEPATHÚ PACKAGEPATH)Úlog)Úadd_suffix_to_extension)ÚBAD_MODULE_TYPESÚBINARY_MODULE_TYPESÚMODULE_TYPES_TO_TOC_DICTÚPURE_PYTHON_MODULE_TYPESÚPY3_BASE_MODULESÚVALID_MODULE_TYPESÚimportlib_load_sourceÚis_win)Úbytecode)ÚAdditionalFilesCacheÚModuleHookCache)ÚPreFindModulePathAPIÚPreSafeImportModuleAPI)Ú get_implies)Ú ModuleGraphÚDEFAULT_IMPORT_LEVELÚABSOLUTE_IMPORT_LEVEL)ÚDEBUGÚINFOÚTRACE)Úcollect_submodulesÚ
is_packagecsReZdZdZeeeeedœZd?‡fdd„    Zdd„Z    dd    „Z
e d
d „ƒZ d d „Z e Ze Zdd„Zdd„Zd@‡fdd„    Zdd„Zdd„Zedf‡fdd„    Z‡fdd„Z‡fdd„Zdd „ZdAd!d"„Zd#d$„Zd%d&„Zd'd(„Ze dBd)d*„ƒZd+d,„Zd-d.„Z d/d0„Z!d1d2„Z"d3d4„Z#e$e%d5œd6d7„Z&e'd8œd9d:„Z(dCe'd8œd;d<„Z)e*d8œd=d>„Z+‡Z,S)DÚPyiModuleGraphaþ
    Directed graph whose nodes represent modules and edges represent dependencies between these modules.
 
    This high-level subclass wraps the lower-level `ModuleGraph` class with support for graph and runtime hooks.
    While each instance of `ModuleGraph` represents a set of disconnected trees, each instance of this class *only*
    represents a single connected tree whose root node is the Python script originally passed by the user on the
    command line. For that reason, while there may (and typically do) exist more than one `ModuleGraph` instance,
    there typically exists only a singleton instance of this class.
 
    Attributes
    ----------
    _hooks : ModuleHookCache
        Dictionary mapping the fully-qualified names of all modules with normal (post-graph) hooks to the absolute paths
        of such hooks. See the the `_find_module_path()` method for details.
    _hooks_pre_find_module_path : ModuleHookCache
        Dictionary mapping the fully-qualified names of all modules with pre-find module path hooks to the absolute
        paths of such hooks. See the the `_find_module_path()` method for details.
    _hooks_pre_safe_import_module : ModuleHookCache
        Dictionary mapping the fully-qualified names of all modules with pre-safe import module hooks to the absolute
        paths of such hooks. See the `_safe_import_module()` method for details.
    _user_hook_dirs : list
        List of the absolute paths of all directories containing user-defined hooks for the current application.
    _excludes : list
        List of module names to be excluded when searching for dependencies.
    _additional_files_cache : AdditionalFilesCache
        Cache of all external dependencies (e.g., binaries, datas) listed in hook scripts for imported modules.
    _module_collection_mode : dict
        A dictionary of module/package collection mode settings set by hook scripts for their modules.
    _base_modules: list
        Dependencies for `base_library.zip` (which remain the same for every executable).
    )réééé©c s>tƒjfd|i|—Ž||_d|_||_| |¡| ¡dS)NÚexcludes)ÚsuperÚ__init__Z    _homepathÚ_top_script_nodeÚ    _excludesÚ_resetÚ_analyze_base_modules)ÚselfZ pyi_homepathÚuser_hook_dirsr$Úkwargs©Ú    __class__r#úRd:\z\workplace\vscode\pyvenv\venv\Lib\site-packages\PyInstaller/depend/analysis.pyr&bs 
zPyiModuleGraph.__init__c Cs&d|_tƒ|_tƒ|_|tj td¡f•|_    t
  d¡|  d¡|_ |  d¡|_|  d¡|_ttƒ|_|j    D]ª}tj tj |d¡¡}z,t|dd    d
}t | ¡¡}W5QRXWnTtk
rÈYqjYn>tk
r}zt
 d ||f¡WY¢qjW5d}~XYnX| |||¡qjt|jƒ|_dS) zh
        Reset for another set of scripts. This is primary required for running the test-suite.
        NÚhookszCaching module graph hooks...ÚÚpre_safe_import_moduleÚpre_find_module_pathz rthooks.datÚrzutf-8)Úencodingz)Unable to read run-time hooks from %r: %s)r'rÚ_additional_files_cacheÚdictÚ_module_collection_modeÚosÚpathÚjoinrÚ_user_hook_dirsÚloggerÚinfoÚ _cache_hooksÚ_hooksÚ_hooks_pre_safe_import_moduleÚ_hooks_pre_find_module_pathrÚlistÚ_available_rthooksÚabspathÚopenÚastÚ literal_evalÚreadÚFileNotFoundErrorÚ    ExceptionÚerrorÚ_merge_rthooks)r+r,ÚuhdÚuhd_pathÚfÚrthooksÚer#r#r0r)ns*
 
 
zPyiModuleGraph._resetc
Csìt|tƒstd|ƒ‚| ¡D]È\}}t|tƒs@td||fƒ‚t|tƒsZtd||fƒ‚||jkr€t d||t    j
  |d¡¡q|D]`}t|tƒs¤td|||fƒ‚t    j
  |d|¡}t    j
  |¡sÔtd||||fƒ‚|j|  |¡q„qdS)    a9
        The expected data structure for a run-time hook file is a Python dictionary of type ``Dict[str, List[str]]``,
        where the dictionary keys are module names and the sequence strings are Python file names.
 
        Check then merge this data structure, updating the file names to be absolute.
        z&The root element in %s must be a dict.z=%s must be a dict whose keys are strings; %s is not a string.z&The value of %s key %s must be a list.ziRuntime hooks for %s have already been defined. Skipping the runtime hooks for %s that are defined in %s.rRz$%s key %s, item %r must be a string.zGIn %s, key %s, the file %r expected to be located at %r does not exist.N)Ú
isinstancer8ÚAssertionErrorÚitemsÚstrrDrEr>Úwarningr:r;r<ÚexistsÚappend)r+rRrOrPÚ module_nameZpython_file_name_listZpython_file_nameÚabs_pathr#r#r0rN‘s6 
ÿ 
ÿ
 þ  ÿ
ÿÿzPyiModuleGraph._merge_rthookscOs tj||ŽS©N)r>Ú
findCaller)Úargsr-r#r#r0Ú _findCaller¶szPyiModuleGraph._findCallerc
Gs®z|j|}Wntk
r$YdSXt |¡s4dSd|d tt|ƒ¡f}z| ¡\}}}}Wn tk
r€d\}}}}YnXt     tj
||||gd|d|¡
}    t  |    ¡dS)aÇ
        Print a debug message with the given level.
 
        1. Map the msg log level to a logger log level.
        2. Generate the message format (the same format as ModuleGraph)
        3. Find the caller, which findCaller expects three stack-frames above itself:
            [3] caller -> [2] msg (here) -> [1] _findCaller -> [0] logger.findCaller
        4. Create a logRecord with the caller's information.
        5. Handle the logRecord.
        Nz%s %sú )z(unknown file)rz(unknown function)N) ÚLOG_LEVEL_MAPPINGÚKeyErrorr>Ú isEnabledForr<ÚmapÚreprr`Ú
ValueErrorÚ
makeRecordÚnameÚhandle)
r+ÚlevelÚsr_ÚmsgÚfnÚlnoÚfuncÚsinfoÚrecordr#r#r0rm¼s 
zPyiModuleGraph.msgcCs>g}|jD](}tj ||¡}tj |¡r
| |¡q
t||ƒS)aó
        Get a cache of all hooks of the passed type.
 
        The cache will include all official hooks defined by the PyInstaller codebase _and_ all unofficial hooks
        defined for the current application.
 
        Parameters
        ----------
        hook_type : str
            Type of hooks to be cached, equivalent to the basename of the subpackage of the `PyInstaller.hooks`
            package containing such hooks (e.g., `post_create_package` for post-create package hooks).
        )r=r:r;r<ÚisdirrZr)r+Z    hook_typeZ    hook_dirsZ user_hook_dirZuser_hook_type_dirr#r#r0r@Üs 
  zPyiModuleGraph._cache_hookscsPt d¡g}tD]$}t|ƒr,|t|ƒ7}q| |¡q‡fdd„|Dƒˆ_dS)zN
        Analyze dependencies of the the modules in base_library.zip.
        zAnalyzing base_library.zip ...cs g|]}ˆ |¡D]}|‘qqSr#)Ú import_hook)Ú.0ÚreqÚmod©r+r#r0Ú
<listcomp>s z8PyiModuleGraph._analyze_base_modules.<locals>.<listcomp>N)r>r?r rrrZÚ _base_modules)r+Z required_modsÚmr#rxr0r*ôs
 z$PyiModuleGraph._analyze_base_modulesNcs°|jdkr’ztƒ |¡|_WnTtk
rptd|tjdt ¡     d¡}t|dd…dtjiŽt 
d¡YnX|j D]}|  |j|¡qx|jS|sœ|j}tƒj||dSdS)    a
        Wrap the parent's 'run_script' method and create graph from the first script in the analysis, and save its
        node to use as the "caller" node for all others. This gives a connected graph rather than a collection of
        unrelated trees.
        Nz
Syntax error in)ÚfileTéüÿÿÿr|r)Úcaller) r'r%Ú
add_scriptÚ SyntaxErrorÚprintÚsysÚstderrÚ    tracebackÚ
format_excÚ
splitlinesÚexitrzÚadd_edge)r+Úpathnamer~Zformatted_linesÚnoder.r#r0rs
 
zPyiModuleGraph.add_scriptcCs®t d¡tƒ}|j ¡D]z\}}|j|dd}|dkr:qt|ƒjtkrT|     |¡q|D]0}| 
|¡|j      ||j |j ¡|j |j¡qX|     |¡q|jj|Ž|s
qªq
dS)zÒ
        For each imported module, run this module's post-graph hooks if any.
 
        Parameters
        ----------
        analysis: build_main.Analysis
            The Analysis that calls the hooks
 
        zProcessing module hooks...F)Z create_nspkgN)r>r?ÚsetrArVÚ    find_nodeÚtypeÚ__name__r ÚaddZ
post_graphr7ZbinariesZdatasr9ÚupdateZmodule_collection_modeZremove_modules)r+ZanalysisZhooked_module_namesr[Z module_hooksZ module_nodeÚ module_hookr#r#r0Úprocess_post_graph_hookss"
 
 
  z'PyiModuleGraph.process_post_graph_hookscCs>tƒ}|r:|j |g¡D]}| |j¡q| d¡d}q|S)ze
        Collect excludedimports from the hooks of the specified module and all its parents.
        Ú.r)r‹rAÚgetrZexcludedimportsÚ
rpartition)r+r[Úexcluded_importsr‘r#r#r0Ú_find_all_excluded_imports\s z)PyiModuleGraph._find_all_excluded_importsc s|dk    rì| |j¡}|rì|tkrb|r4|jd|}n|j}|dkrfd | d¡d|d …¡}n|}dd„}|||ƒ}    |    r–t d||j|    |j¡gS|rìg}
|D]@} |d| } || |ƒ}    |    rØt d| |j|    |j¡q¢|
 | ¡q¢|
pêd}tƒ     |||||¡S)Nr“rcSsB| d¡}|D].}| d¡}|dt|ƒ…|k}|r|SqdS)zË
                    Helper for checking whether given module should be excluded.
                    Returns the name of exclusion rule if module should be excluded, None otherwise.
                    r“N)ÚsplitÚlen)r[r–Zmodule_name_partsZexcluded_importZexcluded_import_partsÚmatchr#r#r0Ú_exclude_moduleƒs
 
 
z9PyiModuleGraph._safe_import_hook.<locals>._exclude_modulezxSuppressing import of %r from module %r due to excluded import %r specified in a hook for %r (or its parent package(s)).)
r—Ú
identifierrr<r˜r>ÚdebugrZr%Ú_safe_import_hook) r+Ztarget_module_partnameZ source_moduleZtarget_attr_namesrkZ    edge_attrr–Zbase_module_namer›Zexcluded_import_ruleZfiltered_target_attr_namesZtarget_attr_nameZsubmodule_namer.r#r0ržisJ  
ý 
ý z PyiModuleGraph._safe_import_hookcsš||jkrŠ|j|D]l}t d||j¡d| dd¡}t||jƒ}t||||d}t|dƒsjtd|ƒ‚|     |¡|j
}|j }q|j|=t ƒ  |||¡S)a
        Create a new graph node for the module with the passed name under the parent package signified by the passed
        graph node.
 
        This method wraps the superclass method with support for pre-import module hooks. If such a hook exists for
        this module (e.g., a script `PyInstaller.hooks.hook-{module_name}` containing a function
        `pre_safe_import_module()`), that hook will be run _before_ the superclass method is called.
 
        Pre-Safe-Import-Hooks are performed just *prior* to importing the module. When running the hook, the modules
        parent package has already been imported and ti's `__path__` is set up. But the module is just about to be
        imported.
 
        See the superclass method for description of parameters and return value.
        z2Processing pre-safe import module hook %s from %r.Z)PyInstaller_hooks_pre_safe_import_module_r“Ú_)Ú module_graphÚmodule_basenamer[Úparent_packager3z9pre_safe_import_module() function not defined by hook %r.)rBr>r?Ú hook_filenameÚreplacerrÚhasattrÚ    NameErrorr3r¡r[r%Ú_safe_import_module)r+r¡r[r¢ÚhookZhook_module_nameÚ hook_moduleÚhook_apir.r#r0r§²s$
 ü
 
z"PyiModuleGraph._safe_import_modulecs’||jkr‚|j|D]d}t d||j¡d| dd¡}t||jƒ}t|||d}t|dƒshtd|ƒ‚|     |¡|j
}q|j|=t ƒ  |||¡S)a,
        Get a 3-tuple detailing the physical location of the module with the passed name if that module exists _or_
        raise `ImportError` otherwise.
 
        This method wraps the superclass method with support for pre-find module path hooks. If such a hook exists
        for this module (e.g., a script `PyInstaller.hooks.hook-{module_name}` containing a function
        `pre_find_module_path()`), that hook will be run _before_ the superclass method is called.
 
        See superclass method for parameter and return value descriptions.
        z0Processing pre-find module path hook %s from %r.Z'PyInstaller_hooks_pre_find_module_path_r“rŸ)r r[Ú search_dirsr4z7pre_find_module_path() function not defined by hook %r.) rCr>r?r£r¤rrr¥r¦r4r«r%Ú_find_module_path)r+Úfullnamer[r«r¨Z hook_fullnamer©rªr.r#r0r¬ás 
 ý
 
z PyiModuleGraph._find_module_pathcCsDi}t}|j|jdD](}t|ƒj}||kr|jr|j||j<q|S)zÐ
        Get code objects from ModuleGraph for pure Python modules. This allows to avoid writing .pyc/pyo files to hdd
        at later stage.
 
        :return: Dict with module name and code object.
        ©Ústart)r Ú
iter_graphr'rrŽÚcoderœ)r+Z    code_dictZ    mod_typesrŠÚmg_typer#r#r0Úget_code_objects
s
zPyiModuleGraph.get_code_objectscCsfdd t¡d}t |¡}tƒ}|j|jdD]0}| |j¡rBq0|     ||¡}|dk    r0| 
|¡q0|S)ai
        Return the name, path and type of selected nodes as a TOC. The selection is determined by the given list
        of PyInstaller TOC typecodes. If that list is empty we return the complete flattened graph as a TOC with the
        ModuleGraph note types in place of typecodes -- meant for debugging only. Normally we return ModuleGraph
        nodes whose types map to the requested PyInstaller typecode(s) as indicated in the MODULE_TYPES_TO_TOC_DICT.
 
        We use the ModuleGraph (really, ObjectGraph) flatten() method to scan all the nodes. This is patterned after
        ModuleGraph.report().
        ú(ú|z)(\.|$)r®N) r<r ÚreÚcompilerDr°r'ršrœÚ _node_to_tocrZ)r+ÚtypecodeZ    regex_strZ module_filterZtocrŠÚentryr#r#r0Ú    _make_tocs
   zPyiModuleGraph._make_toccCs
| t¡S)zB
        Return all pure Python modules formatted as TOC.
        )r»r rxr#r#r0Ú make_pure_toc=szPyiModuleGraph.make_pure_toccCs
| t¡S)zD
        Return all binary Python modules formatted as TOC.
        )r»r    rxr#r#r0Úmake_binaries_tocDsz PyiModuleGraph.make_binaries_toccCs
| t¡S)zE
        Return all MISSING Python modules formatted as TOC.
        )r»rrxr#r#r0Úmake_missing_tocJszPyiModuleGraph.make_missing_toccCs–t|ƒj}|dk    st‚|r&||kr&dS|dkrNtj |j¡\}}tj |¡}n|dkrb|jd}n|j}|jdk    rx|jnd}t    |ƒ}t
|}|||fS)NÚScriptZExtensionPackagez    .__init__r2) rrŽrUr:r;ÚsplitextÚfilenameÚbasenamerœrWr
)rŠr¹r²riÚextr;Ztoc_typer#r#r0r¸Ps
   zPyiModuleGraph._node_to_toccs‡fdd„|DƒS)a+
        Given a list of nodes, create a TOC representing those nodes. This is mainly used to initialize a TOC of
        scripts with the ones that are runtime hooks. The process is almost the same as _make_toc(), but the caller
        guarantees the nodes are valid, so minimal checking.
        csg|]}ˆ |¡‘qSr#)r¸©rurŠrxr#r0ryysz/PyiModuleGraph.nodes_to_toc.<locals>.<listcomp>r#)r+Únodesr#rxr0Ú nodes_to_tocsszPyiModuleGraph.nodes_to_toccCs$| |¡}|dkrdSt|ƒjdkS)NFZ BuiltinModule)rŒrrŽ)r+rirŠr#r#r0Ú is_a_builtin|s
zPyiModuleGraph.is_a_builtincsR‡‡fdd„‰ˆ ˆ¡}|dkr$gSˆ |¡\}}dd„|Dƒ}‡fdd„|DƒS)a-
        List all modules importing the module with the passed name.
 
        Returns a list of (identifier, DependencyIinfo)-tuples. If the names module has not yet been imported, this
        method returns an empty list.
 
        Parameters
        ----------
        name : str
            Fully-qualified name of the module to be examined.
 
        Returns
        ----------
        list
            List of (fully-qualified names, DependencyIinfo)-tuples of all modules importing the module with the passed
            fully-qualified name.
 
        cs&ˆj |ˆ¡}|dk    r"ˆj |¡SdSr])ÚgraphZ edge_by_nodeZ    edge_data)ÚimporterZedge)rir+r#r0Úget_importer_edge_data•sz<PyiModuleGraph.get_importers.<locals>.get_importer_edge_dataNcss|]}|dk    r|jVqdSr])rœ©rurÉr#r#r0Ú    <genexpr>Ÿsz/PyiModuleGraph.get_importers.<locals>.<genexpr>csg|]}|ˆ|ƒf‘qSr#r#rË)rÊr#r0ry sz0PyiModuleGraph.get_importers.<locals>.<listcomp>)rŒZ    get_edges)r+rirŠrŸÚ    importersr#)rÊrir+r0Ú get_importers‚s
zPyiModuleGraph.get_importersc    Cs˜g}t d¡|rD|D],}t d|¡tj |¡}| | |¡¡q| t¡}|D]@\}}}||j    krR|j    |D] }t d|¡| | |¡¡qpqR|S)z„
        Analyze custom run-time hooks and run-time hooks implied by found modules.
 
        :return : list of Graph nodes.
        zAnalyzing run-time hooks ...z!Including custom run-time hook %rzIncluding run-time hook %r)
r>r?r:r;rFrZrr»r rE)    r+Zcustom_runhooksZ rthooks_nodesZ    hook_fileZtemp_tocÚmod_namer;r¹r\r#r#r0Úanalyze_runtime_hooks£s
 
 
 z$PyiModuleGraph.analyze_runtime_hooksc    Cs¢|jdk    st‚|D]Š}| |¡}|dk    r6t d|¡nXt d|¡z&| |¡}t|ƒdks^t‚|d}Wn$tk
rŒt     d|¡YqYnX| 
|j|¡qdS)zÅ
        Add hidden imports that are either supplied as CLI option --hidden-import=MODULENAME or as dependencies from
        some PyInstaller features when enabled (e.g., crypto feature).
        NzHidden import %r already foundzAnalyzing hidden import %rrrzHidden import %r not found) r'rUrŒr>rr?rtr™Ú ImportErrorrMrˆ)r+Z module_listZmodnmrŠrÅr#r#r0Úadd_hiddenimportsÃs
 
 
z PyiModuleGraph.add_hiddenimports)ÚmoduleÚreturncCs„i}tdhB}| |¡}|r€| |¡}|D]T}|dkr8q*t|ƒj|krHq*|j}||ks*| |d¡rfq*|jdkrrq*|j||j<q*|S)z>
        Find modules that import a given **module**.
        r¿Nr“)r rŒÚincomingrrŽrœÚ
startswithr±)r+rÓZco_dictZpure_python_module_typesrŠZ    referrersr5rœr#r#r0Úget_code_usingÜs&ÿ
 
 
zPyiModuleGraph.get_code_using)rÔc
CsFtƒ}|| ddgdg¡O}dD] }|| |ddddd    gg¡O}q |S)
zK
        Collect metadata for all packages that appear to need it.
        Ú pkg_resourcesÚget_distributionÚrequire)zimportlib.metadataÚimportlib_metadataÚmetadataÚ distributionÚversionÚfilesÚrequires)r‹Ú_metadata_from)r+ÚoutrÛr#r#r0Úmetadata_requiredúsý ýz PyiModuleGraph.metadata_requiredc Csddlm}ddlm}tƒ}tƒ}|D]}| t |d|¡¡q(|D]}| t |d|¡¡qJtƒ}    | |¡     ¡D]’\}
} t 
| ¡  ¡D]z} | D]p\} }t |ƒdkr°qš|d}z6| |krÒ|     ||ƒ¡n| |krì|     ||dd¡Wqš|k
rYqšYqšXqšq’q||    S)aÛ
        Collect metadata whose requirements are implied by given function names.
 
        Args:
            package:
                The module name that must be imported in a source file to trigger the search.
            methods:
                Function names from **package** which take a distribution name as an argument and imply that metadata
                is required for that distribution.
            recursive_methods:
                Like **methods** but also implies that a distribution's dependencies' metadata must be collected too.
        Returns:
            Required metadata in hook data ``(source, dest)`` format as returned by
            :func:`PyInstaller.utils.hooks.copy_metadata()`.
 
        Scan all source code to be included for usage of particular *key* functions which imply that that code will
        require metadata for some distribution (which may not be its own) at runtime. In the case of a match,
        collect the required metadata.
        r)ÚDistributionNotFound)Ú copy_metadatar“rT)Ú    recursive) rØräÚPyInstaller.utils.hooksrår‹rrZ    any_aliasr×rVZrecursive_function_callsÚvaluesr™)r+ÚpackageÚmethodsZrecursive_methodsräråZ need_metadataZneed_recursive_metadataÚmethodrârir±ZcallsZ function_namer_r#r#r0rás.    zPyiModuleGraph._metadata_fromcCsdd„|j|jdDƒS)z?
        Return the list of collected python packages.
        cSs$g|]}t|ƒjdkrt|jƒ‘qS)ÚPackage)rrŽrWrœrÄr#r#r0ryMsÿz9PyiModuleGraph.get_collected_packages.<locals>.<listcomp>r®)r°r'rxr#r#r0Úget_collected_packagesHs ÿz%PyiModuleGraph.get_collected_packages)r#r#)N)N)N)r#r#)-rŽÚ
__module__Ú __qualname__Ú__doc__rrrrbr&r)rNÚ staticmethodr`rmZmsginZmsgoutr@r*rr’r—rržr§r¬r³r»r¼r½r¾r¸rÆrÇrÎrÐrÒrWr8r×r‹rãrárDríÚ __classcell__r#r#r.r0r>sH! #%
?ÿI / )
 "    ! 5rr#cCs†|pd}|pd}tr>tj|kr>t d¡ttƒ}| |¡|St d¡tt|tƒ|d}ts‚t d¡t|ƒadt_    dt_
dt_ |S)a¦
    Create the cached module graph.
 
    This function might appear weird but is necessary for speeding up test runtime because it allows caching basic
    ModuleGraph object that gets created for 'base_library.zip'.
 
    Parameters
    ----------
    excludes : list
        List of the fully-qualified names of all modules to be "excluded" and hence _not_ frozen into the executable.
    user_hook_dirs : list
        List of the absolute paths of all directories containing user-defined hooks for the current application or
        `None` if no such directories were specified.
 
    Returns
    ----------
    PyiModuleGraph
        Module graph with core dependencies.
    r#z)Reusing cached module dependency graph...z'Initializing module dependency graph...)r$Zimpliesr,z"Caching module dependency graph...N) Ú_cached_module_graph_r(r>r?rr)rrrrArBrC)r$r,rÈr#r#r0Úinitialize_modgraphVs*
 
 
û
rôcCstdƒ}tƒ}tj tdd¡}dD]\}t|ƒ}t|dƒr"tj |j¡}tj     tj 
|¡¡dkrltj d|¡}|  t ||dƒ¡q"|  dtj |j¡df¡|d    tj |d
¡dfd tj |d ¡dfd tj |d¡dfg7}t rö|  dtj |d¡df¡|  dtj |d¡df¡|S)zf
    Get TOC with the bootstrapping modules and their dependencies.
    :return: TOC with modules
    ÚstructÚ PyInstallerÚloader)Ú_structÚzlibÚ__file__z lib-dynloadZ    EXTENSIONZPYMODULEZpyimod01_archivezpyimod01_archive.pyZpyimod02_importerszpyimod02_importers.pyZpyimod03_ctypeszpyimod03_ctypes.pyZpyimod04_pywin32zpyimod04_pywin32.pyZpyiboot01_bootstrapzpyiboot01_bootstrap.pyZPYSOURCE)Ú
__import__rDr:r;r<rr¥rFrúrÂÚdirnamerZrr)Z
mod_structZ loader_modsZ
loaderpathrÏrwZmod_filer#r#r0Úget_bootstrap_modules‘s(
ýrý)r#r#)6rðrHr:r¶r‚r„Ú collectionsrÚcopyrrörrrÚloggingZPyInstaller.building.utilsrZPyInstaller.compatrr    r
r r r rrZPyInstaller.dependrZPyInstaller.depend.imphookrrZPyInstaller.depend.imphookapirrZ(PyInstaller.lib.modulegraph.find_modulesrZ'PyInstaller.lib.modulegraph.modulegraphrrrZPyInstaller.logrrrrçrrÚ    getLoggerrŽr>rrórôrýr#r#r#r0Ú<module> s:    (  

;