U kf_ @sdZddlmZddlmZddlmZddlmZddlmZddlmZddlm Z dd lm Z dd lm Z dd lm Z dd lm Z dd lmZddlmZddlmZddlmZddlmZddlZddlmZddlmZddlmZddlmZddlmZddlmZddlmZddlmZddlm Z ddlm!Z!ddl"m#Z#dd l"m$Z$erdd!lm%Z%dd"lm&Z&dd#lm'Z'dd$lm(Z(dd%lm)Z)dd&l*m+Z+dd'l,m-Z-dd(l.m/Z/dd)lm0Z0dd*lm1Z1ed+ed,Z2e3d-Z4Gd.d/d/e$Z5Gd0d1d1e$Z6Gd2d3d3e!ee7d4fe ee Z8Gd5d6d6Z9Gd7d8d8e Z:e:Z;ej<ZZ>Z?ej@Z@ZAejBZBZCdKd:d;dd?d@dAdBdCdDZDdEdFZEdGdHZFdIdJZGdS)LaDefines SQLAlchemy's system of class instrumentation. This module is usually not directly visible to user applications, but defines a large part of the ORM's interactivity. instrumentation.py deals with registration of end-user classes for state tracking. It interacts closely with state.py and attributes.py which establish per-instance and per-class-attribute instrumentation, respectively. The class instrumentation system can be customized on a per-class or global basis using the :mod:`sqlalchemy.ext.instrumentation` module, which provides the means to build and specify alternate instrumentation forms. .. versionchanged: 0.8 The instrumentation extension system was moved out of the ORM and into the external :mod:`sqlalchemy.ext.instrumentation` package. When that package is imported, it installs itself within sqlalchemy.orm so that its more comprehensive resolution mechanics take effect. ) annotations)Any)Callable)cast) Collection)Dict)Generic)Iterable)List)Optional)Set)Tuple)Type) TYPE_CHECKING)TypeVar)UnionN)base) collections)exc) interfaces)state)_O)_is_collection_attribute_impl)util) EventTarget) HasMemoized)Literal)Protocol) _RegistryType) AttributeImpl)QueryableAttribute)_AdaptedCollectionProtocol)_CollectionFactoryType) _MapperConfig)InstanceEvents)Mapper) InstanceState) dispatcher_T)boundDEL_ATTRc@s eZdZdddddddZdS) _ExpiredAttributeLoaderProtostate.InstanceState[Any]zSet[str]zbase.PassiveFlagNone)rtoloadpassivereturncCsdSN)selfrr0r1r4r4N/opt/hc_python/lib64/python3.8/site-packages/sqlalchemy/orm/instrumentation.py__call__Ssz%_ExpiredAttributeLoaderProto.__call__N__name__ __module__ __qualname__r7r4r4r4r6r-Rsr-c@seZdZdddddZdS)_ManagerFactoryType[_O]ClassManager[_O]class_r2cCsdSr3r4r5r@r4r4r6r7\z_ManagerFactory.__call__Nr8r4r4r4r6r<[sr<c @sbeZdZUdZded<ejZejZ e e e Z ded<ded<dZded <d ed <dZd ed <ded<espdZded<ded<ee jdddddZeje jdddddZddZddddd d!dd"d#d$d%Zd"d&d'd(Zd)d&d*d+Zd,dd-d.d/Zedd&d0d1Zejd2d3Zejd4d5Zejd6d7Z ejd8d9Z!e j"d:d&d;d<Z#dd=d>Z$dd?d@Z%dAddBdCdDZ&dEdFdGdHdIZ'dJdKZ(e j"dLd&dMdNZ)dOdPZ*e j+dQdRZ,e j+dSdTZ-e j+dUdVZ.ddAdWdd"dXdYdZZ/d[d\Z0d]d^Z1dd_d`Z2d"d&dadbZ3dAdWd"dcdddeZ4dAd"dBdfdgZ5dAd,d"dhdidjZ6dAd"dBdkdlZ7dAdmdndodpdqZ8dAdrdndsdtdudvZ9ddAdddwdxdyZ:dAdzdBd{d|Z;ed}d&d~dZdd"dddZ?drdddddZ@dddddZAdddddZBddrdAdddddZCdd&ddZDdAd&ddZEdS) ClassManagerz,Tracks state information at the class level.zdispatcher[ClassManager[_O]]dispatchr-expired_attribute_loader$Optional[Callable[(Ellipsis, None)]] init_methodN original_initzOptional[_ManagerFactory]factoryz$Optional[weakref.ref[_MapperConfig]]declarative_scanr registryr=r@zList[ClassManager[Any]]_basesz1.4zWThe ClassManager.deferred_scalar_loader attribute is now named expired_attribute_loader)messagecCs|jSr3rEr5r4r4r6deferred_scalar_loadersz#ClassManager.deferred_scalar_loadercCs ||_dSr3rN)r5objr4r4r6rPscCs||_i|_d|_i|_i|_d|_d|_d|_ddtddd|jj DD|_ |j D]}| |qZtd|j j |||jD]"}t|}|dk r|j |j q|d|jkrtd|dS) NFcSsg|]}|dk r|qSr3r4).0mgrr4r4r6 sz)ClassManager.__init__..z!List[Optional[ClassManager[Any]]]cSsg|]}t|trt|qSr4) isinstancetypeopt_manager_of_class)rRrr4r4r6rTs r&__del__z__del__() method on class %s will cause unreachable cycles and memory leaks, as SQLAlchemy instrumentation often creates reference cycles. Please remove this method.)r@infonew_init local_attrs originals _finalizedrIrGr __bases__rLupdaterDZ_eventsZ_new_classmanager_instance__mro__rW_updatemanage__dict__rwarn)r5r@Zbase_ZbaseclsrSr4r4r6__init__sH    zClassManager.__init__FboolOptional[Mapper[_O]]Optional[_RegistryType]Optional[_MapperConfig]&Optional[_ExpiredAttributeLoaderProto]r/)finalizemapperrKrJrErGr2cCs|r ||_|r|||r(t||_|r2||_|rN|jrHtd|||_|js||jdk rr|j j t j krr|jn|j j |_ |r|js| dS)Nz>class is already instrumented, init_method %s can't be applied)rlZ _add_managerweakrefrefrJrEr]AssertionErrorrGr@reobjectrH _finalize)r5rkrlrKrJrErGr4r4r6 _update_states0     zClassManager._update_state)r2cCs*|jr dSd|_|tj|jdSNT)r]_instrument_init_instrumentation_factoryrDZclass_instrumentr@rOr4r4r6rqs zClassManager._finalizeintcCst|Sr3)idrOr4r4r6__hash__szClassManager.__hash__r)otherr2cCs||kSr3r4)r5ryr4r4r6__eq__szClassManager.__eq__cCs d|jkS)Nrl)rcrOr4r4r6 is_mappedszClassManager.is_mappedcCst|Sr3) frozensetrOr4r4r6 _all_key_setszClassManager._all_key_setcCstdd|DS)NcSsg|]}|jjr|jqSr4)implZ collectionkeyrRattrr4r4r6rTsz6ClassManager._collection_impl_keys..r|valuesrOr4r4r6_collection_impl_keyssz"ClassManager._collection_impl_keyscCstdd|DS)NcSsg|]}|jjr|jqSr4)r~Zaccepts_scalar_loaderrr4r4r6rTsz5ClassManager._scalar_loader_impls..rrOr4r4r6_scalar_loader_implss z!ClassManager._scalar_loader_implscCstdd|DS)NcSsg|] }|jqSr4r~rr4r4r6rTsz.ClassManager._loader_impls..rrOr4r4r6 _loader_implsszClassManager._loader_implsz Mapper[_O]cCst|jdSr3)rZUnmappedClassErrorr@rOr4r4r6rlszClassManager.mapperccsvi}|jjddD]\}|jd}|jD]F}|||||jkrDq(||j|}t|tjr(|jr(||fVq(qdS)areturn an iterator of all classbound attributes that are implement :class:`.InspectionAttr`. This includes :class:`.QueryableAttribute` as well as extension types such as :class:`.hybrid_property` and :class:`.AssociationProxy`. rrN)r@r`rc setdefaultrUrZInspectionAttrZ is_attribute)r5excludefoundsuperclsZinheritsrvalr4r4r6_all_sqla_attributess       z!ClassManager._all_sqla_attributescCs*|jjD]}||jkr|j|Sq|S)z5return an attribute on the class without tripping it.N)r@r`rc)r5rdefaultrr4r4r6_get_class_attr_mro8s  z ClassManager._get_class_attr_mrostr)rr2cCs||ko||jdk S)z\Return True if the given attribute is fully initialized. i.e. has an impl. Nrr5rr4r4r6_attr_has_implAszClassManager._attr_has_implzType[_T]zClassManager[_T])clsr2cCs t|ddS)aCreate a new ClassManager for a subclass of this ClassManager's class. This is called automatically when attributes are instrumented so that the attributes can be propagated to subclasses against their own class-local manager, without the need for mappers etc. to have already pre-configured managers for the full class hierarchy. Mappers can post-configure the auto-generated ClassManager when needed. F)rk)register_class)r5rr4r4r6_subclass_managerIs zClassManager._subclass_managercCs$t|j||j|_|d|jdS)Nre)_generate_initr@rHrZinstall_memberrOr4r4r6rtVszClassManager._instrument_initzType[state.InstanceState[_O]]cCs|j||jtjSr3)rDZ first_initr@rr(rOr4r4r6_state_constructorZszClassManager._state_constructorcCst|j|j|dS)z0Mark this instance as the manager for its class.N)setattrr@ MANAGER_ATTRrOr4r4r6rb_szClassManager.managecCstSr3)_default_manager_getterrOr4r4r6manager_getterdszClassManager.manager_gettercCstS)zReturn a (instance) -> InstanceState callable. "state getter" callables should raise either KeyError or AttributeError if no InstanceState could be found for the instance. )_default_state_getterrOr4r4r6 state_getterhs zClassManager.state_gettercCstSr3)_default_dict_getterrOr4r4r6 dict_gettersszClassManager.dict_getterQueryableAttribute[Any])rinst propagatedr2cCsf|r||jkr*dSn||j|<|||||||<|jD]}||}|||dqDdSrs)r[install_descriptor_reset_memoizationsr@__subclasses__rinstrument_attribute)r5rrrrmanagerr4r4r6rws    z!ClassManager.instrument_attributeccsF|jD]6}t|}|dk r ||k r |V|r |dEdHq dSrs)r@rrWsubclass_managers)r5 recursiverrSr4r4r6rs zClassManager.subclass_managerscCstj|j|||dSr3)rurDZattribute_instrumentr@rr4r4r6post_configure_attributes z%ClassManager.post_configure_attributecCsl||kr dS|r ||jkr2dSn|j|=|||||=|jD]}t|}|rJ||dqJdSrs)r[uninstall_descriptorrr@rrWuninstrument_attribute)r5rrrrr4r4r6rs  z#ClassManager.uninstrument_attributecCsxt|jD]}||q d|_d|_d|_|jt|D]}||jkr>| |q>|j |j j krtt |j |j dS)z)rr9r@rwrOr4r4r6__repr__5s zClassManager.__repr__)FNNNNN)N)N)F)F)F)N)N)F)Fr9r:r;__doc____annotations__rZDEFAULT_MANAGER_ATTRrZDEFAULT_STATE_ATTRr staticmethodrZ attrsetterrrHrJrrKproperty deprecatedrPsetterrerrrqrxrzr{rZmemoized_attributer}rrrZmemoized_propertyrlrrrrrtrrbZ hybridmethodrrrrrrrrrrrrrrrrrrrrrrrrrrr4r4r4r6rC_s     /&      !          rCrc@s(eZdZdZdddddZddZd S) rzProvide serialization of a :class:`.ClassManager`. The :class:`.InstanceState` uses ``__init__()`` on serialize and ``__call__()`` on deserialize. r.r)rdcCs |j|_|j}|j||dSr3)r@rrDpickle)r5rrrr4r4r6reEsz_SerializeManager.__init__cCsjt|j|_}|dkr,t|d|jn|jrD|jjsD|j|dk rX| |||j ||dS)NzxCannot deserialize object of type %r - no mapper() has been configured for this class within the current Python process!) rWr@rrZUnmappedInstanceErrorr{rlZ configuredZ_check_configurerrDZunpickle)r5rrrrr4r4r6r7Js  z_SerializeManager.__call__N)r9r:r;rrer7r4r4r4r6r=src@s\eZdZUdZded<dddddZdd dd d Zdd d dddZdd dddZdS)InstrumentationFactoryz'Factory for new ClassManager instances.z"dispatcher[InstrumentationFactory]rDr=r>r?cCsb|dk s tt|dkst||\}}|dkr@t}t|}n |dk sLt|||||_|Sr3)rorW_locate_extended_factoryrC_check_conflictsrI)r5r@rrIr4r4r6create_manager_for_clsds    z-InstrumentationFactory.create_manager_for_clsz)r@rkrlrKrJrErGr2cCs4t|}|dkrt|}|j||||||d|S)z_Register class instrumentation. Returns the existing or newly created class manager. N)rlrKrJrErGrk)rWrurrr)r@rkrlrKrJrErGrr4r4r6rs  rcCst|dS)z!Unregister class instrumentation.N)rur)r@r4r4r6unregister_classsrcCst|jj|ddS)zReturn True if the given attribute on the given instance is instrumented by the attributes package. This function may be used regardless of instrumentation applied directly to the class, i.e. no descriptors are required. T)r)rrr)rrr4r4r6rs rc Cs|dkr|j}d}tj|dd}||}t|dd}t|dd}t}t|d<t|||d} |j| _|| _ |r||| _ |r|| _ | S) z>Build an __init__ decorator that triggers ClassManager events.Nzdef __init__(%(apply_pos)s): new_state = class_manager._new_state_if_none(%(self_arg)s) if new_state: return new_state._initialize_instance(%(apply_kw)s) else: return original_init(%(apply_kw)s) F)grouped __defaults____kwdefaults__r9re) rerZformat_argspec_initgetattrlocalscopyr9execrZ_sa_original_initrr) r@Z class_managerrHZ func_bodyZ func_varsZ func_textZ func_defaultsZfunc_kw_defaultsenvrer4r4r6rs$    r)TNNNNN)Hr __future__rtypingrrrrrrr r r r r rrrrrmrrrrrZ_typingrrrreventrrZ util.typingrrr r!r"r#r$Z decl_baser%eventsr&rlr'r(r)r*symbolr,r-r<rrCrrruZinstance_stater instance_dictrrrrWZ_default_opt_manager_getterrrrrr4r4r4r6 s                                           a",