
WV                 @   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 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   9/afs/.cs/s/python-3.5.2/amd64_ubu14/lib/python3.5/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   nm t |  r* n^ | |  j k rL t d |   n< t |  s | |  k rx t d |  |   |  j j |  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                   sN  e  Z d  Z d Z e d d    Z   f d d   Z d d   Z d d	 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 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                s^  |  j  |  \  } |  j    |  \ } } }   f d d     j D } x   j D] }	   |	 =qY Wt |  d h @}
 |
 r t d j d j |
     d   k r d   d <t   j |  | |    } g  | _	 t
   | _  | _ d d	   | j   D } i  | _ d
   k rY t k	 rYd } t  f d d   | D  sYt |  xk  j D]`} | | } t | t  s| f } n | }  t k r| f } | s| |  } t | d  s| | _ n- | | |  } t | d  s |   | _ | j } | | _ | | _ | j |   xF | j j   D]% \ }	 } | j | j k r;| } Pq;W| j	 j |  | | k rt | | |  | | j | <y | | j | <Wqct k
 rYqcXqcWxi d D]a }	 t | |	  } t  |	 d   } t | |	 d   } | d  k	 r| | k rt | |	 |  qWt d  k	 rZ| rN| | _ t j | _ | 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},r1   zAn enumeration.c             S   s&   h  |  ] } | j  D] } |  q q Sr   )__dict__)r6   bar   r   r   	<setcomp>y   s   	 z#EnumMeta.__new__.<locals>.<setcomp>r!   __getnewargs_ex____getnewargs__
__reduce__c             3   s   |  ] } |   j  k Vq d  S)N)r<   )r6   m)member_typer   r   	<genexpr>   s    z#EnumMeta.__new__.<locals>.<genexpr>_value___repr____str__
__format__)z__getnewargs_ex__z__getnewargs____reduce_ex__z
__reduce__)z__repr__z__str__z
__format__rJ   ) _get_mixins_
_find_new_r(   setr*   formatjoinr&   __new___member_names_r   _member_map__member_type_r:   _value2member_map_objectanyr$   
isinstancetupler   rF   _name___objclass__r'   itemsr+   setattrr   getattrr   __new_member__)r3   r#   r4   r8   
first_enumrP   save_newuse_argsmembersr   invalid_names
enum_classbase_attributesmethodsmember_namer.   argsenum_membercanonical_memberclass_method
obj_methodenum_method)r)   )r8   rD   r   rP   X   s    	
			 

						zEnumMeta.__new__c             C   s   d S)z6
        classes/types should always be True.
        Tr   )r   r   r   r   __bool__   s    zEnumMeta.__bool__Nmodulequalnametypestartr   c            C   sD   | d k r |  j  |  |  S|  j | | d | 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 `start`), 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.

        Nro   rp   rq   rr   )rP   _create_)r#   r.   namesro   rp   rq   rr   r   r   r   __call__   s    zEnumMeta.__call__c             C   s   t  | |   o | j |  j k S)N)rW   rY   rR   )r#   memberr   r   r   __contains__   s    zEnumMeta.__contains__c                s6   | |  j  k r" t d |  j   t   j |  d  S)Nz%s: cannot delete Enum member.)rR   AttributeErrorr/   r&   __delattr__)r#   attr)r)   r   r   ry      s    zEnumMeta.__delattr__c             C   s   d d d d g |  j  S)Nr)   r1   __members__r"   )rQ   )r   r   r   r   __dir__   s    zEnumMeta.__dir__c             C   sO   t  |  r t |   y |  j | SWn! t k
 rJ 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   rx   rR   KeyError)r#   r   r   r   r   __getattr__  s    	zEnumMeta.__getattr__c             C   s   |  j  | S)N)rR   )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)rR   )r6   r   )r#   r   r   rE     s    z$EnumMeta.__iter__.<locals>.<genexpr>)rQ   )r#   r   )r#   r   __iter__  s    zEnumMeta.__iter__c             C   s   t  |  j  S)N)r   rQ   )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   rR   )r#   r   r   r   r{     s    zEnumMeta.__members__c             C   s   d |  j  S)Nz	<enum %r>)r/   )r#   r   r   r   rG   '  s    zEnumMeta.__repr__c                s      f d d   t    j  D S)Nc             3   s   |  ] }   j  | Vq d  S)N)rR   )r6   r   )r#   r   r   rE   +  s    z(EnumMeta.__reversed__.<locals>.<genexpr>)reversedrQ   )r#   r   )r#   r   __reversed__*  s    zEnumMeta.__reversed__c                sD   |  j  j d i   } | | k r- t d   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.

        rR   zCannot reassign members.N)r<   getrx   r&   __setattr__)r#   r   r.   
member_map)r)   r   r   r   -  s    zEnumMeta.__setattr__c            C   s  |  j  } | d k r |  f n	 | |  f } | j | |  }	 t | t  rc | j d d  j   } t | t t f  r t | d t  r d d   t | |  D } xG | D]? }
 t |
 t  r |
 | |
 } } n |
 \ } } | |	 | <q W| j	 | | | |	  } | d k r]y t
 j d  j d } Wn+ t t f k
 r\} z WYd d } ~ Xn X| d k rvt |  n	 | | _ | d k	 r| | _ | 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 incremented by 1 from `start`.
        * An iterable of member names.  Values are incremented by 1 from `start`.
        * An iterable of (member name, value) pairs.
        * A mapping of member name -> value pairs.

        Nr;    r   c             S   s"   g  |  ] \ } } | | f  q Sr   r   )r6   ier   r   r   
<listcomp>N  s   	 z%EnumMeta._create_.<locals>.<listcomp>r   r/   )r)   r5   rW   strreplacesplitrX   list	enumeraterP   sys	_getframe	f_globalsrx   r*   r$   r"   r0   )r#   
class_namert   ro   rp   rq   rr   r3   r4   r8   itemrg   member_valuerd   excr   r   r   rs   :  s0    	!(		zEnumMeta._create_c             C   s   |  s t  t f Sd } } x> |  D]6 } | t k	 r! t | t  r! | j r! t d   q! Wt | t  sv t d   t |  d t  s |  d } |  d } nN xK |  d j D]< } t | t  r | d k r | } q | d k r | } 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   )rU   r   
issubclassrQ   r   __mro__)r4   rD   r_   baser   r   r   rK   i  s(    

	
	
zEnumMeta._get_mixins_c       	      C   s   |  j  d d  } | d k	 } | d k r xu d D]d } xN | | f D]@ } t | | d  } | d d j t j t j h k rD | } PqD W| d k	 r1 Pq1 Wt j } | 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__

        rP   Nr^   FT)z__new_member__z__new__)r   r]   rP   rU   r   )	r8   rD   r_   rP   r`   methodpossibletargetra   r   r   r   rL     s(    		zEnumMeta._find_new_)r/   r"   r0   r1   classmethodr5   rP   rn   ru   rw   ry   r|   r~   r   r   r   propertyr{   rG   r   r   rs   staticmethodrK   rL   r   r   )r)   r   r2   R   s&   y'
'/-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 e d 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)rq   rT   r   rR   valuesrF   r*   r/   )r#   r.   rv   r   r   r   rP     s    zEnum.__new__c             C   s   d |  j  j |  j |  j f S)Nz<%s.%s: %r>)r)   r/   rY   rF   )r   r   r   r   rG     s    zEnum.__repr__c             C   s   d |  j  j |  j f S)Nz%s.%s)r)   r/   rY   )r   r   r   r   rH     s    zEnum.__str__c                s3     f d d     j  j   D } d d d g | S)Nc                sE   g  |  ]; } | j  D]+ } | d  d k r |   j k r |  q q S)r   r   )r<   rR   )r6   r#   rC   )r   r   r   r     s   	z Enum.__dir__.<locals>.<listcomp>r)   r1   r"   )r)   r:   )r   added_behaviorr   )r   r   r|     s    zEnum.__dir__c             C   sF   |  j  t k r$ t } t |   } n |  j  } |  j } | j | |  S)N)rS   rU   r   rF   rI   )r   format_specr#   valr   r   r   rI     s    		zEnum.__format__c             C   s   t  |  j  S)N)hashrY   )r   r   r   r   __hash__  s    zEnum.__hash__c             C   s   |  j  |  j f f S)N)r)   rF   )r   r   r   r   r   r!      s    zEnum.__reduce_ex__c             C   s   |  j  S)zThe name of the Enum member.)rY   )r   r   r   r   r   
  s    z	Enum.namec             C   s   |  j  S)zThe value of the Enum member.)rF   )r   r   r   r   r.     s    z
Enum.valueNc                s   t  t j |  } | r( t  |  } n | }   f d d   | j   D } |  | | d | }  t |  _ | j |  j  |  | | <|  S)z[
        Create a new Enum subclass that replaces a collection of global constants
        c                s+   i  |  ]! \ } }   |  r | |  q Sr   r   )r6   r   r.   )filterr   r   r9   #  s   	 	z!Enum._convert.<locals>.<dictcomp>ro   )varsr   modulesr[   _reduce_ex_by_namer!   updater{   )r#   r   ro   r   sourcemodule_globalsrb   r   )r   r   _convert  s    
	
zEnum._convert)r/   r"   r0   r1   rP   rG   rH   r|   rI   r   r!   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   |  j  S)N)r   )r   r   r   r   r   r   0  s    r   c             C   s   g  } xB |  j  j   D]1 \ } } | | j k r | j | | j f  q W| r d j d d   | D  } t d |  | f   |  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)r{   r[   r   r+   rO   r*   )enumeration
duplicatesr   rv   alias_detailsr   r   r   r   3  s    )r   collectionsr   typesr   r   __all__r   r   r   r$   dictr%   r   rq   r2   intr   r   r   r   r   r   r   <module>   s   ' tg