U
    e*                     @   s   d dl mZ ddlmZmZ ddlmZ ddlmZ ddlm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 )    )absolute_import   )parse_from_stringsStringParseContext)Symtab)Naming)Codec                       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-7k3cqui1/Cython/Compiler/UtilityCode.pyr      s    zNonManglingModuleScope.__init__c                    s   d|_ tt| |||S )NT)usedsuperr	   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_fallbackZ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                   @   sl   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dddZdddZedd Zd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
PyrexTypesr-   items
isinstancer   Zsub_tempitaimplr   filer   requires
from_scopeouter_module_scopecompiler_directivescontext_types)r   r0   r   r   r2   r1   r3   r$   r5   r4   r6   r-   keyvaluer   r   r   r   F   s"    	


zCythonUtilityCode.__init__c                 C   s"   t |tr|  | kS dS d S )NF)r/   r*   _equality_params)r   otherr   r   r   __eq__a   s    
zCythonUtilityCode.__eq__c                 C   s&   | j }t|tr|j}q| j|| jfS N)r4   r/   r	   outer_scoper0   r5   )r   r=   r   r   r   r9   g   s    
z"CythonUtilityCode._equality_paramsc                 C   s
   t | jS r<   )hashr0   r   r   r   r   __hash__m   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)r5   r
   T)r$   Zallow_struct_enum_decoratorZ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(   rI   r   rH   r   merge_scope   s    z/CythonUtilityCode.get_tree.<locals>.merge_scopetreec                    s    j | j_| S r<   )r4   r(   r=   rF   r?   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)objectr6   r.   getattrr(   Zdeclare_typer   Zin_cinclude)rG   Zdummy_entryr   typeZold_type_entryr   r?   r   r   rL      s    )Z	printtree)ZAnalysedTreeTransformsrA   r,   rB   rC   r"   r   r5   Zis_cppr   r   r   r0   Zcreate_pipelineappendr/   ZAnalyseDeclarationsTransformZCnameDirectivesTransformZInterpretCompilerDirectivesZinsert_into_pipeliner3   r2   r*   hasattrrK   r(   r4   r6   Zrun_pipeliner%   )r   entries_onlyr   rA   ZexcludesrB   rC   r$   rK   ZpipelineptZ	transformrD   rJ   deprL   errr   r?   r   get_treep   s|        

 
 
  zCythonUtilityCode.get_treec                 C   s   d S r<   r   )r   outputr   r   r   put_code   s    zCythonUtilityCode.put_codec                 K   s   | j ||f|}|j|jfS )zR
        Load a utility code as a string. Returns (proto, implementation)
        )loadprotor0   )clsZutil_code_name	from_filekwargs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)rS   r   r   __file____builtins____doc__)Zmerge_unused	allowlist)r   )rX   r(   entriesr   valuesZutility_code_definitionr   rE   r2   is_cython_utilitydeclare_in_scope)
r   Z
dest_scoper   r   re   rK   rf   r   Zoriginal_scoperV   r   r   r   ri      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)Optionsrj   dict)Zcurrent_directivesrj   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    rd   rh   r   r;   r9   r@   rX   rZ   classmethodra   ri   staticmethodrm   r   r   r   r   r*   3   s*            

V  
r*   Tc                 O   s   t | f||| dS )z`
    Declare some declarations given as Cython code in declaration_string
    in scope env.
    N)r*   ri   )Zdeclaration_stringenvZprivate_typer   r_   r   r   r   declare_declarations_in_scope  s    rq   N)T)
__future__r   ZTreeFragmentr   r   r,   r   r   r   r   r	   r"   ZUtilityCodeBaser*   rq   r   r   r   r   <module>   s    R