U
    ccʮ                     @   s  d Z ddlm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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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mZ ddlmZ ddl m!Z! ddl m"Z" ddlm#Z# dd Z$dd Z%d@d d!Z&d"d# Z'd$d% Z(d&d' Z)e*d(d)d* Z+d+d, Z,G d-d. d.e-Z.G d/d0 d0e.Z/G d1d2 d2e.Z0e*d(d3d4 Z1G d5d6 d6e0Z2d7d8 Z3d9d: Z4d;d< Z5d=e5_6d>d? Z7dS )Az(Internal implementation for declarative.    )absolute_importN)
attributes)instrumentation   )clsregistry)exc)mapper)InstrumentedAttribute)QueryableAttribute)_is_mapped_class)InspectionAttr)CompositeProperty)SynonymProperty)MapperProperty)Mapper)ColumnProperty)class_mapper   )event)util)
expression)Column)Table)topologicalc                 C   s0   t | rt | S t| r(t| ddS d S d S )NF)	configure)_DeferredMapperConfighas_clsconfig_for_clsr   r   cls r    </tmp/pip-unpacked-wheel-8u86ls_i/sqlalchemy/orm/decl_base.py_declared_mapping_info%   s
    

r"   c                 C   s\   | t krd S | jddrB| jD ]}t|}|d k	r |  S q d S t| }|rT|jS | S d S )N__abstract__F)object__dict__get	__bases__"_resolve_for_abstract_or_classical_dive_for_cls_managerclass_)r   supZ
clsmanagerr    r    r!   r(   0   s    

r(   Fc                 C   s   |dkst t| tsdS || jkr.t| |S | jdd D ]@}t|}||jkr<|| ksn|rj|| jkr<n |s<t||  S q<dS )a  return an attribute of the class that is either present directly
    on the class, e.g. not on a superclass, or is from a superclass but
    this superclass is a non-mapped mixin, that is, not a descendant of
    the declarative base and is also not classically mapped.

    This is used to detect attributes that indicate something about
    a mapped class independently from any mapped classes that it may
    inherit from.

    r#   Nr   T)AssertionError
issubclassr$   r%   getattr__mro__r)   r'   )r   attrnamestrictbaseZ_is_classicial_inheritsr    r    r!   _get_immediate_cls_attrD   s(    



  r3   c                 C   s4   t | dsd S | jD ]}t|}|r|  S qd S )Nr/   )hasattrr/   r   manager_of_class)r   r2   managerr    r    r!   r)   i   s    



r)   c                 C   s   t | ||d i S N)_MapperConfigsetup_mapping)registryr   dict_r    r    r!   _as_declarativey   s    r<   c                 C   s   t | ||| |jS r7   )_ImperativeMapperConfig
__mapper__)r:   r   table	mapper_kwr    r    r!   _mapper   s    rA   zsqlalchemy.orm.decl_apic                 C   s   t jjj}t| |t jfS r7   )r   	preloadedorm_decl_apideclared_attr
isinstanceZclassproperty)objrD   r    r    r!   _is_declarative_props   s    
rG   c                 C   s2   t | r*t| ddr&td||f  dS dS d S )N
_cascadingFz~@declared_attr.cascading is not supported on the %s attribute on class %s.  This attribute invokes for subclasses in any case.T)rG   r.   r   warn)rF   namer   r    r    r!   _check_declared_props_nocascade   s    rK   c                   @   s4   e Zd ZdZedd Zdd Zdd Zdd	 Zd
S )r8   )r   	classname
propertiesdeclared_attr_reg__weakref__c           	      C   sn   t | }|r&|j|kr&td|  |jddr8d S t|dddpNt|d}|rZt	}nt
}||||||S )Nz4Class %r already has been instrumented declarativelyr#   F_sa_decl_prepare_nocascadeTr1   Z_sa_decl_prepare)r   r5   r*   r   InvalidRequestErrorr%   r&   r3   r4   r   _ClassScanMapperConfig)	r   r:   cls_r;   r?   r@   r6   Z	defer_mapZcfg_clsr    r    r!   r9      s$    
  z_MapperConfig.setup_mappingc                 C   sx   t |td| _|j| _t  | _i | _|	ddsNt
j| jd|| |jd n&t| j}|rd|jsttd| j d S )NrT   non_primaryF)finalizer:   Zdeclarative_scanZinit_methodztClass %s has no primary mapper configured.  Configure a primary mapper first before setting up a non primary Mapper.)r   Zassert_arg_typetyper   __name__rL   OrderedDictrM   rN   r&   r   Zregister_classconstructorr   r5   Z	is_mappedr   rR   )selfr:   rT   r@   r6   r    r    r!   __init__   s&    

z_MapperConfig.__init__c                 C   s   t | j}||| |S r7   )r   r5   r   Zinstall_member)r[   r0   valuer6   r    r    r!   set_cls_attribute   s    z_MapperConfig.set_cls_attributec                 C   s   |  | d S r7   )mapr[   r@   r    r    r!   _early_mapping   s    z_MapperConfig._early_mappingN)	rX   
__module____qualname__	__slots__classmethodr9   r\   r^   ra   r    r    r    r!   r8      s   
r8   c                       s6   e Zd ZdZ fddZejfddZdd Z  Z	S )r=   )r;   local_tableinheritsc              	      sr   t t| ||| i | _| d|| _tj: |ddsPt	
| j| j|j | | | | W 5 Q R X d S )N	__table__rU   F)superr=   r\   r;   r^   rf   	mapperlib_CONFIGURE_MUTEXr&   r   	add_classrL   r   _class_registry_setup_inheritancera   )r[   r:   rT   r?   r@   	__class__r    r!   r\      s     
    
z _ImperativeMapperConfig.__init__c                 C   s   t }| d|| j| jf|S )Nr>   )r   r^   r   rf   r[   r@   Z
mapper_clsr    r    r!   r_      s
    z_ImperativeMapperConfig.mapc                 C   s   | j }|dd }|d krg }|jD ]:}t|}|d kr:q$t|d k	r$t|ddds$|| q$|rt|dkrt	d||f |d }nt
|tr|j}|| _d S )Nrg   rP   TrQ   r   &Class %s has multiple mapped bases: %rr   )r   r&   r'   r(   r"   r3   appendlenr   rR   rE   r   r*   rg   )r[   r@   r   rg   inherits_searchcr    r    r!   rn      s>    
  

z*_ImperativeMapperConfig._setup_inheritance)
rX   rb   rc   rd   r\   r   
EMPTY_DICTr_   rn   __classcell__r    r    ro   r!   r=      s   r=   c                       s   e Zd ZdZ fddZdd Zdd Zdd	 Zd
d Zdd Z	dd Z
dd Zdd ZdddZdd Zdd Zdd ZejfddZ  ZS ) rS   )
r;   rf   persist_selectabledeclared_columnscolumn_copies
table_args	tablenamemapper_argsmapper_args_fnrg   c              	      s   |rt |ni | _tt| ||| d | _t | _i | _| 	  | 
  tjH t| j| j|j |   |   | | | | | | W 5 Q R X d S r7   )dictr;   ri   rS   r\   ry   setrz   r{   _setup_declared_events_scan_attributesrj   rk   r   rl   rL   r   rm   _extract_mappable_attributes_extract_declared_columns_setup_tablern   ra   )r[   r:   rT   r;   r?   r@   ro   r    r!   r\   ,  s$      

z_ClassScanMapperConfig.__init__c                    sL   t  jdr$ttd fdd}t  jdrHttd fdd}d S )	N__declare_last__after_configuredc                      s    j   d S r7   )r   r   r    r[   r    r!   r   T  s    zG_ClassScanMapperConfig._setup_declared_events.<locals>.after_configured__declare_first__before_configuredc                      s    j   d S r7   )r   r   r    r   r    r!   r   Z  s    zH_ClassScanMapperConfig._setup_declared_events.<locals>.before_configured)r3   r   r   Zlistens_forr   )r[   r   r   r    r   r!   r   Q  s    

z-_ClassScanMapperConfig._setup_declared_eventsc                    sn   t dddkr"fdd}nHfddtD fddtD t   fdd}|S )	zProduce a function that checks if a class has overridden an
        attribute, taking SQLAlchemy-enabled dataclass fields into account.

        __sa_dataclass_metadata_key__Nc                    s   t  | |k	S r7   )r.   )keyrF   r   r    r!   attribute_is_overriddeni  s    zR_ClassScanMapperConfig._cls_attr_override_checker.<locals>.attribute_is_overriddenc                    s$   i | ]} |j kr|j|j   qS r    metadatarJ   .0fsa_dataclass_metadata_keyr    r!   
<dictcomp>n  s   
 zE_ClassScanMapperConfig._cls_attr_override_checker.<locals>.<dictcomp>c                    s$   i | ]} |j kr|j|j   qS r    r   r   r   r    r!   r   s  s   
 c                    s   t |r|j}|  }t |r(|j}||kr4dS | k	r@dS |  }t| |}||krddS | k	rzt|trzdS ||krdS | k	rdS dS )NFT)rG   fgetr&   r.   rE   r	   )r   rF   retZ	all_field)absentall_datacls_fieldsr   local_datacls_fieldsr    r!   r   {  s.    
 )r3   r   Zdataclass_fieldslocal_dataclass_fieldsr$   )r[   r   r   r    )r   r   r   r   r   r!   _cls_attr_override_checker^  s       

(z1_ClassScanMapperConfig._cls_attr_override_checkerc                    s<   t  dddkr" fdd}nt  fdd}|S )zproduce a function to iterate the "attributes" of a class,
        adjusting for SQLAlchemy fields embedded in dataclass fields.

        r   Nc                  3   s&   t   D ]\} }| |dfV  qd S )NF)varsitems)rJ   rF   r   r    r!   local_attributes_for_class  s    zM_ClassScanMapperConfig._cls_attr_resolver.<locals>.local_attributes_for_classc                  3   sj   t  D ]0} | jkr
| j | jt| jdfV  q
t  D ]\}}|krH||dfV  qHd S )NTF)r   r   r   addrJ   _as_dc_declaredattrr   r   )fieldrJ   rF   r   field_namesr   r    r!   r     s    
 )r3   r   )r[   r   r   r    r   r!   _cls_attr_resolver  s      z)_ClassScanMapperConfig._cls_attr_resolverc              	      sJ  | j  | j}| j}d }d  }}d }| | j }g } jD ]b}	|	 k	o^t|	d k	o^t|	ddd }
| |	}|
s|	 k	r| ||}ni }|	|	|
||f q8|D ]\}	}
}}|
| | D ]`\}}}|dkrt|| }|s|
r|r fdd}q|dkr(t|| }|s |
r |r  j}q|dkrt|| }|s |
rP|r  j}t|tttd fsvtd	|	 k	r d}q|
rt|rtd
|	j||	 f  qq|	 k	rt|trqq t|trtdnt|r|jr<||krtd| f  ||  ||<  ||< }t || nj|rdt |d }t|tsn|  }n
t |}t|tr|j!rt|j"ts|j#}| ||< ||< t|ttfr|j$d kr|j%|_$n| &|	|| q|r||ks|| |k	r|||rt't|r|  }|||< qq|r4|s4d }|| _(|| _)|| _*d S )NrP   TrQ   __mapper_args__c                      s
   t  jS r7   )r   r   r    r   r    r!   r     s    z?_ClassScanMapperConfig._scan_attributes.<locals>.mapper_args_fn__tablename____table_args__z3__table_args__ value must be a tuple, dict, or NonezRegular (i.e. not __special__) attribute '%s.%s' uses @declared_attr, but owning class %s is mapped - not applying to subclass %s.zMapper properties (i.e. deferred,column_property(), relationship(), etc.) must be declared as @declared_attr callables on declarative mixin classes.  For dataclass field() objects, use a lambda:zXAttribute '%s' on class %s cannot be processed due to @declared_attr.cascading; skipping)+r   r;   r{   r   r/   r"   r3   r   _produce_column_copiesrs   updaterK   r   r   rE   tupler   rW   r   ArgumentErrorrG   r   rI   rX   r   r   rR   rH   __get__setattrr.   r   r   Z_is_internal_proxyZoriginal_propertyZ
descriptordoc__doc___warn_for_decl_attributesr,   r|   r}   r   )r[   r;   r{   r   r|   Zinherited_table_argsr}   r   basesr2   Zclass_mappedr   Zlocally_collected_columnsrJ   rF   is_dataclassZ
check_declr   r    r   r!   r     s   

  

  
  
   






 


z'_ClassScanMapperConfig._scan_attributesc                 C   s"   t |tjrtd||f  d S )NzAttribute '%s' on class %s appears to be a non-schema 'sqlalchemy.sql.column()' object; this won't be part of the declarative mapping)rE   r   ZColumnClauser   rI   )r[   r   r   rv   r    r    r!   r     s    z0_ClassScanMapperConfig._warn_for_decl_attributesc                 C   s   | j }| j}i }| j}| D ]\}}}	t|tr|||r>qq|jrPtdq||krd|krt|jph||d j	ks|
  ||< }
|j|
_t|||
 |
||< q|S )NzColumns with foreign keys to other columns must be declared as @declared_attr callables on declarative mixin classes.  For dataclass field() objects, use a lambda:.rh   )r   r;   r{   rE   r   Zforeign_keysr   rR   rJ   rv   Z_copy_creation_orderr   )r[   Zattributes_for_classr   r   r;   Zlocally_collected_attributesr{   rJ   rF   r   Zcopy_r    r    r!   r     s,    


z-_ClassScanMapperConfig._produce_column_copiesc                 C   s@  | j }| j}| j}t|ddd}t|D ]}|dkr8q(|| }t|rj|jr^td| j   t	||}n4t
|tr|j|k	r|j|krt|j}t||| t
|trt|dkrt
|d ttfrtd|  q(nZt
|ttfs|d	s(|| | ||| |s(t||| q(n|d
kr2td|||< q(d S )NrP   TrQ   )rh   r   r   zUse of @declared_attr.cascading only applies to Declarative 'mixin' and 'abstract' classes.  Currently, this flag is ignored on mapped class %sr   r   zIgnoring declarative-like tuple value of attribute '%s': possibly a copy-and-paste error with a comma accidentally placed at the end of the line?__r   zdAttribute name 'metadata' is reserved for the MetaData instance when using a declarative base class.)r   r;   rM   r3   listrG   rH   r   rI   r.   rE   r
   r*   r   r   r   r   rt   r   r   
startswithpopr   r   rR   )r[   r   r;   	our_stuffZlate_mappedkr]   r    r    r!   r     sh      




z3_ClassScanMapperConfig._extract_mappable_attributesc              
      s   | j  tj  fddd | j}tt}t  D ]\}}t	|t
tfr|jD ]F}t	|trT|jd krTt|| t	|ts||j | || qTq8t	|tr8t|| ||j | || ||jkr8 |= q8| D ]4\}}t|dkrtd| j|dt|f  qd S )Nc                    s
    |  j S r7   r   r   r   r    r!   <lambda>	      zB_ClassScanMapperConfig._extract_declared_columns.<locals>.<lambda>r   r   zzOn class %r, Column object %r named directly multiple times, only one will be used: %s. Consider using orm.synonym insteadz, )rM   r   Zsort_dictionaryrz   collectionsdefaultdictr   r   r   rE   r   r   columnsr   r?   _undefer_column_namerJ   r   r   rt   rI   rL   joinsorted)r[   rz   Zname_to_prop_keyr   rv   colrJ   keysr    r   r!   r     s8     








z0_ClassScanMapperConfig._extract_declared_columnsNc                 C   sn  | j }| j}| j}| j}| j}t|}t|dd d }| _d|kr$|d kr$t|drjt	
|j}nt}|d k	rddi  }	}
|rt|tr|}
n4t|trt|d tr|dd |d  }	}
n|}	|d	}|r||
d
< |d}|rd|
d< | d||| |ft|t|	 |
}n@|d kr4|j}|rd|D ]$}|j|s>td|j q>|| _d S )Nc                 S   s   | j S r7   r   )rv   r    r    r!   r   7  r   z5_ClassScanMapperConfig._setup_table.<locals>.<lambda>r   rh   __table_cls__r    r   Z__autoload_with__autoload_withZ__autoload__Tautoloadz8Can't add additional column %r when specifying __table__)r   r}   r|   r;   rz   r   r5   r   r4   r   unbound_method_to_callabler   r   rE   r   r   r&   r^   _metadata_for_clsrh   rv   Zcontains_columnr   r   r   rf   )r[   r?   r   r}   r|   r;   rz   r6   Z	table_clsargsZtable_kwr   r   rv   r    r    r!   r   -  sf    
 








z#_ClassScanMapperConfig._setup_tablec                 C   s    t | jdr| jjS |jjS d S )Nr   )r4   r   r   r:   )r[   r6   r    r    r!   r   i  s    z(_ClassScanMapperConfig._metadata_for_clsc                 C   s  | j }| j}| j}| j}|dd }|d krg }|jD ]B}t|}|d krLq6t|d k	r6t|ddds6||kr6|	| q6|rt
|dkrtd||f |d }nt|tr|j}|| _|d kr| jd krt|dstd	| n| jrt| j}	|	j }
|	j}|d kr|r td
|D ]}|j|
jkrh|
j|j |krLq$td|||
j|j f |jrztd|
| |d k	r$||
k	r$|| q$d S )Nrg   rP   TrQ   r   rr   r   Z__no_table__zwClass %r does not have a __table__ or __tablename__ specified and does not inherit from an existing table-mapped class.z?Can't place __table_args__ on an inherited class with no table.z;Column '%s' on class %s conflicts with existing column '%s'zDCan't place primary key columns on an inherited class with no table.)rf   r   r|   rz   r&   r'   r(   r"   r3   rs   rt   r   rR   rE   r   r*   rg   ry   r   rJ   rv   Zprimary_keyappend_columnZ_refresh_for_new_column)r[   r@   r?   r   r|   rz   rg   ru   rv   inherited_mapperinherited_tableZinherited_persist_selectabler    r    r!   rn   o  s    
  




z)_ClassScanMapperConfig._setup_inheritancec                    s  | j }| jr|  }ni }|r(|| d|krFt|}||d  dD ]&}||krJ|| }| j||||< qJd|kr|d }t|tr|j}|| j	k	rt
d|d  | j	r| j	|d< | j	r|ddst| j	  j}d|kr2t fdd	|jD  jpd
 |d< }|dd	 | jD  t| D ]N\}}	t|	tjsXq>| jkr> j| }
t|
tr>|	g|
j ||< q>| }||d< || _d S )NrM   )Zversion_id_colZpolymorphic_onrg   z:mapper inherits argument given for non-inheriting class %sZconcreteFexclude_propertiesc                    s   g | ]}| j kr|jqS r    )Z_columntopropertyr   r   rv   r   r    r!   
<listcomp>  s   
zD_ClassScanMapperConfig._prepare_mapper_arguments.<locals>.<listcomp>r    c                 S   s   g | ]
}|j qS r    r   r   r    r    r!   r     s     )rM   r   r   r   r{   r&   rE   r   r*   rg   r   rR   r"   rf   r   rv   unionr   difference_updaterz   r   r   r   ZColumnElementZ_propsr   r   copyr~   )r[   r@   rM   r~   r   vZinherits_argr   r   r   pZresult_mapper_argsr    r   r!   _prepare_mapper_arguments  sb    










z0_ClassScanMapperConfig._prepare_mapper_argumentsc                 C   sF   |  | t| jdr&t| jj}nt}| d|| j| jf| j	S )N__mapper_cls__r>   )
r   r4   r   r   r   r   r   r^   rf   r~   rq   r    r    r!   r_     s    
z_ClassScanMapperConfig.map)N)rX   rb   rc   rd   r\   r   r   r   r   r   r   r   r   r   r   rn   r   r   rw   r_   rx   r    r    ro   r!   rS     s    %G R	!E)
<RKrS   c                 C   s6   t jj}| | }t|r.t||js.||S |S d S r7   )r   rB   rC   callablerE   rD   )Zfield_metadatar   Zdecl_apirF   r    r    r!   r     s
    
r   c                       s   e Zd Ze Zdd Zedd Zej	dd Ze
dd Ze
dd	 Ze
d
d Ze
dd Ze
dddZejf fdd	Z  ZS )r   c                 C   s   d S r7   r    r`   r    r    r!   ra   +  s    z$_DeferredMapperConfig._early_mappingc                 C   s   |   S r7   )_clsr   r    r    r!   r   .  s    z_DeferredMapperConfig.clsc                 C   s    t || j| _| | j| j< d S r7   )weakrefref_remove_config_clsr   _configs)r[   r*   r    r    r!   r   2  s    c                 C   s   | j |d  d S r7   )r   r   )r   r   r    r    r!   r   7  s    z(_DeferredMapperConfig._remove_config_clsc                 C   s   t |tot|| jkS r7   )rE   rW   r   r   r   r   r*   r    r    r!   r   ;  s    z_DeferredMapperConfig.has_clsc                 C   s.   t |dr|  tj|dt| dd S )N_sa_raise_deferred_configzOClass %s has a deferred mapping on it.  It is not yet usable as a mapped class.)msg)r4   r   orm_excZUnmappedClassErrorZ_safe_cls_namer   r    r    r!   raise_unmapped_for_cls@  s    
z,_DeferredMapperConfig.raise_unmapped_for_clsc                 C   s   | j t| S r7   )r   r   r   r   r    r    r!   r   K  s    z$_DeferredMapperConfig.config_for_clsTc                    sv   fdddd | j  D D }|s*|S tdd |D  g } D ] | fddjD  qDtt||S )Nc                    s&   g | ]\}}|d k	rt | r|qS r7   )r-   )r   mrT   )base_clsr    r!   r   Q  s    
z:_DeferredMapperConfig.classes_for_base.<locals>.<listcomp>c                 S   s   g | ]}||j fqS r    r   r   r   r    r    r!   r   S  s     c                 s   s   | ]}|j |fV  qd S r7   r   r   r    r    r!   	<genexpr>Z  s     z9_DeferredMapperConfig.classes_for_base.<locals>.<genexpr>c                 3   s&   | ]}| kr |   fV  qd S r7   r    )r   r   )all_m_by_clsm_clsr    r!   r   ^  s   )r   valuesr   extendr'   r   r   sort)r   r   r   classes_for_baseZtuplesr    )r   r   r   r!   r   O  s    

z&_DeferredMapperConfig.classes_for_basec                    s    | j | jd  tt| |S r7   )r   r   r   ri   r   r_   r`   ro   r    r!   r_   e  s    z_DeferredMapperConfig.map)T)rX   rb   rc   r   rY   r   ra   propertyr   setterre   r   r   r   r   r   rw   r_   rx   r    r    ro   r!   r   (  s"   






r   c                 C   s  d| j krt|tr>t|| | jj|dd | j|| nt|tr|j	D ]2}t|trN|j
dkrNt|| | jj|dd qN| j|| n`t|tr| j|| nFt|tr|j|krt|j}| j|| nt| || | j  nt| || dS )zadd an attribute to an existing declarative class.

    This runs through the logic to determine MapperProperty,
    adds it to the Mapper, adds a column to the mapped Table, etc.

    r>   T)Zreplace_existingN)r%   rE   r   r   rh   r   r>   Zadd_propertyr   r   r?   r   r
   r   r   rW   __setattr___expire_memoizations)r   r   r]   r   r    r    r!   _add_attributej  s&    







r   c                 C   sj   d| j krZ|| j krZ| jjsZ| j | }t|ttttfrBtdqft	
| | | j  nt	
| | d S )Nr>   z<Can't un-map individual mapped attributes on a mapped class.)r%   r>   Z_dispose_calledrE   r   r   r   r
   NotImplementedErrorrW   __delattr__r   )r   r   r]   r    r    r!   _del_attribute  s"    
 
r   c                 K   sB   t | }|D ]0}t||s,td||jf t| |||  qdS )a=  A simple constructor that allows initialization from kwargs.

    Sets attributes on the constructed instance using the names and
    values in ``kwargs``.

    Only keys that are present as
    attributes of the instance's class are allowed. These could be,
    for example, any mapped columns or relationships.
    z(%r is an invalid keyword argument for %sN)rW   r4   	TypeErrorrX   r   )r[   kwargsrT   r   r    r    r!   _declarative_constructor  s    

r   r\   c                 C   s$   |j d kr| |_ |jd kr | |_d S r7   )r   rJ   )r   columnr    r    r!   r     s    

r   )F)8r   
__future__r   r   r   Zsqlalchemy.ormr   r    r   r   r   r   rj   r	   r
   r2   r   r   Zdescriptor_propsr   r   Z
interfacesr   r   rM   r   r   r   r   Zsqlr   Z
sql.schemar   r   r   r"   r(   r3   r)   r<   rA   Zpreload_modulerG   rK   r$   r8   r=   rS   r   r   r   r   r   rX   r   r    r    r    r!   <module>   sf   
%
@D      
B!