ó
¿b›]c           @   s  d  Z  d d l m 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	 e j
 e ƒ Z d
 „  Z d Z d Z d e f d „  ƒ  YZ d e f d „  ƒ  YZ e ƒ  e _ d e f d „  ƒ  YZ d e f d „  ƒ  YZ d e e f d „  ƒ  YZ d S(   s@   Path tracking utilities, representing mapper graph traversals.

iÿÿÿÿ(   t   chainNi   (   t   class_mapperi   (   t   exc(   t
   inspection(   t   utilc         C   s   t  j |  ƒ S(   N(   t   PathRegistryt   deserialize(   t   path(    (    s;   lib/python2.7/site-packages/sqlalchemy/orm/path_registry.pyt   _unreduce_path   s    t   *t   _sa_defaultR   c           B   s
  e  Z d  Z e Z e Z d „  Z d „  Z d „  Z d d „ Z
 d „  Z e d „  ƒ Z d „  Z d „  Z d	 „  Z d
 „  Z e d „  ƒ Z e d „  ƒ Z e d „  ƒ Z e d „  ƒ Z d „  Z e d „  ƒ Z e d „  ƒ Z e d „  ƒ Z d „  Z d „  Z d „  Z RS(   sÜ  Represent query load paths and registry functions.

    Basically represents structures like:

    (<User mapper>, "orders", <Order mapper>, "items", <Item mapper>)

    These structures are generated by things like
    query options (joinedload(), subqueryload(), etc.) and are
    used to compose keys stored in the query._attributes dictionary
    for various options.

    They are then re-composed at query compile/result row time as
    the query is formed and as rows are fetched, where they again
    serve to compose keys to look up options in the context.attributes
    dictionary, which is copied from query._attributes.

    The path structure has a limited amount of caching, where each
    "root" ultimately pulls from a fixed registry associated with
    the first mapper, that also contains elements for each of its
    property keys.  However paths longer than two elements, which
    are the exception rather than the rule, are generated on an
    as-needed basis.

    c         C   s   | d  k	 o |  j | j k S(   N(   t   NoneR   (   t   selft   other(    (    s;   lib/python2.7/site-packages/sqlalchemy/orm/path_registry.pyt   __eq__<   s    c         C   s-   t  j d | |  | ƒ | | | |  j f <d  S(   Ns   set '%s' on path '%s' to '%s'(   t   logt   debugt   natural_path(   R   t
   attributest   keyt   value(    (    s;   lib/python2.7/site-packages/sqlalchemy/orm/path_registry.pyt   set?   s    c         C   s3   t  j d | |  | ƒ | j | |  j f | ƒ d  S(   Ns$   setdefault '%s' on path '%s' to '%s'(   R   R   t
   setdefaultR   (   R   R   R   R   (    (    s;   lib/python2.7/site-packages/sqlalchemy/orm/path_registry.pyR   C   s    c         C   s+   | |  j  f } | | k r# | | S| Sd  S(   N(   R   (   R   R   R   R   (    (    s;   lib/python2.7/site-packages/sqlalchemy/orm/path_registry.pyt   getG   s    c         C   s   t  |  j ƒ S(   N(   t   lenR   (   R   (    (    s;   lib/python2.7/site-packages/sqlalchemy/orm/path_registry.pyt   __len__N   s    c         C   s   t  |  j ƒ S(   N(   R   R   (   R   (    (    s;   lib/python2.7/site-packages/sqlalchemy/orm/path_registry.pyt   lengthQ   s    c         c   sG   |  j  } x7 t d t | ƒ d ƒ D] } | | | | d f Vq" Wd  S(   Ni    i   i   (   R   t   rangeR   (   R   R   t   i(    (    s;   lib/python2.7/site-packages/sqlalchemy/orm/path_registry.pyt   pairsU   s    	c         C   sd   x] g  t  d t |  j ƒ d ƒ D] } |  j | ^ q D]" } | j r6 | j | ƒ r6 t Sq6 Wt Sd  S(   Ni    i   (   R   R   R   t	   is_mappert   isat   Truet   False(   R   t   mapperR   t   path_mapper(    (    s;   lib/python2.7/site-packages/sqlalchemy/orm/path_registry.pyt   contains_mapperZ   s    <c         C   s   | |  j  f | k S(   N(   R   (   R   R   R   (    (    s;   lib/python2.7/site-packages/sqlalchemy/orm/path_registry.pyt   containsa   s    c         C   s   t  |  j ƒ  f f S(   N(   R   t	   serialize(   R   (    (    s;   lib/python2.7/site-packages/sqlalchemy/orm/path_registry.pyt
   __reduce__d   s    c         C   s…   t  t g  g  t d t | ƒ d ƒ D] } | | ^ q" D] } | j ^ q6 g  t d t | ƒ d ƒ D] } | | j ^ qa d  g ƒ ƒ S(   Ni    i   i   (   t   listt   zipR   R   t   class_R   R   (   t   clsR   R   t   m(    (    s;   lib/python2.7/site-packages/sqlalchemy/orm/path_registry.pyt   _serialize_pathg   s    Bc         C   s€   t  t g  | D]= \ } } t | ƒ | d  k	 rA t | ƒ j | n d  f ^ q Œ  ƒ } | r| | d d  k r| | d d !} n  | S(   Niÿÿÿÿi    (   t   tupleR    R   R   t   attrs(   R+   R   t   mclsR   t   p(    (    s;   lib/python2.7/site-packages/sqlalchemy/orm/path_registry.pyt   _deserialize_pathp   s    Mc         C   s|   g  g  | j  ƒ  D]7 \ } } t | t ƒ r | d | k r | | f ^ q D]- \ \ } } } | |  j | ƒ f | f ^ qK S(   Ni    (   t   itemst
   isinstanceR.   R-   (   R+   t   dict_t   tokenst   kt   vR   R   R   (    (    s;   lib/python2.7/site-packages/sqlalchemy/orm/path_registry.pyt   serialize_context_dictƒ   s    c            s   t  j ‡  f d †  | Dƒ ƒ S(   Nc         3   s<   |  ]2 \ \ } } } | t  ˆ  j | ƒ ƒ f | f Vq d  S(   N(   R.   R2   (   t   .0R   R   R   (   R+   (    s;   lib/python2.7/site-packages/sqlalchemy/orm/path_registry.pys	   <genexpr>‘   s   (   R   t   OrderedDict(   R+   t
   serialized(    (   R+   s;   lib/python2.7/site-packages/sqlalchemy/orm/path_registry.pyt   deserialize_context_dictŽ   s    c         C   s   |  j  } |  j | ƒ S(   N(   R   R-   (   R   R   (    (    s;   lib/python2.7/site-packages/sqlalchemy/orm/path_registry.pyR&   •   s    	c         C   s,   | d  k r d  S|  j | ƒ } |  j | ƒ S(   N(   R   R2   t   coerce(   R+   R   R1   (    (    s;   lib/python2.7/site-packages/sqlalchemy/orm/path_registry.pyR   ™   s    c         C   s   t  |  j | ƒ S(   N(   t   EntityRegistryt   root(   R+   R"   (    (    s;   lib/python2.7/site-packages/sqlalchemy/orm/path_registry.pyt
   per_mapper    s    c         C   s   t  j d „  | |  j ƒ S(   Nc         S   s   |  | S(   N(    (   t   prevt   next(    (    s;   lib/python2.7/site-packages/sqlalchemy/orm/path_registry.pyt   <lambda>¦   t    (   R   t   reduceR@   (   R+   t   raw(    (    s;   lib/python2.7/site-packages/sqlalchemy/orm/path_registry.pyR>   ¤   s    c         C   sZ   | j  d t ƒ r  t |  | ƒ S| j  d t ƒ rC t |  j | ƒ St j d | ƒ ‚ d  S(   Nt   :s   invalid token: %s(   t   endswitht   _WILDCARD_TOKENt   TokenRegistryt   _DEFAULT_TOKENR@   R   t   ArgumentError(   R   t   token(    (    s;   lib/python2.7/site-packages/sqlalchemy/orm/path_registry.pyRN   ¨   s
    c         C   s   t  j d „  | j |  ƒ S(   Nc         S   s   |  | S(   N(    (   RB   RC   (    (    s;   lib/python2.7/site-packages/sqlalchemy/orm/path_registry.pyRD   ±   RE   (   R   RF   R   (   R   R   (    (    s;   lib/python2.7/site-packages/sqlalchemy/orm/path_registry.pyt   __add__°   s    c         C   s   d |  j  j |  j f S(   Ns   %s(%r)(   t	   __class__t   __name__R   (   R   (    (    s;   lib/python2.7/site-packages/sqlalchemy/orm/path_registry.pyt   __repr__³   s    N(   RQ   t
   __module__t   __doc__R!   t   is_tokent   is_rootR   R   R   R   R   R   t   propertyR   R   R$   R%   R'   t   classmethodR-   R2   R9   R=   R&   R   RA   R>   RN   RO   RR   (    (    (    s;   lib/python2.7/site-packages/sqlalchemy/orm/path_registry.pyR      s0   												t   RootRegistryc           B   s3   e  Z d  Z d Z Z e Z e Z e Z	 d „  Z
 RS(   sX   Root registry, defers to mappers so that
    paths are maintained per-root-mapper.

    c         C   s   | j  S(   N(   t   _path_registry(   R   t   entity(    (    s;   lib/python2.7/site-packages/sqlalchemy/orm/path_registry.pyt   __getitem__Â   s    (    (   RQ   RS   RT   R   R   R!   t
   has_entityt   is_aliased_classR    RV   R\   (    (    (    s;   lib/python2.7/site-packages/sqlalchemy/orm/path_registry.pyRY   ·   s   
RK   c           B   s/   e  Z d  „  Z e Z e Z d „  Z d „  Z RS(   c         C   s<   | |  _  | |  _ | j | f |  _ | j | f |  _ d  S(   N(   RN   t   parentR   R   (   R   R_   RN   (    (    s;   lib/python2.7/site-packages/sqlalchemy/orm/path_registry.pyt   __init__Ê   s    		c         c   s¶   |  j  j rU |  j  j rU x• |  j  j j ƒ  D]! } t |  j  j  | |  j ƒ Vq- Wn] |  j  j r­ |  j  j j r­ |  Vx: |  j  j j	 D]! } t |  j  j  | |  j ƒ Vq… Wn |  Vd  S(   N(
   R_   R^   RV   R"   t   iterate_to_rootRK   RN   R[   t   _is_with_polymorphict   _with_polymorphic_entities(   R   t   ent(    (    s;   lib/python2.7/site-packages/sqlalchemy/orm/path_registry.pyt   generate_for_superclassesÔ   s    ""c         C   s   t  ƒ  ‚ d  S(   N(   t   NotImplementedError(   R   R[   (    (    s;   lib/python2.7/site-packages/sqlalchemy/orm/path_registry.pyR\   â   s    (	   RQ   RS   R`   R!   R]   R    RU   Re   R\   (    (    (    s;   lib/python2.7/site-packages/sqlalchemy/orm/path_registry.pyRK   É   s
   		t   PropRegistryc           B   se   e  Z d  „  Z d „  Z e j d „  ƒ Z e j d „  ƒ Z e d „  ƒ Z	 e d „  ƒ Z
 d „  Z RS(   c         C   s  t  j | d ƒ } | j s& | j r9 | j | j } n_ | j r˜ | j r˜ | j | j k	 r˜ | j | j k r˜ | d j | j ƒ } | j | } q˜ n  | |  _ | |  _ | j	 | f |  _	 | j
 | f |  _
 d |  j j	 |  j j f |  _ |  j j |  _ d |  j	 f |  _ d  S(   Niÿÿÿÿt   loader(   R   t   inspectR^   t   _use_mapper_pathR_   t   with_polymorphic_mappersR"   t   _entity_for_mappert   propR   R   t   _wildcard_tokent   _wildcard_path_loader_keyt   _default_path_loader_keyt   _loader_key(   R   R_   Rm   t   inspt   subclass_entity(    (    s;   lib/python2.7/site-packages/sqlalchemy/orm/path_registry.pyR`   ç   s     		c         C   s   d j  d „  |  j Dƒ ƒ S(   Ns    -> c         s   s   |  ] } t  | ƒ Vq d  S(   N(   t   str(   R:   t   elem(    (    s;   lib/python2.7/site-packages/sqlalchemy/orm/path_registry.pys	   <genexpr>  s    (   t   joinR   (   R   (    (    s;   lib/python2.7/site-packages/sqlalchemy/orm/path_registry.pyt   __str__  s    c         C   s   t  |  j d ƒ S(   NR"   (   t   hasattrRm   (   R   (    (    s;   lib/python2.7/site-packages/sqlalchemy/orm/path_registry.pyR]     s    c         C   s
   |  j  j S(   N(   Rm   R"   (   R   (    (    s;   lib/python2.7/site-packages/sqlalchemy/orm/path_registry.pyR[     s    c         C   s   |  j  S(   N(   R[   (   R   (    (    s;   lib/python2.7/site-packages/sqlalchemy/orm/path_registry.pyR"     s    c         C   s   |  |  j  S(   N(   R[   (   R   (    (    s;   lib/python2.7/site-packages/sqlalchemy/orm/path_registry.pyt   entity_path  s    c         C   s1   t  | t t f ƒ r  |  j | St |  | ƒ Sd  S(   N(   R4   t   intt   sliceR   R?   (   R   R[   (    (    s;   lib/python2.7/site-packages/sqlalchemy/orm/path_registry.pyR\     s    (   RQ   RS   R`   Rw   R   t   memoized_propertyR]   R[   RW   R"   Ry   R\   (    (    (    s;   lib/python2.7/site-packages/sqlalchemy/orm/path_registry.pyRg   æ   s   		R?   c           B   sM   e  Z e Z e Z d  „  Z e d „  ƒ Z d „  Z	 e	 Z
 d „  Z d „  Z RS(   c         C   sº   | |  _  | |  _ | j |  _ | |  _ | j | f |  _ | j r¡ |  j r¡ | j j | j d j ƒ r | j | j f |  _ q­ | j | j d j f |  _ n |  j |  _ |  |  _ d  S(   Niÿÿÿÿ(	   R   R_   R^   R[   R   R"   R   R   Ry   (   R   R_   R[   (    (    s;   lib/python2.7/site-packages/sqlalchemy/orm/path_registry.pyR`     s    			
c         C   s   t  j |  j ƒ j S(   N(   R   Ri   R[   R"   (   R   (    (    s;   lib/python2.7/site-packages/sqlalchemy/orm/path_registry.pyR"   9  s    c         C   s   t  S(   N(   R    (   R   (    (    s;   lib/python2.7/site-packages/sqlalchemy/orm/path_registry.pyt   __bool__=  s    c         C   s4   t  | t t f ƒ r  |  j | St j |  | ƒ Sd  S(   N(   R4   Rz   R{   R   t   dictR\   (   R   R[   (    (    s;   lib/python2.7/site-packages/sqlalchemy/orm/path_registry.pyR\   B  s    c         C   s   t  |  | ƒ |  | <} | S(   N(   Rg   (   R   R   t   item(    (    s;   lib/python2.7/site-packages/sqlalchemy/orm/path_registry.pyt   __missing__H  s    (   RQ   RS   R!   R^   R    R]   R`   RW   R"   R}   t   __nonzero__R\   R€   (    (    (    s;   lib/python2.7/site-packages/sqlalchemy/orm/path_registry.pyR?     s   			(   RT   t	   itertoolsR    t   loggingt   baseR   RE   R   R   R   t	   getLoggerRQ   R   R   RJ   RL   t   objectR   RY   R@   RK   Rg   R~   R?   (    (    (    s;   lib/python2.7/site-packages/sqlalchemy/orm/path_registry.pyt   <module>	   s    	˜5