
[[\O                 @   s   d  d l  Z  d  d l m Z d  d l m Z m Z d d d g Z d d   Z d	 d
   Z d d   Z	 d d   Z
 Gd d   d e  Z d Z Gd d   d e  Z Gd d   d d e Z Gd d   d e e  Z d d   Z d S)    N)OrderedDict)MappingProxyTypeDynamicClassAttributeEnumIntEnumuniquec             C   s+   t  |  d  p* t  |  d  p* t  |  d  S)z5Returns True if obj is a descriptor, False otherwise.__get____set__
__delete__)hasattr)obj r   /usr/lib/python3.4/enum.py_is_descriptor   s    r   c             C   sl   |  d d  |  d d  k o+ d k n ok |  d d  d k ok |  d d	  d k ok t  |   d k S)
z3Returns True if a __dunder__ name, False otherwise.N   __   _   r   )len)namer   r   r   
_is_dunder   s    0r   c             C   s`   |  d |  d k o d k n o_ |  d d  d k o_ |  d d  d k o_ t  |   d k S)z1Returns True if a _sunder_ name, False otherwise.r      r   r   r   r   )r   )r   r   r   r   
_is_sunder   s    $r   c             C   s"   d d   } | |  _  d |  _ d S)z"Make the given class un-picklable.c             S   s   t  d |    d  S)Nz%r cannot be pickled)	TypeError)selfprotor   r   r   _break_on_call_reduce"   s    z6_make_class_unpicklable.<locals>._break_on_call_reducez	<unknown>N)__reduce_ex__
__module__)clsr    r   r   r   _make_class_unpicklable    s    	r$   c                   s:   e  Z d  Z d Z   f d d   Z   f d d   Z   S)	_EnumDictzTrack enum member order and ensure member names are not reused.

    EnumMeta will use the names found in self._member_names as the
    enumeration member names.

    c                s   t    j   g  |  _ d  S)N)super__init___member_names)r   )	__class__r   r   r'   /   s    z_EnumDict.__init__c                s   t  |  r t d   ns t |  r* nd | |  j k rL t d |   nB t |  s | |  k r{ t d |  |   n  |  j j |  n  t   j | |  d S)zChanges anything not dundered or not a descriptor.

        If an enum member name is used twice, an error is raised; duplicate
        values are not checked for.

        Single underscore (sunder) names are reserved.

        z(_names_ are reserved for future Enum usezAttempted to reuse key: %rzKey already defined as: %rN)	r   
ValueErrorr   r(   r   r   appendr&   __setitem__)r   keyvalue)r)   r   r   r,   3   s    	z_EnumDict.__setitem__)__name__r"   __qualname____doc__r'   r,   r   r   )r)   r   r%   (   s   r%   c            	       s6  e  Z d  Z d Z e d d    Z   f d d   Z d d d d d d	 d d
 d Z d d   Z   f d d   Z	 d d   Z
 d d   Z d d   Z d d   Z d d   Z e d d    Z d d   Z d d   Z   f d  d!   Z d d d d d d	 d d" d# Z e d$ d%    Z e d& d'    Z   S)(EnumMetazMetaclass for Enumc             C   s   t    S)N)r%   )metaclsr#   basesr   r   r   __prepare__T   s    zEnumMeta.__prepare__c                s4  |  j  |  \  } |  j    |  \ } } }   f d d     j D } x   j D] }	   |	 =qY Wt |  d h @}
 |
 r t d j d j |
     n  t   j |  | |    } g  | _	 t
   | _  | _ i  | _ d   k r6 t k	 r6d } t  f d
 d   | D  s3t |  q3q6n  x[  j D]P} | | } t | t  sk| f } n | }  t k r| f } n  | s| |  } t | d  s| | _ qn0 | | |  } t | d  s |   | _ n  | j } | | _ | | _ | j |   xI | j j   D]( \ }	 } | j | j k r!| } Pq!q!W| j	 j |  | | j | <y | | j | <Wq@t k
 rYq@Xq@Wxl d D]d }	 t | |	  } t  |	 d   } t | |	 d   } | d  k	 r| | k rt | |	 |  qqWt d  k	 r0| r!| | _ n  t j | _ n  | S)Nc                s   i  |  ] }   | |  q Sr   r   ).0k)	classdictr   r   
<dictcomp>c   s   	 z$EnumMeta.__new__.<locals>.<dictcomp>mrozInvalid enum member name: {0},r!   __getnewargs_ex____getnewargs__
__reduce__c             3   s   |  ] } |   j  k Vq d  S)N)__dict__)r6   m)member_typer   r   	<genexpr>   s    z#EnumMeta.__new__.<locals>.<genexpr>_value___repr____str__
__format__)r<   z__getnewargs____reduce_ex__z
__reduce__)z__repr__z__str__z
__format__rG   )_get_mixins_
_find_new_r(   setr*   formatjoinr&   __new___member_names_r   _member_map__member_type__value2member_map_objectanyr$   
isinstancetupler   rC   _name___objclass__r'   itemsr+   r   getattrsetattrr   __new_member__)r3   r#   r4   r8   
first_enumrM   save_newuse_argsZmembersr   Zinvalid_names
enum_classmethodsmember_namer.   argsZenum_memberZcanonical_memberZclass_methodZ
obj_methodZenum_method)r)   )r8   rA   r   rM   X   sx    				 
				zEnumMeta.__new__Nmodulequalnametypec         	   C   s>   | d k r |  j  |  |  S|  j | | d | d | d | S)a  Either returns an existing member, or creates a new enum class.

        This method is used both when an enum class is given a value to match
        to an enumeration member (i.e. Color(3)) and for the functional API
        (i.e. Color = Enum('Color', names='red green blue')).

        When used for the functional API:

        `value` will be the name of the new class.

        `names` should be either a string of white-space/comma delimited names
        (values will start at 1), or an iterator/mapping of name, value pairs.

        `module` should be set to the module this class is being created in;
        if it is not set, an attempt to find that module will be made, but if
        it fails the class will not be picklable.

        `qualname` should be set to the actual location this class can be found
        at in its module; by default it is set to the global scope.  If this is
        not correct, unpickling will fail in some circumstances.

        `type`, if set, will be mixed in as the first base class.

        Nrc   rd   re   )rM   _create_)r#   r.   namesrc   rd   re   r   r   r   __call__   s    zEnumMeta.__call__c             C   s   t  | |   o | j |  j k S)N)rT   rV   rO   )r#   memberr   r   r   __contains__   s    zEnumMeta.__contains__c                s9   | |  j  k r% t d |  j   n  t   j |  d  S)Nz%s: cannot delete Enum member.)rO   AttributeErrorr/   r&   __delattr__)r#   attr)r)   r   r   rl      s    zEnumMeta.__delattr__c             C   s   d d d d g |  j  S)Nr)   r1   __members__r"   )rN   )r   r   r   r   __dir__   s    zEnumMeta.__dir__c             C   sR   t  |  r t |   n  y |  j | SWn! t k
 rM t |  d  Yn Xd S)a5  Return the enum member matching `name`

        We use __getattr__ instead of descriptors or inserting into the enum
        class' __dict__ in order to support `name` and `value` being both
        properties for enum members (which live in the class' __dict__) and
        enum members themselves.

        N)r   rk   rO   KeyError)r#   r   r   r   r   __getattr__   s    	zEnumMeta.__getattr__c             C   s   |  j  | S)N)rO   )r#   r   r   r   r   __getitem__  s    zEnumMeta.__getitem__c                s     f d d     j  D S)Nc             3   s   |  ] }   j  | Vq d  S)N)rO   )r6   r   )r#   r   r   rB     s    z$EnumMeta.__iter__.<locals>.<genexpr>)rN   )r#   r   )r#   r   __iter__  s    zEnumMeta.__iter__c             C   s   t  |  j  S)N)r   rN   )r#   r   r   r   __len__  s    zEnumMeta.__len__c             C   s   t  |  j  S)zReturns a mapping of member name->value.

        This mapping lists all enum members, including aliases. Note that this
        is a read-only view of the internal mapping.

        )r   rO   )r#   r   r   r   rn   
  s    zEnumMeta.__members__c             C   s   d |  j  S)Nz	<enum %r>)r/   )r#   r   r   r   rD     s    zEnumMeta.__repr__c                s      f d d   t    j  D S)Nc             3   s   |  ] }   j  | Vq d  S)N)rO   )r6   r   )r#   r   r   rB     s    z(EnumMeta.__reversed__.<locals>.<genexpr>)reversedrN   )r#   r   )r#   r   __reversed__  s    zEnumMeta.__reversed__c                sG   |  j  j d i   } | | k r0 t d   n  t   j | |  d S)zBlock attempts to reassign Enum members.

        A simple assignment to the class namespace only changes one of the
        several possible ways to get an Enum member from the Enum class,
        resulting in an inconsistent Enumeration.

        rO   zCannot reassign members.N)r?   getrk   r&   __setattr__)r#   r   r.   Z
member_map)r)   r   r   rx     s    zEnumMeta.__setattr__c            C   s  |  j  } | d k r |  f n	 | |  f } | j | |  } t | t  rf | j d d  j   } n  t | t t f  r t | d t  r d d   t | d  D } n  xG | D]? }	 t |	 t  r |	 | |	 }
 } n |	 \ }
 } | | |
 <q W| j	 | | | |  } | d k rfy t
 j d  j d	 } Wqft t f k
 rb} z WYd d } ~ XqfXn  | d k rt |  n	 | | _ | d k	 r| | _ n  | S)
a}  Convenience method to create a new Enum class.

        `names` can be:

        * A string containing member names, separated either with spaces or
          commas.  Values are auto-numbered from 1.
        * An iterable of member names.  Values are auto-numbered from 1.
        * An iterable of (member name, value) pairs.
        * A mapping of member name -> value.

        Nr;    r   c             S   s"   g  |  ] \ } } | | f  q Sr   r   )r6   ier   r   r   
<listcomp>;  s   	 z%EnumMeta._create_.<locals>.<listcomp>r   r   r/   )r)   r5   rT   strreplacesplitrU   list	enumeraterM   sys	_getframe	f_globalsrk   r*   r$   r"   r0   )r#   Z
class_namerg   rc   rd   re   r3   r4   r8   itemra   Zmember_valuer_   excr   r   r   rf   '  s0    	!(	zEnumMeta._create_c             C   s  |  s t  t f Sd } } xA |  D]9 } | t k	 r! t | t  r! | j r! t d   q! q! Wt | t  s| t d   n  t |  d t  s |  d } |  d } nT xQ |  d j D]B } t | t  r | d k r | } q q | d k r | } q q W| | f S)zReturns the type for creating enum members, and the first inherited
        enum class.

        bases: the tuple of bases that was given to __new__

        NzCannot extend enumerationszHnew enumerations must be created as `ClassName([mixin_type,] enum_type)`r   r   r   )rR   r   
issubclassrN   r   __mro__)r4   rA   r\   baser   r   r   rH   V  s(    

	
zEnumMeta._get_mixins_c       	      C   s   |  j  d d  } | d k	 } | d k r x~ d D]j } xQ | | f D]C } t | | d  } | d d j t j t j h k rD | } PqD qD W| d k	 r1 Pq1 q1 Wt j } n  | t j k r d } n d } | | | f S)a  Returns the __new__ to be used for creating the enum members.

        classdict: the class dictionary given to __new__
        member_type: the data type whose __new__ will be used by default
        first_enum: enumeration to check for an overriding __new__

        rM   Nr[   FT)z__new_member__z__new__)rw   rY   rM   rR   r   )	r8   rA   r\   rM   r]   methodZpossibletargetr^   r   r   r   rI     s(    	zEnumMeta._find_new_)r/   r"   r0   r1   classmethodr5   rM   rh   rj   rl   ro   rq   rr   rs   rt   propertyrn   rD   rv   rx   rf   staticmethodrH   rI   r   r   )r)   r   r2   R   s$   l!
!/-r2   c               @   s   e  Z d  Z d Z d d   Z d d   Z d d   Z d d	   Z d
 d   Z d d   Z	 d d   Z
 e d d    Z e d d    Z d S)r   zRGeneric enumeration.

    Derive from this class to define new enumerations.

    c             C   s   t  |  |  k r | Sy | |  j k r3 |  j | SWn? t k
 ru x* |  j j   D] } | j | k rT | SqT WYn Xt d | |  j f   d  S)Nz%r is not a valid %s)re   rQ   r   rO   valuesrC   r*   r/   )r#   r.   ri   r   r   r   rM     s    zEnum.__new__c             C   s   d |  j  j |  j |  j f S)Nz<%s.%s: %r>)r)   r/   rV   rC   )r   r   r   r   rD     s    zEnum.__repr__c             C   s   d |  j  j |  j f S)Nz%s.%s)r)   r/   rV   )r   r   r   r   rE     s    zEnum.__str__c             C   s0   d d   |  j  j D } d d d d d g | S)Nc             S   s&   g  |  ] } | d  d k r |  q S)r   r   r   )r6   r@   r   r   r   r|     s   	 z Enum.__dir__.<locals>.<listcomp>r)   r1   r"   r   r.   )r)   r?   )r   Zadded_behaviorr   r   r   ro     s    zEnum.__dir__c             C   sF   |  j  t k r$ t } t |   } n |  j  } |  j } | j | |  S)N)rP   rR   r}   rC   rF   )r   Zformat_specr#   valr   r   r   rF     s    		zEnum.__format__c             C   s   t  |  j  S)N)hashrV   )r   r   r   r   __hash__  s    zEnum.__hash__c             C   s   |  j  |  j f f S)N)r)   rC   )r   r   r   r   r   r!     s    zEnum.__reduce_ex__c             C   s   |  j  S)zThe name of the Enum member.)rV   )r   r   r   r   r     s    z	Enum.namec             C   s   |  j  S)zThe value of the Enum member.)rC   )r   r   r   r   r.     s    z
Enum.valueN)r/   r"   r0   r1   rM   rD   rE   ro   rF   r   r!   r   r   r.   r   r   r   r   r     s   
	metaclassc               @   s   e  Z d  Z d Z d S)r   z.Enum where members are also (and must be) intsN)r/   r"   r0   r1   r   r   r   r   r     s   c             C   s   g  } xE |  j  j   D]4 \ } } | | j k r | j | | j f  q q W| r d j d d   | D  } t d |  | f   n  |  S)z?Class decorator for enumerations ensuring unique member values.z, c             S   s&   g  |  ] \ } } d  | | f  q S)z%s -> %sr   )r6   aliasr   r   r   r   r|   
  s   	 zunique.<locals>.<listcomp>z duplicate values found in %r: %s)rn   rX   r   r+   rL   r*   )ZenumerationZ
duplicatesr   ri   Zalias_detailsr   r   r   r     s    )r   collectionsr   typesr   r   __all__r   r   r   r$   dictr%   r   re   r2   intr   r   r   r   r   r   <module>   s   ' aL