U
    {h7                     @   s   d dl Z ddlmZmZ ddlmZ ddlmZ ddlm	Z	 ddlm
Z
 ddlmZ dd	lmZ d dlZd dlZd dlZG d
d de	jZG dd deZG dd dejZG dd deZG dd dejZdddZdS )    N   )parse_from_stringsStringParseContext)FileSourceDescriptor)CompileError)Symtab)Naming)Code)Optionsc                       s.   e Zd Zdd Z fddZdddZ  ZS )	NonManglingModuleScopec                 O   s2   || _ d | _|dd| _tjj| f|| d S )NcppF)prefixcython_scopepopr   r   ModuleScope__init__)selfr   argskw r   ?/tmp/pip-unpacked-wheel-fhl22ezh/Cython/Compiler/UtilityCode.pyr      s    zNonManglingModuleScope.__init__c                    s   d|_ t |||S )NT)usedsuperadd_imported_entry)r   nameentrypos	__class__r   r   r      s    z)NonManglingModuleScope.add_imported_entryNc                 C   s@   |r.|t jt jt jt jfkr"| j}d||f S tj| |S d S )Nz%s%s)	r   Ztypeobj_prefixZfunc_prefixZ
var_prefixZpyfunc_prefixr   r   r   mangle)r   r   r   r   r   r   r      s
    zNonManglingModuleScope.mangle)N)__name__
__module____qualname__r   r   r   __classcell__r   r   r   r   r      s   r   c                   @   s   e Zd ZdZdddZdS )CythonUtilityCodeContextNTFc                 C   s\   |rt d|| jkr4|| jkr*t dn
| j| S | jd krVt| j|d | | jd| _| jS )Nz/Relative imports not supported in utility code.z%Only the cython cimport is supported.)parent_modulecontextr   )AssertionErrormodule_namemodulesscoper   r   r   )r   r(   Zfrom_moduler   Zneed_pxdZabsolute_fallbackrelative_importr   r   r   find_module)   s    




    z$CythonUtilityCodeContext.find_module)NNTTF)r    r!   r"   r*   r,   r   r   r   r   r$   &   s   r$   c                       s   e Zd ZdZdZdddZdd	 Zd
d Zdd ZdddZ	dd Z
e fddZedddZdddZedd Z  ZS )CythonUtilityCodeaR  
    Utility code written in the Cython language itself.

    The @cname decorator can set the cname for a function, method of cdef class.
    Functions decorated with @cname('c_func_name') get the given cname.

    For cdef classes the rules are as follows:
        obj struct      -> <cname>_obj
        obj type ptr    -> <cname>_type
        methods         -> <class_cname>_<method_cname>

    For methods the cname decorator is optional, but without the decorator the
    methods will not be prototyped. See Cython.Compiler.CythonScope and
    tests/run/cythonscope.pyx for examples.
    T	__pyxutil Nc
                 C   s   i }
|d k	rTddl m} | D ]"\}}t||r |||< ||
|< q t||||}|| _|| _|| _|| _	|prg | _
|| _|	| _|| _|
| _d S )Nr   )BaseType)Z
PyrexTypesr0   items
isinstancer	   sub_tempitaimplr   filer   requires
from_scopeouter_module_scopecompiler_directivescontext_types)r   r4   r   r   r6   r5   r7   r&   r9   r8   r:   r0   keyvaluer   r   r   r   L   s"    	


zCythonUtilityCode.__init__c                 C   s"   t |tr|  | kS dS d S )NF)r2   r-   _equality_params)r   otherr   r   r   __eq__g   s    
zCythonUtilityCode.__eq__c                 C   s&   | j }t|tr|j}q| j|| jfS N)r8   r2   r   outer_scoper4   r9   )r   rA   r   r   r   r=   m   s    
z"CythonUtilityCode._equality_paramsc                 C   s
   t | jS r@   )hashr4   r   r   r   r   __hash__s   s    zCythonUtilityCode.__hash__Fc                    s  ddl m} |g}ddlm}m} t j j|r8| ndd} j	|_	||_
t j j|ddd}|j|d|d	}	|rg }
|	D ]}|
| t||jr qq|
}	||}|j}|j|	||d
}	dd } jr|j|	| j|jd
}	 jD ]6}t|trt|dr|s|j|	||jj|jd
}	q jrN fdd}|j|	||jd
}	 jrt fdd}|j|	||jd
}	|j|	|dd\}}|rt|| _|S )Nr   )AutoTestDictTransform)PipelineParseTreeTransformsF)r9   r   T)r&   Zallow_struct_enum_decoratorin_utility_codeZpyx)Zexclude_classes)beforec                    s    fdd}|S )Nc                    s   | j   | S r@   )r*   merge_inmodule_noder*   r   r   merge_scope_transform   s    zNCythonUtilityCode.get_tree.<locals>.merge_scope.<locals>.merge_scope_transformr   )r*   rN   r   rM   r   merge_scope   s    z/CythonUtilityCode.get_tree.<locals>.merge_scopetreec                    s    j | j_| S r@   )r8   r*   rA   rK   rC   r   r   scope_transform   s    
z3CythonUtilityCode.get_tree.<locals>.scope_transformc                    sR   t  } j D ]<\}}t|d|}| jj||d dd}||k	rF||_d|_q| S )Nr   extern)Z
visibilityT)objectr:   r1   getattrr*   Zdeclare_typer   Zin_cinclude)rL   Zdummy_entryr   typeZold_type_entryr   rC   r   r   rQ      s    )Z	printtree)ZAnalysedTreeTransformsrE   r/   rF   rG   r$   r   r9   Zis_cppr   r   r   r4   Zcreate_pipelineappendr2   ZAnalyseDeclarationsTransformZCnameDirectivesTransformZInterpretCompilerDirectivesZinsert_into_pipeliner7   r6   r-   hasattrrP   r*   r8   r:   Zrun_pipeliner'   )r   entries_onlyr   rE   ZexcludesrF   rG   r&   rP   ZpipelineptZ	transformrI   rO   deprQ   errr   rC   r   get_treev   s|        

 
 
  zCythonUtilityCode.get_treec                 C   s   d S r@   r   )r   outputr   r   r   put_code   s    zCythonUtilityCode.put_codec                    s,   t d|rtj||S t j||f|S )Nz[.]c(pp)?::)researchr	   ZUtilityCodeZload_cachedr   load)clsutil_code_name	from_filekwargsr   r   r   rb      s    zCythonUtilityCode.loadc                 K   s   | j ||f|}|j|jfS )zR
        Load a utility code as a string. Returns (proto, implementation)
        )rb   protor4   )rc   rd   re   rf   utilr   r   r   load_as_string   s    z CythonUtilityCode.load_as_stringc           
      C   s   | j d|d}|jj}|d |d |d |d | D ]}| |_||_qF|j}|j|d|d ||_| jD ]}	|	j	rz|	j
||d qz|S )	z
        Declare all entries from the utility code in dest_scope. Code will only
        be included for used entries. If module_name is given, declare the
        type entries with that name.
        T)rX   r   r    __file____builtins____doc__)Zmerge_unused	allowlistr   )r]   r*   entriesr   valuesZutility_code_definitionr   rJ   r6   is_cython_utilitydeclare_in_scope)
r   
dest_scoper   r   rm   rP   ro   r   Zoriginal_scoper[   r   r   r   rr      s     




z"CythonUtilityCode.declare_in_scopec                 C   s:   ddl m} t|}d}|D ]}|| kr| | ||< q|S )a   
        Cython utility code should usually only pick up a few directives from the
        environment (those that intentionally control its function) and ignore most
        other compiler directives. This function provides a sensible default list
        of directives to copy.
        r   )_directive_defaults)ZbindingZalways_allow_keywordsZallow_none_for_extension_argsZauto_pickleZccomplexZc_string_typeZc_string_encodingzoptimize.inline_defnode_callszoptimize.unpack_method_callsz&optimize.unpack_method_calls_in_pyinitzoptimize.use_switch)r
   rt   dict)Zcurrent_directivesrt   Zutility_code_directivesZinherited_directive_namesr   r   r   r   filter_inherited_directives   s    z-CythonUtilityCode.filter_inherited_directives)r.   r/   NNNNNN)FN)N)FNN)r    r!   r"   rl   rq   r   r?   r=   rD   r]   r_   classmethodrb   ri   rr   staticmethodrv   r#   r   r   r   r   r-   9   s.            

V  
r-   c                       s*   e Zd Z fddZd fdd	Z  ZS )TemplatedFileSourceDescriptorc                    s   t  || || _d S r@   )r   r   _context)r   filenameZpath_descriptionr&   r   r   r   r     s    z&TemplatedFileSourceDescriptor.__init__Nc              	      sX   t  ||@}| }t|| j| j}tjt	|
|j|j|d}W 5 Q R X |S )N)encodingerrors)r   get_file_objectreadr	   r3   rz   r{   ioTextIOWrapperBytesIOencoder|   )r   r|   Zerror_handlingfdataretstreamr   r   r   r~     s
    *z-TemplatedFileSourceDescriptor.get_file_object)NN)r    r!   r"   r   r~   r#   r   r   r   r   ry     s   ry   c                   @   s.   e Zd Zdd Zdd ZdddZd	d
 ZdS )CythonSharedUtilityCodec                 C   s"   || _ || _|| _|| _d | _d S r@   )	_pxd_name_shared_utility_qualified_nametemplate_contextr6   _shared_library_scope)r   Zpxd_nameZshared_utility_qualified_namer   r6   r   r   r   r   "  s
    z CythonSharedUtilityCode.__init__c                 C   s   |}|j | jddD ]\}}|j||d}qtjtjtjd d| j	}zr| j
dtjtj|d  }t||| j}d|_|||| j\}}	|	\}
}|
|f|j| j	< d|_|r|W n tk
r   Y nX |S )	NF)r+   )Z
as_packager   ZUtility.r   T)Z_split_qualified_namer   Zfind_submoduleospathjoinsplitCythonrj   r   replacesepsplitextry   r   rH   Zprocess_pxdutility_pxdsZpxd_file_loadedr   )r   r&   r*   r   
is_packageZpxd_pathnamerel_pathZsource_descr\   resultZpxd_codenodesZ	pxd_scoper   r   r   r,   )  s*     z#CythonSharedUtilityCode.find_moduleFNc                 C   s`   | j |jjkr| |j| _| jD ]}|jr"|jt|d q"| jj	D ]}|
|j||j qD|S )Nrn   )r   r&   r   r,   r   r6   rq   rr   r*   Zc_class_entriesr   r   r   )r   rs   r   r   rm   r[   er   r   r   rr   A  s    
z(CythonSharedUtilityCode.declare_in_scopec                 C   s"   | j |jjkr| |j| _| jS r@   )r   r&   r   r,   r   )r   r   r   r   r   get_shared_library_scopeL  s    z0CythonSharedUtilityCode.get_shared_library_scope)FNN)r    r!   r"   r   r,   rr   r   r   r   r   r   r   !  s     
r   Tc                 O   s   t | f||| dS )z`
    Declare some declarations given as Cython code in declaration_string
    in scope env.
    N)r-   rr   )Zdeclaration_stringenvZprivate_typer   rf   r   r   r   declare_declarations_in_scopeR  s    r   )T)r   ZTreeFragmentr   r   ZScanningr   ZErrorsr   r/   r   r   r	   r
   os.pathr   r`   r   r   r   r$   ZUtilityCodeBaser-   ry   ZAbstractUtilityCoder   r   r   r   r   r   <module>   s"    Z1