ó
¿b›]c           @   sª  d  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 e f d „  ƒ  YZ e j j d d e ƒd e f d „  ƒ  Yƒ Z e j j d d e ƒd e f d „  ƒ  Yƒ Z e j j d d e ƒd e f d „  ƒ  Yƒ Z e j j d d e ƒe j d d ƒ d e f d „  ƒ  Yƒ ƒ Z d S(   sŸ   Descriptor properties are more "auxiliary" properties
that exist as configurational elements, but don't participate
as actively in the load/persist ORM loop.

i   (   t
   attributes(   t
   properties(   t   query(   t   MapperProperty(   t   PropComparator(   t	   _none_seti   (   t   event(   t   exc(   t   schema(   t   sql(   t   util(   t
   expressiont   DescriptorPropertyc           B   s   e  Z d  Z d Z d „  Z RS(   sS   :class:`.MapperProperty` which proxies access to a
        user-defined descriptor.c      	      s;  ˆ ‰ d t  f ‡  ‡ f d †  ƒ  Y} ˆ j d  k rj t ˆ  j ˆ j d  ƒ } ˆ  j | ƒ rj | ˆ _ qj n  ˆ j d  k rÇ ‡ f d †  } ‡ f d †  } ‡ f d †  } t d | d | d | ƒ ˆ _ n  t j	 ˆ j ƒ ˆ j
 j ˆ j ˆ j ‡  ‡ f d	 †  d
 ˆ j d ˆ ƒ} | ˆ j ƒ | _ ˆ  j j ˆ j | ƒ d  S(   Nt
   _ProxyImplc              sb   e  Z e Z e Z e Z e ‡  ‡ f d  †  ƒ Z d „  Z	 e
 ˆ d ƒ r` e j ‡ f d † Z n  RS(   c            s   t  ˆ  j ˆ j ƒ j j S(   N(   t   getattrt   class_t   namet   implt   uses_objects(   t   self(   t   mappert   prop(    s>   lib/python2.7/site-packages/sqlalchemy/orm/descriptor_props.pyR   *   s    c         S   s   | |  _  d  S(   N(   t   key(   R   R   (    (    s>   lib/python2.7/site-packages/sqlalchemy/orm/descriptor_props.pyt   __init__.   s    t   get_historyc            s   ˆ  j  | | | ƒ S(   N(   R   (   R   t   statet   dict_t   passive(   R   (    s>   lib/python2.7/site-packages/sqlalchemy/orm/descriptor_props.pyR   3   s    (   t   __name__t
   __module__t   Falset   accepts_scalar_loadert   Truet   expire_missingt
   collectiont   propertyR   R   t   hasattrR    t   PASSIVE_OFFR   (    (   R   R   (    s>   lib/python2.7/site-packages/sqlalchemy/orm/descriptor_props.pyR   %   s   	c            s   t  |  ˆ  j | ƒ d  S(   N(   t   setattrR   (   t   objt   value(   R   (    s>   lib/python2.7/site-packages/sqlalchemy/orm/descriptor_props.pyt   fset?   s    c            s   t  |  ˆ  j ƒ d  S(   N(   t   delattrR   (   R'   (   R   (    s>   lib/python2.7/site-packages/sqlalchemy/orm/descriptor_props.pyt   fdelB   s    c            s   t  |  ˆ  j ƒ S(   N(   R   R   (   R'   (   R   (    s>   lib/python2.7/site-packages/sqlalchemy/orm/descriptor_props.pyt   fgetE   s    R,   R)   R+   c              s   ˆ j  ˆ  ƒ S(   N(   t   _comparator_factory(    (   R   R   (    s>   lib/python2.7/site-packages/sqlalchemy/orm/descriptor_props.pyt   <lambda>N   t    t   doct   original_property(   t   objectt
   descriptort   NoneR   R   R   t   _is_userland_descriptorR#   R    t   create_proxied_attributet   parentR0   R   t   class_managert   instrument_attribute(   R   R   R   t   descR)   R+   R,   t
   proxy_attr(    (   R   R   R   s>   lib/python2.7/site-packages/sqlalchemy/orm/descriptor_props.pyt   instrument_class"   s(    !			N(   R   R   t   __doc__R4   R0   R<   (    (    (    s>   lib/python2.7/site-packages/sqlalchemy/orm/descriptor_props.pyR      s   s   sqlalchemy.orm.propertiest
   add_to_allt   CompositePropertyc           B   së   e  Z d  Z e j d d ƒ d „  ƒ Z d „  Z d „  Z d „  Z e j	 d „  ƒ Z
 e j	 d	 „  ƒ Z e d
 „  ƒ Z d „  Z d „  Z e j	 d „  ƒ Z e j d „ Z d „  Z d e j f d „  ƒ  YZ d e f d „  ƒ  YZ d „  Z RS(   sö   Defines a "composite" mapped attribute, representing a collection
    of columns as one attribute.

    :class:`.CompositeProperty` is constructed using the :func:`.composite`
    function.

    .. seealso::

        :ref:`mapper_composite`

    t	   extensions   0.7s½   :class:`.AttributeExtension` is deprecated in favor of the :class:`.AttributeEvents` listener interface.  The :paramref:`.composite.extension` parameter will be removed in a future release.c         O   s»   t  t |  ƒ j ƒ  | |  _ | |  _ | j d t ƒ |  _ | j d t ƒ |  _ | j d d ƒ |  _
 | j d |  j j ƒ |  _ d | k r  | j d ƒ |  _ n  t j |  ƒ |  j ƒ  d S(   sQ  Return a composite column-based property for use with a Mapper.

        See the mapping documentation section :ref:`mapper_composite` for a
        full usage example.

        The :class:`.MapperProperty` returned by :func:`.composite`
        is the :class:`.CompositeProperty`.

        :param class\_:
          The "composite type" class, or any classmethod or callable which
          will produce a new instance of the composite object given the
          column values in order.

        :param \*cols:
          List of Column objects to be mapped.

        :param active_history=False:
          When ``True``, indicates that the "previous" value for a
          scalar attribute should be loaded when replaced, if not
          already loaded.  See the same flag on :func:`.column_property`.

        :param group:
          A group name for this property when marked as deferred.

        :param deferred:
          When True, the column property is "deferred", meaning that it does
          not load immediately, and is instead loaded when the attribute is
          first accessed on an instance.  See also
          :func:`~sqlalchemy.orm.deferred`.

        :param comparator_factory:  a class which extends
          :class:`.CompositeProperty.Comparator` which provides custom SQL
          clause generation for comparison operations.

        :param doc:
          optional string that will be applied as the doc on the
          class-bound descriptor.

        :param info: Optional data dictionary which will be populated into the
            :attr:`.MapperProperty.info` attribute of this object.

        :param extension:
          an :class:`.AttributeExtension` instance,
          or list of extensions, which will be prepended to the list of
          attribute listeners for the resulting descriptor placed on the
          class.

        t   active_historyt   deferredt   groupt   comparator_factoryt   infoN(   t   superR?   R   t   attrst   composite_classt   getR   RA   RB   R4   RC   t   popt	   __class__t
   ComparatorRD   RE   R
   t   set_creation_ordert   _create_descriptor(   R   R   RG   t   kwargs(    (    s>   lib/python2.7/site-packages/sqlalchemy/orm/descriptor_props.pyR   d   s    :		c         C   s$   t  t |  ƒ j | ƒ |  j ƒ  d  S(   N(   RF   R?   R<   t   _setup_event_handlers(   R   R   (    (    s>   lib/python2.7/site-packages/sqlalchemy/orm/descriptor_props.pyR<   ®   s    c         C   s   |  j  ƒ  d S(   s   Initialization which occurs after the :class:`.CompositeProperty`
        has been associated with its parent mapper.

        N(   t   _setup_arguments_on_columns(   R   (    (    s>   lib/python2.7/site-packages/sqlalchemy/orm/descriptor_props.pyt   do_init²   s    c            sF   ‡  f d †  } ‡  f d †  } ‡  f d †  } t  | | | ƒ ˆ  _ d S(   st   Create the Python descriptor that will serve as
        the access point on instances of the mapped class.

        c            sÎ   t  j |  ƒ } t  j |  ƒ } ˆ  j | k r» g  ˆ  j D] } t |  | ƒ ^ q7 } ˆ  j | k r» | j d  k	 s€ t j | ƒ r» ˆ  j	 | Œ  | ˆ  j <| j
 j j | d  ˆ  j g ƒ q» n  | j ˆ  j d  ƒ S(   N(   R    t   instance_dictt   instance_stateR   t   _attribute_keysR   R4   R   t
   issupersetRH   t   managert   dispatcht   refreshRI   (   t   instanceR   R   R   t   values(   R   (    s>   lib/python2.7/site-packages/sqlalchemy/orm/descriptor_props.pyR,   ¿   s    %%c            sò   t  j |  ƒ } t  j |  ƒ } | j ˆ  j } | j ˆ  j t  j ƒ } x, | j j D] } | | | | | j	 ƒ } qS W| | ˆ  j <| d  k rµ x] ˆ  j D] } t |  | d  ƒ q˜ Wn9 x6 t ˆ  j | j ƒ  ƒ D] \ } } t |  | | ƒ qÎ Wd  S(   N(   R    RS   RT   RW   R   RI   t   NO_VALUERX   t   setR   R4   RU   R&   t   zipt   __composite_values__(   RZ   R(   R   R   t   attrt   previoust   fnR   (   R   (    s>   lib/python2.7/site-packages/sqlalchemy/orm/descriptor_props.pyR)   Ø   s    c            s‡   t  j |  ƒ } t  j |  ƒ } | j ˆ  j t  j ƒ } | j ˆ  j } | j j | | | j	 ƒ x! ˆ  j
 D] } t |  | d  ƒ qi Wd  S(   N(   R    RT   RS   RJ   R   R\   RW   RX   t   removeR   RU   R&   R4   (   RZ   R   R   Ra   R`   R   (   R   (    s>   lib/python2.7/site-packages/sqlalchemy/orm/descriptor_props.pyR+   é   s    N(   R#   R3   (   R   R,   R)   R+   (    (   R   s>   lib/python2.7/site-packages/sqlalchemy/orm/descriptor_props.pyRN   ¹   s    	c         C   s,   g  |  j  D] } t |  j j | j ƒ ^ q
 S(   N(   t   propsR   R7   R   R   (   R   R   (    (    s>   lib/python2.7/site-packages/sqlalchemy/orm/descriptor_props.pyt   _comparable_elementsô   s    c         C   s®   g  } x¡ |  j  D]– } t | t ƒ r@ |  j j | d t ƒ} nY t | t j ƒ re |  j j | } n4 t | t	 j
 ƒ rƒ | j } n t j d | f ƒ ‚ | j | ƒ q W| S(   Nt   _configure_mapperss[   Composite expects Column objects or mapped attributes/attribute names as arguments, got: %r(   RG   t
   isinstancet   strR7   t   get_propertyR   R   t   Columnt   _columntopropertyR    t   InstrumentedAttributeR#   t   sa_exct   ArgumentErrort   append(   R   Rd   R`   R   (    (    s>   lib/python2.7/site-packages/sqlalchemy/orm/descriptor_props.pyRd   ø   s    c         C   s,   g  |  j  D] } t | t j ƒ r
 | ^ q
 S(   N(   RG   Rg   R   Rj   (   R   t   a(    (    s>   lib/python2.7/site-packages/sqlalchemy/orm/descriptor_props.pyt   columns  s    c         C   sc   x\ |  j  D]Q } |  j | _ |  j rO |  j | _ d t f d t f f | _ n  |  j | _ q
 Wd S(   sw   Propagate configuration arguments made on this composite
        to the target columns, for those that apply.

        RB   t
   instrumentN(   Rd   RA   RB   R    t   strategy_keyRC   (   R   R   (    (    s>   lib/python2.7/site-packages/sqlalchemy/orm/descriptor_props.pyRQ     s    	c            sí   ‡  f d †  } ‡  f d †  } ‡ f d †  ‰  ‡ f d †  } ‡ f d †  } t  j ˆ j d | d t ƒt  j ˆ j d | d t ƒt  j ˆ j d	 | d t d
 t ƒt  j ˆ j d | d t d
 t ƒt  j ˆ j d | d t d
 t ƒd S(   s>   Establish events that populate/expire the composite attribute.c            s   ˆ  |  | d t  ƒd  S(   Nt
   is_refresh(   R   (   R   t   args(   t   _load_refresh_handler(    s>   lib/python2.7/site-packages/sqlalchemy/orm/descriptor_props.pyt   load_handler  s    c            s   ˆ  |  | d t  ƒd  S(   NRt   (   R    (   R   Ru   (   Rv   (    s>   lib/python2.7/site-packages/sqlalchemy/orm/descriptor_props.pyt   refresh_handler!  s    c            s~   |  j  } | r# ˆ  j | k r# d  Sx! ˆ  j D] } | | k r- d  Sq- Wˆ  j g  ˆ  j D] } |  j  | ^ qW Œ  | ˆ  j <d  S(   N(   t   dictR   RU   RH   (   R   Ru   Rt   R   t   kR   (   R   (    s>   lib/python2.7/site-packages/sqlalchemy/orm/descriptor_props.pyRv   $  s    	c            sA   | d  k s$ t ˆ  j ƒ j | ƒ r= |  j j ˆ  j d  ƒ n  d  S(   N(   R4   R]   RU   t   intersectionRy   RJ   R   (   R   t   keys(   R   (    s>   lib/python2.7/site-packages/sqlalchemy/orm/descriptor_props.pyt   expire_handler5  s    $c            s   | j  j ˆ  j d ƒ d S(   sê   After an insert or update, some columns may be expired due
            to server side defaults, or re-populated due to client side
            defaults.  Pop out the composite value here so that it
            recreates.

            N(   Ry   RJ   R   R4   (   R   t
   connectionR   (   R   (    s>   lib/python2.7/site-packages/sqlalchemy/orm/descriptor_props.pyt   insert_update_handler9  s    t   after_insertt   rawt   after_updatet   loadt	   propagateRY   t   expireN(   R   t   listenR7   R    (   R   Rw   Rx   R}   R   (    (   Rv   R   s>   lib/python2.7/site-packages/sqlalchemy/orm/descriptor_props.pyRP     s    
c         C   s   g  |  j  D] } | j ^ q
 S(   N(   Rd   R   (   R   R   (    (    s>   lib/python2.7/site-packages/sqlalchemy/orm/descriptor_props.pyRU   U  s    c         C   s  g  } g  } t  } x£ |  j D]˜ } | j } | j | j j | | ƒ }	 |	 j ƒ  r\ t } n  |	 j ƒ  }
 |
 r~ | j	 |
 ƒ n | j
 d ƒ |	 j r§ | j	 |	 j ƒ q | j
 d ƒ q W| ré t j |  j | Œ  g d |  j | Œ  g ƒ St j d |  j | Œ  g d ƒ Sd S(   s>   Provided for userland code that uses attributes.get_history().N(    (    (    (   R   Rd   R   RW   R   R   t   has_changesR    t   non_deletedt   extendRo   R4   t   deletedR    t   HistoryRH   (   R   R   R   R   t   addedRŠ   t   has_historyR   R   t   histRˆ   (    (    s>   lib/python2.7/site-packages/sqlalchemy/orm/descriptor_props.pyR   Y  s*    			c         C   s   |  j  |  | ƒ S(   N(   RD   (   R   R   (    (    s>   lib/python2.7/site-packages/sqlalchemy/orm/descriptor_props.pyR-   y  s    t   CompositeBundlec           B   s   e  Z d  „  Z d „  Z RS(   c         C   s,   | |  _  t t j |  ƒ j | j | Œ d  S(   N(   R#   RF   R?   R   R   R   (   R   t	   property_t   expr(    (    s>   lib/python2.7/site-packages/sqlalchemy/orm/descriptor_props.pyR   }  s    	c            s   ‡  ‡ f d †  } | S(   Nc            s)   ˆ j  j g  ˆ  D] } | |  ƒ ^ q Œ  S(   N(   R#   RH   (   t   rowt   proc(   t   procsR   (    s>   lib/python2.7/site-packages/sqlalchemy/orm/descriptor_props.pyR“   „  s    	(    (   R   R   R”   t   labelsR“   (    (   R”   R   s>   lib/python2.7/site-packages/sqlalchemy/orm/descriptor_props.pyt   create_row_processorƒ  s    (   R   R   R   R–   (    (    (    s>   lib/python2.7/site-packages/sqlalchemy/orm/descriptor_props.pyR   |  s   	RL   c           B   sb   e  Z d  Z d Z e d „  ƒ Z d „  Z d „  Z d „  Z	 e
 j d „  ƒ Z d „  Z d „  Z RS(	   s¿  Produce boolean, comparison, and other operators for
        :class:`.CompositeProperty` attributes.

        See the example in :ref:`composite_operations` for an overview
        of usage , as well as the documentation for :class:`.PropComparator`.

        .. seealso::

            :class:`.PropComparator`

            :class:`.ColumnOperators`

            :ref:`types_operators`

            :attr:`.TypeEngine.comparator_factory`

        c         C   s
   |  j  ƒ  S(   N(   t   __clause_element__(   R   (    (    s>   lib/python2.7/site-packages/sqlalchemy/orm/descriptor_props.pyt   clauses   s    c         C   s   t  j d t |  j Œ S(   NRC   (   R   t
   ClauseListR   Re   (   R   (    (    s>   lib/python2.7/site-packages/sqlalchemy/orm/descriptor_props.pyR—   ¤  s    	c         C   s   t  j |  j |  j ƒ  ƒ S(   N(   R?   R   R   R—   (   R   (    (    s>   lib/python2.7/site-packages/sqlalchemy/orm/descriptor_props.pyt   _query_clause_element©  s    c         C   s~   | d  k r. g  |  j j D] } d  ^ q } n@ t | |  j j ƒ rR | j ƒ  } n t j d |  j | f ƒ ‚ t |  j	 | ƒ S(   Ns)   Can't UPDATE composite attribute %s to %r(
   R4   R   RU   Rg   RH   R_   Rm   Rn   R^   Re   (   R   R(   R   R[   (    (    s>   lib/python2.7/site-packages/sqlalchemy/orm/descriptor_props.pyt   _bulk_update_tuples®  s    "c         C   sF   |  j  r8 g  |  j j D] } t |  j  j | j ƒ ^ q S|  j j Sd  S(   N(   t   _adapt_to_entityR   Re   R   t   entityR   (   R   R   (    (    s>   lib/python2.7/site-packages/sqlalchemy/orm/descriptor_props.pyRe   »  s    	,c         C   s£   | d  k r( d  g t |  j j ƒ } n | j ƒ  } g  t |  j j | ƒ D] \ } } | | k ^ qJ } |  j r– g  | D] } |  j | ƒ ^ qx } n  t j	 | Œ  S(   N(
   R4   t   lenR   Re   R_   R^   Rœ   t   adapterR	   t   and_(   R   t   otherR[   Rp   t   bt   comparisonst   x(    (    s>   lib/python2.7/site-packages/sqlalchemy/orm/descriptor_props.pyt   __eq__Å  s    4	%c         C   s   t  j |  j | ƒ ƒ S(   N(   R	   t   not_R¥   (   R   R¡   (    (    s>   lib/python2.7/site-packages/sqlalchemy/orm/descriptor_props.pyt   __ne__Ñ  s    N(   R   R   R=   R4   t   __hash__R#   R˜   R—   Rš   R›   R
   t   memoized_propertyRe   R¥   R§   (    (    (    s>   lib/python2.7/site-packages/sqlalchemy/orm/descriptor_props.pyRL   ‹  s   			
	c         C   s   t  |  j j j ƒ d |  j S(   Nt   .(   Rh   R7   R   R   R   (   R   (    (    s>   lib/python2.7/site-packages/sqlalchemy/orm/descriptor_props.pyt   __str__Ô  s    (   s   0.7s½   :class:`.AttributeExtension` is deprecated in favor of the :class:`.AttributeEvents` listener interface.  The :paramref:`.composite.extension` parameter will be removed in a future release.(   R   R   R=   R
   t   deprecated_paramsR   R<   RR   RN   R©   Re   Rd   R#   Rq   RQ   RP   RU   R    R%   R   R-   R   t   BundleR   R   RL   R«   (    (    (    s>   lib/python2.7/site-packages/sqlalchemy/orm/descriptor_props.pyR?   V   s$   	 G			;		: 	It   ConcreteInheritedPropertyc           B   s    e  Z d  Z d „  Z d „  Z RS(   s4  A 'do nothing' :class:`.MapperProperty` that disables
    an attribute on a concrete subclass that is only present
    on the inherited mapper, not the concrete classes' mapper.

    Cases where this occurs include:

    * When the superclass mapper is mapped against a
      "polymorphic union", which includes all attributes from
      all subclasses.
    * When a relationship() is configured on an inherited mapper,
      but not on the subclass mapper.  Concrete mappers require
      that relationship() is configured explicitly on each
      subclass.

    c         C   sP   d  } xC |  j j ƒ  D]2 } | j |  j } t | t ƒ s | j } Pq q W| S(   N(   R4   R7   t   iterate_to_roott   _propsR   Rg   R®   RD   (   R   R   t   comparator_callablet   mt   p(    (    s>   lib/python2.7/site-packages/sqlalchemy/orm/descriptor_props.pyR-   ê  s    	c            sQ   t  t ˆ  ƒ j ƒ  ‡  f d †  ‰ d t f ‡  ‡ f d †  ƒ  Y} | ƒ  ˆ  _ d  S(   Nc              s&   t  d ˆ  j ˆ  j ˆ  j f ƒ ‚ d  S(   Nsg   Concrete %s does not implement attribute %r at the instance level.  Add this property explicitly to %s.(   t   AttributeErrorR7   R   (    (   R   (    s>   lib/python2.7/site-packages/sqlalchemy/orm/descriptor_props.pyt   warn÷  s    t   NoninheritedConcretePropc              s8   e  Z ‡ f d  †  Z ‡ f d †  Z ‡  ‡ f d †  Z RS(   c            s   ˆ  ƒ  d  S(   N(    (   t   sR'   R(   (   Rµ   (    s>   lib/python2.7/site-packages/sqlalchemy/orm/descriptor_props.pyt   __set__   s    c            s   ˆ  ƒ  d  S(   N(    (   R·   R'   (   Rµ   (    s>   lib/python2.7/site-packages/sqlalchemy/orm/descriptor_props.pyt
   __delete__  s    c            s   | d  k r ˆ  j Sˆ ƒ  d  S(   N(   R4   R3   (   R·   R'   t   owner(   R   Rµ   (    s>   lib/python2.7/site-packages/sqlalchemy/orm/descriptor_props.pyt   __get__  s    (   R   R   R¸   R¹   R»   (    (   R   Rµ   (    s>   lib/python2.7/site-packages/sqlalchemy/orm/descriptor_props.pyR¶   ÿ  s   (   RF   R®   R   R2   R3   (   R   R¶   (    (   R   Rµ   s>   lib/python2.7/site-packages/sqlalchemy/orm/descriptor_props.pyR   ô  s    (   R   R   R=   R-   R   (    (    (    s>   lib/python2.7/site-packages/sqlalchemy/orm/descriptor_props.pyR®   Ø  s   	
t   SynonymPropertyc           B   sM   e  Z d d d d d d  „ Z e j d „  ƒ Z d „  Z d „  Z d „  Z	 RS(   c         C   sx   t  t |  ƒ j ƒ  | |  _ | |  _ | |  _ | |  _ | pO | rL | j pO d |  _	 | rg | |  _
 n  t j |  ƒ d S(   s}  Denote an attribute name as a synonym to a mapped property,
        in that the attribute will mirror the value and expression behavior
        of another attribute.

        e.g.::

            class MyClass(Base):
                __tablename__ = 'my_table'

                id = Column(Integer, primary_key=True)
                job_status = Column(String(50))

                status = synonym("job_status")


        :param name: the name of the existing mapped property.  This
          can refer to the string name ORM-mapped attribute
          configured on the class, including column-bound attributes
          and relationships.

        :param descriptor: a Python :term:`descriptor` that will be used
          as a getter (and potentially a setter) when this attribute is
          accessed at the instance level.

        :param map_column: **For classical mappings and mappings against
          an existing Table object only**.  if ``True``, the :func:`.synonym`
          construct will locate the :class:`.Column` object upon the mapped
          table that would normally be associated with the attribute name of
          this synonym, and produce a new :class:`.ColumnProperty` that instead
          maps this :class:`.Column` to the alternate name given as the "name"
          argument of the synonym; in this way, the usual step of redefining
          the mapping of the :class:`.Column` to be under a different name is
          unnecessary. This is usually intended to be used when a
          :class:`.Column` is to be replaced with an attribute that also uses a
          descriptor, that is, in conjunction with the
          :paramref:`.synonym.descriptor` parameter::

            my_table = Table(
                "my_table", metadata,
                Column('id', Integer, primary_key=True),
                Column('job_status', String(50))
            )

            class MyClass(object):
                @property
                def _job_status_descriptor(self):
                    return "Status: %s" % self._job_status


            mapper(
                MyClass, my_table, properties={
                    "job_status": synonym(
                        "_job_status", map_column=True,
                        descriptor=MyClass._job_status_descriptor)
                }
            )

          Above, the attribute named ``_job_status`` is automatically
          mapped to the ``job_status`` column::

            >>> j1 = MyClass()
            >>> j1._job_status = "employed"
            >>> j1.job_status
            Status: employed

          When using Declarative, in order to provide a descriptor in
          conjunction with a synonym, use the
          :func:`sqlalchemy.ext.declarative.synonym_for` helper.  However,
          note that the :ref:`hybrid properties <mapper_hybrids>` feature
          should usually be preferred, particularly when redefining attribute
          behavior.

        :param info: Optional data dictionary which will be populated into the
            :attr:`.InspectionAttr.info` attribute of this object.

            .. versionadded:: 1.0.0

        :param comparator_factory: A subclass of :class:`.PropComparator`
          that will provide custom comparison behavior at the SQL expression
          level.

          .. note::

            For the use case of providing an attribute which redefines both
            Python-level and SQL-expression level behavior of an attribute,
            please refer to the Hybrid attribute introduced at
            :ref:`mapper_hybrids` for a more effective technique.

        .. seealso::

            :ref:`synonyms` - Overview of synonyms

            :func:`.synonym_for` - a helper oriented towards Declarative

            :ref:`mapper_hybrids` - The Hybrid Attribute extension provides an
            updated approach to augmenting attribute behavior more flexibly
            than can be achieved with synonyms.

        N(   RF   R¼   R   R   t
   map_columnR3   RD   R=   R4   R0   RE   R
   RM   (   R   R   R½   R3   RD   R0   RE   (    (    s>   lib/python2.7/site-packages/sqlalchemy/orm/descriptor_props.pyR     s    l				c         C   sm   t  |  j j |  j ƒ } t | d ƒ s; t | j t ƒ rf t j	 d |  j j j
 |  j | f ƒ ‚ n  | j S(   NR#   sG   synonym() attribute "%s.%s" only supports ORM mapped attributes, got %r(   R   R7   R   R   R$   Rg   R#   R   Rm   t   InvalidRequestErrorR   (   R   R`   (    (    s>   lib/python2.7/site-packages/sqlalchemy/orm/descriptor_props.pyt   _proxied_property‹  s    "c         C   s=   |  j  } |  j r' |  j | | ƒ } n | j | | ƒ } | S(   N(   R¿   RD   (   R   R   R   t   comp(    (    s>   lib/python2.7/site-packages/sqlalchemy/orm/descriptor_props.pyR-   ˜  s
    		c         O   s+   t  |  j j |  j ƒ } | j j | | Ž  S(   N(   R   R7   R   R   R   R   (   R   t   argt   kwR`   (    (    s>   lib/python2.7/site-packages/sqlalchemy/orm/descriptor_props.pyR   ¡  s    c         C   s  |  j  r|  j | j j k rI t j d |  j | j j |  j f ƒ ‚ np | j j |  j | j k r¹ | j | j j |  j j |  j k r¹ t j d |  j |  j |  j |  j f ƒ ‚ n  t	 j
 | j j |  j ƒ } | j |  j | d | d t ƒ|  j | _ n  | |  _ d  S(   Ns>   Can't compile synonym '%s': no column on table '%s' named '%s'sp   Can't call map_column=True for synonym %r=%r, a ColumnProperty already exists keyed to the name %r for column %rt   initt	   setparent(   R½   R   t   persist_selectablet   cRm   Rn   R   t   descriptionRk   R   t   ColumnPropertyt   _configure_propertyR    t   _mapped_by_synonymR7   (   R   R7   RÃ   R³   (    (    s>   lib/python2.7/site-packages/sqlalchemy/orm/descriptor_props.pyt
   set_parent¥  s(    		%N(
   R   R   R4   R   R
   R©   R¿   R-   R   RË   (    (    (    s>   lib/python2.7/site-packages/sqlalchemy/orm/descriptor_props.pyR¼     s   t			s   0.7s‘   :func:`.comparable_property` is deprecated and will be removed in a future release.  Please refer to the :mod:`~sqlalchemy.ext.hybrid` extension.t   ComparablePropertyc           B   s)   e  Z d  Z d d d d „ Z d „  Z RS(   s;   Instruments a Python property for use in query expressions.c         C   sf   t  t |  ƒ j ƒ  | |  _ | |  _ | p= | r: | j p= d |  _ | rU | |  _ n  t	 j
 |  ƒ d S(   sš	  Provides a method of applying a :class:`.PropComparator`
        to any Python descriptor attribute.


        Allows any Python descriptor to behave like a SQL-enabled
        attribute when used at the class level in queries, allowing
        redefinition of expression operator behavior.

        In the example below we redefine :meth:`.PropComparator.operate`
        to wrap both sides of an expression in ``func.lower()`` to produce
        case-insensitive comparison::

            from sqlalchemy.orm import comparable_property
            from sqlalchemy.orm.interfaces import PropComparator
            from sqlalchemy.sql import func
            from sqlalchemy import Integer, String, Column
            from sqlalchemy.ext.declarative import declarative_base

            class CaseInsensitiveComparator(PropComparator):
                def __clause_element__(self):
                    return self.prop

                def operate(self, op, other):
                    return op(
                        func.lower(self.__clause_element__()),
                        func.lower(other)
                    )

            Base = declarative_base()

            class SearchWord(Base):
                __tablename__ = 'search_word'
                id = Column(Integer, primary_key=True)
                word = Column(String)
                word_insensitive = comparable_property(lambda prop, mapper:
                                CaseInsensitiveComparator(
                                    mapper.c.word, mapper)
                            )


        A mapping like the above allows the ``word_insensitive`` attribute
        to render an expression like::

            >>> print SearchWord.word_insensitive == "Trucks"
            lower(search_word.word) = lower(:lower_1)

        :param comparator_factory:
          A PropComparator subclass or factory that defines operator behavior
          for this property.

        :param descriptor:
          Optional when used in a ``properties={}`` declaration.  The Python
          descriptor or property to layer comparison behavior on top of.

          The like-named descriptor will be automatically retrieved from the
          mapped class if left blank in a ``properties`` declaration.

        :param info: Optional data dictionary which will be populated into the
            :attr:`.InspectionAttr.info` attribute of this object.

            .. versionadded:: 1.0.0

        N(   RF   RÌ   R   R3   RD   R=   R4   R0   RE   R
   RM   (   R   RD   R3   R0   RE   (    (    s>   lib/python2.7/site-packages/sqlalchemy/orm/descriptor_props.pyR   Ó  s    B		c         C   s   |  j  |  | ƒ S(   N(   RD   (   R   R   (    (    s>   lib/python2.7/site-packages/sqlalchemy/orm/descriptor_props.pyR-     s    N(   R   R   R=   R4   R   R-   (    (    (    s>   lib/python2.7/site-packages/sqlalchemy/orm/descriptor_props.pyRÌ   É  s   IN(   R=   R/   R    R   R   t
   interfacesR   R   R
   R   R   R   Rm   R   R	   R   R   t   langhelperst   dependency_forR    R?   R®   R¼   t   deprecated_clsRÌ   (    (    (    s>   lib/python2.7/site-packages/sqlalchemy/orm/descriptor_props.pyt   <module>   s2   :ÿ ‚5º	