B 4]7@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_collectionattrkwrR/opt/alt/python37/lib64/python3.7/site-packages/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:`.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|S)N) _as_instanceget)robjclass_instrrr__get__s   zAssociationProxy.__get__cCst|}|||||S)N)rr set)rr"valuesr#rrr__set__szAssociationProxy.__set__cCst|}||||S)N)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:`.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_classcCsy|j|jd}WnLtk r`||}|dk rXt|||}t||jd|nd}YnX|dk rz|jsz||S|SdS)NZ_inst) __dict__rKeyError _calc_ownerAssociationProxyInstance for_proxysetattr _is_canonical_non_canonical_get_for_object)rr#r"r$ownerrrrr s   zAssociationProxy._as_instancecCs2y t|}Wntjk r"dSX|jjjSdS)N)rrNoInspectionAvailablemapperZ class_managerr#)rZ target_clsinsprrrr.s  zAssociationProxy._calc_ownercsF|jtfdd}|tkr2fdd}n fdd}||fS)Ncs|dk r|SdS)Nr)target)_getterrrgettersz0AssociationProxy._default_getset..gettercst||dS)N)r1)okv)r rrsetter sz0AssociationProxy._default_getset..settercst||dS)N)r1)r;r=)r rrr>%s)roperator attrgetterdict)rcollection_classr:r>r)r9r r_default_getsets   z AssociationProxy._default_getsetcCsd|j|jfS)NzAssociationProxy(%r, %r))r r)rrrr__repr__*szAssociationProxy.__repr__)NNNNNF)N)r __module__ __qualname____doc__Z is_attributerZextension_typerr%r(r*r+r r.rCrDrrrrr ]s" P  #r c@s eZdZdZddZdZeddZeddZd d Z e d d Z ed dZ e jddZe ddZe ddZe ddZe jddZe jddZe ddZddZdd Ze d!d"Zd#d$Zd%d&Zd'd(Zd)d*Zd+d,Zd-d.Zd7d/d0Zd8d1d2Z d9d3d4Z!d5d6Z"dS):r/aA per-class object that serves class- and object-specific results. This is used by :class:`.AssociationProxy` when it is invoked in terms of a specific class or instance of a class, i.e. when it is used as a regular Python descriptor. When referring to the :class:`.AssociationProxy` as a normal Python descriptor, the :class:`.AssociationProxyInstance` is the object that actually serves the information. Under normal circumstances, its presence is transparent:: >>> 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|_||_||_dS)N)parentr owning_classr rB target_classr)rrHrIrJrrrrrOsz!AssociationProxyInstance.__init__Nc Cs~|j}|j}t||}t|tjs0td|jj }y| ||}Wnt k rft ||||SX| |||||SdS)NzEassociation proxy to a non-relationship intermediary is not supported)r rr class_mapper get_property isinstanceZRelationshipPropertyNotImplementedErrorr6r#_cls_unwrap_target_assoc_proxyAttributeError!AmbiguousAssociationProxyInstance_construct_for_assoc) clsrHrIparent_instancer rproprJ target_assocrrrr0as  z"AssociationProxyInstance.for_proxycCsb|dk rt||||St||}t|ds8t||||S|j}|rPt||||St||||SdS)NZ_is_internal_proxy)ObjectAssociationProxyInstancegetattrhasattrrQZ_impl_uses_objectsColumnAssociationProxyInstance)rSrVrHrIrJrr Z is_objectrrrrRs     z-AssociationProxyInstance._construct_for_assoccCst|j|jS)N)rrKrIrLr )rrrr _get_propertys z&AssociationProxyInstance._get_propertycCs |jS)N)r[Z comparator)rrrr _comparatorsz$AssociationProxyInstance._comparatorcCs t||}t|ttfr|SdS)N)rXrMr r/)rSrJrr rrrrOs z7AssociationProxyInstance._cls_unwrap_target_assoc_proxycCs||j|jS)N)rOrJr)rrrr_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` )rXrJr)rrrr 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` )rXrIr )rrrr local_attrs z#AssociationProxyInstance.local_attrcCs |j|jfS)azReturn a tuple of ``(local_attr, remote_attr)``. This attribute is convenient when specifying a join using :meth:`.Query.join` across two relationships:: sess.query(Parent).join(*Parent.proxied.attr) .. seealso:: :attr:`.AssociationProxyInstance.local_attr` :attr:`.AssociationProxyInstance.remote_attr` )r_r^)rrrrr szAssociationProxyInstance.attrcCs|j }|r||S)zsReturn ``True`` if this :class:`.AssociationProxyInstance` proxies a scalar relationship on the local side.)r[uselist_initialize_scalar_accessors)rscalarrrrrbs zAssociationProxyInstance.scalarcCs|j|jj S)N)r[r6rLrr`)rrrr_value_is_scalars z)AssociationProxyInstance._value_is_scalarcCs tdS)N)rN)rrrr_target_is_objectsz*AssociationProxyInstance._target_is_objectcCs>|jjr|jd|\}}n|jd\}}|||_|_dS)N)rHrrC _scalar_get _scalar_set)rr!Zset_rrrrasz5AssociationProxyInstance._initialize_scalar_accessorscsF|jtfdd}|tkr2fdd}n fdd}||fS)Ncs|dk r|SdS)Nr)r8)r9rrr:sz8AssociationProxyInstance._default_getset..gettercs t||S)N)r1)r;r<r=)r rrr>sz8AssociationProxyInstance._default_getset..settercs t||S)N)r1)r;r=)r rrr>s)rr?r@rA)rrBr:r>r)r9r rrCs   z(AssociationProxyInstance._default_getsetcCs|jjS)N)rHr)rrrrr szAssociationProxyInstance.infocCs|dkr |S|jr(t||j}||Syt||j\}}}Wntk rRYn,Xt||kr~t||kr~|jdk szt|S| t ||j\|_}t ||jt|t||f|SdS)N) rbrXr rerrPrrBAssertionError_new_lazy_collectionr1)rr"r8Z creator_idZself_idproxyrrrr!s   zAssociationProxyInstance.getcCs|jr||jjr|jjn|j}t||j}|dkrP|dkrrrrrhIs0 zAssociationProxyInstance._newcCsh|jjr|j||nL|jtkr.||n6|jtkrD||n |jtkrZ||n t ddS)NzEno proxy_bulk_set supplied for custom collection_class implementation) rHrrBrmextendrAupdater&rrq)rrjr'rrr_setys      zAssociationProxyInstance._setcCs\|jjr|jjp|j}|jjr4|j|j|\}}n|j|j\}}||_||_||_dS)N)rHrrJrrBrCr:r>)rrjrr:r>rrr_inflatesz!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 ==) popr]_criterion_existsr\rdrXrJrrrq)rrxkwargsrwrVinnerrUZ value_exprrrrrzs"    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().F)rxrw)r]rbrdrcrInvalidRequestErrorrz)rrxr{rrranys  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().T)rxrw)r]rbrdrcrr}rz)rrxr{rrrhass  zAssociationProxyInstance.hascCsd|jj|jfS)Nz%s(%r)) __class__rrH)rrrrrDsz!AssociationProxyInstance.__repr__)N)N)N)#rrErFrGrrJ classmethodr0rRr[propertyr\rOrmemoized_propertyr]r^r_r rbrcrdrarCrr!r&r)rhrurvrzr~rrDrrrrr/1s8            0   r/csneZdZdZdZddZfddZddZd d Zdd d Z dddZ e j ddZ ddZddZZS)rQzcan :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)rPrIrr rrJ)rrrr _ambiguouss z,AmbiguousAssociationProxyInstance._ambiguouscs |dkr |Stt||SdS)N)superrQr!)rr")rrrr!sz%AmbiguousAssociationProxyInstance.getcCs |dS)N)r)rr"rrr__eq__sz(AmbiguousAssociationProxyInstance.__eq__cCs |dS)N)r)rr"rrr__ne__sz(AmbiguousAssociationProxyInstance.__ne__NcKs |dS)N)r)rrxr{rrrr~sz%AmbiguousAssociationProxyInstance.anycKs |dS)N)r)rrxr{rrrrsz%AmbiguousAssociationProxyInstance.hascCsiS)Nr)rrrr _lookup_cachesz/AmbiguousAssociationProxyInstance._lookup_cachecCs|dk rt||j}|dk ry t|}Wntjk r>YnDX|j}|j}||jkrb|||y |j|St k rYnX|S)N) rXr rrr5r6r#r_populate_cacher-)rrTZ actual_objr7r6instance_classrrrr3s      z?AmbiguousAssociationProxyInstance._non_canonical_get_for_objectcCsnt|j|j}||jrj|}y|||j}Wnt k rJYn X| ||j |j||j|j |<dS)N) rrKrIrLr Zisar6rOrrPrRrHr)rrr6rUrJrVrrrr&s  z1AmbiguousAssociationProxyInstance._populate_cache)N)N)rrErFrGr2rr!rrr~rrrrr3r __classcell__rr)rrrQs   rQc@s0eZdZdZdZdZddZddZddZd S) rWzJan :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)abProduce 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. NzrH)rrrrr:r>rHrrrrs z_AssociationCollection.__init__cCs|S)N)rr)rrrrz_AssociationCollection.cCs t|jS)N)lencol)rrrr__len__sz_AssociationCollection.__len__cCs t|jS)N)boolr)rrrr__bool__sz_AssociationCollection.__bool__cCs|j|jdS)N)rHrr)rHrr)rrrrrsz#_AssociationCollection.__getstate__cCs$|d|_|d|_|j|dS)NrHrr)rHrrrv)rrrrrrs  z#_AssociationCollection.__setstate__cCs||||dS)N)clearru)r assoc_proxyr'rrrrksz$_AssociationCollection._bulk_replaceN) rrErFrrrrr __nonzero__rrrkrrrrrs 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(xVe)e*+D]D\Z,Z-e./e-rBe-je,krBe-jsBe0e)e,rBe1e)e,je-_qBW[,[-dKS)Mrnz(Generic, converting, list-to-list proxy.cCs ||S)N)r)rvaluerrr_createsz_AssociationList._createcCs ||S)N)r:)robject_rrr_getsz_AssociationList._getcCs |||S)N)r>)rrrrrrrusz_AssociationList._setcs6t|tsj|Sfddj|DSdS)Ncsg|]}|qSr)r).0member)rrr sz0_AssociationList.__getitem__..)rMslicerr)rindexr)rr __getitem__s z_AssociationList.__getitem__c Cst|ts||j||n|jdkr2t|}n |jdkrLt||j}n|j}|jpZd}|jpdd}tt |jprd||}|dkrx|D] }||=qW|}xt|D]}| |||d7}qWnRt|t|krt dt|t|fx(t ||D]\}}||j||qWdS)NrzBattempt to assign sequence of size %s to extended slice of size %s) rMrrurstoprstepstartrmrangeinsert ValueErrorzip) rrrrrrrngiitemrrr __setitem__s.          z_AssociationList.__setitem__cCs |j|=dS)N)r)rrrrr __delitem__ sz_AssociationList.__delitem__cCs&x |jD]}|||krdSqWdS)NTF)rr)rrrrrr __contains__ s z_AssociationList.__contains__csfddj||DS)Ncsg|]}|qSr)r)rr)rrrrsz1_AssociationList.__getslice__..)r)rrendr)rr __getslice__sz_AssociationList.__getslice__cs$fdd|D}|j||<dS)Ncsg|]}|qSr)r)rr=)rrrrsz1_AssociationList.__setslice__..)r)rrrr'membersr)rr __setslice__sz_AssociationList.__setslice__cCs|j||=dS)N)r)rrrrrr __delslice__sz_AssociationList.__delslice__ccs x|jD]}||VqWdS)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. N)rr)rrrrr__iter__s z_AssociationList.__iter__cCs|j}||}||dS)N)rrappend)rrrrrrrr)s z_AssociationList.appendcs&tddtfddt|DS)NcSsg|]}dqS)rr)r_rrrr1sz*_AssociationList.count..cs|kS)Nr)r=)rrrr3rz(_AssociationList.count..)sumrZitertools_filteriter)rrr)rrcount.sz_AssociationList.countcCsx|D]}||qWdS)N)r)rr'r=rrrrs8s z_AssociationList.extendcCs||g|j||<dS)N)rr)rrrrrrr<sz_AssociationList.insertcCs||j|S)N)r:rry)rrrrrry?sz_AssociationList.popcCs6x(t|D]\}}||kr |j|=dSq WtddS)Nzvalue not in list) enumeraterr)rrrvalrrrremoveBs z_AssociationList.removecCstdS)z#Not supported, use reversed(mylist)N)rN)rrrrreverseIsz_AssociationList.reversecCstdS)z!Not supported, use sorted(mylist)N)rN)rrrrsortNsz_AssociationList.sortcCs|jdt|j=dS)Nr)rr)rrrrrSsz_AssociationList.clearcCs t||kS)N)rm)rrrrrrVsz_AssociationList.__eq__cCs t||kS)N)rm)rrrrrrYsz_AssociationList.__ne__cCs t||kS)N)rm)rrrrr__lt__\sz_AssociationList.__lt__cCs t||kS)N)rm)rrrrr__le___sz_AssociationList.__le__cCs t||kS)N)rm)rrrrr__gt__bsz_AssociationList.__gt__cCs t||kS)N)rm)rrrrr__ge__esz_AssociationList.__ge__cCstt||S)N)rcmprm)rrrrr__cmp__hsz_AssociationList.__cmp__cCs.y t|}Wntk r tSXt||S)N)rm TypeErrorNotImplemented)riterablerrrr__add__ks  z_AssociationList.__add__cCs.y t|}Wntk r tSX|t|S)N)rmrr)rrrrrr__radd__rs  z_AssociationList.__radd__cCst|tstSt||S)N)rMintrrm)rnrrr__mul__ys z_AssociationList.__mul__cCs|||S)N)rs)rrrrr__iadd__s z_AssociationList.__iadd__cCsBt|tstS|dkr |n|dkr>|t||d|S)Nrr)rMrrrrsrm)rrrrr__imul__s  z_AssociationList.__imul__cGst|j|f|S)N)rmr)rrargsrrrrsz_AssociationList.indexcCst|S)N)rm)rrrrcopysz_AssociationList.copycCs tt|S)N)reprrm)rrrrrDsz_AssociationList.__repr__cCstdt|jdS)Nz%s objects are unhashable)rrr)rrrr__hash__sz_AssociationList.__hash__N)r)2rrErFrGrrrurrrrrrrrrrrsrryrrrrrrrrrrrrrr__rmul__rrrrrDrrmlocalsitems func_namefuncrcallablerYrXrrrrrnsZ       rn _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&xVe'e(D]D\Z)Z*e+e*r)rrrrrrrrusz_AssociationDict._setcCs||j|S)N)rr)rrrrrrsz_AssociationDict.__getitem__cCs6||jkr ||j|||n||||j|<dS)N)rrur)rrrrrrrs z_AssociationDict.__setitem__cCs |j|=dS)N)r)rrrrrrsz_AssociationDict.__delitem__cCs ||jkS)N)r)rrrrrrsz_AssociationDict.__contains__cCs ||jkS)N)r)rrrrrhas_keysz_AssociationDict.has_keycCst|jS)N)rrkeys)rrrrrsz_AssociationDict.__iter__cCs|jdS)N)rr)rrrrrsz_AssociationDict.clearcCs t||kS)N)rA)rrrrrrsz_AssociationDict.__eq__cCs t||kS)N)rA)rrrrrrsz_AssociationDict.__ne__cCs t||kS)N)rA)rrrrrrsz_AssociationDict.__lt__cCs t||kS)N)rA)rrrrrrsz_AssociationDict.__le__cCs t||kS)N)rA)rrrrrrsz_AssociationDict.__gt__cCs t||kS)N)rA)rrrrrrsz_AssociationDict.__ge__cCstt||S)N)rrrA)rrrrrrsz_AssociationDict.__cmp__cCstt|S)N)rrAr)rrrrrDsz_AssociationDict.__repr__NcCs"y||Stk r|SXdS)N)r-)rrdefaultrrrr!sz_AssociationDict.getcCs,||jkr ||||j|<|S||SdS)N)rr)rrrrrr setdefaults z_AssociationDict.setdefaultcCs |jS)N)rr)rrrrrsz_AssociationDict.keyscsfddjDS)Nc3s"|]}|j|fVqdS)N)rr)rr)rrr sz-_AssociationDict.iteritems..)r)rr)rr iteritemssz_AssociationDict.iteritemscsfddjDS)Nc3s|]}j|VqdS)N)rr)rr)rrrrsz._AssociationDict.itervalues..)r)rr)rr itervaluessz_AssociationDict.itervaluescCs |jS)N)riterkeys)rrrrrsz_AssociationDict.iterkeyscsfddjDS)Ncsg|]}|qSr)r)rr)rrrrsz+_AssociationDict.values..)rr')rr)rrr'sz_AssociationDict.valuescsfddDS)Ncs g|]}|j|fqSr)rr)rr<)rrrrsz*_AssociationDict.items..r)rr)rrrsz_AssociationDict.itemscsfddjDS)Nc3s"|]}|j|fVqdS)N)rr)rr)rrrr sz)_AssociationDict.items..)r)rr)rrr scsfddjDS)Nc3s|]}j|VqdS)N)rr)rr)rrrrsz*_AssociationDict.values..)r)rr)rrr'scCs.|tkr|j|}n|j||}||S)N)rrryr)rrrrrrrrysz_AssociationDict.popcCs |j}|d||dfS)Nrr)rpopitemr)rrrrrrs z_AssociationDict.popitemc Ost|dkrtdt|nvt|dkr|d}t|drXxV|D]}||||<qBWndD]*\}}||krZ|||<q@||kr@|||<q@Wx|D] }||=qtWdS)Nr)r& intersection differencer) rrr'existing constants additionsremovalsrrrrrrk7s    z_AssociationDict._bulk_replacecCs t|S)N)rAr)rrrrrFsz_AssociationDict.copycCstdt|jdS)Nz%s objects are unhashable)rrr)rrrrrIsz_AssociationDict.__hash__)N)N)/rrErFrGrrrurrrrrrrrrrrrrrrDr!rrrZpy2krrrr'rrryrrtrkrrrmrrrrrYrArXrrrrrosV       roc@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,xVe-e./D]D\Z0Z1e23e1rPe1je0krPe1jsPe4e5e0rPe6e5e0je1_qPW[0[1dJS)Krpz&Generic, converting, set-to-set proxy.cCs ||S)N)r)rrrrrrZsz_AssociationSet._createcCs ||S)N)r:)rrrrrr]sz_AssociationSet._getcCs t|jS)N)rr)rrrrr`sz_AssociationSet.__len__cCs|jr dSdSdS)NTF)r)rrrrrcsz_AssociationSet.__bool__cCs&x |jD]}|||krdSqWdS)NTF)rr)rrrrrrrks z_AssociationSet.__contains__ccs x|jD]}||VqWdS)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. N)rr)rrrrrrrs z_AssociationSet.__iter__cCs||kr|j||dS)N)raddr)rrrrrr}sz_AssociationSet.addcCs0x*|jD] }|||kr|j|PqWdS)N)rrdiscard)rrrrrrrs  z_AssociationSet.discardcCs:x,|jD]"}|||kr|j|dSqWt|dS)N)rrrr-)rrrrrrrs   z_AssociationSet.removecCs"|jstd|j}||S)Nzpop from an empty set)rr-ryr)rrrrrrys z_AssociationSet.popcCsx|D]}||qWdS)N)r)rrrrrrrts z_AssociationSet.updatec Cst|}||pd}t|pd|}||}|j}|j}x2|pFdD]&} | |kr^|| qH| |krH|| qHWx|D] } || qxWdS)Nr)r&rrrr) rrr'rrrrZappenderZremoverrrrrrks    z_AssociationSet._bulk_replacecCs,t||stSx|D]}||qW|S)N)r_set_binops_check_strictrr)rrrrrr__ior__s   z_AssociationSet.__ior__cCs tt|S)N)r&r)rrrrrusz_AssociationSet._setcCst||S)N)r&union)rrrrrrsz_AssociationSet.unioncCst||S)N)r&r)rrrrrrsz_AssociationSet.differencecCsx|D]}||qWdS)N)r)rrrrrrdifference_updates z!_AssociationSet.difference_updatecCs,t||stSx|D]}||qW|S)N)rrrr)rrrrrr__isub__s   z_AssociationSet.__isub__cCst||S)N)r&r)rrrrrrsz_AssociationSet.intersectioncCsZ||t|}}||||}}x|D]}||q,Wx|D]}||qDWdS)N)rr&rr)rrwanthaverrrrrrintersection_updates   z#_AssociationSet.intersection_updatecCsjt||stS||t|}}||||}}x|D]}||qs:        7 U3\; 7P -