B
    \ c                 @   s&  d dl Z d dlmZmZ yd dlmZ W n  ek
rH   d dlmZ Y nX dddddd	d
gZdd Z	dd Z
dd Zdd Ze ZG dd	 d	ZG dd deZdZG dd deZG dd dedZG dd deeZdd ZG dd deZG dd deeZdd Zd d
 Zd!d" Zd#d$ ZdS )%    N)MappingProxyTypeDynamicClassAttribute)OrderedDictEnumMetaEnumIntEnumFlagIntFlagauto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   lib/python3.7/enum.py_is_descriptor   s    

r   c             C   sL   t | dkoJ| dd | dd   ko.dkn  oJ| d dkoJ| d dkS )z3Returns True if a __dunder__ name, False otherwise.   N   ___)len)namer   r   r   
_is_dunder   s    (r   c             C   sL   t | dkoJ| d | d   ko&dkn  oJ| dd dkoJ| dd dkS )z1Returns True if a _sunder_ name, False otherwise.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eZdS )r
   zP
    Instances are replaced with an appropriate value in Enum class suites.
    N)__name__r%   __qualname____doc__
_auto_nullvaluer   r   r   r   r
   2   s   c                   s,   e Zd ZdZ fddZ fddZ  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    g | _g | _g | _d| _d S )NF)super__init___member_names_last_values_ignore_auto_called)r!   )	__class__r   r   r/   @   s
    
z_EnumDict.__init__c                sd  t |r|dkrtd|dkr<| jr.tdt| d| nV|dkrt|tr`|dd }nt	|}|| _
t|t| j@ }|rtd	|f nt|r|d
krd}n|| jkrtd| n|| j
krnt|sR|| krtd|| | f t|tr:d| _|jtkr4| |dt| j| jdd |_|j}| j| | j| t || 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.

        )_order__create_pseudo_member__generate_next_value_	_missing__ignore_z(_names_ are reserved for future Enum user7   z4_generate_next_value_ must be defined before members_generate_next_valuer9   , z-_ignore_ cannot specify already set names: %r	__order__r5   zAttempted to reuse key: %rz%r already defined as: %rTr   N)r   
ValueErrorr3   r    setattr
isinstancestrreplacesplitlistr2   setr0   r   r   r
   r,   r+   r:   r   r1   appendr.   __setitem__)r!   keyr,   already)r4   r   r   rG   G   sD    	



"z_EnumDict.__setitem__)r(   r%   r)   r*   r/   rG   __classcell__r   r   )r4   r   r-   9   s   r-   c                   s   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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$Zed%d& Zed'd( Z  ZS )*r   zMetaclass for Enumc             C   s0   t  }| |\}}|d k	r,t|dd |d< |S )Nr7   )r-   _get_mixins_getattr)metaclsr&   bases	enum_dictmember_type
first_enumr   r   r   __prepare__   s
    zEnumMeta.__prepare__c          	      s"    dg d  d }x|D ]} |d  q W | |\}|  |\}}}	 fdd jD }
x jD ]
} |= qrW  dd }t|
ddh@ }|rtdd	|d	 krd
 d	< t
 | || }g |_t |_|_dd | D }i |_d kr:tk	r:d}tfdd|D s:t| x6 jD ]*}|
| }t|tsf|f}n|}tkrz|f}|	s||}t|ds||_n6||f| }t|ds҈tkr||_n
| |_|j}||_||_|j|  x8|j D ]\}}|j|jkr|}P qW |j| ||kr>t||| ||j|< y||j|< W n tk
rl   Y nX qDW xPdD ]H}t||}t|d }t||d }|d k	rz||krzt||| qzW t d k	r|r||_!t j|_|d k	rt|t"r
|#dd$ }||jkrtd|S )Nr9   c                s   i | ]} | |qS r   r   ).0k)	classdictr   r   
<dictcomp>   s    z$EnumMeta.__new__.<locals>.<dictcomp>r5   mro zInvalid enum member name: {0}r;   r*   zAn enumeration.c             S   s.   h | ]&}|j  D ]\}}t|tr|qqS r   )__dict__itemsr@   r   )rS   crT   vr   r   r   	<setcomp>   s    z#EnumMeta.__new__.<locals>.<setcomp>r$   )__getnewargs_ex____getnewargs__r$   
__reduce__c             3   s   | ]}| j kV  qd S )N)rY   )rS   m)rP   r   r   	<genexpr>   s    z#EnumMeta.__new__.<locals>.<genexpr>_value_)__repr____str__
__format__r$   r<   z#member order does not match _order_)%
setdefaultrF   poprK   
_find_new_r0   rE   r>   formatjoinr.   __new___member_names_r   _member_map__member_type_rW   _value2member_map_objectanyr'   r@   tupler   rc   _name___objclass__r/   rZ   r?   r    rL   r   __new_member__rA   rB   rC   )rM   r&   rN   rU   ignorerH   rQ   rl   save_newuse_argsenum_membersr   r5   invalid_names
enum_classdynamic_attributesmethodsmember_namer,   argsenum_membercanonical_memberclass_method
obj_methodenum_method)r4   )rU   rP   r   rl      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__Nr   )modulequalnametypestartc            C   s*   |dkr|  | |S | j||||||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.

        N)r   r   r   r   )rl   _create_)r&   r,   namesr   r   r   r   r   r   r   __call__!  s    zEnumMeta.__call__c             C   s6   t |ts dd l}|dtd t || o4|j| jkS )Nr   zHusing non-Enums in containment checks will raise TypeError in Python 3.8r   )r@   r   warningswarnDeprecationWarningrt   rn   )r&   memberr   r   r   r   __contains__?  s    
zEnumMeta.__contains__c                s(   || j krtd| j t | d S )Nz%s: cannot delete Enum member.)rn   AttributeErrorr(   r.   __delattr__)r&   attr)r4   r   r   r   H  s    
zEnumMeta.__delattr__c             C   s   ddddg| j  S )Nr4   r*   __members__r%   )rm   )r!   r   r   r   __dir__P  s    
zEnumMeta.__dir__c             C   s>   t |rt|y
| j| S  tk
r8   t|dY nX d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   r   rn   KeyError)r&   r   r   r   r   __getattr__T  s    	
zEnumMeta.__getattr__c             C   s
   | j | S )N)rn   )r&   r   r   r   r   __getitem__d  s    zEnumMeta.__getitem__c                s    fdd j D S )Nc             3   s   | ]} j | V  qd S )N)rn   )rS   r   )r&   r   r   rb   h  s    z$EnumMeta.__iter__.<locals>.<genexpr>)rm   )r&   r   )r&   r   __iter__g  s    zEnumMeta.__iter__c             C   s
   t | jS )N)r   rm   )r&   r   r   r   __len__j  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   rn   )r&   r   r   r   r   m  s    zEnumMeta.__members__c             C   s
   d| j  S )Nz	<enum %r>)r(   )r&   r   r   r   rd   w  s    zEnumMeta.__repr__c                s    fddt  jD S )Nc             3   s   | ]} j | V  qd S )N)rn   )rS   r   )r&   r   r   rb   {  s    z(EnumMeta.__reversed__.<locals>.<genexpr>)reversedrm   )r&   r   )r&   r   __reversed__z  s    zEnumMeta.__reversed__c                s0   | j di }||krtdt || 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.

        rn   zCannot reassign members.N)rY   getr   r.   __setattr__)r&   r   r,   
member_map)r4   r   r   r   }  s    zEnumMeta.__setattr__c         
   C   s  | j }|dkr| fn|| f}| |\}	}
|||}t|trP|dd }t|ttfr|rt|d tr|g  }}g }xDt	|D ]8\}}|

||||dd }|| |||f qW x6|D ].}t|tr|||  }}n|\}}|||< qW |||||}|dkrVytdjd }W n* tttfk
rT } zW dd}~X Y nX |dkrjt| 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<   r   r   r(   )r4   rK   rR   r@   rA   rB   rC   rs   rD   	enumerater7   rF   rl   sys	_getframe	f_globalsr   r>   r   r'   r%   r)   )r&   
class_namer   r   r   r   r   rM   rN   r   rQ   rU   original_nameslast_valuescountr   r,   itemr   member_valuer|   excr   r   r   r     s<    
 







zEnumMeta._create_c             C   sP   | st tfS dd }| d }t|ts.td|| p8t }|jrHtd||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__

        c             S   sH   xB| D ]:}x4|j D ]*}|tkr"qqd|jkrt|tr8q|S qW qW d S )Nrl   )__mro__rq   rY   
issubclassr   )rN   chainbaser   r   r   _find_data_type  s    


z.EnumMeta._get_mixins_.<locals>._find_data_typer   zZnew enumerations should be created as `EnumName([mixin_type, ...] [data_type,] enum_type)`zCannot extend enumerations)rq   r   r   r    rm   )rN   r   rQ   rP   r   r   r   rK     s    
zEnumMeta._get_mixins_c       	      C   s   |  dd}|dk	}|dkrtxVdD ]H}x8||fD ],}t||d}|ddjtjtjhkr0|}P q0W |dk	r"P q"W tj}|tjkrd}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__

        rl   N)rv   rl   FT)r   rL   rl   rq   r   )	rU   rP   rQ   rl   rx   methodpossibletargetry   r   r   r   ri     s(    


zEnumMeta._find_new_)N)r(   r%   r)   r*   classmethodrR   rl   r   r   r   r   r   r   r   r   r   propertyr   rd   r   r   r   staticmethodrK   ri   rJ   r   r   )r4   r   r      s(   
 	
5 c               @   s   e Zd ZdZdd Zdd Ze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|S y
| j| S  tk
r.   Y n6 tk
rb   x | j D ]}|j|krH|S qHW Y nX yd }| |}W n* tk
r } z|}d }W d d }~X Y nX t	|| r|S t
d|| jf }|d kr|d kr|n|d krtd| j|f }||_|d S )Nz%r is not a valid %szDerror in %s._missing_: returned %r instead of None or a valid member)r   rp   r   r    rn   valuesrc   r8   	Exceptionr@   r>   r(   __context__)r&   r,   r   r   resulteve_excr   r   r   rl     s6    


zEnum.__new__c          	   C   s8   x2t |D ]"}y|d S  tk
r*   Y q
X q
W |S d S )Nr   )r   r    )r   r   r   r   
last_valuer   r   r   r7   ;  s    
zEnum._generate_next_value_c             C   s   t d|| jf d S )Nz%r is not a valid %s)r>   r(   )r&   r,   r   r   r   r8   D  s    zEnum._missing_c             C   s   d| j j| j| jf S )Nz<%s.%s: %r>)r4   r(   rt   rc   )r!   r   r   r   rd   H  s    zEnum.__repr__c             C   s   d| j j| jf S )Nz%s.%s)r4   r(   rt   )r!   r   r   r   re   L  s    zEnum.__str__c                s&    fdd j  D }dddg| S )Nc                s2   g | ]*}|j D ]}|d  dkr| jkr|qqS )r   r   )rY   rn   )rS   r&   ra   )r!   r   r   
<listcomp>Q  s   
z Enum.__dir__.<locals>.<listcomp>r4   r*   r%   )r4   rW   )r!   added_behaviorr   )r!   r   r   O  s    
zEnum.__dir__c             C   s0   | j tkrt}t| }n| j }| j}|||S )N)ro   rq   rA   rc   rf   )r!   format_specr&   valr   r   r   rf   X  s    

zEnum.__format__c             C   s
   t | jS )N)hashrt   )r!   r   r   r   __hash__g  s    zEnum.__hash__c             C   s   | j | jffS )N)r4   rc   )r!   r"   r   r   r   r$   j  s    zEnum.__reduce_ex__c             C   s   | j S )zThe name of the Enum member.)rt   )r!   r   r   r   r   t  s    z	Enum.namec             C   s   | j S )zThe value of the Enum member.)rc   )r!   r   r   r   r,   y  s    z
Enum.valueNc                s   t tj| }rt n| fdd D }y|jdd d W n$ tk
rp   |jdd d Y nX | |||d} t| _|| j	 | ||< | S )z[
        Create a new Enum subclass that replaces a collection of global constants
        c                s    g | ]} |r|| fqS r   r   )rS   r   )filtersourcer   r   r     s   z!Enum._convert.<locals>.<listcomp>c             S   s   | d | d fS )Nr   r   r   )tr   r   r   <lambda>      zEnum._convert.<locals>.<lambda>)rH   c             S   s   | d S )Nr   r   )r   r   r   r   r     r   )r   )
varsr   moduleskeyssortr    _reduce_ex_by_namer$   updater   )r&   r   r   r   r   module_globalsmembersr   )r   r   r   _convert~  s    

zEnum._convert)N)r(   r%   r)   r*   rl   r7   r   r8   rd   re   r   rf   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%   r)   r*   r   r   r   r   r     s   c             C   s   | j S )N)r   )r!   r"   r   r   r   r     s    r   c               @   sp   e Zd ZdZdd Zedd Zedd Zdd	 Zd
d Z	dd Z
dd Zdd Zdd Zdd Zdd ZdS )r   zSupport for flagsc          	   C   sd   |s|dk	r|S dS xBt |D ]6}yt|}P W q tk
rR   td| dY qX qW d|d  S )z
        Generate the next value when not given.

        name: the name of the member
        start: the initial start value or None
        count: the number of existing members
        last_value: the last value assigned or None
        Nr   zInvalid Flag value: %rr   )r   	_high_bitr   r    )r   r   r   r   r   high_bitr   r   r   r7     s    	zFlag._generate_next_value_c             C   s.   |}|dk r| }|  |}|dk r*| }|S )Nr   )r6   )r&   r,   original_valuepossible_memberr   r   r   r8     s    
zFlag._missing_c             C   sb   | j |d}|dkr^t| |\}}|r:td|| jf t| }d|_||_| j 	||}|S )zL
        Create a composite member iff value contains only members.
        Nz%r is not a valid %s)
rp   r   
_decomposer>   r(   rq   rl   rt   rc   rg   )r&   r,   pseudo_memberr   extra_flagsr   r   r   r6     s    
zFlag._create_pseudo_member_c             C   s8   t || js&dd l}|dtd dS |j| j@ |jkS )Nr   zHusing non-Flags in containment checks will raise TypeError in Python 3.8r   F)r@   r4   r   r   r   rc   )r!   otherr   r   r   r   r     s    zFlag.__contains__c             C   sV   | j }| jd k	r$d|j| j| jf S t|| j\}}d|jddd |D | jf S )Nz<%s.%s: %r>|c             S   s   g | ]}t |jp|jqS r   )rA   rt   rc   )rS   ra   r   r   r   r     s    z!Flag.__repr__.<locals>.<listcomp>)r4   rt   r(   rc   r   rk   )r!   r&   r   	uncoveredr   r   r   rd     s    
zFlag.__repr__c             C   s   | j }| jd k	r d|j| jf S t|| j\}}t|dkr^|d jd kr^d|j|d jf S d|jddd |D f S d S )Nz%s.%sr   r   z%s.%rr   c             S   s   g | ]}t |jp|jqS r   )rA   rt   rc   )rS   ra   r   r   r   r     s    z Flag.__str__.<locals>.<listcomp>)r4   rt   r(   r   rc   r   rk   )r!   r&   r   r   r   r   r   re     s    
zFlag.__str__c             C   s
   t | jS )N)boolrc   )r!   r   r   r   r      s    zFlag.__bool__c             C   s"   t || jstS | | j|jB S )N)r@   r4   NotImplementedrc   )r!   r   r   r   r   __or__  s    zFlag.__or__c             C   s"   t || jstS | | j|j@ S )N)r@   r4   r   rc   )r!   r   r   r   r   __and__  s    zFlag.__and__c             C   s"   t || jstS | | j|jA S )N)r@   r4   r   rc   )r!   r   r   r   r   __xor__  s    zFlag.__xor__c             C   sR   t | j| j\}}| d}x*| jD ] }||kr$|j| j@ s$||B }q$W | |S )Nr   )r   r4   rc   )r!   r   r   invertedra   r   r   r   
__invert__  s    
zFlag.__invert__N)r(   r%   r)   r*   r7   r   r8   r6   r   rd   re   r   r   r   r   r   r   r   r   r   r     s   

c               @   sT   e Zd ZdZedd Zedd Zdd Zdd	 Zd
d Z	eZ
eZe	Zdd ZdS )r	   zSupport for integer-based Flagsc             C   s*   t |tstd|| jf | |}|S )Nz%r is not a valid %s)r@   intr>   r(   r6   )r&   r,   
new_memberr   r   r   r8     s    

zIntFlag._missing_c             C   s   | j |d }|d kr|g}t| |\}}xL|rvt|}d| }|| j kr\||kr\|| || krld}q,||N }q,W x6t|D ]*}t| |}d |_||_	| j 
||}qW |S )Nr   r   )rp   r   r   r   rF   r   r   rl   rt   rc   rg   )r&   r,   r   need_to_creater   r   bit
flag_valuer   r   r   r6   %  s&    


zIntFlag._create_pseudo_member_c             C   s0   t || jtfstS | | j| |jB }|S )N)r@   r4   r   r   rc   )r!   r   r   r   r   r   r   C  s    zIntFlag.__or__c             C   s,   t || jtfstS | | j| |j@ S )N)r@   r4   r   r   rc   )r!   r   r   r   r   r   I  s    zIntFlag.__and__c             C   s,   t || jtfstS | | j| |jA S )N)r@   r4   r   r   rc   )r!   r   r   r   r   r   N  s    zIntFlag.__xor__c             C   s   |  | j }|S )N)r4   rc   )r!   r   r   r   r   r   W  s    zIntFlag.__invert__N)r(   r%   r)   r*   r   r8   r6   r   r   r   __ror____rand____rxor__r   r   r   r   r   r	     s   c             C   s   |   d S )z@returns index of highest bit, or -1 if value is zero or negativer   )
bit_length)r,   r   r   r   r   \  s    r   c             C   sb   g }x0| j  D ]"\}}||jkr|||jf qW |r^d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   )rS   aliasr   r   r   r   r   h  s    zunique.<locals>.<listcomp>z duplicate values found in %r: %s)r   rZ   r   rF   rk   r>   )enumeration
duplicatesr   r   alias_detailsr   r   r   r   `  s    
c             C   s   |}|dk }|r*dd t | j D }ndd t | j D }g }x4|D ],\}}|rL||@ |krL|| || M }qLW |s|| jkr|| j|  |jdd dd t|d	kr|d j|kr|d ||fS )
z#Extract all members from the value.r   c             S   s"   g | ]\}}|j d k	r||fqS )N)r   )rS   r\   ra   r   r   r   r   x  s   z_decompose.<locals>.<listcomp>c             S   s*   g | ]"\}}|j d k	st|r||fqS )N)r   _power_of_two)rS   r\   ra   r   r   r   r     s   c             S   s   | j S )N)rc   )ra   r   r   r   r     r   z_decompose.<locals>.<lambda>T)rH   reverser   )rD   rp   rZ   rF   r   r   r,   rh   )flagr,   not_coverednegativeflags_to_checkr   r   r   r   r   r   r   m  s$    

r   c             C   s   | dk rdS | dt |  kS )Nr   Fr   )r   )r,   r   r   r   r     s    r   )r   typesr   r   _collectionsr   ImportErrorcollections__all__r   r   r   r'   rq   r+   r
   dictr-   r   r   r   r   r   r   r   r	   r   r   r   r   r   r   r   r   <module>   s<   D    qA#