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      ?Zsha512_cryptZsha256_cryptZ
sha1_cryptZbcryptZ	md5_cryptZ
bsdi_cryptZ	des_cryptZlinearZ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 rS   <./venv/lib/python3.8/site-packages/passlib/utils/__init__.py	_as_tuple   s    zSequenceMixin._as_tuplec                 C   s   t |  S N)reprrU   rQ   rS   rS   rT   __repr__   s    zSequenceMixin.__repr__c                 C   s   |   | S rV   rU   )rR   idxrS   rS   rT   __getitem__   s    zSequenceMixin.__getitem__c                 C   s   t |  S rV   )iterrU   rQ   rS   rS   rT   __iter__   s    zSequenceMixin.__iter__c                 C   s   t |  S rV   )lenrU   rQ   rS   rS   rT   __len__   s    zSequenceMixin.__len__c                 C   s   |   |kS rV   rY   rR   otherrS   rS   rT   __eq__   s    zSequenceMixin.__eq__c                 C   s   |  | S rV   )rb   r`   rS   rS   rT   __ne__   s    zSequenceMixin.__ne__N)__name__
__module____qualname____doc__rU   rX   r[   r]   r_   rb   rc   rS   rS   rS   rT   rO      s   rO   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)	inspectZ	signaturer/   Z
parametersgetkind_VAR_ANY_SETlist_VAR_KEYWORD)funckeyparamsargrS   rS   rT   accepts_keyword   s    
rt   c                 C   s"   t t| }||jkp |jdk	S )rh   N)rj   Z
getargspecr/   argskeywords)rp   rq   specrS   rS   rT   rt      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 rV   )
issubclass).0baseZmixinrS   rT   	<genexpr>   s     z'update_mixin_classes.<locals>.<genexpr>   r   N)
isinstancetypern   	__bases__removeany	enumeraterx   r^   reversedAssertionErrorinserttuple)targetaddr   appendbeforeZafterZdryrunbasesrZ   rz   Zend_idxrS   r{   rT   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   r^   r	   r\   	itertoolsislicenextStopIterationchain	TypeError)sourcesizeendinitrZ	chunk_itrfirstrS   rS   rT   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'   r^   zipord)leftrightZis_py3_bytesZ	same_sizeZtmpresultlrrS   rS   rT   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.
    Nri   c                 S   s   g | ]}|  qS rS   )stripry   elemrS   rS   rT   
<listcomp>  s     zsplitcomma.<locals>.<listcomp>)r   endswithsplit)r   seprS   rS   rT   
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 rV   )_USPACEry   cin_table_b1in_table_c12rS   rT   r|     s   zsaslprep.<locals>.<genexpr>ZNFKCr   ri   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   rS   r   rT   r6     sj    ,








c                 C   s   t dt dS )zstub for saslprep()z>saslprep() support requires the 'stringprep' module, which is N)rP   _stringprep_missing_reason)r   r   rS   rS   rT   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)ry   rs   rS   rS   rT   r|   ,  s   zrender_bytes.<locals>.<genexpr>)r~   r   r   r   encode)r   ru   r   rS   rS   rT   r8     s    



c                 C   s   t | dS NZbig)int
from_bytesr   rS   rS   rT   bytes_to_int2  s    r   c                 C   s   |  |dS r   )r;   r   countrS   rS   rT   int_to_bytes4  s    r   )hexlify	unhexlifyc                 C   s   t t| dS )N   )r   r   r   rS   rS   rT   r   9  s    c                 C   s   t d|d>  |  S )Nz%%0%dxr}   )r   r   rS   rS   rT   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   r^   r   r   rS   rS   rT   r7   A  s    c                 C   s$   d|d t |   }| | d| S )zE
    repeat or truncate <source> string, so it has length <size>
    r}   N)r^   r   r   ZmultrS   rS   rT   repeat_stringE  s    r   c                 C   s"   d|d t |   }t| | |S )zN
    variant of repeat_string() which truncates to nearest UTF8 boundary.
    r}   )r^   utf8_truncater   rS   rS   rT   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)r^   r~   r*   _UNULL_BNULL)r   r   ZpadZcurrS   rS   rT   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   rS   rT   sanity_check  s    z#utf8_truncate.<locals>.sanity_check)r~   r   r    r^   maxminr+   r   )r   indexr   r   rS   r   rT   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)codecrS   rS   rT   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   rS   rS   rT   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 rV   rS   r   r   rS   rT   r|     s     z is_ascii_safe.<locals>.<genexpr>)r~   r   _B80_U80all)r   rS   r   rT   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   Zsource_encodingrS   rS   rT   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   rS   rS   rT   r<     s    


c                 C   s0   t | tr| |S t | tr"| S t| |d S rV   )r~   r   r   r*   r   r   rS   rS   rT   r=     s
    


c                 C   s0   t | tr| S t | tr"| |S t| |d S rV   )r~   r   r*   r   r   r   rS   rS   rT   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   rS   rS   rT   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   ZcleanrS   rS   rT   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   rS   rS   rT   is_safe_crypt_inputG  s    
r  )cryptc                 C   s   d S rV   rS   secretr   rS   rS   rT   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   Zorigr   rS   rS   rT   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   rS   rS   rT   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  rS   rS   rT   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 rV   )r   r   rS   rS   rT   r|     s     z parse_version.<locals>.<genexpr>r}   .N)researchr   groupr   )r   mrS   rS   rT   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   )Zhashlibr  hasattrr  rP   r  r(   osr  idobjecttimerA   has_urandomurandomr   r   r   Z	hexdigest)r   r  r   rS   rS   rT   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   rS   rT   helperM  s    
zgetrandbytes.<locals>.helper)_BEMPTYr#   )rB   r   r(  rS   r'  rT   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}   )Z	randranger&  charsetr   ZlettersrB   rS   rT   r(  f  s    zgetrandstr.<locals>.helperN)r   r^   r~   r*   r)   r$   )rB   r+  r   r(  rS   r*  rT   rD   W  s    	

Z42346789ABCDEFGHJKMNPQRTUVWXYZabcdefghjkmnpqrstuvwxyzz2.0z/passlib.pwd.genword() / passlib.pwd.genphrase())r   r   Z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   r+  rS   rS   rT   rE   v  s    )r   setting_kwdsZ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 rV   r  ry   r   objrS   rT   r|     s     z#is_crypt_handler.<locals>.<genexpr>)r   _handler_attrsr2  rS   r2  rT   rF     s    )Zneeds_updateZ	genconfigZgenhashr.  Zencryptr/  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 rV   r0  r1  r2  rS   rT   r|     s     z#is_crypt_context.<locals>.<genexpr>)r   _context_attrsr2  rS   r2  rT   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roundsZ
min_roundsNr-  getattrZhandlerrS   rS   rT   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>` attributesZsaltZmin_salt_sizeNr7  r9  rS   rS   rT   rI     s    
)NNFNNF)r   )r   )r   )N)r   r   N)r   r   )r   r   )r   r   )r   )Nr   )N)rg   Zpasslib.utils.compatr   Zbinasciir   r   r   Z_BinAsciiErrorbase64r   r   Zcollections.abcr   r	   ImportErrorcollectionscodecsr
   r   	functoolsr   r   rj   ZloggingZ	getLoggerrd   logZmathr  sysZrandomr  r   r   r!  r   	threadingZtimeittypeswarningsr   Zpasslib.utils.binaryr   r   r   r   r   r   r   r   r   r   r   r   r   Zpasslib.utils.decorr   r   r   r   r   Z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   rK   r)  r   r   environrk   ZMAX_PASSWORD_SIZEr   rO   Z	ParameterZVAR_KEYWORDro   setZVAR_POSITIONALrm   rt   r   r   r5   Zstr_consteqZ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_timerZtimerrA   r  r#  r"  rP   r$  ZSystemRandomrB   ZRandomrC   rD   Z
_52charsetrE   r4  rF   r5  rG   rH   rI   rS   rS   rS   rT   <module>   s   

<L."   	
      
W>

 





F

%



*
/



!

