yj
2026-03-31 033d919018b3a3e12755f008c0b9093364942512
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
o
ã@s¾dZddlZddlZddlZddlZddlZddlmZmZej    ej
Z e e ƒZ eeƒZejjr8ejr8dd„Zndd„Zdd„ZGd    d
„d
ƒZGd d „d ƒZGd d„dƒZdd„Zdd„ZdS)z8
PEP-302 and PEP-451 importers for frozen applications.
éN)ÚArchiveReadErrorÚZlibArchiveReadercGs tj ||¡tj d¡dS)NÚ
)ÚsysÚstderrÚwrite©ÚmsgÚa©r ú(PyInstaller\loader\pyimod02_importers.pyÚtrace&sr cGsdS)Nr rr r r r +scCsBddlm}t |¡j}||ƒ}tjddd}| | |d¡¡S)a
    Decode bytes representing source code and return the string. Universal newline support is used in the decoding.
    Based on CPython's implementation of the same functionality:
    https://github.com/python/cpython/blob/3.9/Lib/importlib/_bootstrap_external.py#L679-L688
    r)Údetect_encodingNT)ÚdecoderÚ    translate)ÚtokenizerÚioÚBytesIOÚreadlineÚIncrementalNewlineDecoderÚdecode)Ú source_bytesrÚsource_bytes_readlineÚencodingÚnewline_decoderr r r Ú_decode_source/s
 rc@seZdZdZdd„ZdS)ÚPyiFrozenImporterStatea
    An object encapsulating extra information for PyiFrozenImporter, to be stored in `ModuleSpec.loader_state`. Having
    a custom type allows us to verify that module spec indeed contains the original loader state data, as set by
    `PyiFrozenImporter.find_spec`.
    cCs
||_dS)N)Úpyz_entry_name)ÚselfÚ
entry_namer r r Ú__init__Cs
zPyiFrozenImporterState.__init__N)Ú__name__Ú
__module__Ú __qualname__Ú__doc__r r r r r r=s rc@s~eZdZdZdd„Zedd„ƒZdd„Zdd    „Zd
d „Z    d d „Z
dd„Z dd„Z dd„Z ddd„Zdd„Zdd„Zdd„ZdS)ÚPyiFrozenImportera8
    Load bytecode of Python modules from the executable created by PyInstaller.
 
    Python bytecode is zipped and appended to the executable.
 
    NOTE: PYZ format cannot be replaced by zipimport module.
 
    The problem is that we have no control over zipimport; for instance, it does not work if the zip file is embedded
    into a PKG that is appended to an executable, like we create in one-file mode.
 
    This used to be PEP-302 finder and loader class for the ``sys.meta_path`` hook. A PEP-302 finder requires method
    find_module() to return loader class with method load_module(). However, both of these methods were deprecated in
    python 3.4 by PEP-451 (see below). Therefore, this class now provides only optional extensions to the PEP-302
    importer protocol.
 
    This is also a PEP-451 finder and loader class for the ModuleSpec type import system. A PEP-451 finder requires
    method find_spec(), a PEP-451 loader requires methods exec_module(), load_module() and (optionally) create_module().
    All these methods are implemented in this one class.
    c    Cs†tjD](}zt|dd|_td|ƒtj |¡Wnty#Yqty+Yqwtdƒ‚t    |jj
  ¡ƒ|_
t   ¡|_d|_dS)zY
        Load, unzip and initialize the Zip archive bundled with the executable.
        T)Ú check_pymagicz$# PyInstaller: PyiFrozenImporter(%s)zCannot load frozen modules.N)rÚpathrÚ _pyz_archiver ÚremoveÚIOErrorrÚ ImportErrorÚsetÚtocÚkeysÚ_threadÚRLockÚ_lockÚ    _toc_tree)rZ pyz_filepathr r r r \s
 
   þ
 
zPyiFrozenImporter.__init__cCsD|j|jdur| ¡|_|jWdƒS1swYdS)N)r1r2Ú_build_pyz_prefix_tree©rr r r Útoc_tree€s
 
 
$ýzPyiFrozenImporter.toc_treecCsrtƒ}|jD]0}| d¡}|}|j |¡r!|D]}| |i¡}qq|dd…D]}| |i¡}q'd||d<q|S)NÚ.éÿÿÿÿÚ)Údictr-Úsplitr(Ú
is_packageÚ
setdefault)rÚtreerZname_componentsÚcurrentZname_componentr r r r3ˆs
 
 ÿz(PyiFrozenImporter._build_pyz_prefix_treec
CóP||jvr!z|j |¡WSty }ztd|›ƒ|‚d}~wwtd|›ƒ‚)Nú'PyiFrozenImporter cannot handle module )r-r(Úis_pep420_namespace_packageÚ    Exceptionr+©rÚfullnameÚer r r Ú_is_pep420_namespace_package™ó
€ÿz.PyiFrozenImporter._is_pep420_namespace_packagec
Cr?)Nr@)r-r(r;rBr+rCr r r r;¤rGzPyiFrozenImporter.is_packagec
CsNz|dkr tjdjWS|j |¡WSty&}ztd|›ƒ|‚d}~ww)z|
        Get the code object associated with the module.
 
        ImportError should be raised if module not found.
        Ú__main__r@N)rÚmodulesZ _pyi_main_cor(ÚextractrBr+rCr r r Úget_code­s€ÿzPyiFrozenImporter.get_codecCs–||jvrE| |¡r|d7}tj t| dtj¡d¡}zt|dƒ }|     ¡}Wdƒn1s1wYt
|ƒWSt yDYdSwt d|ƒ‚)zò
        Method should return the source code for the module as a string.
        But frozen modules does not contain source code.
 
        Return None, unless the corresponding source file was explicitly collected to the filesystem.
        ú    .__init__r6z.pyÚrbNzNo module named ) r-r;Úosr'ÚjoinÚ
SYS_PREFIXÚreplaceÚsepÚopenÚreadrÚFileNotFoundErrorr+)rrDÚfilenameÚfprr r r Ú
get_source¿s
 
 
ÿ
 þ zPyiFrozenImporter.get_sourcecCs6t|dƒ }| ¡WdƒS1swYdS)a 
        Returns the data as a string, or raises IOError if the file was not found. The data is always returned as if
        "binary" mode was used.
 
        The 'path' argument is a path that can be constructed by munging module.__file__ (or pkg.__path__ items).
 
        This assumes that the file in question was collected into frozen application bundle as a file, and is available
        on the filesystem. Older versions of PyInstaller also supported data embedded in the PYZ archive, but that has
        been deprecated in v6.
        rMN)rSrT)rr'rWr r r Úget_data×s $ÿzPyiFrozenImporter.get_datacCsL| |¡rtj t| dtjj¡d¡}|Stj t| dtjj¡d¡}|S)z¸
        This method should return the value that __file__ would be set to if the named module was loaded. If the module
        is not found, an ImportError should be raised.
        r6z __init__.pycú.pyc)r;rNr'rOrPrQrR)rrDrVr r r Ú get_filenameçs
 
    ÿzPyiFrozenImporter.get_filenameNc sld}|durK| d¡d}|D]9}| t¡sq|td…}| tj¡}|s&q|ds0|dd…}| |¡d |¡}|ˆj    vrHt
d|||ƒnqd}|dur[|ˆj    vr[|}t
d|ƒ|durft
d|ƒdSˆ  |¡rŽdd    l m }tj|dd
d }    ||tj ˆ |¡¡g‡fd d „ƒ|    _|    Sˆ |¡}
ˆ |¡} tj|ˆ| |
t|ƒd}    d
|    _| r´tj ˆ |¡¡g|    _|    S)aì
        PEP-451 finder.find_spec() method for the ``sys.meta_path`` hook.
 
        fullname     fully qualified name of the module
        path         None for a top-level module, or package.__path__ for
                     submodules or subpackages.
        target       unused by this Finder
 
        Finders are still responsible for identifying, and typically creating, the loader that should be used to load a
        module. That loader will now be stored in the module spec returned by find_spec() rather than returned directly.
        As is currently the case without the PEP-452, if a loader would be costly to create, that loader can be designed
        to defer the cost until later.
 
        Finders must return ModuleSpec objects when find_spec() is called. This new method replaces find_module() and
        find_loader() (in the PathEntryFinder case). If a loader does not have find_spec(), find_module() and
        find_loader() are used instead, for backward-compatibility.
        Nr6r7réz9import %s as %s # PyInstaller PYZ (__path__ override: %s)zimport %s # PyInstaller PYZz# %s not found in PYZ)Ú_NamespacePathT)r;cs ˆ ||¡S)N)Ú    find_spec)Únamer'r4r r Ú<lambda>=s z-PyiFrozenImporter.find_spec.<locals>.<lambda>)r;ÚoriginÚ loader_state)ÚrsplitÚ
startswithrPÚ SYS_PREFIXLENr:rNrRÚappendrOr-r rFÚimportlib._bootstrap_externalr]Ú_frozen_importlibÚ
ModuleSpecr'Údirnamer[Úsubmodule_search_locationsr;rÚ has_location) rrDr'ÚtargetrÚmodnameÚpÚpartsr]ÚspecraÚis_pkgr r4r r^ös`
 
 
 
þ
 
 
 
 
û
 
ú zPyiFrozenImporter.find_speccCsdS)a†
        PEP-451 loader.create_module() method for the ``sys.meta_path`` hook.
 
        Loaders may also implement create_module() that will return a new module to exec. It may return None to indicate
        that the default module creation code should be used. One use case, though atypical, for create_module() is to
        provide a module that is a subclass of the builtin module type. Most loaders will not need to implement
        create_module().
 
        create_module() should properly handle the case where it is called more than once for the same spec/module. This
        may include returning None or raising ImportError.
        Nr )rrqr r r Ú create_module[szPyiFrozenImporter.create_modulecCsð|j}t|jtƒr|jj}n;t|jtƒr?|j t¡sJ‚|jt    d… 
t j d¡}|  d¡r3|dd…}|  d¡r>|dd…}n
tdt|jƒ›ƒ‚| |¡}|dur[td|j›d    ƒ‚t|d
ƒsbJ‚|jdurpt j |j¡g|_t||jƒdS) aô
        PEP-451 loader.exec_module() method for the ``sys.meta_path`` hook.
 
        Loaders will have a new method, exec_module(). Its only job is to "exec" the module and consequently populate
        the module's namespace. It is not responsible for creating or preparing the module object, nor for any cleanup
        afterward. It has no return value. exec_module() will be used during both loading and reloading.
 
        exec_module() should properly handle the case where it is called more than once. For some kinds of modules this
        may mean raising ImportError every time after the first time the method is called. This is particularly relevant
        for reloading, where some kinds of modules do not support in-place reloading.
        Nr6rZéüÿÿÿrLi÷ÿÿÿz:Module's spec contains loader_state of incompatible type: z Failed to retrieve bytecode for ú!Ú__file__)Ú__spec__Ú
isinstancerbrrr9rardrPrerQrNrRÚendswithÚ RuntimeErrorÚtyperKr_Úhasattrrkr'rjrvÚ__path__ÚexecÚ__dict__)rÚmodulerqÚ module_nameÚbytecoder r r Ú exec_modulels& 
 
 
 €
 
    zPyiFrozenImporter.exec_modulecCs
t||ƒS)zG
        Return importlib.resource-compatible resource reader.
        )ÚPyiFrozenResourceReader)rrDr r r Úget_resource_reader¥s
z%PyiFrozenImporter.get_resource_reader)NN)r!r"r#r$r Úpropertyr5r3rFr;rKrXrYr[r^rsrƒr…r r r r r%Hs $
     
e 9r%c@s@eZdZdZdd„Zdd„Zdd„Zdd    „Zd
d „Zd d „Z    dS)r„a®
    Resource reader for importlib.resources / importlib_resources support.
 
    Supports only on-disk resources, which should cover the typical use cases, i.e., the access to data files;
    PyInstaller collects data files onto filesystem, and as of v6.0.0, the embedded PYZ archive is guaranteed
    to contain only .pyc modules.
 
    When listing resources, source .py files will not be listed as they are not collected by default. Similarly,
    sub-directories that contained only .py files are not reconstructed on filesystem, so they will not be listed,
    either. If access to .py files is required for whatever reason, they need to be explicitly collected as data files
    anyway, which will place them on filesystem and make them appear as resources.
 
    For on-disk resources, we *must* return path compatible with pathlib.Path() in order to avoid copy to a temporary
    file, which might break under some circumstances, e.g., metpy with importlib_resources back-port, due to:
    https://github.com/Unidata/MetPy/blob/a3424de66a44bf3a92b0dcacf4dff82ad7b86712/src/metpy/plots/wx_symbols.py#L24-L25
    (importlib_resources tries to use 'fonts/wx_symbols.ttf' as a temporary filename suffix, which fails as it contains
    a separator).
 
    Furthermore, some packages expect files() to return either pathlib.Path or zipfile.Path, e.g.,
    https://github.com/tensorflow/datasets/blob/master/tensorflow_datasets/core/utils/resource_utils.py#L81-L97
    This makes implementation of mixed support for on-disk and embedded resources using importlib.abc.Traversable
    protocol rather difficult.
 
    So in order to maximize compatibility with unfrozen behavior, the below implementation is basically equivalent of
    importlib.readers.FileReader from python 3.10:
      https://github.com/python/cpython/blob/839d7893943782ee803536a47f1d4de160314f85/Lib/importlib/readers.py#L11
    and its underlying classes, importlib.abc.TraversableResources and importlib.abc.ResourceReader:
      https://github.com/python/cpython/blob/839d7893943782ee803536a47f1d4de160314f85/Lib/importlib/abc.py#L422
      https://github.com/python/cpython/blob/839d7893943782ee803536a47f1d4de160314f85/Lib/importlib/abc.py#L312
    cCs.ddlm}||_|tjƒj| d¡Ž|_dS)Nr)ÚPathr6)Úpathlibr‡ÚimporterrÚ_MEIPASSÚjoinpathr:r')rr‰r_r‡r r r r Ës z PyiFrozenResourceReader.__init__cCs| ¡ |¡ d¡S)NrM)Úfilesr‹rS©rÚresourcer r r Ú open_resourceÑsz%PyiFrozenResourceReader.open_resourcecCst|j |¡ƒS)N)Ústrr'r‹rr r r Ú resource_pathÔsz%PyiFrozenResourceReader.resource_pathcCs| ¡ |¡ ¡S)N)rŒr‹Úis_file)rr'r r r Ú is_resource×sz#PyiFrozenResourceReader.is_resourcecCsdd„| ¡ ¡DƒS)Ncss|]}|jVqdS)N)r_)Ú.0Úitemr r r Ú    <genexpr>Ûs€z3PyiFrozenResourceReader.contents.<locals>.<genexpr>)rŒÚiterdirr4r r r ÚcontentsÚsz PyiFrozenResourceReader.contentscCs|jS)N)r'r4r r r rŒÝszPyiFrozenResourceReader.filesN)
r!r"r#r$r rr‘r“r˜rŒr r r r r„¬s r„cCsÐtƒ}tj |¡tjD]}t|dƒr |jdkr tj |¡nq g}ttjƒD]}t|ddƒdkrAtj |¡||vrA| |¡q(tj     t|ƒ¡z|tj
d_ Wn    t y[Ynwtj dkrftƒdSdS)a
    Install PyiFrozenImporter class into the import machinery.
 
    This function installs the PyiFrozenImporter class into the import machinery of the running process. The importer
    is added to sys.meta_path. It could be added to sys.path_hooks, but sys.meta_path is processed by Python before
    looking at sys.path!
 
    The order of processing import hooks in sys.meta_path:
 
    1. built-in modules
    2. modules from the bundled ZIP archive
    3. C extension modules
    4. Modules from sys.path
    r!ÚWindowsRegistryFinderNÚ
PathFinderrH)éé )r%rÚ    meta_pathrfr|r!r)ÚreversedÚgetattrÚextendrIÚ
__loader__rBÚ version_infoÚ_fixup_frozen_stdlib)r‰r•Z path_findersr r r Úinstallás. 
 € 
€ ÿ
 
ÿr¤c    CsÖddl}tjsztjt_Wn    tyYnwtj ¡D]L\}}| |¡s&q| |¡}|j    j
}|j }|r8|d7}t j jtjg| d¡¢RŽd}t|dƒs\z||_Wn    ty[Ynw|jdurh|dkrh||_qdS)NrrLr6rZrvzimportlib._bootstrap)Ú_imprZ _stdlib_dirrŠÚAttributeErrorrIÚitemsÚ    is_frozenÚis_frozen_packagerwrbZorignamerNr'rOr:r|rvrV)r¥rr€rrrbÚ    orig_namerVr r r r£s4  ÿ
 
 
 
 ÿ€år£)r$rrNrrhr/Úpyimod01_archiverrrŠrRrPÚlenrer{Zimp_new_moduleÚflagsÚverboserr rrr%r„r¤r£r r r r Ú<module>s*
     
 f5 7