
    gf                     ~    d Z ddlmZmZmZmZ ddlZddlZddlZ	 ddZ	d Z
d Z G d de      Z G d	 d
ee      Zy)z)
flyingcircus.BitField: Bit Field class.
    )divisionabsolute_importprint_functionunicode_literalsNc                 |    |*t        j                         }|j                  j                  }| j	                  |      S )a  
    Perform string formatting from a mapping source.

    Args:
        text (str): Text to format.
        source (Mapping|None): The mapping to use as source.
            If None, uses caller's `vars()`.

    Returns:
        result (str): The formatted text.

    Examples:
        >>> a, b, c = 1, 2, 3
        >>> dd = dict(a=10, b=20, c=30)
        >>> fmtm('{a} + {a} = {b}')
        '1 + 1 = 2'
        >>> fmtm('{a} + {a} = {b}', dd)
        '10 + 10 = 20'
        >>> fmtm('{} + {} = {}', 2, 2, 4)  # doctest:+ELLIPSIS
        Traceback (most recent call last):
            ...
        TypeError: ...
        >>> fmtm('{b} + {b} = {}', 4)  # doctest:+ELLIPSIS
        Traceback (most recent call last):
            ...
        TypeError: ...
    )inspectcurrentframef_backf_locals
format_map)textsourceframes      m/var/dept/share/cheung/public_html/OutSchool/python/env/lib/python3.12/site-packages/flyingcircus/BitField.pyfmtmr      s5    < ~$$&&&??6""    c              #   6   K   | r| dz  dk(   | dz  } | ryyw)a	  
    Get the bit values for a number (lower to higher significance).

    Args:
        value (int): The input value.

    Yields:
        result (int): The bits.

    Examples:
        >>> list(bits(100))
        [False, False, True, False, False, True, True]
       N )values    r   bitsr   9   s(       qyQ! s   c              #   p   K   | j                         }t        |dz
  dd      D ]  }| |z	  dz  dk(    yw)a  
    Get the reversed bit values for a number (higher to lower significance).

    Args:
        value (int): The input value.

    Yields:
        result (int): The bits.

    Examples:
        >>> list(bits(100))
        [False, False, True, False, False, True, True]
    r   N)
bit_lengthrange)r   bis      r   bits_rr   O   sF       	A1q5"b! &
aA%%&s   46c                       e Zd Zd Zy)BitFieldMetac                     |d   }|d   }t        |      t        t        |            k7  rt        t        d            ||v rt        t        d            t        j                  | |||      S )NKEYSEMPTYz{cls_name}.KEYS must be uniquez/{cls_name}.EMPTY must not be in {cls_name}.KEYS)sortedset
ValueErrorr   type__new__)mcscls_name	cls_basescls_dictkeysemptys         r   r(   zBitFieldMeta.__new__f   su    !$<6#d),,568 8D=FGI I||C9h??r   N)__name__
__module____qualname__r(   r   r   r   r    r    e   s    	@r   r    c                   &    e Zd ZdZej
                  ZdZdZdZ		 d3 fd	Z
e fd       Zej                   fd       Zej                  d        Zed	        Zed
        Zej$                  Zed        Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd ZeZ eZ!d Z"d Z#d Z$d Z%d4dZ&d5dZ'd Z(d Z)d  Z*e*Z+e)Z,d! Z-d" Z.e.Z/e-Z0d# Z1d$ Z2d% Z3d& Z4d' Z5d( Z6d) Z7d* Z8d+ Z9d, Z:e:Z;e	 	 	 	 d6d-       Z<e	 	 	 d7d.       Z=d/ Z>d0 Z? fd1Z@d2 ZA xZBS )8BitFielda  
    Generic bit-field class.

    The recommended usage is to subclass for specialized representations.

    Typically, while subclassing, `KEYS` and `EMPTY` should probably be
    replaced.
    Additionally, `FULL_REPR` and `IGNORE_INVALID` control the bit-field
    default behavior.
    In particular:
     - `KEYS` determines which flags to use for encoding/decoding the bit-field.
       **IMPORTANT!**: Items in `KEYS` must be unique.
     - `EMPTY` is used during encoding/decoding for marking empty/unset flags.
       **IMPORTANT!**: `EMPTY` must not be present in `KEYS`.
     - `FULL_REPR` determines whether the default decoding, including its
        string representation, should include empty/unset flags.
     - `IGNORE_INVALID` determines whether invalid input values should be
       ignored during encoding or rather a ValueError should be raised.

    Examples:
        >>> print(BitField(127))
        BitField(abcdefg)
        >>> repr(BitField(127))
        "BitField(0b1111111){'a': True, 'b': True, 'c': True, 'd': True, 'e': True, 'f': True, 'g': True, 'h': False, 'i': False, 'j': False, 'k': False, 'l': False, 'm': False, 'n': False, 'o': False, 'p': False, 'q': False, 'r': False, 's': False, 't': False, 'u': False, 'v': False, 'w': False, 'x': False, 'y': False, 'z': False, 'A': False, 'B': False, 'C': False, 'D': False, 'E': False, 'F': False, 'G': False, 'H': False, 'I': False, 'J': False, 'K': False, 'L': False, 'M': False, 'N': False, 'O': False, 'P': False, 'Q': False, 'R': False, 'S': False, 'T': False, 'U': False, 'V': False, 'W': False, 'X': False, 'Y': False, 'Z': False}"

        >>> int(BitField(12))
        12

        >>> print(BitField(8) + BitField(1))
        BitField(ad)
        >>> print(BitField('a') + BitField('d'))
        BitField(ad)

        >>> print(list(BitField(11)))
        ['a', 'b', 'd']

        >>> print(list(reversed(BitField(11))))
        ['d', 'b', 'a']

        >>> class UnixPermissions(BitField):
        ...     KEYS = 'rwx'
        ...     EMPTY = '-'
        ...     FULL_REPR = True
        >>> acl = UnixPermissions()
        >>> print(acl)
        UnixPermissions(---)
        >>> repr(acl)
        "UnixPermissions(0b0){'r': False, 'w': False, 'x': False}"
        >>> acl.r = True
        >>> print(acl)
        UnixPermissions(r--)
        >>> acl['x'] = True
        >>> print(acl)
        UnixPermissions(r-x)
        >>> acl.BitField = 7
        >>> print(acl)
        UnixPermissions(rwx)
        >>> del acl.x
        >>> print(acl)
        UnixPermissions(rw-)

        >>> class RGB(BitField):
        ...     KEYS = ['red', 'green', 'blue']
        ...     EMPTY = None
        ...     FULL_REPR = True
        >>> rgb = RGB()
        >>> print(rgb)
        RGB([None, None, None])
        >>> repr(rgb)
        "RGB(0b0){'red': False, 'green': False, 'blue': False}"
        >>> rgb.red = True
        >>> print(rgb)
        RGB(['red', None, None])
        >>> rgb['blue'] = True
        >>> print(rgb)
        RGB(['red', None, 'blue'])
        >>> print(list(rgb))
        ['red', 'blue']
        >>> rgb.BitField = 7
        >>> print(rgb)
        RGB(['red', 'green', 'blue'])
        >>> del rgb.blue
        >>> print(rgb)
        RGB(['red', 'green', None])
     FTc                     t        |       }t        ||   dd       t        |t              r|| _        y| j                  ||j                  |j                  |j                        | _        y)aR  
        Instantiate a BitField object.

        Args:
            BitField (int|Sequence): The input bit-field.
                If int, the flags of the bit-field are according to the bit
                boolean values.
                If a sequence, uses `KEYS` to encode the input into the
                corresponding bit-field, using `from_keys()` method.
                The value of `EMPTY` is used to mark empty / unset bits.
                The value of `IGNORE_INVALID` determines whether invalid
                items in the sequence are ignored or will raise a ValueError.
        	_BitFieldN)
r'   super__setattr__
isinstanceintr3   encoder"   r#   IGNORE_INVALID)selfr3   cls	__class__s      r   __init__zBitField.__init__   sX      4jh)+t<h$$DM KK#((CIIs/A/ACDMr   c                 *    t         t        |   d      S )Nr6   )r7   r3   __getattribute__)r=   r?   s    r   r3   zBitField.BitField   s    Xt5kBBr   c                     d| j                   z  dz
  }d|cxk  r|k  rn nt        t        |   d|       y t	        t        d            )Nr   r   r6   z]{self.__class__.__name__}() bit-field must be between 0 and {max_BitField}, not `{BitField_}`)sizer7   r3   r8   r&   r   )r=   	BitField_max_BitFieldr?   s      r   r3   zBitField.BitField   sL    TYY!+	)\)(D-k9ET;< = =r   c                     | ` y Nr6   r=   s    r   r3   zBitField.BitField   s    Nr   c                     t        | j                        t        t        | j                              k(  }| j                  | j                  v}|xr |S rH   )r$   r"   r%   r#   )r>   
valid_keysvalid_emptys      r   is_validzBitField.is_valid  s?    CHH%CHH)>>
iisxx/)k)r   c                 >    t        t        |       j                        S )aN  
        Compute the maximum lenght for the bit-field (given the class keys).

        Returns:
            result (int): The maximum length for the bit-field.

        Examples:
            >>> BitField().size
            52
            >>> BitField(123).size
            52
            >>> len(BitField(123))
            52
        )lenr'   r"   rJ   s    r   rD   zBitField.size  s      4:??##r   c                 6    | j                   j                         S )a  
        Compute the actual lenght for the bit-field.

        Returns:
            result (int): The actual length of the bit-field.

        Examples:
            >>> BitField().active_len
            0
            >>> BitField(123).active_len
            7
        )r6   r   rJ   s    r   
active_lenzBitField.active_len"  s     ~~((**r   c              #   n   K   t        | j                        D ]  }| j                  d|z  z  dkD    yw)a)  
        Iterate forward over the bit-field values.

        The iteration is from the least to the most significant bit.

        Yields:
            value (bool): The next bit value.

        Examples:
            >>> print(list(BitField('ac').values()))
            [True, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False]
            >>> print(list(BitField(11).values()))
            [True, True, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False]
        r   r   Nr   rD   r6   r=   r   s     r   valueszBitField.values3  s8     . tyy! 	2A>>Q!V,11	2s   35c              #   x   K   t        | j                  dz
  dd      D ]  }| j                  |z	  dz  dkD    yw)a2  
        Iterate backward over the bit-field values.

        The iteration is from the most to the least significant bit.

        Yields:
            value (bool): The previous bit value.

        Examples:
            >>> print(list(BitField('ac').values_r()))
            [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, True]
            >>> print(list(BitField(11).values_r()))
            [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, True, True]
        r   r   r   NrT   rU   s     r   values_rzBitField.values_rN  sA     . tyy1}b"- 	2ANNa'1,11	2s   8:c              #   J   K   t        | j                        E d{    y7 w)ar  
        Iterate forward over the active bit-field values.

        Yields:
            value (bool): The next active value.

        Examples:
            >>> flags = BitField('ac')
            >>> print(list(flags.active_values()))
            [True, False, True]
            >>> print(list(BitField(11).active_values()))
            [True, True, False, True]
        N)r   r6   rJ   s    r   active_valueszBitField.active_valuesi  s      '''   #!#c              #   J   K   t        | j                        E d{    y7 w)aw  
        Iterate backward over the active bit-field values.

        Yields:
            value (bool): The previous active value.

        Examples:
            >>> flags = BitField('ac')
            >>> print(list(flags.active_values()))
            [True, False, True]
            >>> print(list(BitField(11).active_values()))
            [True, True, False, True]
        N)r   r6   rJ   s    r   active_values_rzBitField.active_values_rz  s      $..)))r[   c              #   H   K   t        |       j                  D ]  }|  yw)z
        Yields the keys of the bit-field.

        Yields:
            key (str): The next key.

        Examples:
            >>> print(''.join((BitField(7).keys())))
            abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
        N)r'   r"   r=   keys     r   r-   zBitField.keys  s$      :?? 	CI	s    "c              #   Z   K   t        t        |       j                        D ]  }|  yw)a
  
        Yields the keys of the bit-field in reversed order.

        Yields:
            key (str): The previous key.

        Examples:
            >>> print(''.join((BitField(7).keys_r())))
            ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba
        N)reversedr'   r"   r_   s     r   keys_rzBitField.keys_r  s)      DJOO, 	CI	s   )+c              #      K   t        t        |       j                  t        | j                              D ]  \  }}|s	|  yw)a$  
        Yields the active keys of the bit-field.

        Yields:
            key (str): The next key.

        Examples:
            >>> print(list(BitField(7).active_keys()))
            ['a', 'b', 'c']
            >>> print(list(BitField(5).active_keys()))
            ['a', 'c']
        Nzipr'   r"   r   r6   r=   r`   r   s      r   active_keyszBitField.active_keys  s>      T
dnn!57 	JC		s
   ;AAc              #      K   t        t        t        |       j                  d| j                         t        | j                              D ]  \  }}|s	|  yw)z
        Yields the active keys of the bit-field in reversed order.

        Yields:
            key (str): The previous key.

        Examples:
            >>> print(list(BitField(7).active_keys_r()))
            ['c', 'b', 'a']
        Nrf   rb   r'   r"   rR   r   r6   rg   s      r   active_keys_rzBitField.active_keys_r  sR      d)9$//:;t~~&( 	JC 			s   AAAc              #      K   t        t        |       j                  | j                               D ]  \  }}||f  yw)a\  
        Yields the key-value pairs of the bit-field.

        Yields:
            key (str): The next key.
            value (bool): The next value.

        Examples:
            >>> print(dict(BitField(7).items()))
            {'a': True, 'b': True, 'c': True, 'd': False, 'e': False, 'f': False, 'g': False, 'h': False, 'i': False, 'j': False, 'k': False, 'l': False, 'm': False, 'n': False, 'o': False, 'p': False, 'q': False, 'r': False, 's': False, 't': False, 'u': False, 'v': False, 'w': False, 'x': False, 'y': False, 'z': False, 'A': False, 'B': False, 'C': False, 'D': False, 'E': False, 'F': False, 'G': False, 'H': False, 'I': False, 'J': False, 'K': False, 'L': False, 'M': False, 'N': False, 'O': False, 'P': False, 'Q': False, 'R': False, 'S': False, 'T': False, 'U': False, 'V': False, 'W': False, 'X': False, 'Y': False, 'Z': False}
        N)rf   r'   r"   rV   rg   s      r   itemszBitField.items  s:     ( d4joot{{}= 	JCu*	s   =?c              #      K   t        t        t        |       j                        | j	                               D ]  \  }}||f  yw)a^  
        Yields the key-value pairs of the bit-field.

        Yields:
            key (str): The next key.
            value (bool): The next value.

        Examples:
            >>> print(dict(BitField(7).items_r()))
            {'Z': False, 'Y': False, 'X': False, 'W': False, 'V': False, 'U': False, 'T': False, 'S': False, 'R': False, 'Q': False, 'P': False, 'O': False, 'N': False, 'M': False, 'L': False, 'K': False, 'J': False, 'I': False, 'H': False, 'G': False, 'F': False, 'E': False, 'D': False, 'C': False, 'B': False, 'A': False, 'z': False, 'y': False, 'x': False, 'w': False, 'v': False, 'u': False, 't': False, 's': False, 'r': False, 'q': False, 'p': False, 'o': False, 'n': False, 'm': False, 'l': False, 'k': False, 'j': False, 'i': False, 'h': False, 'g': False, 'f': False, 'e': False, 'd': False, 'c': True, 'b': True, 'a': True}
        N)rf   rb   r'   r"   rX   rg   s      r   items_rzBitField.items_r  sB     ( d)4==?< 	JCu*	s   AAc              #      K   t        t        |       j                  t        | j                              D ]  \  }}|s	||f  yw)ay  
        Yields the active key-value pairs of the bit-field.

        Yields:
            key (str): The next key.
            value (bool): The next value.

        Examples:
            >>> print(dict(BitField(7).active_items()))
            {'a': True, 'b': True, 'c': True}
            >>> print(dict(BitField(5).active_items()))
            {'a': True, 'c': True}
        Nre   rg   s      r   active_itemszBitField.active_items  sC      T
dnn!57 	!JC5j 	!s
   ;A	Ac              #      K   t        t        t        |       j                  d| j                         t        | j                              D ]  \  }}|s	||f  yw)a}  
        Yields the active key-value pairs of the bit-field.

        Yields:
            key (str): The next key.
            value (bool): The next value.

        Examples:
            >>> print(dict(BitField(7).active_items_r()))
            {'c': True, 'b': True, 'a': True}
            >>> print(dict(BitField(5).active_items_r()))
            {'c': True, 'a': True}
        Nrj   rg   s      r   active_items_rzBitField.active_items_r  sW      d)9$//:;t~~&( 	!JC 5j 		!s   AA	Ac                     t        |t              r| j                  j                  |      }| j                  d|z  z  dkD  S )a  
        Get the value at the specified key or position.

        Args:
            key (int|str): The index or key of the item.

        Returns:
            result (bool): The bit value at the given index in the bit-field.

        Examples:
            >>> flags = BitField('ac')
            >>> print([flags[i] for i in range(flags.active_len)])
            [True, False, True]
            >>> print([flags[c] for c in 'abc'])
            [True, False, True]
        r   r   r9   strr"   indexr6   r_   s     r   __getitem__zBitField.__getitem__,  s8    " c3))//#&C!s(+q00r   c                     t        |t              r| j                  j                  |      }|r| j                  d|z  z  | _        y| j                  d|z   z  | _        y)a  
        Set the item at the specified position.

        Args:
            key (int|str): The index or key of the item.
            value (bool): The bit value to set.

        Returns:
            None.

        Examples:
            >>> flags = BitField('c')
            >>> flags[0] = True
            >>> print(flags)
            BitField(ac)
            >>> flags[0] = False
            >>> print(flags)
            BitField(c)
            >>> flags[1] = True
            >>> print(flags)
            BitField(bc)
            >>> flags[2] = False
            >>> print(flags)
            BitField(b)
            >>> flags['a'] = True
            >>> print(flags)
            BitField(ab)
            >>> flags['b'] = False
            >>> print(flags)
            BitField(a)
        r   Nru   rg   s      r   __setitem__zBitField.__setitem__B  sN    @ c3))//#&C!^^qCx8DN!^^Sk9DNr   c                     | |   }d| |<   |S )a  
        Unset the item at the specified position.

        Args:
            key (int|str): The index or key of the item.

        Returns:
            result (bool): The bit value before deletion.

        Examples:
            >>> flags = BitField(7)
            >>> print(flags)
            BitField(abc)
            >>> del flags[0]
            >>> print(flags)
            BitField(bc)
            >>> del flags['b']
            >>> print(flags)
            BitField(c)
        Fr   )r=   r`   	bit_values      r   __delitem__zBitField.__delitem__j  s    * I	S	r   c                     || j                   v S )a  
        Check if the specified key is present in the bit-field.

        Args:
            key (str): The key of the item.

        Returns:
            result (bool): The result of the check.

        Examples:
            >>> 'a' in BitField()
            True
            >>> 'fc' in BitField()
            False
            >>> 'a' in BitField(0) and 'a' in BitField(1)
            True
        )r"   r_   s     r   __contains__zBitField.__contains__  s    $ diir   c                     ||| j                   j                  |      S ||| j                   j                  ||      S ||| j                   j                  ||      S | j                   j                  |||      S )a  
        Return the index of a specific key.

        Args:
            key (str): The key of the item.
            start (int|None): The minimum index to look into.
            stop (int|None): The maximum index to look into.

        Returns:
            result (int): The index corresponding to a specific key.

        Examples:
            >>> print(BitField().index('a'))
            0
            >>> print(BitField().index('A'))
            26
        )start)stop)r"   rw   )r=   r`   r   r   s       r   rw   zBitField.index  sy    $ =T\99??3''99??3e?44]t/99??3T?2299??3t44r   c                     t        | j                        j                  d      }|dv r|S |dv r| j                  |z
  S t	        d      )a  
        Count the number of values (True or False).

        When counting the values of True, this is also known as the
        Hamming weight (or the Hamming distance to 0).

        Args:
            value (bool): The value to count.

        Returns:
            result (int): The number of matches found.

        Examples:
            >>> BitField().count(True)
            0
            >>> BitField().count(False)
            52

            >>> flags = BitField(127)
            >>> print(flags.count())
            7
            >>> print(flags.count(True))
            7
            >>> print(flags.count(False))
            45
        1)r   T)r   Fz&BitField only contains boolean values.)binr6   countrD   r&   )r=   r   oness      r   r   zBitField.count  sM    6 4>>"((-IKj 99t##EFFr   c                     d| _         y )Nr   rI   rJ   s    r   clearzBitField.clear  s	    r   c                 ~    t        |       t        |      k(  r!| xj                  |j                  z  c_        | S t        rH   r'   r6   NotImplementedr=   others     r   __ior__zBitField.__ior__  /    :e$NNeoo-NK  r   c                 F     t        |       | j                        }||z  }|S )a\  
        Perform bitwise-or operation between two bit-fields.

        Args:
            other (BitField): The other bit-field.

        Returns:
            result (BitField): The result of the operation.

        Examples:
            >>> a = BitField(1)
            >>> b = BitField(2)

            >>> print(a | b)
            BitField(ab)
            >>> print(a)
            BitField(a)
            >>> print(b)
            BitField(b)

            >>> print(a + b)
            BitField(ab)
            >>> print(a)
            BitField(a)
            >>> print(b)
            BitField(b)

        r'   r6   r=   r   results      r   __or__zBitField.__or__  &    : dDNN+%r   c                 ~    t        |       t        |      k(  r!| xj                  |j                  z  c_        | S t        rH   r   r   s     r   __iand__zBitField.__iand__	  r   r   c                 F     t        |       | j                        }||z  }|S )a_  
        Perform bitwise-and operation between two bit-fields.

        Args:
            other (BitField): The other bit-field.

        Returns:
            result (BitField): The result of the operation.

        Examples:
            >>> a = BitField(3)
            >>> b = BitField(6)

            >>> print(a & b)
            BitField(b)
            >>> print(a)
            BitField(ab)
            >>> print(b)
            BitField(bc)

            >>> print(a * b)
            BitField(b)
            >>> print(a)
            BitField(ab)
            >>> print(b)
            BitField(bc)

        r   r   s      r   __and__zBitField.__and__  r   r   c                 T    t        |t              r| j                  |       | S t        rH   )r9   r:   flipr   r   s     r   __ixor__zBitField.__ixor__6  s#    eS!IIeK  r   c                 F     t        |       | j                        }||z  }|S )a  
        Flip the specified bit from the bit-fields.

        Args:
            item (int): The position of the bit to flip.

        Returns:
            result (BitField): The result of the operation.

        Examples:
            >>> flags = BitField('bd')
            >>> flags ^= 0
            >>> print(flags)
            BitField(abd)
            >>> flags ^= 0
            >>> print(flags)
            BitField(bd)
            >>> print(flags ^ 0)
            BitField(abd)
        r   )r=   itemr   s      r   __xor__zBitField.__xor__>  s&    * dDNN+$r   c                 f    t        |       t        |      k(  xr | j                  |j                  k(  S rH   r   r   s     r   __eq__zBitField.__eq__X  s'    DzT%[(NT^^u-NNr   c                 f    t        |       t        |      k7  xs | j                  |j                  k7  S rH   r   r   s     r   __ne__zBitField.__ne__\  s'    DzT%[(MDNNeoo,MMr   c                     | j                   j                  dz   t        | j                        z   dz   t	        t        | j                                     z   S N())r?   r/   r   r6   rv   dictrm   rJ   s    r   __repr__zBitField.__repr__`  sD    ~~&&,s4>>/BBSHT$**,'() 	)r   c                     | j                  | j                        }|rt        |      n| j                  }| j                  j
                  dz   |z   dz   S r   )decoder6   rv   r#   r?   r/   )r=   r-   r   s      r   __str__zBitField.__str__e  sD    {{4>>* s4ydjj~~&&,t3c99r   c                 L    | j                  | j                  |dd |d   dd      S )a  
        Decode bit-field using the specified extended keys.

        Extended keys include the empty token as first element.

        Args:
            ext_keys (Sequence): The extended decoding keys.
                The first element is used for decoding the empty bits.
                All the other keys follow.

        Returns:
            result (Sequence): The decoded bit-field.

        Examples:
            >>> flags = BitField(3)
            >>> flags % '-rwx'
            'rw-'
        r   Nr   Tr   r6   )r=   ext_keyss     r   __mod__zBitField.__mod__k  s0    & {{NNHQRL(1+tTC 	Cr   c                 @    | j                  | j                  |ddd      S )aQ  
        Decode bit-field using the specified keys.

        Args:
            keys (Sequence): The decoding keys.
                Unset bits are ignored.

        Returns:
            result (Sequence): The decoded bit-field.

        Examples:
            >>> flags = BitField(3)
            >>> flags / '123'
            '12'
        NFTr   r=   r-   s     r   __truediv__zBitField.__truediv__  s      {{4>>4udCCr   c                 H    | j                  | j                  |ddt              S )ao  
        Decode bit-field using the specified keys (and a list container).

        Args:
            keys (Sequence): The decoding keys.
                Unset bits are ignored.

        Returns:
            result (Sequence): The decoded bit-field.

        Examples:
            >>> flags = BitField(3)
            >>> flags // '123'
            ['1', '2']
        NF)r   r6   listr   s     r   __floordiv__zBitField.__floordiv__  s      {{4>>4udCCr   c                     | |    | |<   | |   S )a"  
        Flip (toggle) the item at the specified position.

        Args:
            item (int): The index of the item to access.

        Returns:
            result (bool): The value of the item after flipping.

        Examples:
            >>> flags = BitField(7)
            >>> print(flags[0])
            True
            >>> print(flags.flip_slice(0))
            False
            >>> print(flags[0])
            False
            >>> print(flags.flip_slice(0))
            True
            >>> print(flags[0])
            True
        r   )r=   r   s     r   r   zBitField.flip  s    . d^T
Dzr   c                 |   || j                   }| j                  || j                  }|r+fdt        j                  |t        |      d      D        }nd t        |t        |            D        }t        |      r ||      S |r2t        |t              rdj                  |      S  t        |      |      S |S )a  
        Decode a bit-field according to the specified keys.

        Args:
            BitField (int): The input BitField.
            keys (Iterable): The keys to use for decoding the bit-field.
            empty (Any|None): The value to use for unset flags.
            full_repr (bool): Represent all available flags.
            container (bool|callable|None): Determine the container to use.
                If callable, must be a sequence constructor.
                If True, the container is inferred from the type of `KEYS`.
                Otherwise, the generator itself is returned.

        Returns:
            result (Sequence|generator): The keys associated to the bit-field.

        Examples:
            >>> BitField.decode(42)
            'bdf'
        c              3   0   K   | ]  \  }}|r|n  y wrH   r   ).0r`   r   r.   s      r   	<genexpr>z"BitField.decode.<locals>.<genexpr>  s&      NC %'Ns   F)	fillvaluec              3   ,   K   | ]  \  }}|s	|  y wrH   r   )r   r`   r   s      r   r   z"BitField.decode.<locals>.<genexpr>  s     Ojc5cOs   
 )r"   r#   	FULL_REPR	itertoolszip_longestr   rf   callabler9   rv   joinr'   )r>   r3   r-   r.   	full_repr	containerr   s      `   r   r   zBitField.decode  s    8 <88D=IIEIN %%dDNeLNF
 PCd8n,EOFIV$$$$wwv&!tDz&))Mr   c                 ,   || j                   }|| j                  }|| j                  }t        |      }|j	                  |       d}t        |      D ]=  \  }}||v r||k7  s|d|j                  |      z  z  }(|r+t        t        d             |S )a  
        Encode a bit-field according to the specified keys.

        Args:
            items (Iterable): The items from the bit-field.
            keys (Iterable): The keys to use for decoding the bit-field.
            empty (Any|None): The value to use for unset flags.
            ignore_invalid (bool): Ignore invalid items.
                If False, a ValueError is raised if invalid items are present.

        Returns:
            result (int): The value associated to the items in the bit-field.

        Raises:
            ValueError: If ignore is False and invalid items are present in
                in the input.

        Examples:
            >>> BitField.encode('acio')
            16645
        r   r   z%Invalid input `{item}` at index: {i}.)	r"   r#   r<   r%   add	enumeraterw   r&   r   )	r>   rm   r-   r.   ignore_invalidrL   r   r   r   s	            r   r;   zBitField.encode  s    8 <88D=IIE! //NY
u ' 	CGAtz!5=Q$**T"222E# @AC C	C r   c                     | j                   S rH   rI   rJ   s    r   __int__zBitField.__int__(  s    ~~r   c                     |dv rt        t        |       |      S 	 t        |       j                  j                  |      }|t        t        d            | |   S # t        $ r d}Y (w xY w)a  
        Get the value of a given flag using attributes.

        Args:
            name (str): The attribute name.

        Returns:
            value (bool): The value of the flag.

        Examples:
            >>> print(BitField(1).a)
            True
            >>> print(BitField(0).a)
            False
            >>> print(BitField(1).something)
            Traceback (most recent call last):
                ...
            AttributeError: Unknown key `something`.
        >   r"   r#   NUnknown key `{name}`.)getattrr'   r"   rw   r&   AttributeErrorr   r=   namer   s      r   __getattr__zBitField.__getattr__,  sr    ( $$4:t,,JOO))$/ y$T*A%BCCAw  s   $A A('A(c                     |dv rt         t        |   ||       y	 t        |       j                  j                  |      }|t        t        d            || |<   y# t        $ r d}Y )w xY w)aX  
        Set the value of a given flag using attributes.

        Args:
            name (str): The attribute name.

        Returns:
            None.

        Examples:
            >>> flags = BitField(6)
            >>> print(flags)
            BitField(bc)
            >>> flags.a = True
            >>> print(flags)
            BitField(abc)
            >>> flags.a = False
            >>> print(flags)
            BitField(bc)
            >>> flags.something = True
            Traceback (most recent call last):
                ...
            AttributeError: Unknown key `something`.
        >   r3   r6   Nr   )	r7   r3   r8   r'   r"   rw   r&   r   r   )r=   r   r   r   r?   s       r   r8   zBitField.__setattr__M  ss    2 ,,(D-dE:JOO))$/ y$T*A%BCCQ  s   $A A*)A*c                     	 t        |       j                  j                  |      }|t	        t        d            | |= y# t        $ r d}Y 'w xY w)aR  
        Delete the value of a given flag using attributes.

        Args:
            name (str): The attribute name.

        Returns:
            None.

        Examples:
            >>> flags = BitField(6)
            >>> print(flags)
            BitField(bc)
            >>> del flags.a
            >>> print(flags)
            BitField(bc)
            >>> del flags.b
            >>> print(flags)
            BitField(c)
            >>> flags.something = True
            Traceback (most recent call last):
                ...
            AttributeError: Unknown key `something`.
        Nr   )r'   r"   rw   r&   r   r   r   s      r   __delattr__zBitField.__delattr__s  sT    2	T
%%d+A 9 &=!>??Q  	A	s   $A   AA)r   )NN)T)NNNT)NNN)Cr/   r0   r1   __doc__stringascii_lettersr"   r#   r   r<   r@   propertyr3   setterdeleterclassmethodrN   rD   __len__rR   rV   rX   rZ   r]   r-   rc   rh   rk   rm   ro   rq   rs   __iter____reversed__rx   rz   r}   r   rw   r   r   r   r   __add____iadd__r   r   __mul____imul__r   r   r   r   r   r   r   r   r   r   toggler   r;   r   r   r8   r   __classcell__)r?   s   @r   r3   r3   s   s   \z DEIN
 C2 C C __= =   * * $ $$ llG + + 2626("*"&$02!(!* H L1,%:P4 *58!GF!B GH!B GH!4ON)
:C.D&D&4 F  0 0f  + +\B# L r   r3   )	metaclassrH   )r   
__future__r   r   r   r   r   r   r   r   r   r   r'   r    objectr3   r   r   r   <module>r      sT   C C
    !#J,&,
@4 
@`v `r   