o
    i]}                     @   s  d 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 a a!dd Z"dd Z#dd Z$d2dd Z%d!d" Z&d#d$ Z'G d%d& d&e(Z)G d'd( d(e)Z*d)d* Z+d+d, Z,d-d. Z-d/e-_.d0d1 Z/dS )3z(Internal implementation for declarative.    N)instrumentation   )clsregistry   )event)exc)util)class_mapper)mapper)	mapperlib)synonym)QueryableAttribute)_is_mapped_class)InspectionAttr)MapperProperty)ColumnProperty)CompositeProperty)Column)Table)
expression)topologicalc                 C   s,   t | r
t | S t| rt| ddS d S )NF)	configure)_DeferredMapperConfighas_clsconfig_for_clsr   r	   cls r   Z/var/www/edux/Edux_v2/venv/lib/python3.10/site-packages/sqlalchemy/ext/declarative/base.py_declared_mapping_info%   s
   

r   c                 C   sZ   | t u rd S t| dddr!| jD ]}t|}|d ur|  S qd S t| }|d ur+|S | S )N__abstract__Tstrict)object_get_immediate_cls_attr	__bases__"_resolve_for_abstract_or_classical"_dive_for_classically_mapped_class)r   sup	classicalr   r   r   r&   0   s   
r&   c                 C   sL   t | drd S t| }|d ur| S | jD ]}t|}|d ur#|  S qd S )N_decl_class_registry)hasattrr   manager_of_classr%   r'   )r   managerr(   r
   r   r   r   r'   C   s   


r'   Fc                 C   st   t | tsdS | jD ]-}t|d}| ot|du}||jv r7|| u s0|r+|| jv r7n	 |s7|s7t||  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.

    Nr*   )
issubclassr#   __mro__r+   r'   __dict__r%   getattr)r   attrnamer"   base_is_declarative_inherits_is_classicial_inheritsr   r   r   r$   W   s&   




r$   c                 C   sB   t d u rddlm a  t tjfat| dddrd S t| || d S )Nr   )declared_attrr    Tr!   )r6   apir   classpropertydeclarative_propsr$   _MapperConfigsetup_mapping)r   	classnamedict_r   r   r   _as_declarativey   s   
r>   c                 C   s0   t | trt| ddrtd||f  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)
isinstancer9   r1   r   warn)objnamer   r   r   r   _check_declared_props_nocascade   s   
rD   c                   @   sx   e Zd Ze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 Zdd Zdd Zdd ZdS )r:   c                 C   s6   t |dddpt|d}|rt}nt}|||| d S )N_sa_decl_prepare_nocascadeTr!   _sa_decl_prepare)r$   r+   r   r:   )r   cls_r<   r=   	defer_mapcfg_clsr   r   r   r;      s   z_MapperConfig.setup_mappingc                 C   s   || _ t|| _|| _d | _t | _t | _	i | _
|   i | j _|   tj  z$t| j| j  |   |   |   |   |   W tj  d S tj  w N)r   dictr=   r<   persist_selectabler   OrderedDict
propertiessetdeclared_columnscolumn_copies_setup_declared_events_sa_declared_attr_reg_scan_attributesr   _CONFIGURE_MUTEXacquirer   	add_class_extract_mappable_attributes_extract_declared_columns_setup_table_setup_inheritance_early_mappingrelease)selfrG   r<   r=   r   r   r   __init__   s&   



z_MapperConfig.__init__c                 C   s   |    d S rJ   )mapr^   r   r   r   r\      s   z_MapperConfig._early_mappingc                    sP   t  jdrttd fdd}t  jdr&ttd fdd}d S d S )	N__declare_last__after_configuredc                          j   d S rJ   )r   rb   r   ra   r   r   rc         z>_MapperConfig._setup_declared_events.<locals>.after_configured__declare_first__before_configuredc                      rd   rJ   )r   rf   r   ra   r   r   rg      re   z?_MapperConfig._setup_declared_events.<locals>.before_configured)r$   r   r   listens_forr
   )r^   rc   rg   r   ra   r   rR      s   

z$_MapperConfig._setup_declared_eventsc              	      s  | j  | j}| j}d }d  }}d } jD ]}| uo(t|d uo(t|ddd }|s4| ur4| | t| D ]\}	}
|	dkrUt	|
|	 }|sT|rN|rT fdd}q:|	dkrit	|
|	 }|sh|re|rh j
}q:|	dkrt	|
|	 }|s|ry|r j}t|tttd fstd	| urd}q:|rt|
trtd
|j|	| f  q:| ur0t|
trq:t|
trtdt|
tr)t|
tj}|s|
jr|	|v rtd|	 f  |
|
  ||	<  ||
< }t |	| n(|rtd t |	}t|tr|j rt|j!ts|j"}| ||	< ||
< t|ttfr(|j#d u r(|
j$|_#q:| %||	|
 q:q|r:|s:d }|| _&|| _'|| _(d S )NrE   Tr!   __mapper_args__c                      s
   t  jS rJ   )rK   ri   r   r   r   r   mapper_args_fn   s   
z6_MapperConfig._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.zXAttribute '%s' on class %s cannot be processed due to @declared_attr.cascading; skippingzJUse of sqlalchemy.util.classproperty on declarative classes is deprecated.))r   r=   rQ   r/   r   r$   _produce_column_copiesvarsitemsrD   rk   rl   r@   tuplerK   typer   ArgumentErrorr9   r   rA   __name__r   r   InvalidRequestErrorr8   r?   __get__setattrwarn_deprecatedr1   r   _is_internal_proxyoriginal_property
descriptordoc__doc___warn_for_decl_attributes
table_args	tablenamerj   )r^   r=   rQ   rj   r~   inherited_table_argsr   r3   class_mappedrC   rB   
check_decloldclasspropretr   r   r   rT      s   








r
z_MapperConfig._scan_attributesc                 C   s&   t |tjrtd||f  d S 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)r@   r   ColumnClauser   rA   )r^   r   keycr   r   r   r}   c  s   z'_MapperConfig._warn_for_decl_attributesc                 C   s   | j }| j}| j}t| D ]A\}}t|trPt|||ur q|jr(t	
d||vrPd|v r:|jp4||d jv sP|  ||< }|j|_t||| |||< qd S )NzvColumns with foreign keys to other columns must be declared as @declared_attr callables on declarative mixin classes. 	__table__)r   r=   rQ   rn   ro   r@   r   r1   foreign_keysr   rt   rC   r   copy_creation_orderrv   )r^   r3   r   r=   rQ   rC   rB   copy_r   r   r   rm   l  s(   
z$_MapperConfig._produce_column_copiesc                 C   sN  | j }| j}| j}t|ddd}t|D ]}|dv rq|| }t|tr:t|tr4|jr4t	
d| j   t||}nt|trT|j|urT|j|krTt|j}t||| t|trpt|dkrpt|d ttfrpt	
d|  qt|ttfs|d	s|| | ||| |st||| q|d
krtdt||}|||< qd S )NrE   Tr!   )r   rk   ri   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?__metadatazdAttribute name 'metadata' is reserved for the MetaData instance when using a declarative base class.)r   r=   rN   r$   listr@   r9   r6   r?   r   rA   r1   r   class_r   r   rv   rp   lenr   r   
startswithpopr}   r   rt   r   _deferred_relationship)r^   r   r=   	our_stufflate_mappedkvaluepropr   r   r   rX     sb   






z*_MapperConfig._extract_mappable_attributesc              
      s  | j   j fddd | j}tt}t  D ]R\}}t|t	t
frN|jD ]#}t|trL|jd u rLt|| t|t
sG||j | || q)qt|trmt|| ||j | || ||jkrm |= q| D ]\}}t|dkrtd| j|dt|f  qrd S )Nc                    s
    |  j S rJ   r   r   r   r   r   <lambda>  s   
 z9_MapperConfig._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, )rN   sortrP   collectionsdefaultdictrO   r   ro   r@   r   r   columnsr   table_undefer_column_namerC   addr   r   r   rA   r<   joinsorted)r^   rP   name_to_prop_keyr   r   colrC   keysr   r   r   rY     s<   








z'_MapperConfig._extract_declared_columnsc                 C   s4  | j }| j}| j}| j}| j}t|dd d }| _d }t|dr(t|j	}nt
}d|vr}|d ur|di }}	|r[t|trA|}	nt|tr[t|d trY|dd |d }}	n|}|d	}
|
rfd
|	d< |||jgt|t| R i |	 |_}n|j}|r|D ]}|j|std|j q|| _d S )Nc                 S   s   | j S rJ   r   )r   r   r   r   r     s    z,_MapperConfig._setup_table.<locals>.<lambda>r   __table_cls__r   r   r   __autoload__Tautoloadz8Can't add additional column %r when specifying __table__)r   r   r~   r=   rP   r   r+   r   unbound_method_to_callabler   r   r@   rK   rp   getr   r   r   contains_columnr   rr   r   local_table)r^   r   r   r~   r=   rP   r   	table_clsargstable_kwr   r   r   r   r   rZ     sZ   





z_MapperConfig._setup_tablec           
      C   sr  | j }| j}| j}| j}g }|jD ]}t|}|d u rqt|d ur.t|ddds.|| q|rFt	|dkr@t
d||f |d | _nd | _|d u r^| jd u r^t|ds^t
d| | jrt| j}|j }|j}	|d u r|rwt
d	|D ]=}|j|jv r|j|j |u rqyt
d
|||j|j f |jrt
d|| |	d ur|	|ur|	| qyd S d S d S )NrE   Tr!   r   z&Class %s has multiple mapped bases: %rr   __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.)r   r   r~   rP   r%   r&   r   r$   appendr   r   rt   inheritsrL   rr   rC   r   primary_keyappend_column_refresh_for_new_column)
r^   r   r   r~   rP   r   r   inherited_mapperinherited_tableinherited_persist_selectabler   r   r   r[   '  s   






	z _MapperConfig._setup_inheritancec           
         s>  | j }| jr|  }ni }dD ]}||v r"|| }| j||||< qd|vs+J d| jr3| j|d< | jr|ddst| j  j}d|vrit fdd|jD 	 j
pXd	 |d< }|d
d | jD  t| D ]"\}}t|tjszqo| jv r j| }t|tr|g|j ||< qo| }	||	d< |	| _d S )N)version_id_colpolymorphic_onr   z=Can't specify 'inherits' explicitly with declarative mappingsconcreteFexclude_propertiesc                    s   g | ]
}| j vr|jqS r   )_columntopropertyr   .0r   r   r   r   
<listcomp>  s
    
z;_MapperConfig._prepare_mapper_arguments.<locals>.<listcomp>r   c                 S   s   g | ]}|j qS r   r   r   r   r   r   r     s    rN   )rN   rj   rQ   r   r   r   r   rO   r   unionr   difference_updaterP   r   ro   r@   r   ColumnElement_propsr   r   r   mapper_args)
r^   rN   r   r   vr   r   r   presult_mapper_argsr   r   r   _prepare_mapper_argumentsr  sN   










z'_MapperConfig._prepare_mapper_argumentsc                 C   sR   |    t| jdrt| jj}nt}|| j| jfi | j | j_	}| j`
|S )N__mapper_cls__)r   r+   r   r   r   r   r
   r   r   
__mapper__rS   )r^   
mapper_clsmp_r   r   r   r`     s   z_MapperConfig.mapN)rs   
__module____qualname__classmethodr;   r_   r\   rR   rT   r}   rm   rX   rY   rZ   r[   r   r`   r   r   r   r   r:      s     
$ 	F'3K<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 fddZ  ZS )r   c                 C   s   d S rJ   r   ra   r   r   r   r\     s   z$_DeferredMapperConfig._early_mappingc                 C   s   |   S rJ   )_clsra   r   r   r   r     s   z_DeferredMapperConfig.clsc                 C   s    t || j| _| | j| j< d S rJ   )weakrefref_remove_config_clsr   _configs)r^   r   r   r   r   r     s   c                 C   s   | j |d  d S rJ   )r   r   )r   r   r   r   r   r     s   z(_DeferredMapperConfig._remove_config_clsc                 C   s   t |tot|| jv S rJ   )r@   rq   r   r   r   r   r   r   r   r   r     s   z_DeferredMapperConfig.has_clsc                 C   s*   t |dr	|  tj|dt| d)N_sa_raise_deferred_configzOClass %s has a deferred mapping on it.  It is not yet usable as a mapped class.)msg)r+   r   orm_excUnmappedClassError_safe_cls_namer   r   r   r   raise_unmapped_for_cls  s   
z,_DeferredMapperConfig.raise_unmapped_for_clsc                 C   s   | j t| S rJ   )r   r   r   r   r   r   r   r     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  q"tt||S )Nc                    s&   g | ]\}}|d urt | r|qS rJ   )r.   )r   mrG   )base_clsr   r   r     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    c                 s   s    | ]}|j |fV  qd S rJ   r   r   r   r   r   	<genexpr>  s    z9_DeferredMapperConfig.classes_for_base.<locals>.<genexpr>c                 3   s(    | ]}| v r |   fV  qd S rJ   r   )r   r   )all_m_by_clsm_clsr   r   r     s    )r   valuesrK   extendr%   r   r   r   )r   r   r   classes_for_basetuplesr   )r   r   r   r   r     s   

z&_DeferredMapperConfig.classes_for_basec                    s   | j | jd  tt|  S rJ   )r   r   r   superr   r`   ra   	__class__r   r   r`     s   z_DeferredMapperConfig.map)T)rs   r   r   r   rM   r   r\   propertyr   setterr   r   r   r   r   r   r`   __classcell__r   r   r   r   r     s$    






r   c                 C   s  d| j v rt|trt|| | j| | j|| dS t|trG|j	D ]}t|tr=|j
du r=t|| | j| q&| j|| dS t|trY| j|t| | dS t|tru|j|krut|j}| j|t| | dS t| || | j  dS 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   N)r0   r@   r   r   r   r   r   add_propertyr   r   r   r   r   r   r   r   r   rq   __setattr___expire_memoizations)r   r   r   r   r   r   r   _add_attribute   s0   







r   c                 C   sj   d| j v r-|| j v r-| jjs-| j | }t|ttttfr tdt	
| | | j  d S t	
| | d S )Nr   z<Can't un-map individual mapped attributes on a mapped class.)r0   r   _dispose_calledr@   r   r   r   r   NotImplementedErrorrq   __delattr__r   )r   r   r   r   r   r   _del_attribute%  s   


r   c                 K   sB   t | }|D ]}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)rq   r+   	TypeErrorrs   rv   )r^   kwargsrG   r   r   r   r   _declarative_constructor:  s   

r   r_   c                 C   s(   |j d u r| |_ |jd u r| |_d S d S rJ   )r   rC   )r   columnr   r   r   r   P  s
   


r   )F)0r|   r   r   sqlalchemy.ormr    r   r   r   r   ormr	   r   r
   r   r   orm.attributesr   orm.baser   r   orm.interfacesr   orm.propertiesr   r   schemar   r   sqlr   r   r6   r9   r   r&   r'   r$   r>   rD   r#   r:   r   r   r   r   rs   r   r   r   r   r   <module>   sR   
"    .B%