projet crepp_git/crepp-projects/feutrage-de-laine · branche main
pyimod02_importers.pyc Voir sur GitLab
o

�@s�dZddlZddlZddlZddlZddlZddlZddlmZm	Z	ej
ejZe
e�Zee�Zejjr<ejr<dd�Zndd�ZGdd�d�Zd	d
�ZGdd�d�ZGd
d�d�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)Nrrrrrr
,sc@s eZdZdZdd�Zdd�ZdS)�FrozenPackageImporteraW
    Wrapper class for FrozenImporter that imports one specific fullname from a module named by an alternate fullname.
    The alternate fullname is derived from the __path__ of the package module containing that module.

    This is called by FrozenImporter.find_module whenever a module is found as a result of searching module.__path__
    cCs||_||_dS)N)�_entry_name�	_importer)�self�importer�
entry_namerrr�__init__7s
zFrozenPackageImporter.__init__cCs|j�||j�S)N)r�load_moduler�r�fullnamerrrr;sz!FrozenPackageImporter.load_moduleN)�__name__�
__module__�__qualname__�__doc__rrrrrrr0srcCs8t�|�j}t�|�}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
    NT)�decoder�	translater)�io�BytesIO�readline�tokenize�detect_encoding�IncrementalNewlineDecoder�decode)�source_bytes�source_bytes_readline�encoding�newline_decoderrrr�_decode_source@s
r)c@s~eZdZdZdd�Zdd�Zddd�Zdd	d
�Zdd�Zd
d�Z	dd�Z
dd�Zdd�Zddd�Z
dd�Zdd�Zdd�ZdS)�FrozenImportera�
    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 is 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(). Both these methods are implemented in one class.

    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(9 and (optionally) create_module().
    All these methods are implemented in this one class.

    To use this class just call:
        FrozenImporter.install()
    c	CsptjD]0}zt|�|_tj�|�t|jj���|_td|�WdSt	y+Yqt
y3Yqwtd��)zY
        Load, unzip and initialize the Zip archive bundled with the executable.
        z!# PyInstaller: FrozenImporter(%s)NzCannot load frozen modules.)r�pathr�_pyz_archive�remove�set�toc�keysr
�IOErrorr�ImportError)r�pyz_filepathrrrras


�zFrozenImporter.__init__c
C�L||jvr z|j�|�WSty}ztd|�|�d}~wwtd|��)N�+Loader FrozenImporter cannot handle module )r/r,�is_pep420_namespace_package�	Exceptionr2�rr�errr�_is_pep420_namespace_package��
��z+FrozenImporter._is_pep420_namespace_packageNcCs�d}||jvr|}td|�nL|dur[|�d�d}|D]>}|�t�s$q|td�}|�tj�}|s3q|ds=|dd�}|�|�d�	|�}||jvrZt
||�}td|||�nq|durdtd|�|S)	a�
        PEP-302 finder.find_module() 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.

        Return a loader object if the module was found, or None if it was not. If find_module() raises an exception,
        it will be propagated to the caller, aborting the import.
        N�import %s # PyInstaller PYZ�.���r��9import %s as %s # PyInstaller PYZ (__path__ override: %s)�# %s not found in PYZ)r/r
�split�
startswith�
SYS_PREFIX�
SYS_PREFIXLEN�os�sep�append�joinr)rrr+�
module_loader�modname�p�partsrrrr�find_module�s2





�
zFrozenImporter.find_modulecCs�d}|dur|}zXtj�|�}|dur^|j�|�\}}t|�}|�|�|_|r0tj	�
|j�g|_||_|r9||_
n	|�dd�d|_
tj|||d�|_|tj|<t||j�tj|}W|SW|Stys|tjvrrtj�|��w)a�
        PEP-302 loader.load_module() method for the ``sys.meta_path`` hook.

        Return the loaded module (instance of imp_new_module()) or raise an exception, preferably ImportError if an
        existing exception is not being propagated.

        When called from FrozenPackageImporter, `entry_name` is the name of the module as it is stored in the archive.
        This module will be loaded and installed into sys.modules using `fullname` as its name.
        Nr=r?r��
is_package)r�modules�getr,�extract�imp_new_module�get_filename�__file__rFr+�dirname�__path__�
__loader__�__package__�rsplit�_frozen_importlib�
ModuleSpec�__spec__�exec�__dict__r7�pop)rrr�module�is_pkg�bytecoderrrr�s6
�C�
�zFrozenImporter.load_modulec
Cr4)Nr5)r/r,rPr7r2r8rrrrPr;zFrozenImporter.is_packagec
CsPz|dkrtjdjWS|j�|�dWSty'}ztd|�|�d}~ww)z|
        Get the code object associated with the module.

        ImportError should be raised if module not found.
        �__main__r?r5N)rrQ�_pyi_main_cor,rSr7r2r8rrr�get_codes��zFrozenImporter.get_codecCs�||jvrE|�|�r|d7}tj�t|�dtj�d�}zt|d��}|�	�}Wd�n1s1wYt
|�WStyDYdSwt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.
        z	.__init__r=z.py�rbNzNo module named )
r/rPrFr+rIrD�replacerG�open�readr)�FileNotFoundErrorr2)rr�filename�fpr%rrr�
get_source.s


�
�zFrozenImporter.get_sourcecCsj|�t�sJ�|td�}||jvr|j�|�dSt|d��}|��Wd�S1s.wYdS)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.

        This method is useful for getting resources with 'pkg_resources' that are bundled with Python modules in the
        PYZ archive.

        The 'path' argument is a path that can be constructed by munging module.__file__ (or pkg.__path__ items).
        Nr?rh)rCrDrEr/r,rSrjrk)rr+rrnrrr�get_dataFs

$�zFrozenImporter.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.
        r=z__init__.pycz.pyc)rPrFr+rIrDrirG)rrrmrrrrU[s

	�zFrozenImporter.get_filenamecCsLd}|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�tj
|dd	d
�}tj�|�|��g|_|S|�|�}	|�|�}
tj
|||
|	|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.
        Nr=r>rr?r@r<rATrO)rP�origin�loader_state)r[rCrDrErBrFrGrHrIr/r
r:r\r]r+rWrU�submodule_search_locationsrP�has_location)rrr+�targetrrKrLrM�specrqrcrrr�	find_specjsV



�





�
zFrozenImporter.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)rrvrrr�
create_module�szFrozenImporter.create_modulecCsL|j}|�|j�}t|d�sJ�|jdurtj�|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.
        rVN)r^rgrr�hasattrrsrFr+rWrVrXr_r`)rrbrvrdrrr�exec_module�s
	zFrozenImporter.exec_modulecCs
t||�S)zG
        Return importlib.resource-compatible resource reader.
        )�FrozenResourceReaderrrrr�get_resource_reader�s
z"FrozenImporter.get_resource_reader)N)NN)rrrrrr:rNrrPrgrorprUrwrxrzr|rrrrr*Ls"
	
+\	
Z r*c@s@eZdZdZdd�Zdd�Zdd�Zdd	�Zd
d�Zdd
�Z	dS)r{ag	
    Resource reader for importlib.resources / importlib_resources support.

    Currently supports only on-disk resources (support for resources from the embedded archive is missing).
    However, this should cover the typical use cases (access to data files), as PyInstaller collects data files onto
    filesystem, and only .pyc modules are collected into embedded archive. One exception are resources collected from
    zipped eggs (which end up collected into embedded archive), but those should be rare anyway.

    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$||_t�tj�j|�d��|_dS)Nr=)r�pathlib�Pathr�_MEIPASS�joinpathrBr+)rr�namerrrrszFrozenResourceReader.__init__cCs|���|��d�S)Nrh)�filesr�rj�r�resourcerrr�
open_resource sz"FrozenResourceReader.open_resourcecCst|j�|��S)N)�strr+r�r�rrr�
resource_path#sz"FrozenResourceReader.resource_pathcCs|���|���S)N)r�r��is_file)rr+rrr�is_resource&sz FrozenResourceReader.is_resourcecCsdd�|����D�S)Ncss�|]}|jVqdS)N)r�)�.0�itemrrr�	<genexpr>*s�z0FrozenResourceReader.contents.<locals>.<genexpr>)r��iterdir�rrrr�contents)szFrozenResourceReader.contentscCs|jS)N)r+r�rrrr�,szFrozenResourceReader.filesN)
rrrrrr�r�r�r�r�rrrr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_WdSty]YdSw)a

    Install FrozenImporter class and other classes into the import machinery.

    This function installs the FrozenImporter 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�
PathFinderre)
r*r�	meta_pathrHryrr-�reversed�getattr�extendrQrYr7)�fimpr��pathFindersrrr�install0s(
�
��r�)rrrFr}rr!r\�pyimod01_archiverrrrGrD�lenrE�typerT�flags�verboserr
rr)r*r{r�rrrr�<module>s,
	
34