a
    .=ic&                     @   s  d Z ddlZddlZddlZddlZddlZddlmZ ddlm	Z	 ddl
mZ ddlZdZdZdZed	Zd
Zg dZdZdd ZeG dd dZG dd dZedkrejddZejdddd ejdddd ejddd  ejd!dd"d ejd#d$d%d& e ZeejZej D ]XZ!e	e!Z"e"# rle	$e"d' sle%e"&dD ]Z'e(e'e' qVne(e"e" q"e)ej* e+ej*ej,ej- dS )(a4  
Freeze Python packages.

Freezing makes it possible to ship arbitrary Python modules as part of a C++
library. The Python source of the module is compiled to bytecode and written
to `.c` files, to be imported by Python's built-in FrozenImporter.

In a normal Python installation, FrozenImporter is only used to bootstrap the
initialization of the import machinery. Python's importers are defined in
Python (see `_bootstrap.py` and `_bootstrap_external.py`) but need to be
retrieved before any importers are available. Freezing the module bytecode
resolves this circular dependency.

This script will freeze the Python standard library. It produces two things:
- Bytecode files: A set of `.c` that define C variables containing Python bytecode.
- Main file: A `main.c` file listing all of these modules in the right form to be
  consumed by FrozenImporter.

The library that wishes to these modules make them available to the local
Python instance by extending `PyImport_FrozenModules` appropriately (see
https://docs.python.org/3/c-api/import.html#c.PyImport_FrozenModules).
    N)	dataclass)Path)Listz<Generated by torch::deploy>z#include <Python.h>

z
// Compiled standard library modules. These should be appended to the existing
// `PyImport_FrozenModules` that ships with CPython.
struct _frozen {}[] = {{
Z_PyImport_FrozenModulesz     {0, 0, 0} /* sentinel */
};
)
dbmZcursestkinterr   testtestsZ	idle_testz__phello__.foo.pyz_bootstrap.pyz_bootstrap_external.py   c                    s   t   fdd}|S )Nc                     s6   | d  j d7  _  | i |}| d  j d8  _ |S )Nr      )indent)argskwargsretfn d/home/droni/.local/share/virtualenvs/DPS-5Je3_V2c/lib/python3.9/site-packages/torch/utils/_freeze.pywrapperN   s    zindent_msg.<locals>.wrapper)	functoolswraps)r   r   r   r   r   
indent_msgM   s    r   c                   @   s.   e Zd ZU eed< eed< eed< eed< dS )FrozenModulemodule_namec_namesizebytecodeN)__name__
__module____qualname__str__annotations__intbytesr   r   r   r   r   X   s   
r   c                   @   s   e Zd ZedddZeedddZdd Zd	d
 Z	e
dddZeedddZeeedddZeeee dddZeejdddZeeedddZdS )Freezer)verbosec                 C   s   g | _ d| _|| _d S )Nr   )frozen_modulesr   r$   )selfr$   r   r   r   __init__e   s    zFreezer.__init__)pathcodec                 C   s<   | j s
d S t| jD ]}tddd qt| d|  d S )Nz     )end )r$   ranger   print)r&   r(   r)   ir   r   r   msgj   s
    zFreezer.msgc                    s`   dd t tD } fdd|D }t|}| jD ]}| |t| q4|D ]}|  qNdS )z|
        Write the `.c` files containing the frozen bytecode. Shard frozen
        modules evenly across the files.
        c                 S   s   g | ]}d | dqS )Z	bytecode_z.cr   ).0r/   r   r   r   
<listcomp>{   s   z*Freezer.write_bytecode.<locals>.<listcomp>c                    s    g | ]}t tj |d qS )w)openosr(   join)r1   nameinstall_rootr   r   r2   ~       N)r-   NUM_BYTECODE_FILES	itertoolscycler%   write_frozennextclose)r&   r9   Zbytecode_file_namesZbytecode_filesitmfr   r8   r   write_bytecodev   s    

zFreezer.write_bytecodec                 C   s   t tj|dd}|t | jD ]}|d|j d q&|t	| | jD ](}|d|j
 d|j d|j d qV|t |r|t |t W d	   n1 s0    Y  d	S )
zh
        Write the `main.c` file containing a table enumerating all the
        frozen modules.
        zmain.cr3   zextern unsigned char z[];
z	{"z", z, z},
N)r4   r5   r(   r6   writeMAIN_INCLUDESr%   r   MAIN_PREFIX_TEMPLATEformatr   r   MAIN_SUFFIXFAKE_PREFIX)r&   r9   osssymbol_nameoutfprB   r   r   r   
write_main   s    


&

zFreezer.write_main)rB   c                 C   sn   | d|j d tdt|jdD ]8}| d t|j||d  D ]}| d|  qJq&| d dS )	zN
        Write a single frozen module's bytecode out to a C variable.
        zunsigned char z[] = {r      z
	z%d,z
};
N)rE   r   r-   lenr   r"   )r&   rB   rM   r/   cr   r   r   r>      s    
zFreezer.write_frozen)r(   top_package_pathc                 C   s&   |  r| || n| || dS )z0Generic entry point for compiling a Path object.N)is_dircompile_packagecompile_file)r&   r(   rR   r   r   r   compile_path   s    zFreezer.compile_pathc                 C   sz   |  sJ |jtv r&| |d dS tdd | D }|sP| |d dS | |d | D ]}| || qddS )z2Compile all the files within a Python package dir.XNc                 S   s   g | ]}|j d kqS )__init__.py)r7   )r1   childr   r   r   r2      r:   z+Freezer.compile_package.<locals>.<listcomp>SP)rS   r7   	DENY_LISTr0   anyiterdirrV   )r&   r(   rR   Zis_package_dirrY   r   r   r   rT      s    
zFreezer.compile_package)	file_pathrR   returnc                 C   sF   | |j}|jdkr*|jj}|jjj}n|j}|jj}t||g S )NrX   )relative_toparentr7   partsstemlist)r&   r_   rR   normalized_pathZmodule_basenameZmodule_parentr   r   r   get_module_qualname   s    
zFreezer.get_module_qualname)file_contentr`   c                 C   s   t }t||dS )Nexec)PATH_MARKERcompile)r&   rh   Zpath_markerr   r   r   compile_string   s    zFreezer.compile_stringc           
      C   s   |  sJ |jdkr&| |d dS |jtv r@| |d dS | |d | ||}d|}d| }t|d}| |	 }W d   n1 s0    Y  t
|}t|}	|jd	kr|	 }	| jtd
|||	| dS )zv
        Compile a Python source file to frozen bytecode. Append the result to
        `self.frozen_modules`.
        z.pyNNrW   F__ZM_rrX   .)is_filesuffixr0   r7   r\   rg   r6   r4   rl   readmarshaldumpsrP   r%   appendr   )
r&   r(   rR   Zmodule_qualnameZmodule_mangled_namer   Zsrc_filecor   r   r   r   r   rU      s(    


,

zFreezer.compile_fileN)r   r   r   boolr'   r   r   r0   rD   rN   r   r>   rV   r   rT   r   rg   typesCodeTyperl   rU   r   r   r   r   r#   d   s   
r#   __main__zCompile py source)descriptionpaths*zPaths to freeze.)nargshelpz	--verbose
store_truezPrint debug logs)actionr   z--install_dirz#Root directory for all output files)r   z--ossz5If it's OSS build, add a fake _PyImport_FrozenModulesz--symbol_namez6The name of the frozen module array symbol to generateZ_PyImport_FrozenModules_torch)r   defaultrX   ).__doc__argparser   r<   ru   r5   dataclassesr   pathlibr   typingr   rz   rj   rF   rG   rH   rJ   rI   r\   r;   r   r   r#   r   ArgumentParserparseradd_argument
parse_argsr   r$   rC   r~   pr(   rS   existssortedglobmodrV   rD   Zinstall_dirrN   rK   rL   r   r   r   r   <module>   sT   
 


