U ar@s0dZddlZddlmZddlmZddlmZddlmZddlmZdd lmZdd l m Z dd l m Z d d Z edZGdddejZGdddeZGdddeZGdddeZGddde eZGdddeZGdddeZGdddeZedZGd d!d!eZGd"d#d#eZdS)$zContain the ``AssociationProxy`` class. The ``AssociationProxy`` is a Python property object which provides transparent proxied access to the endpoint of an association object. See the example ``examples/association/proxied_association.py``. N)exc)inspect)orm)util) collections) interfaces)or_)ColumnOperatorscKst||f|S)aReturn a Python property implementing a view of a target attribute which references an attribute on members of the target. The returned value is an instance of :class:`.AssociationProxy`. Implements a Python property representing a relationship as a collection of simpler values, or a scalar value. The proxied property will mimic the collection type of the target (list, dict or set), or, in the case of a one to one relationship, a simple scalar value. :param target_collection: Name of the attribute we'll proxy to. This attribute is typically mapped by :func:`~sqlalchemy.orm.relationship` to link to a target collection, but can also be a many-to-one or non-scalar relationship. :param attr: Attribute on the associated instance or instances we'll proxy for. For example, given a target collection of [obj1, obj2], a list created by this proxy property would look like [getattr(obj1, *attr*), getattr(obj2, *attr*)] If the relationship is one-to-one or otherwise uselist=False, then simply: getattr(obj, *attr*) :param creator: optional. When new items are added to this proxied collection, new instances of the class collected by the target collection will be created. For list and set collections, the target class constructor will be called with the 'value' for the new instance. For dict types, two arguments are passed: key and value. If you want to construct instances differently, supply a *creator* function that takes arguments as above and returns instances. For scalar relationships, creator() will be called if the target is None. If the target is present, set operations are proxied to setattr() on the associated object. If you have an associated object with multiple attributes, you may set up multiple association proxies mapping to different attributes. See the unit tests for examples, and for examples of how creator() functions can be used to construct the scalar relationship on-demand in this situation. :param \*\*kw: Passes along any other keyword arguments to :class:`.AssociationProxy`. )AssociationProxy)target_collectionattrkwr`C:\Users\vtejo\AppData\Local\Temp\pip-unpacked-wheel-nyjtotrf\sqlalchemy\ext\associationproxy.pyassociation_proxys4rASSOCIATION_PROXYc@sdeZdZdZdZeZdddZddZd d Z d d Z dd dZ ddZ ddZ ddZddZdS)r zDA descriptor that presents a read/write view of an object attribute.TNFc CsR||_||_||_||_||_||_||_dt|j|t |f|_ |rN||_ dS)a Construct a new :class:`.AssociationProxy`. The :func:`.association_proxy` function is provided as the usual entrypoint here, though :class:`.AssociationProxy` can be instantiated and/or subclassed directly. :param target_collection: Name of the collection we'll proxy to, usually created with :func:`_orm.relationship`. :param attr: Attribute on the collected instances we'll proxy for. For example, given a target collection of [obj1, obj2], a list created by this proxy property would look like [getattr(obj1, attr), getattr(obj2, attr)] :param creator: Optional. When new items are added to this proxied collection, new instances of the class collected by the target collection will be created. For list and set collections, the target class constructor will be called with the 'value' for the new instance. For dict types, two arguments are passed: key and value. If you want to construct instances differently, supply a 'creator' function that takes arguments as above and returns instances. :param cascade_scalar_deletes: when True, indicates that setting the proxied value to ``None``, or deleting it via ``del``, should also remove the source object. Only applies to scalar attributes. Normally, removing the proxied target will not remove the proxy source, as this object may have other state that is still to be kept. .. versionadded:: 1.3 .. seealso:: :ref:`cascade_scalar_deletes` - complete usage example :param getset_factory: Optional. Proxied attribute access is automatically handled by routines that get and set values based on the `attr` argument for this proxy. If you would like to customize this behavior, you may supply a `getset_factory` callable that produces a tuple of `getter` and `setter` functions. The factory is called with two arguments, the abstract type of the underlying collection and this proxy instance. :param proxy_factory: Optional. The type of collection to emulate is determined by sniffing the target collection. If your collection type can't be determined by duck typing or you'd like to use a different collection implementation, you may supply a factory function to produce those collections. Only applicable to non-scalar relationships. :param proxy_bulk_set: Optional, use with proxy_factory. See the _set() method for details. :param info: optional, will be assigned to :attr:`.AssociationProxy.info` if present. .. versionadded:: 1.0.9 z _%s_%s_%sN) r value_attrcreatorgetset_factory proxy_factoryproxy_bulk_setcascade_scalar_deletestype__name__idkeyinfo) selfr r rrrrrrrrr__init__csIzAssociationProxy.__init__cCs*|dkr |S|||}|r&||S|SN) _as_instanceget)robjclass_instrrr__get__s   zAssociationProxy.__get__cCst|}|||||Sr )rr!set)rr#valuesr$rrr__set__szAssociationProxy.__set__cCst|}||||Sr )rr!delete)rr#r$rrr __delete__szAssociationProxy.__delete__cCs |||S)aReturn the internal state local to a specific mapped class. E.g., given a class ``User``:: class User(Base): # ... keywords = association_proxy('kws', 'keyword') If we access this :class:`.AssociationProxy` from :attr:`_orm.Mapper.all_orm_descriptors`, and we want to view the target class for this proxy as mapped by ``User``:: inspect(User).all_orm_descriptors["keywords"].for_class(User).target_class This returns an instance of :class:`.AssociationProxyInstance` that is specific to the ``User`` class. The :class:`.AssociationProxy` object remains agnostic of its parent class. :param class\_: the class that we are returning state for. :param obj: optional, an instance of the class that is required if the attribute refers to a polymorphic target, e.g. where we have to look at the type of the actual destination object to get the complete path. .. versionadded:: 1.3 - :class:`.AssociationProxy` no longer stores any state specific to a particular parent class; the state is now stored in per-class :class:`.AssociationProxyInstance` objects. )r!)rr$r#rrr for_classs!zAssociationProxy.for_classcCsz|j|jd}Wntk r,d}YnX|dkrn||}|dk rjt|||}t||jd|nd}|dk r|js||S|SdS)N_inst) __dict__rKeyError _calc_ownerAssociationProxyInstance for_proxysetattr _is_canonical_non_canonical_get_for_object)rr$r#r%ownerrrrr!s   zAssociationProxy._as_instancecCs4z t|}Wntjk r$YdSX|jjjSdSr )rrNoInspectionAvailablemapperZ class_managerr$)rZ target_clsinsprrrr0 s  zAssociationProxy._calc_ownercsF|jtfdd}|tkr2fdd}n fdd}||fS)Ncs|dk r|SdSr rtarget_getterrrgettersz0AssociationProxy._default_getset..gettercst||dSr r3okvr rrsetter$sz0AssociationProxy._default_getset..settercst||dSr r?rArCrDrrrE)sroperator attrgetterdictrcollection_classr>rErr=r r_default_getsets   z AssociationProxy._default_getsetcCsd|j|jfS)NzAssociationProxy(%r, %r))r rrrrr__repr__.szAssociationProxy.__repr__)NNNNNF)N)r __module__ __qualname____doc__Z is_attributerZextension_typerr&r)r+r,r!r0rNrPrrrrr ]s$ Y  #r c@s(eZdZdZddZdZeddZeddZd d Z e d d Z d dZ eddZ ejddZe ddZe ddZe ddZejddZejddZe ddZdd Zd!d"Ze d#d$Zd%d&Zd'd(Zd)d*Zd+d,Zd-d.Zd/d0Zd9d1d2Z d:d3d4Z!d;d5d6Z"d7d8Z#dS)>> User.keywords.scalar False In the special case that the :class:`.AssociationProxy` object is being accessed directly, in order to get an explicit handle to the :class:`.AssociationProxyInstance`, use the :meth:`.AssociationProxy.for_class` method:: proxy_state = inspect(User).all_orm_descriptors["keywords"].for_class(User) # view if proxy object is scalar or not >>> proxy_state.scalar False .. versionadded:: 1.3 cCs2||_|j|_||_|j|_d|_||_||_dSr )parentr owning_classr rL target_classr)rrTrUrVrrrrrSsz!AssociationProxyInstance.__init__Nc Cs|j}|j}t||}t|tjs:tjt ddd|j j }z| ||}Wn"t k rtt||||YSX||||||SdS)NzEassociation proxy to a non-relationship intermediary is not supportedZreplace_context)r rr class_mapper get_property isinstanceZRelationshipPropertyrraise_NotImplementedErrorr8r$_cls_unwrap_target_assoc_proxyAttributeError!AmbiguousAssociationProxyInstance_construct_for_assoc) clsrTrUparent_instancer rproprV target_assocrrrr2es<  z"AssociationProxyInstance.for_proxycCsb|dk rt||||St||}t|ds8t||||S|j}|rPt||||St||||SdS)NZ_is_internal_proxy)ObjectAssociationProxyInstancegetattrhasattrr_Z_impl_uses_objectsColumnAssociationProxyInstance)rardrTrUrVrr Z is_objectrrrr`s:  z-AssociationProxyInstance._construct_for_assoccCst|j|jSr )rrXrUrYr rOrrr _get_propertys z&AssociationProxyInstance._get_propertycCs |jSr )riZ comparatorrOrrr _comparatorsz$AssociationProxyInstance._comparatorcCs tddS)NzqThe association proxy can't be used as a plain column expression; it only works inside of a comparison expressionr\rOrrr__clause_element__sz+AssociationProxyInstance.__clause_element__cCs t||}t|ttfr|SdSr )rfrZr r1)rarVrr rrrr]s z7AssociationProxyInstance._cls_unwrap_target_assoc_proxycCs||j|jSr )r]rVrrOrrr_unwrap_target_assoc_proxysz3AssociationProxyInstance._unwrap_target_assoc_proxycCst|j|jS)zThe 'remote' class attribute referenced by this :class:`.AssociationProxyInstance`. .. seealso:: :attr:`.AssociationProxyInstance.attr` :attr:`.AssociationProxyInstance.local_attr` )rfrVrrOrrr remote_attrs z$AssociationProxyInstance.remote_attrcCst|j|jS)zThe 'local' class attribute referenced by this :class:`.AssociationProxyInstance`. .. seealso:: :attr:`.AssociationProxyInstance.attr` :attr:`.AssociationProxyInstance.remote_attr` )rfrUr rOrrr local_attrs z#AssociationProxyInstance.local_attrcCs |j|jfS)aReturn a tuple of ``(local_attr, remote_attr)``. This attribute is convenient when specifying a join using :meth:`_query.Query.join` across two relationships:: sess.query(Parent).join(*Parent.proxied.attr) .. seealso:: :attr:`.AssociationProxyInstance.local_attr` :attr:`.AssociationProxyInstance.remote_attr` )rornrOrrrr szAssociationProxyInstance.attrcCs|j }|r||S)zsReturn ``True`` if this :class:`.AssociationProxyInstance` proxies a scalar relationship on the local side.)riuselist_initialize_scalar_accessors)rscalarrrrrrs zAssociationProxyInstance.scalarcCs|j|jj Sr )rir8rYrrprOrrr_value_is_scalars z)AssociationProxyInstance._value_is_scalarcCs tdSr rkrOrrr_target_is_objectsz*AssociationProxyInstance._target_is_objectcCs>|jjr|jd|\}}n|jd\}}|||_|_dSr )rTrrN _scalar_get _scalar_set)rr"set_rrrrqsz5AssociationProxyInstance._initialize_scalar_accessorscsF|jtfdd}|tkr2fdd}n fdd}||fS)Ncs|dk r|SdSr rr:r<rrr> sz8AssociationProxyInstance._default_getset..gettercs t||Sr r?r@rDrrrEsz8AssociationProxyInstance._default_getset..settercs t||Sr r?rFrDrrrEsrGrKrrMrrNs   z(AssociationProxyInstance._default_getsetcCs|jjSr )rTrrOrrrrszAssociationProxyInstance.infocCs|dkr |S|jr(t||j}||Szt||j\}}}Wntk rRYn,Xt||kr~t||kr~|jdk szt|S| t ||j\|_}t ||jt|t||f|SdSr ) rrrfr rurr^rrLAssertionError_new_lazy_collectionr3)rr#r;Z creator_idself_idproxyrrrr"s"   zAssociationProxyInstance.getcCs|jr||jjr|jjn|j}t||j}|dkrP|dkrrErrrryVsd  zAssociationProxyInstance._newcCsh|jjr|j||nL|jtkr.||n6|jtkrD||n |jtkrZ||n t ddS)NzEno proxy_bulk_set supplied for custom collection_class implementation) rTrrLrextendrJupdater'rr)rr|r(rrr_sets      zAssociationProxyInstance._setcCs\|jjr|jjp|j}|jjr4|j|j|\}}n|j|j\}}||_||_||_dSr )rTrrVrrLrNr>rE)rr|rr>rErrr_inflates z!AssociationProxyInstance._inflatecKs|dd}|j}|dk r:|jfd|i|}|j|S|jr^t|j|j}|j|f|}n*|rnt dn|r|dk rt d|}|j|S)Nis_has criterionzJCan't apply keyword arguments to column-targeted association proxy; use ==zINon-empty has() not allowed for column-targeted association proxy; use ==) poprm_criterion_existsrjrtrfrVrrr)rrkwargsrrdinnerrcZ value_exprrrrrs,   z*AssociationProxyInstance._criterion_existscKs<|jdkr&|jr&|jr|jr&td|jf|dd|S)a!Produce a proxied 'any' expression using EXISTS. This expression will be a composed product using the :meth:`.RelationshipProperty.Comparator.any` and/or :meth:`.RelationshipProperty.Comparator.has` operators of the underlying proxied attributes. Nz9'any()' not implemented for scalar attributes. Use has().FrrrmrrrtrsrInvalidRequestErrorrrrrrrranys zAssociationProxyInstance.anycKs<|jdkr&|jr|jr&|js&td|jf|dd|S)a!Produce a proxied 'has' expression using EXISTS. This expression will be a composed product using the :meth:`.RelationshipProperty.Comparator.any` and/or :meth:`.RelationshipProperty.Comparator.has` operators of the underlying proxied attributes. Nz4'has()' not implemented for collections. Use any().Trrrrrrhass zAssociationProxyInstance.hascCsd|jj|jfS)Nz%s(%r)) __class__rrTrOrrrrPsz!AssociationProxyInstance.__repr__)N)N)N)$rrQrRrSrrV classmethodr2r`ripropertyrjrlr]rmemoized_propertyrmrnror rrrsrtrqrNrr"r'r*ryrrrrrrPrrrrr15sR   !            0   r1csneZdZdZdZddZfddZddZd d Zdd d Z dddZ e j ddZ ddZddZZS)r_zcan :class:`.AssociationProxyInstance` where we cannot determine the type of target object. FcCs"td|jj|j|j|jfdS)NzAssociation proxy %s.%s refers to an attribute '%s' that is not directly mapped on class %s; therefore this operation cannot proceed since we don't know what type of object is referred towards)r^rUrr rrVrOrrr _ambiguoussz,AmbiguousAssociationProxyInstance._ambiguouscs |dkr |Stt||SdSr )superr_r"rr#rrrr"sz%AmbiguousAssociationProxyInstance.getcCs |dSr rrrrr__eq__ sz(AmbiguousAssociationProxyInstance.__eq__cCs |dSr rrrrr__ne__ sz(AmbiguousAssociationProxyInstance.__ne__NcKs |dSr rrrrrrsz%AmbiguousAssociationProxyInstance.anycKs |dSr rrrrrrsz%AmbiguousAssociationProxyInstance.hascCsiSr rrOrrr _lookup_cachesz/AmbiguousAssociationProxyInstance._lookup_cachecCs|dk rt||j}|dk rz t|}Wntjk r>YnFX|j}|j}||jkrb|||z |j|WSt k rYnX|Sr ) rfr rrr7r8r$r_populate_cacher/)rrbZ actual_objr9r8instance_classrrrr5s      z?AmbiguousAssociationProxyInstance._non_canonical_get_for_objectcCsnt|j|j}||jrj|}z|||j}Wnt k rJYn X| ||j |j||j|j |<dSr ) rrXrUrYr Zisar8r]rr^r`rTr)rrr8rcrVrdrrrr3s&  z1AmbiguousAssociationProxyInstance._populate_cache)N)N)rrQrRrSr4rr"rrrrrrrr5r __classcell__rrrrr_s    r_c@s0eZdZdZdZdZddZddZddZd S) rezEan :class:`.AssociationProxyInstance` that has an object as a target.TcCs|j}|dk r.|j|js$||n||kS|jr\|jr\|js\|jt|j |j |S|jrz|jrz|jrzt dn|jjf|j |iSdS)aaProduce a proxied 'contains' expression using EXISTS. This expression will be a composed product using the :meth:`.RelationshipProperty.Comparator.any`, :meth:`.RelationshipProperty.Comparator.has`, and/or :meth:`.RelationshipProperty.Comparator.contains` operators of the underlying proxied attributes. NzrErT)rrrr>rErTrrrrs z_AssociationCollection.__init__cCs|Sr )rrOrrrz_AssociationCollection.cCs t|jSr lencolrOrrr__len__sz_AssociationCollection.__len__cCs t|jSr )boolrrOrrr__bool__sz_AssociationCollection.__bool__cCs|j|jdS)NrTrrrOrrrrsz#_AssociationCollection.__getstate__cCs$|d|_|d|_|j|dS)NrTr)rTrrrrrrrs  z#_AssociationCollection.__setstate__cCs||||dSr )clearr)r assoc_proxyr(rrrr}sz$_AssociationCollection._bulk_replaceN) rrQrRrrrrr __nonzero__rrr}rrrrrs rc@seZdZdZddZddZddZdd Zd d Zd d Z ddZ ddZ ddZ ddZ ddZddZddZddZddZdLd!d"Zd#d$Zd%d&Zd'd(Zd)d*Zd+d,Zd-d.Zd/d0Zd1d2Zd3d4Zd5d6Zd7d8Zd9d:Zd;d<Z d=d>Z!e!Z"d?d@Z#dAdBZ$dCdDZ%dEdFZ&dGdHZ'dIdJZ(e)e*+D]B\Z,Z-e.e-r@e-je,kr@e-js@e/e)e,r@e0e)e,je-_q@[,[-dKS)Mrz(Generic, converting, list-to-list proxy.cCs ||Sr rrvaluerrr_createsz_AssociationList._createcCs ||Sr r>robject_rrr_getsz_AssociationList._getcCs |||Sr rE)rrrrrrrsz_AssociationList._setcs6t|tsj|Sfddj|DSdS)Ncsg|]}|qSrr.0memberrOrr sz0_AssociationList.__getitem__..)rZslicerrrindexrrOr __getitem__s z_AssociationList.__getitem__c Cs t|ts||j||n|jdkr2t|}n |jdkrLt||j}n|j}|jpZd}|jpdd}tt |jprd||}|dkr|D] }||=q|}|D]}| |||d7}qnNt|t|krt dt|t|ft ||D]\}}||j||qdS)NrzBattempt to assign sequence of size %s to extended slice of size %s) rZrrrstoprstepstartrrangeinsert ValueErrorzip) rrrrrrrngiitemrrr __setitem__s2        z_AssociationList.__setitem__cCs |j|=dSr rrrrr __delitem__sz_AssociationList.__delitem__cCs$|jD]}|||krdSqdSNTFrrrrrrrr __contains__s z_AssociationList.__contains__csfddj||DS)Ncsg|]}|qSrrrrOrrr sz1_AssociationList.__getslice__..rrrendrrOr __getslice__sz_AssociationList.__getslice__cs$fdd|D}|j||<dS)Ncsg|]}|qSr)r)rrCrOrrr#sz1_AssociationList.__setslice__..r)rrrr(membersrrOr __setslice__"sz_AssociationList.__setslice__cCs|j||=dSr rrrrr __delslice__&sz_AssociationList.__delslice__ccs|jD]}||VqdS)zIterate over proxied values. For the actual domain objects, iterate over .col instead or just use the underlying collection directly from its property on the parent. Nrrrrrr__iter__)s z_AssociationList.__iter__cCs|j}||}||dSr )rrappend)rrrrrrrr5s z_AssociationList.appendcs&tddtfddt|DS)NcSsg|]}dqS)rr)r_rrrr<sz*_AssociationList.count..cs|kSr r)rCrrrr?rz(_AssociationList.count..)sumrZitertools_filteriterrrrrcount:s z_AssociationList.countcCs|D]}||qdSr )r)rr(rCrrrrDsz_AssociationList.extendcCs||g|j||<dSr )rr)rrrrrrrHsz_AssociationList.insertcCs||j|Sr )r>rrrrrrrKsz_AssociationList.popcCs4t|D]\}}||kr|j|=dSqtddS)Nzvalue not in list) enumeraterr)rrrvalrrrremoveNs z_AssociationList.removecCstdS)z#Not supported, use reversed(mylist)NrkrOrrrreverseUsz_AssociationList.reversecCstdS)z!Not supported, use sorted(mylist)NrkrOrrrsortZsz_AssociationList.sortcCs|jdt|j=dS)Nr)rrrOrrrr_sz_AssociationList.clearcCs t||kSr rrrrrrrbsz_AssociationList.__eq__cCs t||kSr rrrrrresz_AssociationList.__ne__cCs t||kSr rrrrr__lt__hsz_AssociationList.__lt__cCs t||kSr rrrrr__le__ksz_AssociationList.__le__cCs t||kSr rrrrr__gt__nsz_AssociationList.__gt__cCs t||kSr rrrrr__ge__qsz_AssociationList.__ge__cCstt||Sr )rcmprrrrr__cmp__tsz_AssociationList.__cmp__cCs2z t|}Wntk r$tYSXt||Sr r TypeErrorNotImplementedriterablerrrr__add__ws   z_AssociationList.__add__cCs2z t|}Wntk r$tYSX|t|Sr rrrrr__radd__~s   z_AssociationList.__radd__cCst|tstSt||Sr )rZintrrrnrrr__mul__s z_AssociationList.__mul__cCs|||Sr )r)rrrrr__iadd__s z_AssociationList.__iadd__cCsBt|tstS|dkr |n|dkr>|t||d|SNrr)rZrrrrrrrrr__imul__s  z_AssociationList.__imul__cGst|j|f|Sr )rr)rrargsrrrrsz_AssociationList.indexcCst|Sr rrOrrrcopysz_AssociationList.copycCs tt|Sr )reprrrOrrrrPsz_AssociationList.__repr__cCstdt|jdSNz%s objects are unhashablerrrrOrrr__hash__sz_AssociationList.__hash__N)r)1rrQrRrSrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr__rmul__r r rr rPrrlocalsitems func_namefunccallablergrfrrrrrsb    r _NotProvidedc@seZdZdZddZddZddZdd Zd d Zd d Z ddZ ddZ ddZ ddZ ddZddZddZddZddZd d!Zd"d#Zd$d%ZdEd'd(ZdFd)d*Zd+d,Zejrd-d.Zd/d0Zd1d2Zd3d4Zd5d6Znd7d6Zd8d4Ze fd9d:Z!d;d<Z"d=d>Z#d?d@Z$dAdBZ%dCdDZ&e'e(D]B\Z)Z*e+e*r:e*je)kr:e*js:e,e-e)r:e.e-e)je*_q:[)[*d&S)Grz(Generic, converting, dict-to-dict proxy.cCs |||Sr rrrrrrrrsz_AssociationDict._createcCs ||Sr rrrrrrsz_AssociationDict._getcCs||||Sr r)rrrrrrrrsz_AssociationDict._setcCs||j|Sr rrrrrrrrsz_AssociationDict.__getitem__cCs6||jkr ||j|||n||||j|<dSr )rrrrrrrrs z_AssociationDict.__setitem__cCs |j|=dSr rrrrrrsz_AssociationDict.__delitem__cCs ||jkSr rrrrrrsz_AssociationDict.__contains__cCs ||jkSr rrrrrhas_keysz_AssociationDict.has_keycCst|jSr )rrkeysrOrrrrsz_AssociationDict.__iter__cCs|jdSr rrrOrrrrsz_AssociationDict.clearcCs t||kSr rJrrrrrsz_AssociationDict.__eq__cCs t||kSr rrrrrrsz_AssociationDict.__ne__cCs t||kSr rrrrrrsz_AssociationDict.__lt__cCs t||kSr rrrrrrsz_AssociationDict.__le__cCs t||kSr rrrrrrsz_AssociationDict.__gt__cCs t||kSr rrrrrrsz_AssociationDict.__ge__cCstt||Sr )rrrJrrrrrsz_AssociationDict.__cmp__cCstt|Sr )rrJrrOrrrrPsz_AssociationDict.__repr__NcCs(z ||WStk r"|YSXdSr )r/rrdefaultrrrr"s z_AssociationDict.getcCs,||jkr ||||j|<|S||SdSr )rrr rrr setdefaults z_AssociationDict.setdefaultcCs |jSr )rrrOrrrrsz_AssociationDict.keyscsfddjDS)Nc3s"|]}|j|fVqdSr rrrrOrr sz-_AssociationDict.iteritems..rrOrrOr iteritemssz_AssociationDict.iteritemscsfddjDS)Nc3s|]}j|VqdSr rr#rOrrr$ sz._AssociationDict.itervalues..rrOrrOr itervalues sz_AssociationDict.itervaluescCs |jSr )riterkeysrOrrrr' sz_AssociationDict.iterkeyscsfddjDS)Ncsg|]}|qSrrrrOrrrsz+_AssociationDict.values..)rr(rOrrOrr(sz_AssociationDict.valuescsfddDS)Ncs g|]}|j|fqSrr)rrBrOrrrsz*_AssociationDict.items..rrOrrOrrsz_AssociationDict.itemscsfddjDS)Nc3s"|]}|j|fVqdSr rr#rOrrr$sz)_AssociationDict.items..rrOrrOrrscsfddjDS)Nc3s|]}j|VqdSr rr#rOrrr$sz*_AssociationDict.values..rrOrrOrr(scCs.|tkr|j|}n|j||}||Sr )rrrr)rrr!rrrrrsz_AssociationDict.popcCs |j}|d||dfSr )rpopitemr)rrrrrr(%s z_AssociationDict.popitemc Ost|dkrtdt|nt|dkr|d}t|drT|D]}||||<q@nPz|D]\}}|||<qZWn4tk r}ztjtd|dW5d}~XYnX|D]\}} | ||<qdS)Nrz+update expected at most 1 arguments, got %irrz4dictionary update sequence requires 2-element tuplesrW)rrrgrrr[) rarZ seq_or_maprrBrCerrrrrrrr)s*      z_AssociationDict.updatec Cs~t|}||pd}t|pd|}||}|p||kr>|||<q>|D] }||=qndSNr)r' intersection differencer) rrr(existing constants additionsremovalsrrrrrr}Fs   z_AssociationDict._bulk_replacecCs t|Sr )rJrrOrrrr Usz_AssociationDict.copycCstdt|jdSrrrOrrrrXsz_AssociationDict.__hash__)N)N)/rrQrRrSrrrrrrrrrrrrrrrrrrPr"r"rrZpy2kr%r&r'r(rrrr(rr}r rrrrrrrgrJrfrrrrrs^    rc@seZdZdZddZddZddZdd ZeZd d Z d d Z ddZ ddZ ddZ ddZddZddZddZddZddZeZd d!ZeZd"d#Zd$d%Zd&d'ZeZd(d)Zd*d+Zd,d-ZeZd.d/Zd0d1Z d2d3Z!d4d5Z"d6d7Z#d8d9Z$d:d;Z%dd?Z'd@dAZ(dBdCZ)dDdEZ*dFdGZ+dHdIZ,e-e./D]B\Z0Z1e2e1rNe1je0krNe1jsNe3e4e0rNe5e4e0je1_qN[0[1dJS)Krz&Generic, converting, set-to-set proxy.cCs ||Sr rrrrrrisz_AssociationSet._createcCs ||Sr rrrrrrlsz_AssociationSet._getcCs t|jSr rrOrrrrosz_AssociationSet.__len__cCs|jr dSdSdSrrrOrrrrrsz_AssociationSet.__bool__cCs$|jD]}|||krdSqdSrrrrrrrzs z_AssociationSet.__contains__ccs|jD]}||VqdS)zIterate over proxied values. For the actual domain objects, iterate over .col instead or just use the underlying collection directly from its property on the parent. Nrrrrrrs z_AssociationSet.__iter__cCs||kr|j||dSr )raddrrrrrr2sz_AssociationSet.addcCs.|jD]"}|||kr|j|q*qdSr )rrdiscardrrrrr3s  z_AssociationSet.discardcCs8|jD]$}|||kr|j|dSqt|dSr )rrr3r/rrrrrs   z_AssociationSet.removecCs"|jstd|j}||S)Nzpop from an empty set)rr/rrrrrrrs z_AssociationSet.popcCs|D]}||qdSr )r2rrrrrrrsz_AssociationSet.updatec Cst|}||pd}t|pd|}||}|j}|j}|pDdD]&} | |kr\|| qF| |krF|| qF|D] } || qrdSr+)r'r,r-r2r) rrr(r.r/r0r1ZappenderZremoverrrrrr}s    z_AssociationSet._bulk_replacecCs(t||stS|D]}||q|Sr )r_set_binops_check_strictrr2r4rrr__ior__s   z_AssociationSet.__ior__cCs tt|Sr )r'rrOrrrrsz_AssociationSet._setcCst||Sr )r'unionrrrrr7sz_AssociationSet.unioncCst||Sr )r'r-rrrrr-sz_AssociationSet.differencecCs|D]}||qdSr )r3r4rrrdifference_updatesz!_AssociationSet.difference_updatecCs(t||stS|D]}||q|Sr )rr5rr3r4rrr__isub__s   z_AssociationSet.__isub__cCst||Sr )r'r,rrrrr,sz_AssociationSet.intersectioncCsR||t|}}||||}}|D]}||q*|D]}||q>dSr )r,r'rr2rrZwantZhaverr2rrrrintersection_updates  z#_AssociationSet.intersection_updatecCsbt||stS||t|}}||||}}|D]}||q:|D]}||qN|Sr )rr5rr,r'rr2r:rrr__iand__s   z_AssociationSet.__iand__cCst||Sr )r'symmetric_differencerrrrr=sz$_AssociationSet.symmetric_differencecCsR||t|}}||||}}|D]}||q*|D]}||q>dSr )r=r'rr2r:rrrsymmetric_difference_updates  z+_AssociationSet.symmetric_difference_updatecCsbt||stS||t|}}||||}}|D]}||q:|D]}||qN|Sr )rr5rr=r'rr2r:rrr__ixor__s   z_AssociationSet.__ixor__cCst||Sr )r'issubsetrrrrr@sz_AssociationSet.issubsetcCst||Sr )r' issupersetrrrrrAsz_AssociationSet.issupersetcCs|jdSr rrOrrrrsz_AssociationSet.clearcCst|Sr r'rOrrrr sz_AssociationSet.copycCs t||kSr rBrrrrrsz_AssociationSet.__eq__cCs t||kSr rBrrrrr!sz_AssociationSet.__ne__cCs t||kSr rBrrrrr$sz_AssociationSet.__lt__cCs t||kSr rBrrrrr'sz_AssociationSet.__le__cCs t||kSr rBrrrrr*sz_AssociationSet.__gt__cCs t||kSr rBrrrrr-sz_AssociationSet.__ge__cCs tt|Sr )rr'rOrrrrP0sz_AssociationSet.__repr__cCstdt|jdSrrrOrrrr3sz_AssociationSet.__hash__N)6rrQrRrSrrrrrrrr2r3rrrr}r6rr7__or__r-__sub__r8r9r,__and__r;r<r=__xor__r>r?r@rArr rrrrrrrPrrrrrrrrgr'rfrrrrrfsj     r)rSrHrrrrrrZsqlr Z sql.operatorsr rsymbolrZInspectionAttrInfor objectr1r_rerhrzrrrrrrrrrs>        7 Y<\: 7P 0