U
    h                     @   s  d Z ddlmZ ddlmZmZmZ ddlm	Z	m
Z
 zddlmZ ddlmZ W n, ek
r|   ddlmZ ddlmZ Y nX ddlmZ ddlmZ dd	lZdd	lZdd	lZeeZdd	lZdd	lZdd	lZdd	lZdd	lZerzdd	l Z W n ek
r   d	Z d
Z!Y nX ndd	l Z dd	l"Z"e r2dd	l#Z#zdd	l$Z$W n ek
rX   d	Z$Y nX dd	l%Z%dd	l&Z&ddl'm(Z( ddl)m*Z*m+Z+m,Z,m-Z-m.Z.m/Z/m0Z0m1Z1m2Z2m3Z3m4Z4m5Z5m6Z6 ddl7m8Z8m9Z9m:Z:m;Z;m<Z< ddl=m>Z>m?Z? ddlm@Z@mAZAmBZBmCZCmDZDmEZEmFZFmGZGmHZHmIZImJZJmKZKmLZLmMZMmNZNmOZOmPZP ddddddddddddddddd d!d"d#d$d%d&d'd(gZQeReeFrrejSnejTd)d* ZUd+d,d-d.d/d0d1gZVd2d3gZWdd4l=mXZX d5ZYeGd6ZZeGd7Z[eRej\]d8pd9Z^G d:d; d;e_Z`eFr
ejajbZcedecejajegZfd<d= Zgnd>d= Zgdd@dAZhdBdC ZidDd ZjejZkzddEllmmZj W n ek
rV   Y nX ddGdHZnddJdZoe d	krddKdZodLd ZpeFrdMdN ZqdOdP Zrn ddQlmsZsmtZt dRdN ZqdSdP Zre@eqdT e@erdU dVd ZudWdX ZvdYdZ Zwd[ZxeGd\Zydd]d^Zzd_d` Z{daZ|e|}dbZ~dcdd Zded ZdfZeGdgZdhd ZddjdZddkdZeFrbddldZn
ddmdZe@edn e8dodpdqddrdsZeddt Zeddu Zedd6dvgZddxdyZdzd{ Zzdd|lmZ W n2 ek
r   d	Zd?Zd?Zd?Zd	Zd}d ZY nX d~Zd\Ze$rFePrFdej  kr4dkrFn ne$ Zd~ZnddlmZ e Zd?ZeGdZeFrd~Zzedd W n$ ek
r   d?ZY n   Y nX dd Znd~Zdd Ze@ed dd Ze%jZeZdd Zzed d~ZW n ek
r   d?ZY nX dddZer$e Znee Zdd" Zdd# ZdZe8dpddddefdd$ZdZdd% ZdZdd& Zdd' Zdd( Zd	S )z4passlib.utils -- helpers for writing password hashes    )JYTHON)
b2a_base64
a2b_base64Error)	b64encode	b64decode)Sequence)Iterable)lookup)update_wrapperNznot present under Jython)warn)BASE64_CHARS
AB64_CHARSHASH64_CHARSBCRYPT_CHARSBase64EngineLazyBase64Engineh64h64bigbcrypt64ab64_encodeab64_decodeb64s_encodeb64s_decode)deprecated_functiondeprecated_methodmemoized_propertyclasspropertyhybrid_method)ExpectedStringErrorExpectedTypeError)add_doc
join_bytesjoin_byte_valuesjoin_byte_elemsirangeimapPY3ujoin_unicodeunicodebyte_elem_value
nextgetterunicode_or_strunicode_or_bytes_typesget_method_functionsuppress_causePYPYr   sys_bitsunix_crypt_schemesrounds_cost_valuesconsteqsaslprep	xor_bytesrender_bytesis_same_codecis_ascii_safeto_bytes
to_unicodeto_native_str	has_crypt
test_crypt
safe_crypttickrnggetrandbytes
getrandstrgenerate_passwordis_crypt_handleris_crypt_contexthas_rounds_infohas_salt_info   g      ?sha512_cryptsha256_crypt
sha1_cryptbcrypt	md5_crypt
bsdi_crypt	des_cryptZlinearlog2)MissingBackendError      ZPASSLIB_MAX_PASSWORD_SIZEi   c                   @   sH   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
dS )SequenceMixinz
    helper which lets result object act like a fixed-length sequence.
    subclass just needs to provide :meth:`_as_tuple()`.
    c                 C   s   t dd S )Nzimplement in subclass)NotImplementedErrorself r[   Z/var/www/html/timesheet/backend/venv/lib/python3.8/site-packages/passlib/utils/__init__.py	_as_tuple   s    zSequenceMixin._as_tuplec                 C   s   t |  S N)reprr]   rY   r[   r[   r\   __repr__   s    zSequenceMixin.__repr__c                 C   s   |   | S r^   r]   )rZ   idxr[   r[   r\   __getitem__   s    zSequenceMixin.__getitem__c                 C   s   t |  S r^   )iterr]   rY   r[   r[   r\   __iter__   s    zSequenceMixin.__iter__c                 C   s   t |  S r^   )lenr]   rY   r[   r[   r\   __len__   s    zSequenceMixin.__len__c                 C   s   |   |kS r^   ra   rZ   otherr[   r[   r\   __eq__   s    zSequenceMixin.__eq__c                 C   s   |  | S r^   )rj   rh   r[   r[   r\   __ne__   s    zSequenceMixin.__ne__N)__name__
__module____qualname____doc__r]   r`   rc   re   rg   rj   rk   r[   r[   r[   r\   rW      s   rW   c                 C   sJ   t t| j}|sdS ||}|r4|jtkr4dS |t|d  jtkS )*test if function accepts specified keywordFT)	inspect	signaturer/   
parametersgetkind_VAR_ANY_SETlist_VAR_KEYWORD)funckeyparamsargr[   r[   r\   accepts_keyword   s    
r~   c                 C   s"   t t| }||jkp |jdk	S )rp   N)rr   
getargspecr/   argskeywords)rz   r{   specr[   r[   r\   r~      s    Fc                    s8  t |tr|g}t| j}|rXt |tr.|g}|D ]$ |rD |krDq2 |kr2|  q2|r$|D ] t fdd|D r~qb|rt|D ](\}}	t |	r q|rt|	|r qqt|}nX|rtt	|D ]:\}
}	t|	|rt||
 }||d  |	kst
 qqd}nd}||  qb|s4t|| _dS )a  
    helper to update mixin classes installed in target class.

    :param target:
        target class whose bases will be modified.

    :param add:
        class / classes to install into target's base class list.

    :param remove:
        class / classes to remove from target's base class list.

    :param append:
        by default, prepends mixins to front of list.
        if True, appends to end of list instead.

    :param after:
        optionally make sure all mixins are inserted after
        this class / classes.

    :param before:
        optionally make sure all mixins are inserted before
        this class / classes.

    :param dryrun:
        optionally perform all calculations / raise errors,
        but don't actually modify the class.
    c                 3   s   | ]}t | V  qd S r^   )
issubclass).0baseZmixinr[   r\   	<genexpr>   s     z'update_mixin_classes.<locals>.<genexpr>   r   N)
isinstancetyperx   	__bases__removeany	enumerater   rf   reversedAssertionErrorinserttuple)targetaddr   appendbeforeafterZdryrunbasesrb   r   Zend_idxr[   r   r\   update_mixin_classes   sB    





r   c                 c   s   |dk rt dt| trLt| }d}||k r|| }| || V  |}q&n`t| trt| }t||}zt|}W n t	k
r   Y qY nX t
|f|V  q^ntddS )z8
    split iterable into chunks of <size> elements.
    r   zsize must be positive integerr   zsource must be iterableN)
ValueErrorr   r   rf   r	   rd   	itertoolsislicenextStopIterationchain	TypeError)sourcesizeendinitrZ	chunk_itrfirstr[   r[   r\   batch  s$    


r   c                 C   s   t | tr"t |tstdd}n*t | trDt |ts>tdt}ntdt| t|k}|rh| }d}|st|}d}|rt||D ]\}}|||A O }qn(t||D ]\}}|t|t|A O }q|dkS )a  Check two strings/bytes for equality.

    This function uses an approach designed to prevent
    timing analysis, making it appropriate for cryptography.
    a and b must both be of the same type: either str (ASCII only),
    or any type that supports the buffer protocol (e.g. bytes).

    Note: If a and b are of different lengths, or if an error occurs,
    a timing attack could theoretically reveal information about the
    types and lengths of a and b--but not their values.
    z)inputs must be both unicode or both bytesFr   r   )r   r*   r   bytesr'   rf   zipord)leftrightZis_py3_bytesZ	same_sizetmpresultlrr[   r[   r\   r5   ;  s,    



)compare_digest,c                 C   s:   |   } | |r| dd } | s&g S dd | |D S )zRsplit comma-separated string into list of elements,
    stripping whitespace.
    Nrq   c                 S   s   g | ]}|  qS r[   )stripr   elemr[   r[   r\   
<listcomp>  s     zsplitcomma.<locals>.<listcomp>)r   endswithsplit)r   sepr[   r[   r\   
splitcomma  s    
r   valuec                    s  t | tstdt| f tjtj t fdd| D }t	d|}|sTt
S tj}||d r||d s~td| tj}n|}tj}tj}tj}tj}tj}	tj}
tj}tj}tj}|D ]} |rtd|rtd	||rtd
| ||rtd| ||r(td| ||r>td| |	|rTtd| |
|rjtd| ||rtd| ||rtd| ||rtd| ||rtd| q|S )a  Normalizes unicode strings using SASLPrep stringprep profile.

    The SASLPrep profile is defined in :rfc:`4013`.
    It provides a uniform scheme for normalizing unicode usernames
    and passwords before performing byte-value sensitive operations
    such as hashing. Among other things, it normalizes diacritic
    representations, removes non-printing characters, and forbids
    invalid characters such as ``\n``. Properly internationalized
    applications should run user passwords through this function
    before hashing.

    :arg source:
        unicode string to normalize & validate

    :param param:
        Optional noun identifying source parameter in error messages
        (Defaults to the string ``"value"``). This is mainly useful to make the caller's error
        messages make more sense contextually.

    :raises ValueError:
        if any characters forbidden by the SASLPrep profile are encountered.

    :raises TypeError:
        if input is not :class:`!unicode`

    :returns:
        normalized unicode string

    .. note::

        This function is not available under Jython,
        as the Jython stdlib is missing the :mod:`!stringprep` module
        (`Jython issue 1758320 <http://bugs.jython.org/issue1758320>`_).

    .. versionadded:: 1.6
    z$input must be unicode string, not %sc                 3   s&   | ]} |s|rt n|V  qd S r^   )_USPACEr   cin_table_b1in_table_c12r[   r\   r     s   zsaslprep.<locals>.<genexpr>NFKCr   rq   zmalformed bidi sequence in z$failed to strip B.1 in mapping stagez(failed to replace C.1.2 in mapping stagez$unassigned code points forbidden in z control characters forbidden in z$private use characters forbidden in z"non-char code points forbidden in zsurrogate codes forbidden in z!non-plaintext chars forbidden in z!non-canonical chars forbidden in z1display-modifying / deprecated chars forbidden inztagged characters forbidden in zforbidden bidi character in )r   r*   r   r   
stringprepr   r   r)   unicodedata	normalize_UEMPTYZin_table_d1r   Zin_table_d2in_table_a1in_table_c21_c22in_table_c3in_table_c4in_table_c5in_table_c6in_table_c7in_table_c8in_table_c9r   )r   paramdataZis_ral_charZis_forbidden_bidi_charr   r   r   r   r   r   r   r   r   r   r[   r   r\   r6     sj    ,








c                 C   s   t dt dS )zstub for saslprep()z>saslprep() support requires the 'stringprep' module, which is N)rX   _stringprep_missing_reason)r   r   r[   r[   r\   r6     s    c                 G   s4   t | tr| d} | tdd |D  }|dS )a  Peform ``%`` formating using bytes in a uniform manner across Python 2/3.

    This function is motivated by the fact that
    :class:`bytes` instances do not support ``%`` or ``{}`` formatting under Python 3.
    This function is an attempt to provide a replacement:
    it converts everything to unicode (decoding bytes instances as ``latin-1``),
    performs the required formatting, then encodes the result to ``latin-1``.

    Calling ``render_bytes(source, *args)`` should function roughly the same as
    ``source % args`` under Python 2.

    .. todo::
        python >= 3.5 added back limited support for bytes %,
        can revisit when 3.3/3.4 is dropped.
    latin-1c                 s   s&   | ]}t |tr|d n|V  qdS )r   N)r   r   decode)r   r}   r[   r[   r\   r   ,  s   zrender_bytes.<locals>.<genexpr>)r   r   r   r   encode)r   r   r   r[   r[   r\   r8     s    



c                 C   s   t | dS Nbig)int
from_bytesr   r[   r[   r\   bytes_to_int2  s    r   c                 C   s   |  |dS r   )r;   r   countr[   r[   r\   int_to_bytes4  s    r   )hexlify	unhexlifyc                 C   s   t t| dS )N   )r   r   r   r[   r[   r\   r   9  s    c                 C   s   t d|d>  |  S )Nz%%0%dxr   )r   r   r[   r[   r\   r   ;  s    z/decode byte string as single big-endian integerz/encode integer as single big-endian byte stringc                 C   s   t t| t|A t| S )z;Perform bitwise-xor of two byte strings (must be same size))r   r   rf   r   r   r[   r[   r\   r7   A  s    c                 C   s$   d|d t |   }| | d| S )zE
    repeat or truncate <source> string, so it has length <size>
    r   N)rf   r   r   Zmultr[   r[   r\   repeat_stringE  s    r   c                 C   s"   d|d t |   }t| | |S )zN
    variant of repeat_string() which truncates to nearest UTF8 boundary.
    r   )rf   utf8_truncater   r[   r[   r\   utf8_repeat_stringM  s    r        c                 C   sJ   t | }||kr:|dkr*t| tr&tnt}| |||   S | d| S dS )z>right-pad or truncate <source> string, so it has length <size>N)rf   r   r*   _UNULL_BNULL)r   r   padcurr[   r[   r\   right_pad_stringX  s    r   c                    s   t tsttdt}|dk r4td|| }||kr@S t|d |}||k rvt| d@ dkrlq|d7 }qN||kstd|   fdd	}| st S )
a  
    helper to truncate UTF8 byte string to nearest character boundary ON OR AFTER <index>.
    returned prefix will always have length of at least <index>, and will stop on the
    first byte that's not a UTF8 continuation byte (128 - 191 inclusive).
    since utf8 should never take more than 4 bytes to encode known unicode values,
    we can stop after ``index+3`` is reached.

    :param bytes source:
    :param int index:
    :rtype: bytes
    r   r            r   Nc                     s>   z d} W n tk
r$   Y dS X |   ds:tdS )Nutf-8T)r   UnicodeDecodeError
startswithr   )textr   r   r[   r\   sanity_check  s    z#utf8_truncate.<locals>.sanity_check)r   r   r    rf   maxminr+   r   )r   indexr   r   r[   r   r\   r   c  s"    


r   s	    
 aA:#!asciic                 C   s   t | tkS )zRTest if codec is compatible with 7-bit ascii (e.g. latin-1, utf-8; but not utf-16))_ASCII_TEST_UNICODEr   _ASCII_TEST_BYTES)codecr[   r[   r\   is_ascii_codec  s    r   c                 C   s,   | |krdS | r|sdS t | jt |jkS )z3Check if two codec names are aliases for same codecTF)_lookup_codecnamer   r[   r[   r\   r9     s
    r      c                    s(   t | trtnt t fdd| D S )z<Check if string (bytes or unicode) contains only 7-bit asciic                 3   s   | ]}| k V  qd S r^   r[   r   r   r[   r\   r     s     z is_ascii_safe.<locals>.<genexpr>)r   r   _B80_U80all)r   r[   r  r\   r:     s    r   c                 C   sX   |st t| tr6|r0t||s0| ||S | S nt| trJ| |S t| |dS )a  Helper to normalize input to bytes.

    :arg source:
        Source bytes/unicode to process.

    :arg encoding:
        Target encoding (defaults to ``"utf-8"``).

    :param param:
        Optional name of variable/noun to reference when raising errors

    :param source_encoding:
        If this is specified, and the source is bytes,
        the source will be transcoded from *source_encoding* to *encoding*
        (via unicode).

    :raises TypeError: if source is not unicode or bytes.

    :returns:
        * unicode strings will be encoded using *encoding*, and returned.
        * if *source_encoding* is not specified, byte strings will be
          returned unchanged.
        * if *source_encoding* is specified, byte strings will be transcoded
          to *encoding*.
    N)r   r   r   r9   r   r   r*   r   )r   encodingr   source_encodingr[   r[   r\   r;     s    


c                 C   s8   |st t| tr| S t| tr*| |S t| |dS )a  Helper to normalize input to unicode.

    :arg source:
        source bytes/unicode to process.

    :arg encoding:
        encoding to use when decoding bytes instances.

    :param param:
        optional name of variable/noun to reference when raising errors.

    :raises TypeError: if source is not unicode or bytes.

    :returns:
        * returns unicode strings unchanged.
        * returns bytes strings decoded using *encoding*
    N)r   r   r*   r   r   r   r   r  r   r[   r[   r\   r<     s    


c                 C   s0   t | tr| |S t | tr"| S t| |d S r^   )r   r   r   r*   r   r	  r[   r[   r\   r=     s
    


c                 C   s0   t | tr| S t | tr"| |S t| |d S r^   )r   r   r*   r   r   r	  r[   r[   r\   r=     s
    


a>  Take in unicode or bytes, return native string.

    Python 2: encodes unicode using specified encoding, leaves bytes alone.
    Python 3: leaves unicode alone, decodes bytes using specified encoding.

    :raises TypeError: if source is not unicode or bytes.

    :arg source:
        source unicode or bytes string.

    :arg encoding:
        encoding to use when encoding unicode or decoding bytes.
        this defaults to ``"utf-8"``.

    :param param:
        optional name of variable/noun to reference when raising errors.

    :returns: :class:`str` instance
    z1.6z1.7)
deprecatedremovedc                 C   s   t | |ddS )z'deprecated, use to_native_str() insteadhash)r   )r=   )r   r  r[   r[   r\   to_hash_str$  s    r  z true t yes y on 1 enable enabledz#false f no n off 0 disable disablednonebooleanc                 C   s~   |dkst t| trX|   }|tkr.dS |tkr:dS |tkrF|S td|| f n"t| t	rf| S | dkrr|S t	| S dS )z\
    helper to convert value to boolean.
    recognizes strings such as "true", "false"
    )TFNTFzunrecognized %s value: %rN)
r   r   r.   lowerr   	_true_set
_false_set	_none_setr   bool)r   r  r   cleanr[   r[   r\   as_bool-  s    

r  c                 C   s>   t st| tsdS z| d W dS  tk
r8   Y dS X dS )z
    UT helper --
    test if value is safe to pass to crypt.crypt();
    under PY3, can't pass non-UTF8 bytes to crypt.crypt.
    Tr   FN)crypt_accepts_bytesr   r   r   r   r   r[   r[   r\   is_safe_crypt_inputG  s    
r  )cryptc                 C   s   d S r^   r[   secretr  r[   r[   r\   r@   ]  s    T)   rJ   r   )r  r   r   )nullcontextz*:!   Zxxc              	   C   s  t r>t| tr| d} t| kr(tdt|tr|d}nnt| tr| }z| d} W n tk
rp   Y d S X | d|kst	dt
| krtdt|tr|d}zt t| |}W 5 Q R X W n tk
r   Y d S X t|tr|d}|r
|d tkrd S |S )Nr   null character in secretr   z"utf-8 spec says this can't happen!r   )r  r   r*   r   r   r   r   r   r   r   _NULL_safe_crypt_lock_cryptOSError_invalid_prefixes)r  r  origr   r[   r[   r\   r@     s<    







c              	   C   sx   t | tr| d} t| kr$tdt |tr8|d}t t| |}W 5 Q R X |sZd S |d}|d tkrtd S |S )Nr   r  r   r   )	r   r*   r   r   r   r!  r"  r   r$  )r  r  r   r[   r[   r\   r@     s    




a  Wrapper around stdlib's crypt.

    This is a wrapper around stdlib's :func:`!crypt.crypt`, which attempts
    to provide uniform behavior across Python 2 and 3.

    :arg secret:
        password, as bytes or unicode (unicode will be encoded as ``utf-8``).

    :arg hash:
        hash or config string, as ascii bytes or unicode.

    :returns:
        resulting hash as ascii unicode; or ``None`` if the password
        couldn't be hashed due to one of the issues:

        * :func:`crypt()` not available on platform.

        * Under Python 3, if *secret* is specified as bytes,
          it must be use ``utf-8`` or it can't be passed
          to :func:`crypt()`.

        * Some OSes will return ``None`` if they don't recognize
          the algorithm being used (though most will simply fall
          back to des-crypt).

        * Some OSes will return an error string if the input config
          is recognized but malformed; current code converts these to ``None``
          as well.
    c                 C   s4   t |tstdt| |s&tdt| ||kS )zcheck if :func:`crypt.crypt` supports specific hash
    :arg secret: password to test
    :arg hash: known hash of password to use as reference
    :returns: True or False
    z#hash must be unicode_or_str, got %szhash must be non-empty)r   r-   r   r   r@   r  r[   r[   r\   r?     s
    

c                 C   s2   t d| }|r.tdd |ddD S dS )zhelper to parse version stringz(\d+(?:\.\d+)+)c                 s   s   | ]}t |V  qd S r^   )r   r   r[   r[   r\   r     s     z parse_version.<locals>.<genexpr>r   .N)researchr   groupr   )r   mr[   r[   r\   parse_version  s    r+  r   c              	   C   s   ddl m} t| drLt| drLz|  } W n tk
rJ   | d} Y nX td| ttdrft ndt	t
 t t trtd	d
ndf }t||d dS )z.generate prng seed value from system resourcesr   )sha512getstategetrandbitsi   z%s %s %s %.15f %.15f %sgetpidN    r   r   r   )hashlibr,  hasattrr-  rX   r.  r(   osr/  idobjecttimerA   has_urandomurandomr   r   r   	hexdigest)r   r,  r   r[   r[   r\   genseed  s    r:  c                    s     st S  fdd}t| S )z]return byte-string containing *count* number of randomly generated bytes, using specified rngc                  3   s:     d> } d}| k r6| d@ V  | dL } |d7 }qd S )Nr   r      r   )r.  r   r   r   rB   r[   r\   helperM  s    
zgetrandbytes.<locals>.helper)_BEMPTYr#   )rB   r   r>  r[   r=  r\   rC   B  s    	c                    sl   dk rt dt dkr(t ddkr8  S  fdd}t tr^t| S t| S dS )z|return string containing *count* number of chars/bytes, whose elements are drawn from specified charset, using specified rngr   zcount must be >= 0zalphabet must not be emptyr   c                  3   s@    d } d}|k r< |   V  |  } |d7 }qd S )Nr   r   )	randranger<  charsetr   lettersrB   r[   r\   r>  f  s    zgetrandstr.<locals>.helperN)r   rf   r   r*   r)   r$   )rB   rB  r   r>  r[   rA  r\   rD   W  s    	

Z42346789ABCDEFGHJKMNPQRTUVWXYZabcdefghjkmnpqrstuvwxyzz2.0z/passlib.pwd.genword() / passlib.pwd.genphrase())r
  r  replacement
   c                 C   s   t t|| S )aw  generate random password using given length & charset

    :param size:
        size of password.

    :param charset:
        optional string specified set of characters to draw from.

        the default charset contains all normal alphanumeric characters,
        except for the characters ``1IiLl0OoS5``, which were omitted
        due to their visual similarity.

    :returns: :class:`!str` containing randomly generated password.

    .. note::

        Using the default character set, on a OS with :class:`!SystemRandom` support,
        this function should generate passwords with 5.7 bits of entropy per character.
    )rD   rB   )r   rB  r[   r[   r\   rE   v  s    )r  setting_kwdscontext_kwdsverifyr  identifyc                    s   t  fddtD S )z4check if object follows the :ref:`password-hash-api`c                 3   s   | ]}t  |V  qd S r^   r2  r   r  objr[   r\   r     s     z#is_crypt_handler.<locals>.<genexpr>)r  _handler_attrsrL  r[   rL  r\   rF     s    )needs_update	genconfiggenhashrH  encryptrI  c                    s   t  fddtD S )zOcheck if object appears to be a :class:`~passlib.context.CryptContext` instancec                 3   s   | ]}t  |V  qd S r^   rJ  rK  rL  r[   r\   r     s     z#is_crypt_context.<locals>.<genexpr>)r  _context_attrsrL  r[   rL  r\   rG     s    c                 C   s   d| j kot| dddk	S )z_check if handler provides the optional :ref:`rounds information <rounds-attributes>` attributesrounds
min_roundsNrF  getattrhandlerr[   r[   r\   rH     s    
c                 C   s   d| j kot| dddk	S )z[check if handler provides the optional :ref:`salt information <salt-attributes>` attributessaltZmin_salt_sizeNrV  rX  r[   r[   r\   rI     s    
)NNFNNF)r   )r   )r   )N)r   r   N)r   r   )r   r   )r   r   )r   )Nr  )N)ro   passlib.utils.compatr   binasciir   r   r   Z_BinAsciiErrorbase64r   r   collections.abcr   r	   ImportErrorcollectionscodecsr
   r   	functoolsr   r   rr   logging	getLoggerrl   logmathr3  sysrandomr'  r   r   r6  r   	threadingZtimeittypeswarningsr   passlib.utils.binaryr   r   r   r   r   r   r   r   r   r   r   r   r   passlib.utils.decorr   r   r   r   r   passlib.excr   r    r!   r"   r#   r$   r%   r&   r'   r(   r)   r*   r+   r,   r-   r.   r/   r0   r1   __all__r   maxsizeZmaxintr2   r3   r4   rS   r?  r   r   environru   ZMAX_PASSWORD_SIZEr5  rW   	ParameterVAR_KEYWORDry   setVAR_POSITIONALrw   r~   r   r   r5   Zstr_consteqhmacr   r   r6   r8   r   r   r   r   r7   r   r   r   r   r   r   r   r   r   r   r9   r  r  r:   r;   r<   r=   r  r   r  r  r  r  r  r  r"  r>   r  Zcrypt_needs_lockr!  r@   r   Zpypy_version_infoLockr  r$  r   r?   Zdefault_timertimerrA   r+  r8  r7  rX   r:  SystemRandomrB   RandomrC   rD   Z
_52charsetrE   rN  rF   rS  rG   rH   rI   r[   r[   r[   r\   <module>   s   

<L."   	
      
W>

 





F

%



*
/



!

