+
    i              
       $   R t ^ RIHtHt ^ RIt]P
                  ! ]4      t^ RIt^ RI	t	^ RI
Ht RtRs^ RIHt ^ RIHt ^ RIHtHtHt ^ RIHtHt ^ RIHtHtHtHtHt ^ RIH u H!t" R	.t#]! R
4      t$]! R4      t%]! R4      t&]&]$]%3t'](! ]'4      t)Rt* ^ RI+t],! ]R4      '       g   Rt*RtM],! ]R4      '       g   Rt*Rt],! ]R4      '       d)   ]P\                  ! 4       t/]P`                  Pb                  t2M ! R R4      t3]3! 4       t/^t2 ! R R]"Ph                  ]"Pj                  ]"Pl                  ]"Pn                  ]"Pp                  ]"Pr                  4      t: ! R R]:4      t; ! R R]:4      t< ! R R]:4      t= ! R R	];]:4      t+R#   ]- d    Rt Li ; i)a  passlib.handlers.argon2 -- argon2 password hash wrapper

References
==========
* argon2
    - home: https://github.com/P-H-C/phc-winner-argon2
    - whitepaper: https://github.com/P-H-C/phc-winner-argon2/blob/master/argon2-specs.pdf
* argon2 cffi wrapper
    - pypi: https://pypi.python.org/pypi/argon2_cffi
    - home: https://github.com/hynek/argon2_cffi
* argon2 pure python
    - pypi: https://pypi.python.org/pypi/argon2pure
    - home: https://github.com/bwesterb/argon2pure
)with_statementabsolute_importN)warn)exc)
MAX_UINT32)classpropertyto_bytesrender_bytes)b64s_encodeb64s_decode)uunicodebascii_to_struascii_to_strPY2argon2ididTypezb'argon2' module points to unsupported 'argon2' pypi package; please install 'argon2-cffi' instead.	low_levelz@'argon2-cffi' is too old, please update to argon2_cffi >= 18.2.0PasswordHasherc                   .    ] tR t^]tRt^tRt^t^t^t	Rt
R# )_DummyCffiHasherz
dummy object to use as source of defaults when argon2_cffi isn't present.
this tries to mimic the attributes of ``argon2.PasswordHasher()`` which the rest of
this module reads.

.. note:: values last synced w/ argon2 19.2 as of 2019-11-09
i    N)__name__
__module____qualname____firstlineno____doc__	time_costmemory_costparallelismsalt_lenhash_len__static_attributes__r       U/var/www/html/photoedit/myenv/lib/python3.14/site-packages/passlib/handlers/argon2.pyr   r   ]   s"    	 	r&   r   c                     a a ] tR t^st oRtRtRt]P                  t	]
P                  P                  R,           t]
P                  P                  R,           t]P                  t^t]t]P&                  t^t]tRtRt]tRt^tRtRt/ t] R 4       t!]"t#]PH                  t$]t%]PL                  t&]'R 4       t(Rt)]*RV 3R ll4       t+]*R	 4       t,]-P\                  ! R
4      t/]*R 4       t0]-P\                  ! R]-Pb                  4      t2]*R 4       t3R t4RV 3R llt5]*R 4       t6]*R 4       t7]*R R l4       t8]*R 4       t9V 3R lt:Rt;]*R 4       t<]*R!R l4       t=Rt>Vt?V ;t@# )"_Argon2Commona  
Base class which implements brunt of Argon2 code.
This is then subclassed by the various backends,
to override w/ backend-specific methods.

When a backend is loaded, the bases of the 'argon2' class proper
are modified to prepend the correct backend-specific subclass.
r   linearNFc                L    V P                  4        \        V P                  4      # )zJ
return tuple of types supported by this backend

.. versionadded:: 1.7.2
)get_backendtuple_backend_type_map)clss   &r'   type_values_Argon2Common.type_values   s     	S**++r&   c                (    V P                   \        8H  # )zV
flag indicating a Type D hash

.. deprecated:: 1.7.2; will be removed in passlib 2.0
)typeTYPE_Dselfs   &r'   type_d_Argon2Common.type_d   s     yyF""r&   c	           	     l  < Ve   RV	9   d   \        R4      hWIR&   Ve   RV	9   d   \        R4      hW9R&   Ve   Ve   \        R4      hTpVe   Ve   \        R4      hTp\        \        V `  ! R/ V	B p
Ve   V
P	                  V4      V
n        V	P                  R4      pVeP   \        V\        P                  4      '       d   \        V4      p\        P                  ! W^\        RVR	7      V
n        VeC   \        V\        P                  4      '       d   \        V4      pV
P                  W+R
7      V
n        V
P!                  V
P                  V
P"                  4       VeS   \        V\        P                  4      '       d   \        V4      pV^8  d   VR8w  d   \%        RV3,          4      hWn        V
# )Nroundsz/'time_cost' and 'rounds' are mutually exclusive	salt_sizez1'salt_len' and 'salt_size' are mutually exclusivez3'hash_len' and 'digest_size' are mutually exclusivez8'checksum_size' and 'digest_size' are mutually exclusiverelaxeddigest_size)minmaxparamr<   )r<   z7max_threads (%d) must be -1 (unlimited), or at least 1.r   )	TypeErrorsuperr)   using
_norm_typer3   get
isinstanceuhnative_string_typesintnorm_integerr   checksum_size_norm_memory_costr!   _validate_constraintsr"   
ValueErrormax_threads)r/   r3   r!   r#   r    r=   rL   r$   rP   kwdssubclsr<   	__class__s   &&&&&&&&&,  r'   rD   _Argon2Common.using  s     4 QRR&Nd" STT (& UVV"K$& Z[['K }c0848  ++D1FK ((9%"+r'='=>>!+.#%??6BT^9FPW$YF  "+r'='=>>!+.!'!9!9+!9!WF 	$$V%7%79K9KL "+r'='=>>!+.Q;"#4 !Z"-"0 1 1!,r&   c                b    ^V,          pW8  d    \        RV P                  VW#3,          4      hR# )   zO%s: memory_cost (%d) is too low, must be at least 8 * parallelism (8 * %d = %d)N)rO   name)r/   r!   r"   min_memory_costs   &&& r'   rN   #_Argon2Common._validate_constraintsB  s@     k/( =!hh)<< = = )r&   z^\$argon2[a-z]+\$c                h    \         P                  ! V4      pV P                  P                  V4      R J# N)rH   to_unicode_for_identify_ident_regexmatch)r/   hashs   &&r'   identify_Argon2Common.identifyT  s.    ))$/%%d+477r&   s  
        ^
        \$argon2(?P<type>[a-z]+)\$
        (?:
            v=(?P<version>\d+)
            \$
        )?
        m=(?P<memory_cost>\d+)
        ,
        t=(?P<time_cost>\d+)
        ,
        p=(?P<parallelism>\d+)
        (?:
            ,keyid=(?P<keyid>[^,$]+)
        )?
        (?:
            ,data=(?P<data>[^,$]+)
        )?
        (?:
            \$
            (?P<salt>[^$]+)
            (?:
                \$
                (?P<digest>.+)
            )?
        )?
        $
    c                   \        V\        4      '       d   VP                  R 4      p\        V\        4      '       g   \        P
                  ! VR4      hV P                  P                  V4      pV'       g   \        P                  ! V 4      hVP                  RRRRRRRR	R
4	      w	  r4rVrxrpV'       d   \        R4      hT ! VP                  R4      V'       d   \        V4      M^\        V4      \        V4      \        V4      V
'       d   \        V
4      MRV	'       d   \        V	4      MRV'       d   \        V4      R7      # RR7      # )utf-8r_   r3   versionr!   r    r"   keyiddatasaltdigestz&argon2 'keyid' parameter not supportedasciiN)r3   rd   r!   r:   r"   rg   rf   checksum)rG   r   encodebytesr   ExpectedStringError_hash_regexr^   MalformedHashErrorgroupNotImplementedErrordecoderJ   r   )r/   r_   mr3   rd   r!   r    r"   re   rf   rg   rh   s   &&          r'   from_string_Argon2Common.from_string  s    dG$$;;w'D$&&))$77OO!!$'((--GGFI}k=VVX7 	V{{4v %&NOOW%$+CLK(y>K(&*T"&*T",2[(	
 		
 9=	
 		
r&   c                   V P                   pV^8X  d   RpM	RV,          pV P                  pV'       d'   R\        \        V P                  4      4      ,           pMRpR\	        V P
                  4      VV P                  V P                  V P                  V\        \        V P                  4      4      \        \        V P                  4      4      3,          # )    zv=%d$z,data=z"$argon2%s$%sm=%d,t=%d,p=%d%s$%s$%s)rd   rf   r   r
   r   r3   r!   r:   r"   rg   rj   )r6   rd   vstrrf   kdstrs   &    r'   	to_string_Argon2Common.to_string  s    ,,d?DW$Dyy}[-CDDEE 4$))$KK+dii01+dmm45	7
 	
 		
r&   c                >  < V'       d   \        R 4       Ve   Q h\        pVP                  R4      pVe   \        V4      V n        \
        \        V `  ! R	/ VB  Vf7   \        P                  ! W P                  V P                  RR7      '       g   Q hMV P                  V4      V n
        Vf7   \        P                  ! W P                  V P                  RR7      '       g   Q hMV P                  V4      V n        Vf7   \        P                  ! W P                  V P                  RR7      '       g   Q hMV P                  V4      V n        Vf   V P                   e   Q hR# \#        V\$        4      '       g"   \        P&                  P)                  VRR4      hWPn        R# )
zoargon2 `type_d=True` keyword is deprecated, and will be removed in passlib 2.0; please use ``type="d"`` insteadNrj   r3   )r@   rd   r!   rl   rf   r   )r   r4   rF   lenrL   rC   r)   __init__rH   validate_default_valuer3   rE   rd   _norm_versionr!   rM   rf   rG   rl   r   ExpectedTypeError)	r6   r3   r7   rd   r!   rf   rQ   rj   rS   s	   &&&&&&, r'   r   _Argon2Common.__init__  sq     3 4<<D 88J'!$XD 	mT+3d3 <,,T99dooU[\\\\-DI ?,,T<<ASAS3<> > > >  --g6DL ,,T3C3CTE[E[3@B B B B  $55kBD <99$$$dE**ff..tWfEEIr&   c                J   \        V\        4      '       gV   \        '       d)   \        V\        4      '       d   VP	                  R 4      pM!\
        P                  P                  VRR4      hV\        9   d   V# VP                  4       pV\        9   d   V# \        RV: 24      h)ri   strr3   zunknown argon2 hash type: )rG   r   r   rl   rr   rH   r   r   ALL_TYPES_SETlowerrO   )r/   valuetemps   && r'   rE   _Argon2Common._norm_type  s     %))sz%//W-ff..ueVDD M!L {{}= K 5BCCr&   c                \   \        V\        P                  4      '       g"   \        P                  P	                  VR R4      hV^8  d   V^8w  d   \        RV3,          4      hV P                  4       pWP                  8  d*   \        RV P                  WV P                  3,          4      hV# )integerrd   zinvalid argon2 hash version: %dzk%s: hash version 0x%X not supported by %r backend (max version is 0x%X); try updating or switching backends)	rG   rH   	int_typesr   r   rO   r,   max_versionrW   )r/   rd   backends   && r'   r   _Argon2Common._norm_version	  s    '2<<00&&**7IyII T>go>'KLL //#__$ Y!hh#//JK L L r&   c                J    \         P                  ! WV P                  R VR7      # )r!   )r>   r@   r<   )rH   rK   rX   )r/   r!   r<   s   &&&r'   rM   _Argon2Common._norm_memory_cost  s$    sS5H5H%2GE 	Er&   c                     V P                   V,          #   \         d     Mi ; iRT: RT P                  4       : R2p\        T4      h)z.
helper to resolve backend constant from type
zunsupported argon2 hash (type z not supported by z	 backend))r.   KeyErrorr,   rO   )r/   r   msgs   && r'   _get_backend_type_Argon2Common._get_backend_type%  sL    
	((// 		 coo')os    ##c                n  < \        V 4      pV P                   VP                   8w  d   R # VP                  pVe   W2P                  8  d   VP                  pV P                  V8  d   R # V P                  VP                  8w  d   R # V P
                  VP
                  8w  d   R # \        \        V `"  ! R/ VB # )Tr   )	r3   min_desired_versionr   rd   r!   rL   rC   r)   _calc_needs_update)r6   rQ   r/   minverrS   s   &,  r'   r    _Argon2Common._calc_needs_update7  s    4j99 ((>Voo5__F<<& s.!2!22]D<DtDDr&   z> -- recommend you install one (e.g. 'pip install argon2_cffi')c                x   V P                   p\        V\        4      '       d   V^8  g   Q hV^8  d,   \        RV,          \        P
                  P                  4       \         F  pW@P                  9   g   K  W@n	         R# 	  \        RV,          \        P
                  P                  4       \        V n	        R# )z
helper called by from backend mixin classes' _load_backend_mixin() --
invoked after backend imports have been loaded, and performs
feature detection & testing common to all backends.
z6%r doesn't support argon2 v1.3, and should be upgradedz)%r lacks support for all known hash typesT)r   rG   rJ   r   rH   r   PasslibSecurityWarning	ALL_TYPESr.   r3   PasslibRuntimeWarningTYPE_ID)	mixin_clsrW   dryrunr   r3   s   &&&  r'   _finalize_backend_mixin%_Argon2Common._finalize_backend_mixinM  s      +++s++t0CCCIDP..0 D222!%  
 <tCRVVEaEab$INr&   c                l   V P                  4       pVf   Ve   V P                  V4      pVeG   VP                  VP                  VP                  4       VR8X  d   VP
                  e   \        R4      h\        V4      pVR9  d   V: RV: RV: 2pM\        V4      p\        P                  ! WR7      h)ze
internal helper invoked when backend has hash/verification error;
used to adapt to passlib message.
argon2_cffiz8argon2_cffi backend doesn't support the 'data' parameterz reported: z: hash=)reason)zDecoding failed)r,   rt   rN   r!   r"   rf   rq   r   reprr   ro   )r/   errr_   r6   r   textr   s   &&&&   r'   _adapt_backend_error"_Argon2Common._adapt_backend_errorg  s     //# <D,??4(D &&t'7'79I9IJ -'DII,A)*dee 3x   4;D$GF$ZF$$S88r&   )rL   rf   r!   r3   rd   )
rg   r;   r#   r:   r    r!   r"   r=   r$   r3   )r3   )r#   r    r$   r=   i rA   )NNNNNNNN)NFNNN)F)NN)Ar   r   r   r   r   rW   setting_kwds_default_settingsr$   rL   rH   GenericHandler_always_parse_settings_unparsed_settingsr#   default_salt_sizemin_salt_sizer   max_salt_sizer    default_rounds
min_rounds
max_roundsrounds_costmax_parallelism_default_versionr   r   rX   rP   pure_use_threadsr.   r   r0   r   r3   r"   rd   r!   propertyr7   rf   classmethodrD   rN   recompiler]   r`   Xrn   rt   r{   r   rE   r   rM   r   r   _no_backend_suggestionr   r   r%   __classdictcell____classcell__rS   __classdict__s   @@r'   r)   r)   s   s0      D
L0 &..M  ..EE&' **==MN *22MM '00NJJK
 $O #K  O K 
 , , D $//K G $//K# # D 9 9v = = ::23L8 82 ** 6 
7K: 
 
4
8,d D D(    E E  "E( ^ 2 9 9 9r&   r)   c                      a a ] tR tRt oRt]R 4       t]R 4       t]P                  ! RRR7      ]R 4       4       t
V 3R	 ltR
tVtV ;t# )
_NoBackendi  zt
mixin used before any backend has been loaded.
contains stubs that force loading of one of the available backends.
c                D    V P                  4        V P                  V4      # r[   )_stub_requires_backendr_   )r/   secrets   &&r'   r_   _NoBackend.hash  s    ""$xxr&   c                D    V P                  4        V P                  W4      # r[   )r   verify)r/   r   r_   s   &&&r'   r   _NoBackend.verify  s    ""$zz&''r&   z1.7z2.0)
deprecatedremovedc                D    V P                  4        V P                  W4      # r[   )r   genhash)r/   r   configs   &&&r'   r   _NoBackend.genhash  s     	""${{6**r&   c                J   < V P                  4        \        \        V `  V4      # r[   )r   rC   r   _calc_checksum)r6   r   rS   s   &&r'   r   _NoBackend._calc_checksum  s%     	##% VT1&99r&   r   )r   r   r   r   r   r   r_   r   rH   deprecated_methodr   r   r%   r   r   r   s   @@r'   r   r     se          ( ( UE:+  ;+: :r&   r   c                      a  ] tR tRt o Rt]R 4       t]R 4       t]! R ]	 4       4      t
]R 4       t]R 4       tR tR	tV tR
# )_CffiBackendi  z
argon2_cffi backend
c                   V \         J g   Q h\        f)   \        '       d   \        P                  ! \        4      hR# \        P
                  P                  p\        P                  R\        P                  V4       \        P                  p/ p\         F  p \        WFP                  4       4      WV&   K!  	  WPn        V;V n        V n        V P)                  W4      #   \         d$    T\        \         39  g   Q RT,          4       h Ku  i ; i)NFzOdetected 'argon2_cffi' backend, version %r, with support for 0x%x argon2 hashesunexpected missing type: %r)r   _argon2_cffi_argon2_cffi_errorr   PasslibSecurityErrorr   ARGON2_VERSIONlogdebug__version__r   r   getattrupperAttributeErrorTYPE_Ir4   r.   rd   r   r   )r   rW   r   r   TypeEnumtype_mapr3   s   &&&    r'   _load_backend_mixin _CffiBackend._load_backend_mixin  s     L((( !!../ABB",,;;		c**K	9  $$DZ!(::<!@  '/# 5@?	I100>> " ZFF#33Y5RUY5YY3Zs   C*D
	D
c                   \         P                  ! V4       \        VR 4      p \        \        P
                  P                  V P                  V P                  4      V P                  V P                  V P                  \        V P                  4       4      V P                  VR7      4      #   \        P                  P                   d   pT P!                  T4      hRp?ii ; i)rc   )r3   r!   r    r"   rg   r$   r   N)rH   validate_secretr   r   r   r   hash_secretr   r3   r!   r   r"   _generate_saltrL   
exceptionsHashingErrorr   )r/   r   r   s   && r'   r_   _CffiBackend.hash  s     	6"&'*	0 !7!7!C!C**3884OO,,OOc0023** "D "   &&33 	0**3//	0s   BB+ +C 
CC c              #  \   "   T F"  p\        R VP                  R4      4      V3x  K$  	  R# 5i)s
   $argon2%s$ri   N)r	   rk   ).0r3   s   & r'   	<genexpr>_CffiBackend.<genexpr>  s,      2'0t )G8LMtT'0s   *,c           	        \         P                  ! V4       \        VR 4      p\        VR4      pV P                  P	                  VR^VP                  R^4      ,            \        4      pV P                  V4      p \        P                  P                  W!V4      pVRJ g   Q hR#   \        P                  P                   d     R# \        P                  P                   d   pT P                  YbR7      hRp?ii ; i)rc   ri   N   $TFr_   )rH   r   r   _byte_ident_maprF   findr   r   r   r   verify_secretr   VerifyMismatchErrorVerificationErrorr   )r/   r   r_   r3   	type_coderesultr   s   &&&    r'   r   _CffiBackend.verify  s     	6"&'*g& ""&&t,AQtyyq/A-A'BFK))$/		;!++99$	RFT>!>&&:: 	&&88 	;**3*::	;s$   ;(B% %C<C<$C<%C77C<c                B   \         P                  ! V4       \        VR 4      pV P                  V4      p \	        \
        P                  P                  V P                  VP                  4      VP                  VP                  VP                  \        VP                  4      VP                  VVP                  R7      4      pTP                  ^8X  d   TP'                  RR4      pT#   \
        P                   P"                   d   pT P%                  YRR7      hRp?ii ; i)rc   )r3   r!   r    r"   rg   r$   r   rd   r   Nz$v=16$$)rH   r   r   rt   r   r   r   r   r   r3   r!   r:   r"   rg   rL   rd   r   r   r   replace)r/   r   r   r6   r  r   s   &&&   r'   r   _CffiBackend.genhash  s     	6"&'*v&	="<#9#9#E#E**4995 ,,++ ,,dii(++ $F 	$ 	F <<4^^Hc2F &&33 	=**3*<<	=s   BC( (DDDc                    \        R 4      h)z-shouldn't be called under argon2_cffi backend)AssertionError)r6   r   s   &&r'   r   _CffiBackend._calc_checksum*  s    LMMr&   r   N)r   r   r   r   r   r   r   r_   dictr   r   r   r   r   r%   r   r   s   @r'   r   r     s      ? ?> 0 0&  2'02 2O ; ;,  6N Nr&   r   c                   :   a  ] tR tRt o Rt]R 4       tR tRtV t	R# )_PureBackendi4  z
argon2pure backend
c                .   V \         J g   Q h ^ RIs ^ RIHp \
        P                  RT4       T'       g   \        R\        P                  4       / p\         F+  p \        \        RTP                  4       ,           4      YE&   K-  	  Y@n        T;T n        T n        T P)                  Y4      #   \         d     R# i ; i  \         d    \
        P                  R4        R# i ; i  \         d$    T\        \         39  g   Q RT,          4       h K  i ; i)	    NF)ARGON2_DEFAULT_VERSIONz\detected 'argon2pure' backend, but package is too old (passlib requires argon2pure >= 1.2.3)zBdetected 'argon2pure' backend, with support for 0x%x argon2 hasheszUsing argon2pure backend, which is 100x+ slower than is required for adequate security. Installing argon2_cffi (via 'pip install argon2_cffi') is strongly recommendedARGON2r   )r  
argon2pure_argon2pureImportErrorr  r   warningr   r   r   r   r   r   r   r   r   r4   r.   rd   r   r   )r   rW   r   r   r   r3   s   &&&   r'   r    _PureBackend._load_backend_mixin<  s    L(((	,
	H 			V	  +,/,F,FH
 DZ!(h6M!N  '/#4??	I100>>=  		  	KK A B	$ " ZFF#33Y5RUY5YY3Zs4   B- B? 'C&-B<;B<? C#"C#&*DDc                R   \         P                  ! V4       \        VR 4      p\        VV P                  V P
                  V P                  V P                  V P                  V P                  V P                  4      V P                  R7      pV P                  ^ 8  d   V P                  VR&   V P                  '       d   RVR&   V P                  '       d   V P                  VR&    \        P                   ! R/ VB #   \        P"                   d   pT P%                  Y0R7      hRp?ii ; i)	rc   )passwordrg   r    r!   r"   
tag_lengthr   rd   threadsTuse_threadsassociated_datar5   Nr   )rH   r   r   r
  rg   r:   r!   r"   rL   r   r3   rd   rP   r   rf   r  r   Argon2Errorr   )r6   r   rQ   r   s   &&  r'   r   _PureBackend._calc_checksumn  s    
6"&'*kk(((()),,TYY7LL	
 a"..DO   "&D999&*iiD"#	<%%---&& 	<++C+;;	<s   $C: :D&D!!D&r   N)
r   r   r   r   r   r   r   r   r%   r   r  s   @r'   r  r  4  s)      &? &?b< <r&   r  c                   2    ] tR tRtRtRtRtR]R]R]	/t
RtR# )	r   i  a  
This class implements the Argon2 password hash [#argon2-home]_, and follows the :ref:`password-hash-api`.

Argon2 supports a variable-length salt, and variable time & memory cost,
and a number of other configurable parameters.

The :meth:`~passlib.ifc.PasswordHash.replace` method accepts the following optional keywords:

:type type: str
:param type:
    Specify the type of argon2 hash to generate.
    Can be one of "ID", "I", "D".

    This defaults to "ID" if supported by the backend, otherwise "I".

:type salt: str
:param salt:
    Optional salt string.
    If specified, the length must be between 0-1024 bytes.
    If not specified, one will be auto-generated (this is recommended).

:type salt_size: int
:param salt_size:
    Optional number of bytes to use when autogenerating new salts.

:type rounds: int
:param rounds:
    Optional number of rounds to use.
    This corresponds linearly to the amount of time hashing will take.

:type time_cost: int
:param time_cost:
    An alias for **rounds**, for compatibility with underlying argon2 library.

:param int memory_cost:
    Defines the memory usage in kibibytes.
    This corresponds linearly to the amount of memory hashing will take.

:param int parallelism:
    Defines the parallelization factor.
    *NOTE: this will affect the resulting hash value.*

:param int digest_size:
    Length of the digest in bytes.

:param int max_threads:
    Maximum number of threads that will be used.
    -1 means unlimited; otherwise hashing will use ``min(parallelism, max_threads)`` threads.

    .. note::

        This option is currently only honored by the argon2pure backend.

:type relaxed: bool
:param relaxed:
    By default, providing an invalid value for one of the other
    keywords will result in a :exc:`ValueError`. If ``relaxed=True``,
    and the error can be corrected, a :exc:`~passlib.exc.PasslibHashWarning`
    will be issued instead. Correctable errors include ``rounds``
    that are too small or too large, and ``salt`` strings that are too long.

.. versionchanged:: 1.7.2

    Added the "type" keyword, and support for type "D" and "ID" hashes.
    (Prior versions could verify type "D" hashes, but not generate them).

.. todo::

    * Support configurable threading limits.
r   r  TNr   )r   r  )r   r   r   r   r   backends_backend_mixin_targetr   r   r  _backend_mixin_mapr%   r   r&   r'   r   r     s1    E` -H ! 	j|lr&   )>r   
__future__r   r   logging	getLoggerr   r   r   typeswarningsr   r   r  passlibr   passlib.crypto.digestr   passlib.utilsr   r   r	   passlib.utils.binaryr
   r   passlib.utils.compatr   r   r   r   r   passlib.utils.handlersutilshandlersrH   __all__r   r4   r   r   setr   r   r   hasattrr  r   r   r   r   r   r   SubclassBackendMixinParallelismMixin	HasRounds
HasRawSaltHasRawChecksumr   r)   r   r   r  r   r&   r'   <module>r8     s  " 7 ! 	    , ? ? 9 N N # #   
3	
3
D' ff%	I  ! <((4 	 \;//_ <)**$335#--<<   )*
R9B++R-@-@LL"--1B1B%%R9v!: !:TsN= sNxT<= T<t[Z [Q  Ls   F 	FF