
    i                     b   S r SSKrSSKrSSKrSSKrSSKJr  SSKJr  SSK	J
r
Jr  SSK	Jr  SSKJr  SSKJrJrJrJrJrJrJrJr  SS	KJr  SS
KJrJr  SSKJrJ r   SSK!J"r"  SSK#J$r$J%r%J&r&J'r'  SSK(J)r)J*r*J+r+  SSK,J-r-J.r.  \R^                  " \05      r1Sr2Sr3Sr4Sr5 " S S\$5      r6Sq7SS jr8S r9g)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)destination_name_for_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Package)DEBUGINFOTRACE)collect_submodules
is_packagei0ii  c                   n  ^  \ rS rSrSr\\\\\S.rS&U 4S jjr	S r
S r\S 5       rS r\r\rS	 rS
 rS'U 4S jjrS rS r\S4U 4S jjrU 4S jrU 4S jrS rS'S jrS rS rS r\S'S j5       rS r S r!S r"S r#S r$S\%S\&4S jr'S\(4S  jr)S&S\(4S! jjr*S\+4S" jr,S\+4S# jr-S\+4S$ jr.S%r/U =r0$ )(PyiModuleGraphC   ai  
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.
_bindepend_symlink_suppression : set
    A set of paths or path patterns corresponding to shared libraries for which binary dependency analysis should
    not create symbolic links into top-level application directory.
_base_modules: list
    Dependencies for `base_library.zip` (which remain the same for every executable).
)r               c                    > [         TU ]  " SSU0UD6  Xl        S U l        X0l        U R                  U5        U R                  5         g )Nexcludes )super__init__	_homepath_top_script_node	_excludes_reset_analyze_base_modules)selfpyi_homepathuser_hook_dirsr(   kwargs	__class__s        HC:\des-py\RoboSAPF\venv\Lib\site-packages\PyInstaller\depend\analysis.pyr+   PyiModuleGraph.__init__j   sD    5(5f5% $ "N#""$    c                    SU l         [        5       U l        [        5       U l        [        5       U l        / UQ[        R                  R                  [        S5      [        4PU l        [        R                  S5        U R                  S5      U l        U R                  S5      U l        U R                  S5      U l        ['        [(        5      U l        U R                   H  u  p#[        R                  R-                  [        R                  R                  US5      5      n [/        USS	S
9 n[0        R2                  " UR5                  5       5      nSSS5        U R=                  WX$5        M     [        U R*                  5      U l        g! , (       d  f       N?= f! [6         a     M  [8         a(  n[        R;                  SU< SU< 35         SnAM  SnAff = f)zX
Reset for another set of scripts. This is primary required for running the test-suite.
Nhooksz(Initializing module graph hook caches... pre_safe_import_modulepre_find_module_pathzrthooks.datrzutf-8)encodingz#Unable to read run-time hooks from z: )r-   r   _additional_files_cachedict_module_collection_modeset_bindepend_symlink_suppressionospathjoinr   HOOK_PRIORITY_BUILTIN_HOOKS_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)r1   r3   uhd_uhd_pathfrthookses           r6   r/   PyiModuleGraph._resetv   sr    !%';'=$'+v$.1e+ 
 
WW\\+w/1LM 
 	>?''+-1->->?W-X*+/+<+<=S+T( #.d"3**FCwwrww||C'GHH(C':a!..qvvx8G ; 7 + #'t'>'>"? ;:$  HVWXYs<   "F-%FF
F	FF
G)	G2GGc                    [        U[        5      (       d
   SU-  5       eUR                  5        GHA  u  pE[        U[        5      (       d   U< SU< S35       e[        U[        5      (       d   SU< SU< S35       eX@R
                  ;   a7  [        R                  SXD[        R                  R                  US5      5        M  U H  n[        U[        5      (       d   U< SU< S	U< S
35       e[        R                  R                  USU5      n[        R                  R                  U5      (       d   SU< SU< SU< SU< S3	5       eU R
                  U   R                  U5        M     GMD     g)a  
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( must be a dict whose keys are strings; z is not a string.zThe value of z key z must be a list.ziRuntime hooks for %s have already been defined. Skipping the runtime hooks for %s that are defined in %s.r_   z, item z must be a string.zIn z, key z, the file z expected to be located at z does not exist.N)
isinstancerA   itemsstrrP   rQ   rJ   warningrE   rF   rG   existsappend)r1   r_   r[   r]   module_namepython_file_name_listpython_file_nameabs_paths           r6   rZ   PyiModuleGraph._merge_rthooks   sS    '4((]*RU]*]](29--/.Kk3// jS[]hij/ 3T:: S<DkRS:555%&1SR[@\
 $9 !"2C88 g>FUefg8 77<<Y8HIww~~h// H{,<hHH/ ''4;;HE %: 3Br8   c                  .    [         R                  " U 0 UD6$ N)rJ   
findCaller)argsr4   s     r6   _findCallerPyiModuleGraph._findCaller   s       $1&11r8   c                     U R                   U   n[        R                  U5      (       d  gU< SSR	                  [        [        U5      5      < 3n U R                  5       u  pVpx[        R                  [        R                  XXd/ SUSU5
      n	[        R                  U	5        g! [         a     gf = f! [         a    Su  pVpx Naf = f)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.
N )z(unknown file)r   z(unknown function)N)LOG_LEVEL_MAPPINGKeyErrorrJ   isEnabledForrG   mapreprrr   
ValueError
makeRecordnamehandle)
r1   levelsrq   msgfnlnofuncsinforecords
             r6   r   PyiModuleGraph.msg   s    	**51E ""5))CHHSt_56	S#'#3#3#5 BT ""6;;3RtUY[`af  		  	S#R BT5	Ss#   B& B6 &
B32B36CCc                     / nU R                    H\  u  p4[        R                  R                  X15      n[        R                  R	                  U5      (       d  MJ  UR                  XT45        M^     [        X5      $ )a  
Create a cache of all hooks of the specified 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., empty string for standard hooks, `pre_safe_import_module` for
    pre-safe-import-module hooks, `pre_find_module_path` for pre-find-module-path hooks).
)rI   rE   rF   rG   isdirrh   r   )r1   	hook_type	hook_dirsuser_hook_dirpriorityuser_hook_type_dirs         r6   rL   PyiModuleGraph._cache_hooks   sd     	'+';';#M "$m!Gww}}/00  "4!?@ (< t//r8   c                    [         R                  S5        / n[         H4  n[        U5      (       a  U[	        U5      -  nM#  UR                  U5        M6     U VVs/ s H  o0R                  U5        H  oDPM     M     snnU l        gs  snnf )z>
Analyze dependencies of the the modules in base_library.zip.
z*Analyzing modules for base_library.zip ...N)rJ   rK   r   r   r   rh   import_hook_base_modules)r1   required_modsmreqmods        r6   r0   $PyiModuleGraph._analyze_base_modules  sv     	@A!A!}}!3A!66$$Q'	 " .;\]cFVFVWZF[scF[c]\\s   #BNc                   > U R                   cP   [        TU ]	  U5      U l         U R                   H  nU R                  U R                   U5        M!     U R                   $ U(       d  U R                   n[        TU ]	  XS9$ ! [         ar    [	        SU[
        R                  S9  [        R                  " 5       R                  S5      n[	        USS S[
        R                  06  [
        R                  " S5         Nf = f)	z
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)fileTr   r#   )caller)r-   r*   
add_scriptSyntaxErrorprintsysstderr	traceback
format_exc
splitlinesexitr   add_edge)r1   pathnamer   formatted_linesnoder5   s        r6   r   PyiModuleGraph.add_script  s       ((-(:8(D% **d33T: + (((..7%h%>>  )8#**E"+"6"6"8"C"CD"Irs+=#**=	s   A? ?A9C;:C;c                    [         R                  S5         [        5       nU R                  R	                  5        H  u  p4U R                  USS9nUc  M  [        U5      R                  [        ;  a  UR                  U5        MJ  UR                  U5        U R                  R                  X4R                  UR                  5        U R                  R                  UR                   5        U R"                  R                  UR$                  5        UR                  U5        M     U R                  R&                  " U6   U(       d  gGM2  )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

z-Processing module hooks (post-graph stage)...F)create_nspkgN)rJ   rK   rC   rM   rd   	find_nodetype__name__r   add
post_graphr@   binariesdatasrB   updatemodule_collection_moderD   bindepend_symlink_suppressionremove_modules)r1   analysishooked_module_namesri   module_hookmodule_nodes         r6   process_post_graph_hooks'PyiModuleGraph.process_post_graph_hooks,  s   & 	CD #&% -1KK,=,=,?("nn[unM & $--5GG'++K8 &&x0 ,,00>R>RT_TeTef ,,33K4V4VW 33::;;d;de $''49 -@> KK&&(;< 'U r8   c                     [        5       nU(       a[  U R                  R                  US5      nU(       a  UR                  UR                  5        UR                  S5      S   nU(       a  M[  U$ )zU
Collect excludedimports from the hooks of the specified module and all its parents.
N.r   )rC   rM   getr   excludedimports
rpartition)r1   ri   excluded_importsr   s       r6   _find_all_excluded_imports)PyiModuleGraph._find_all_excluded_importsl  s^     5++//+t<K ''(C(CD%005a8K k  r8   c                   > UGb  U R                  UR                  5      nU(       Gab  U[        :  a  [        U[        5      (       a  UR                  nO-SR                  UR                  R                  S5      S S 5      nUS:  a'  SR                  UR                  S5      S US-
  *  5      nU(       a  USU-   -  nOUnS nU" UUUR                  5      n	U	(       a.  [        R                  SXrR                  U	UR                  5        / $ U(       aw  / n
U Hd  nUS-   U-   nU" UUUR                  5      n	U	(       a-  [        R                  SXR                  XR                  5        MS  U
R                  U5        Mf     U
=(       d    S n[        TU ]-  XX4U5      nU H=  n[        U5      R                  [        ;  a  M"  U R                  UR                  5        M?     U$ )Nr   r#   c                    U R                  S5      nU Hr  nUR                  S5      nUS[        U5       U:H  nU(       d  M.  UR                  S5      nUS[        U5       U:H  nU(       a  [        R                  SX@U5        Mp  Us  $    g)z
Helper for checking whether given module should be excluded.
Returns the name of exclusion rule if module should be excluded, None otherwise.
r   Nz^Deactivating suppression rule %r for module %r because it also applies to the referrer (%r)...)splitlenrJ   debug)	ri   r   referrer_namemodule_name_partsexcluded_importexcluded_import_partsmatchreferrer_name_partsreferrer_matchs	            r6   _exclude_module9PyiModuleGraph._safe_import_hook.<locals>._exclude_module  s    
 )4(9(9#(>%+;0?0E0Ec0J- 12M37L3M NRg g 5 3@2E2Ec2J/-@A\#F[B\-]av-vN- &%78GVc!" !)#22' ,<(  r8   zxSuppressing import of %r from module %r due to excluded import %r specified in a hook for %r (or its parent package(s)).)r   
identifierr   rc   r   rG   r   rJ   r   rh   r*   _safe_import_hookr   r   r   )r1   target_module_partnamesource_moduletarget_attr_namesr   	edge_attrr   base_module_namer   excluded_import_rulefiltered_target_attr_namestarget_attr_namesubmodule_nameret_modules
ret_moduler5   s                  r6   r    PyiModuleGraph._safe_import_hookz  s    $  $>>}?W?WX   00!-99+8+C+C( ,/88M4L4L4R4RSV4WX[Y[4\+]( qy+.884D4J4J34OP]SX[\S\Q]4^+_(-(C2H,HH('=$ > (7$$!,,($
 (LL67GIaIacw%00
 I %13.,=()9C)?BR)R/>*,)440,
 0"LL!EFTVnVn 46N6N 7==>NO ->$ )C(Jd%g/"3DY
 &JJ((0BB ++J,A,AB & r8   c                   > U R                   R                  US5      nUb  [        R                  R	                  UR
                  5      u  pV[        R                  SXe5        SUR                  SS5      -   n[        XtR
                  5      n[        U UUUS9n	[        US5      (       d  [        SU-  5      eUR                  U	5        U	R                  nU	R                  n[         T
U ]E  XU5      $ )	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.
Nz1Processing pre-safe-import-module hook %r from %r)PyInstaller_hooks_pre_safe_import_module_r   r\   )module_graphmodule_basenameri   parent_packager<   z9pre_safe_import_module() function not defined by hook %r.)rN   poprE   rF   r   hook_filenamerJ   rK   replacer   r   hasattr	NameErrorr<   r   ri   r*   _safe_import_module)r1   r   ri   r   hook	hook_pathhook_basenamehook_module_namehook_modulehook_apir5   s             r6   r   "PyiModuleGraph._safe_import_module  s    " 1155k4H')ww}}T5G5G'H$IKKK]fJ[M`M`adfiMjj/0@BTBTUK .! /'-	H ;(@AA [^i ijj..x8 '66O"..K w*?XXr8   c                   > U R                   R                  US5      nUb  [        R                  R	                  UR
                  5      u  pV[        R                  SXe5        SUR                  SS5      -   n[        XtR
                  5      n[        U UUS9n	[        US5      (       d  [        SU-  5      eUR                  U	5        U	R                  n[        T
U ]A  XU5      $ )	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.
Nz/Processing pre-find-module-path hook %r from %r'PyInstaller_hooks_pre_find_module_path_r   r\   )r   ri   search_dirsr=   z7pre_find_module_path() function not defined by hook %r.)rO   r   rE   rF   r   r   rJ   rK   r   r   r   r   r   r=   r   r*   _find_module_path)r1   fullnameri   r   r   r   r   hook_fullnamer   r   r5   s             r6   r    PyiModuleGraph._find_module_path  s     //33HdC')ww}}T5G5G'H$IKKI=dEHXHXY\^aHbbM/?Q?QRK ,!$'H ;(>?? Y\g ghh,,X6 #..K w(LLr8   c                     0 n[         nU R                  U R                  S9 HJ  n[        U5      R                  nXB;   d  M  UR
                  (       d  M2  UR
                  XR                  '   ML     U$ )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   )r1   	code_dict	mod_typesr   mg_types        r6   get_code_objectsPyiModuleGraph.get_code_objectsD  sb     	,	OO$*?*?O@D 4j))G#99915Ioo. A r8   c                     [        5       nU R                  U R                  S9 H*  nU R                  X15      nUc  M  UR	                  U5        M,     U$ )a1  
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().
r   )rP   r   r-   _node_to_tocrh   )r1   typecodetocr   entrys        r6   	_make_tocPyiModuleGraph._make_tocY  sR     fOO$*?*?O@D%%d5E  

5! A 
r8   c                 ,    U R                  [        5      $ )z2
Return all pure Python modules formatted as TOC.
)r
  r   r1   s    r6   make_pure_tocPyiModuleGraph.make_pure_tocl  s    
 ~~677r8   c                 ,    U R                  [        5      $ )z4
Return all binary Python modules formatted as TOC.
)r
  r
   r  s    r6   make_binaries_toc PyiModuleGraph.make_binaries_tocs  s     ~~122r8   c                 ,    U R                  [        5      $ )z5
Return all MISSING Python modules formatted as TOC.
)r
  r	   r  s    r6   make_missing_tocPyiModuleGraph.make_missing_tocy  s     ~~.//r8   c                    [        U 5      R                  nUc   eU(       a  X!;  a  g US:X  aK  [        R                  R	                  U R
                  5      u  p4[        R                  R                  U5      nO"US:X  a  U R                  S-   nOU R                  nU R
                  b  U R
                  OSn[        U5      n[        U   nX5U4$ )NScriptExtensionPackagez	.__init__r;   )
r   r   rE   rF   splitextfilenamebasenamer   re   r   )r   r  r  r}   extrF   toc_types          r6   r  PyiModuleGraph._node_to_toc  s     t*%%"""/h''**4==9KT77##D)D** ??[0D??D $ 9t}}r
 4y+G48##r8   c                 N    U Vs/ s H  o R                  U5      PM     sn$ s  snf )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.
)r  )r1   nodesr   s      r6   nodes_to_tocPyiModuleGraph.nodes_to_toc  s%     5::ED!!$'E:::s   "c                 \    U R                  U5      nUc  g[        U5      R                  S:H  $ )NFBuiltinModule)r   r   r   )r1   r}   r   s      r6   is_a_builtinPyiModuleGraph.is_a_builtin  s-    ~~d#<Dz""o55r8   c                    ^ ^ UU 4S jnT R                  T5      nUc  / $ T R                  U5      u  pES U 5       nU Vs/ s H  ofU" U5      4PM     sn$ s  snf )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.

c                 z   > TR                   R                  U T5      nUb  TR                   R                  U5      $ g ro   )graphedge_by_node	edge_data)importeredger}   r1   s     r6   get_importer_edge_data<PyiModuleGraph.get_importers.<locals>.get_importer_edge_data  s9    ::**8T:Dzz++D11  r8   c              3   B   #    U  H  oc  M  UR                   v   M     g 7fro   )r   ).0r,  s     r6   	<genexpr>/PyiModuleGraph.get_importers.<locals>.<genexpr>  s     [X(X((s   )r   	get_edges)r1   r}   r.  r   r\   	importersr,  s   ``     r6   get_importersPyiModuleGraph.get_importers  s]    &	2 ~~d#<I~~d+[[	MVWY1(;<YWWWs    Ac                 <   / n[         R                  S5        U(       a^  U HX  n[         R                  SU5        [        R                  R	                  U5      nUR                  U R                  U5      5        MZ     U R                  [        5      nU H  u  pVnXPR                  ;   d  M  U R                  U    HZ  n[        R                  R                  U5      u  p[         R                  SX5        UR                  U R                  U5      5        M\     M     U$ )zl
Analyze custom run-time hooks and run-time hooks implied by found modules.

:return : list of Graph nodes.
zAnalyzing run-time hooks ...z!Including custom run-time hook %rz"Including run-time hook %r from %r)rJ   rK   rE   rF   rR   rh   r   r
  r   rQ   r   )r1   custom_runhooksrthooks_nodes	hook_filetemp_tocmod_namerF   r  rl   r   r   s              r6   analyze_runtime_hooks$PyiModuleGraph.analyze_runtime_hooks  s     23 ,	?KGGOOI6	 $$T__Y%?@ - >>"45*2&XX222 $ 7 7 AH/1ww}}X/F,IKK Dm_!(()BC !B	 +3 r8   c                    U R                   c   eU H  nU R                  U5      nUb  [        R                  SU5        O>[        R	                  SU5         U R                  U5      n[        U5      S:X  d   eUS   nU R                  U R                   U5        M     g! [         a    [        R                  SU5         M  f = f)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).
NzHidden import %r already foundzAnalyzing hidden import %rr#   r   zHidden import %r not found)
r-   r   rJ   r   rK   r   r   ImportErrorrY   r   )r1   module_listmodnmr   r   s        r6   add_hiddenimports PyiModuleGraph.add_hiddenimports  s    
 $$000 E>>%(D=uE8%@ ,,U3Eu:?*? 8D MM$//6! ! # LL!=uEs   'B CCmodulereturnc                 h   0 n[         S1-  nU R                  U5      nU(       a  U R                  U5      nU Hv  nUc  M  [        U5      R                  U;  a  M#  UR
                  nXq:X  d  UR                  US-   5      (       a  MO  UR                  c  M^  UR                  X&R
                  '   Mx     U$ )z.
Find modules that import a given **module**.
r  r   )r   r   incomingr   r   r   
startswithr   )r1   rF  co_dictpure_python_module_typesr   	referrersr>   r   s           r6   get_code_usingPyiModuleGraph.get_code_using  s     #;?
 $
  ~~f%d+I 97##+CC\\
':+@+@#+N+N 66>()%! " r8   c                     [        5       nXR                  SS/S/5      -  nS H  nXR                  U/ SQ/ 5      -  nM     U$ )z;
Collect metadata for all packages that appear to need it.
pkg_resourcesget_distributionrequire)zimportlib.metadataimportlib_metadata)metadatadistributionversionfilesrequires)rC   _metadata_from)r1   outrT  s      r6   metadata_required PyiModuleGraph.metadata_required*  sb     e"" K
 	
 #O&&"L C #O 
r8   c           
         SSK Jn  SSKJn  [	        5       n[	        5       nU H.  nUR                  [        R                  " US-   U-   5      5        M0     U H.  nUR                  [        R                  " US-   U-   5      5        M0     [	        5       n	U R                  U5      R                  5        H  u  p[        R                  " U5      R                  5        H`  nU HW  u  p[        U5      S:w  a  M  US   n X;   a  U	R                  U" U5      5        M:  X;   a  U	R                  U" USS95        MW  MY     Mb     M     U	$ ! UR                   a     Mx  f = f)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   )copy_metadata)rT  r   r#   T)	recursive)PyInstaller.utils.hooksr_  PyInstaller.compatrT  rC   r   r   	any_aliasrN  rd   recursive_function_callsvaluesr   PackageNotFoundError)r1   packagemethodsrecursive_methodsr_  rT  need_metadataneed_recursive_metadatamethodr[  r}   r   callsfunction_namerq   s                  r6   rZ  PyiModuleGraph._metadata_fromC  s;   ( 	:9 "%%F  !3!3GcMF4J!KL 'F#**8+=+=gmf>T+UV ( e--g6<<>JD!::4@GGI+0'M4yA~ "1gG!(9JJ}W'=>*EJJ}W'MN F ,1 J ?" 
	 .BB ! !s   <EEE	E	c                     U R                  U R                  S9 Vs/ s H3  n[        U5      R                  S:X  d  M  [	        UR
                  5      PM5     sn$ s  snf )z/
Return the list of collected python packages.
r   r   )r   r-   r   r   re   r   )r1   r   s     r6   get_collected_packages%PyiModuleGraph.get_collected_packagesw  sW     .2__4CXCX_-Y
-YTDz""i/ !C -Y
 	
 
s
   AAc                     / nU R                  U R                  S9 HO  n[        UR                  5      nU R                  R                  U5       H  u  pEUR                  XES45        M     MQ     U$ )z6
Return the TOC list of binaries collected by hooks."
r   BINARY)r   r-   re   r   r@   r   rh   r1   r  r   ri   	dest_namesrc_names         r6   make_hook_binaries_toc%PyiModuleGraph.make_hook_binaries_toc  sj     OO$*?*?O@Ddoo.K'+'C'C'L'L['Y#	

I:; (Z A
 
r8   c                     / nU R                  U R                  S9 HO  n[        UR                  5      nU R                  R                  U5       H  u  pEUR                  XES45        M     MQ     U$ )z8
Return the TOC list of data files collected by hooks."
r   DATA)r   r-   re   r   r@   r   rh   ru  s         r6   make_hook_datas_toc"PyiModuleGraph.make_hook_datas_toc  sj     OO$*?*?O@Ddoo.K'+'C'C'I'I+'V#	

I89 (W A
 
r8   )r@   rQ   r   rD   r.   r,   rM   rO   rN   rB   r-   rI   r)   r)   ro   )1r   
__module____qualname____firstlineno____doc__r   r   r   rv   r+   r/   rZ   staticmethodrr   r   msginmsgoutrL   r0   r   r   r   r   r   r   r   r  r
  r  r  r  r  r!  r%  r6  r>  rD  re   rA   rN  rC   r\  rZ  rP   rq  rx  r|  __static_attributes____classcell__)r5   s   @r6   r!   r!   C   s-   !H !Uu5I
%'@R#FJ 2 2
: EF02]?4>@  Ocnrtl+YZ%MN*&830  $  $D;6XBB72S T <3 223 2h
 

 

T 
 
r8   r!   c                    U=(       d    SnU =(       d    Sn SU ;  a  U S-  n [         (       aK  [         R                  U :X  a7  [        R                  S5        [	        [         5      nUR                  U5        U$ [        R                  S5        [        [        U [        5       US9n[         (       dA  [        R                  S5        [	        U5      q S[         l	        S[         l
        S[         l        U$ )	aj  
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)   __main__)r  z)Reusing cached module dependency graph...z'Initializing module dependency graph...)r(   impliesr3   z"Caching module dependency graph...N)_cached_module_graph_r.   rJ   rK   r   r/   r!   r   r   rM   rN   rO   )r(   r3   r)  s      r6   initialize_modgraphr    s    * $)rN~2H !M! !6!@!@H!L?@./^$
KK9: %E ! 89 ( (,$>B;<@9Lr8   c                     [        S5      n [        5       n[        R                  R	                  [
        SS5      nS Hi  n[        U5      n[        US5      (       d  M!  [        R                  R                  UR                  5      n[        X5S5      nUR                  XeS45        Mk     UR                  S[        R                  R                  U R                  5      S45        US[        R                  R	                  US	5      S4S
[        R                  R	                  US5      S4S[        R                  R	                  US5      S4/-  n[        (       a2  UR                  S[        R                  R	                  US5      S45        UR                  S[        R                  R	                  US5      S45        U$ )zZ
Get TOC with the bootstrapping modules and their dependencies.
:return: TOC with modules
structPyInstallerloader)_structzlib__file__	EXTENSIONPYMODULEpyimod01_archivezpyimod01_archive.pypyimod02_importerszpyimod02_importers.pypyimod03_ctypeszpyimod03_ctypes.pypyimod04_pywin32zpyimod04_pywin32.pypyiboot01_bootstrapzpyiboot01_bootstrap.pyPYSOURCE)
__import__rP   rE   rF   rG   r   r   rR   r  r   rh   r   )
mod_structloader_mods
loaderpathr=  r   mod_filemod_dests          r6   get_bootstrap_modulesr    sj    H%J&Khx@J ("3
##wws||4H 6h+VHK@A ( "''//*2E2E"F
ST 	RWW\\*6KLjY	rww||J8OPR\]	BGGLL5IJJW K
 v.ZI^0_aklm-rww||JH`/acmnor8   r~  ):r  rT   rE   r   r   collectionsr   copyr   r  r   r   r   loggingPyInstaller.building.utilsr   rb  r	   r
   r   r   r   r   r   r   PyInstaller.dependr   PyInstaller.depend.imphookr   r   PyInstaller.depend.imphookapir   r   (PyInstaller.lib.modulegraph.find_modulesr   'PyInstaller.lib.modulegraph.modulegraphr   r   r   r   PyInstaller.logr   r   r   ra  r   r   	getLoggerr   rJ   rH   HOOK_PRIORITY_CONTRIBUTED_HOOKSHOOK_PRIORITY_UPSTREAM_HOOKSHOOK_PRIORITY_USER_HOOKSr!   r  r  r  r)   r8   r6   <module>r     s   2  	 
  #  - & E   ( L X @ u u . . B			8	$ $ "'    T[ Tn  @F!r8   