
    @hY                    p   S r SSKJr  SSKrSSKrSSKrSSKJrJrJ	r	J
r
JrJrJrJr  SSKJr  SSKJr  SSKJr  SSKJrJrJrJr  SS	KJrJr  SS
KJr  \(       a  SSKJ r   Sr!\"" \!5      r#Sr$\"" \$5      r%Sr&\'" / SQ5      r(S&S jr)S'S jr*      S(S jr+\&4S)S jjr,1 Skr-S*S jr.S+S jr/S+S jr0S+S jr1S,S-S jjr2 S.         S/S jjr3\&4S0S jjr4\Rj                  " S\Rl                  " S5      -   S -   5      r7\'" / S!Q5      r8S1S" jr9      S2S# jr:\&SSSS4             S3S$ jjr;S4S% jr<g)5zTools to parse and validate a MongoDB URI.

.. seealso:: This module is compatible with both the synchronous and asynchronous PyMongo APIs.
    )annotationsN)TYPE_CHECKINGAnyMappingMutableMappingOptionalSizedUnioncast)unquote_plus)_have_dnspython)_parse_ssl_options)INTERNAL_URI_OPTION_NAME_MAPURI_OPTIONS_DEPRECATION_MAP_CaseInsensitiveDictionaryget_validated_options)ConfigurationError
InvalidURI)_Address)
SSLContextz
mongodb://zmongodb+srv://ii  ).appnameauthMechanismauthMechanismProperties
authSourcecompressorsconnectTimeoutMSdirectConnectionheartbeatFrequencyMSjournalloadBalancedlocalThresholdMSmaxIdleTimeMSmaxPoolSizemaxConnectingmaxStalenessSecondsminPoolSize	proxyHost	proxyPortproxyUsernameproxyPasswordreadConcernLevelreadPreferencereadPreferenceTags
replicaSet
retryReadsretryWritesserverMonitoringModeserverSelectionTimeoutMSserverSelectionTryOncesocketTimeoutMSsrvMaxHostssrvServiceNamessltlstlsAllowInvalidCertificatestlsAllowInvalidHostnames	tlsCAFiletlsCertificateKeyFiletlsCertificateKeyFilePassword$tlsDisableCertificateRevocationChecktlsDisableOCSPEndpointChecktlsInsecurewwaitQueueTimeoutMS
wTimeoutMSzlibCompressionLevelc                ~    [        [        U 5      5       H%  nX   S:X  d  M  XUS-    n[        U5      U:X  d  M%    g   g)zCheck for unescaped percent signs.

:param s: A string. `s` can have things like '%25', '%2525',
       and '%E2%85%A8' but cannot have unquoted percent like '%foo'.
%   TF)rangelenr   )sisubs      ^C:\Suresh\moveshuttle\MDcreated\moveengine\venv\Lib\site-packages\pymongo/uri_parser_shared.py_unquoted_percentrN   m   sC     3q6]43;A,C C C'      c                    SU ;   d%  U R                  S5      S:  d  [        U 5      (       a  [        S5      eU R                  S5      u  pnU(       d  [        S5      e[	        U5      [	        U5      4$ )aB  Validates the format of user information in a MongoDB URI.
Reserved characters that are gen-delimiters (":", "/", "?", "#", "[",
"]", "@") as per RFC 3986 must be escaped.

Returns a 2-tuple containing the unescaped username followed
by the unescaped password.

:param userinfo: A string of the form <username>:<password>
@:   zXUsername and password must be escaped according to RFC 3986, use urllib.parse.quote_plusz&The empty string is not valid username)countrN   r   	partitionr   )userinfouser_passwds       rM   parse_userinforZ   }   sr     h(..-15Fx5P5P4
 	

 ((-ODVABB|F333rO   c                    U R                  S5      S:X  a  [        S5      eU R                  S5      nUS:X  a  U SS U4$ U SU XS-   S 4$ )a  Validates an IPv6 literal host:port string.

Returns a 2-tuple of IPv6 literal followed by port where
port is default_port if it wasn't specified in entity.

:param entity: A string that represents an IPv6 literal enclosed
                in braces (e.g. '[::1]' or '[::1]:27017').
:param default_port: The port number to use when one wasn't
                      specified in entity.
]zNan IPv6 address literal must be enclosed in '[' and ']' according to RFC 2732.z]:rS      N)find
ValueError)entitydefault_portrK   s      rM   parse_ipv6_literal_hostrc      sf     {{32\
 	
 	DABwa|\))!A;1uw''rO   c                z   U nUnU S   S:X  a  [        X5      u  p#ObU R                  S5      (       a  X4$ U R                  S5      S:w  a4  U R                  S5      S:  a  [	        S5      eUR                  SS5      u  p#[        U[        5      (       a  UR                  5       (       dO  [        S U 5       5      (       a-  U H'  nUR                  5       (       d  M  [	        S	U< 35      e   [	        S
5      e[        U5      S:  d  [        U5      S::  a  [	        S5      e[        U5      nUR                  5       U4$ )aU  Validates a host string

Returns a 2-tuple of host followed by port where port is default_port
if it wasn't specified in the string.

:param entity: A host or host:port string where host could be a
                hostname or IP address.
:param default_port: The port number to use when one wasn't
                      specified in entity.
r   [.sockrR   r]   rS   zReserved characters such as ':' must be escaped according RFC 2396. An IPv6 address literal must be enclosed in '[' and ']' according to RFC 2732.c              3  n   #    U  H+  oR                  5       =(       d    UR                  5       v   M-     g 7fN)isspaceisdigit).0cs     rM   	<genexpr>parse_host.<locals>.<genexpr>   s"     <t!99;-!))+-ts   35z$Port contains whitespace character: zPort contains non-digit characters. Hint: username and password must be escaped according to RFC 3986, use urllib.parse.quote_plusi  z+Port must be an integer between 0 and 65535)rc   endswithr_   rT   r`   split
isinstancestrrj   allri   intlower)ra   rb   hostportrl   s        rM   
parse_hostrx      s.    D&2DayC,VB
d		!	!##	S	R	<<q 1  ZZQ'
$||~~<t<<<Ayy{{(+OPQu)UVV  8  t9uD	QJKK4y ::<rO   >   tlsallowinvalidhostnamestlsallowinvalidcertificatestlsdisableocspendpointcheckc                f   [        5       nU R                  U5       H  nUR                  S5      u  pEUR                  5       S:X  a#  UR                  U/ 5      R	                  U5        MM  XB;   a  [
        R                  " SU S3SS9  UR                  5       S:X  a  UnO[        U5      nXbU'   M     U$ )zHelper method for split_options which creates the options dict.
Also handles the creation of a list for the URI tag_sets/
readpreferencetags portion, and the use of a unicode options string.
=readpreferencetagszDuplicate URI option 'z'.r^   
stacklevelauthmechanismproperties)r   rp   ru   
setdefaultappendwarningswarnr   )optsdelimoptionsurioptkeyvaluevals          rM   _parse_optionsr      s    
 )*G**U#\\#&
99;..sB'..u5~ 6se2>1Myy{77"5)CL $ NrO   c                   U R                  S5      nUbA  [         H7  nX ;   d  M
  Sn[        X0R                  S5      U R                  U5      4-  5      e   U R                  S5      nUb1  SU ;   a!  Sn[        USU R                  S5      4-  5      eUSL a  SU S'   U R                  S5      nUb-  S H'  nU R                  U5      SL d  M  Sn[        X24-  5      e   S	U ;   aj  S
U ;   ad  SS jnU" U R                  S	5      5      U" U R                  S
5      5      :w  a/  Sn[        X0R                  S	5      U R                  S
5      4-  5      eU $ )zRaise appropriate errors when conflicting TLS options are present in
the options dictionary.

:param options: Instance of _CaseInsensitiveDictionary containing
      MongoDB URI options.
tlsinsecurez9URI options %s and %s cannot be specified simultaneously.rz   r{   T
tlscrlfile)r   rz   r{   zDURI option %s=True cannot be specified when CRL checking is enabled.r7   r8   c                J    U S;   a  U S:H  $ [        U [        5      (       a  U $ U $ )N)truefalser   )rq   bool)r   s    rM   truth_value-_handle_security_options.<locals>.truth_value$  s,    ''f}$#t$$
JrO   z=Can not specify conflicting values for URI options %s and %s.)r   r   returnr   )get_IMPLICIT_TLSINSECURE_OPTSr   	cased_key)r   r   opterr_msgtlsallowinvalidcertsr   r   s          rM   _handle_security_optionsr      sv    ++m,K-C~U 00?ARARSVAWXX  . #;;'DE'(G3QG0'2C2CDa2bcd   4'59G12 \*J`C{{34'` 6!122 a
 EW,	 w{{5)*k'++e:L.MMUGW(9(9%(@'BSBSTYBZ'[[\\NrO   c                   [        U 5       H  nU[        ;   d  M  [        U   u  p#US:X  a  UnX@;   aQ  Sn[        R                  " XPR	                  U5      U R	                  U5      4-  [
        SS9  U R                  U5        Mx  Sn[        R                  " XPR	                  U5      U4-  [
        SS9  M  US:X  d  M  Sn[        R                  " XPR	                  U5      U4-  [
        SS9  M     U $ )a'  Issue appropriate warnings when deprecated options are present in the
options dictionary. Removes deprecated option key, value pairs if the
options dictionary is found to also have the renamed option.

:param options: Instance of _CaseInsensitiveDictionary containing
      MongoDB URI options.
renamedz0Deprecated option '%s' ignored in favor of '%s'.r^   r   z,Option '%s' is deprecated, use '%s' instead.removedzOption '%s' is deprecated. %s.)listr   r   r   r   DeprecationWarningpop)r   optnamemodemessage
newoptnamewarn_msgs         rM   _handle_option_deprecationsr   2  s     =117@MDy $
(QHMM $5$5g$>@Q@QR\@]#^^*#$
 KK(I 1 1' :JGG& 
 "; 1 1' :GDD& - !8 NrO   c                    U R                  S5      nUb  [         H  nXU'   M	     [        U 5       H2  n[        R                   " US5      nUc  M  U R	                  U5      X'   M4     U $ )zNormalizes option names in the options dictionary by converting them to
their internally-used names.

:param options: Instance of _CaseInsensitiveDictionary containing
      MongoDB URI options.
r   N)r   r   r   r   r   )r   r   r   r   intnames        rM   _normalize_optionsr   Y  si     ++m,K-C&CL . =.227DA&{{73G !
 NrO   Fc                    [        X5      $ )a  Validates and normalizes options passed in a MongoDB URI.

Returns a new dictionary of validated and normalized options. If warn is
False then errors will be thrown for invalid options, otherwise they will
be ignored and a warning will be issued.

:param opts: A dict of MongoDB URI options.
:param warn: If ``True`` then warnings will be logged and
      invalid options will be ignored. Otherwise invalid options will
      cause errors.
)r   )r   r   s     rM   validate_optionsr   o  s     !,,rO   Tc                   U R                  S5      nU R                  S5      n US:  a  US:  a  [        S5      eUS:  a  [        U S5      nO;US:  a  [        U S5      nO(U R                  S5      S:w  a  [        U S5      nO[        e[	        U5      n[        U5      nU(       a  [        U5      nU(       a9  [        [        [        Xb5      5      nUR                  S	5      S
:X  a  [        S5      eU$ ! [         a    [        S5      Sef = f)a  Takes the options portion of a MongoDB URI, validates each option
and returns the options in a dictionary.

:param opt: A string representing MongoDB URI options.
:param validate: If ``True`` (the default), validate and normalize all
      options.
:param warn: If ``False`` (the default), suppress all warnings raised
      during validation of options.
:param normalize: If ``True`` (the default), renames all options to their
      internally-used names.
&;r   z-Can not mix '&' and ';' for option separatorsr}   r]   Nz'MongoDB URI options are key=value pairs
authsource z1the authSource database cannot be an empty string)r_   r   r   r`   r   r   r   r   r   r   r   )r   validater   	normalizeand_idxsemi_idxr   s          rM   split_optionsr   ~  s    iinGyy~HNa<HMLMM\$T3/G]$T3/GYYs^r!$T40G 'w/G)'2G$W-13CG3RS;;|$*PQQN  NBCMNs   )C3 C3 !!C3 C3 3D
c                    / nU R                  S5       HI  nU(       d  [        S5      eUnUR                  S5      (       a  SnUR                  [	        X45      5        MK     U$ )a  Takes a string of the form host1[:port],host2[:port]... and
splits it into (host, port) tuples. If [:port] isn't present the
default_port is used.

Returns a set of 2-tuples containing the host name (or IP) followed by
port number.

:param hosts: A string of the form host1[:port],host2[:port],...
:param default_port: The port number to use when one wasn't specified
      for a host.
,z(Empty host (or extra comma in host list)rf   N)rp   r   ro   r   rx   )hostsrb   nodesra   rw   s        rM   split_hostsr     s\     E++c"$%OPP??7##DZ-. # LrO   re   z/ "$r\   )r   r   
replicasetr.   loadbalancedr    c                J   [        U 5      S:  a!  UR                  S5      (       a  [        S5      eUR                  S5      (       a]  [        U 5      S:  a  [        S5      eUR                  S5      (       a  [        S5      eUR                  S5      (       a  [        S5      eg g )	NrS   directconnectionz8Cannot specify multiple hosts with directConnection=truer   z4Cannot specify multiple hosts with loadBalanced=truez;Cannot specify directConnection=true with loadBalanced=truer   z0Cannot specify replicaSet with loadBalanced=true)rI   r   r   )r   r   s     rM   _check_optionsr     s    
5zA~'++&899 ![\\{{>""u:>$%[\\;;)**$%bcc;;|$$$%WXX % #rO   c                   U (       d  0 $ [        U [        5      (       d  [        S5      e0 nU R                  5        H  u  p4[        U[        5      (       d  [        SU S35      eUR	                  SS5        [        U5      n[        U5      n[        U5      n[        [
        [        U5      5      n[        XQ5      u  pgUc  [        S5      eU(       a  [        S5      eS H  nX;   a  [        S	U 35      eXbU'   M     M     U$ )
z!Parse KMS TLS connection options.zkms_tls_options must be a dictzkms_tls_options["z"] must be a dictr8   Tz!TLS is required for KMS providerszInsecure TLS options prohibited)r@   r9   r:   r>   z!Insecure TLS options prohibited: )rq   dict	TypeErroritemsr   r   r   r   r   r   r   r   )	kms_tls_optionsis_synccontextsproviderr   r   ssl_contextallow_invalid_hostnamesns	            rM   _parse_kms_tls_optionsr     s   
 	ot,,899H,224'4((/z9JKLL5$')'2'-!$'.0@0FG/A$/P,$%HII"$%FGG
A y(+LQC)PQQ!,X
 5. OrO   c                P   U R                  [        5      (       a  SnU [        S  nOvU R                  [        5      (       aB  [	        5       (       d'  [
        R                  =(       d    Sn[        SU-  5      eSnU [        S  nO[        S[         S[         S35      eU(       d  [        S5      eS n	S n
S nS n[        5       nUR                  S	5      u  pnS
U;   a  UR                  S
5      u  npOUnU(       aN  [        U5      nSU;   a  UR                  SS5      u  p[        R                  U5      (       a  [        SU-  5      eOS nU(       a  UR!                  [#        UX#U5      5        SU;   a#  UR%                  S5      u  nnn['        U5      u  pOUnS
U;   a  [        SU-  5      e[        U5      nS nU=(       d    UR)                  S5      nU(       ar  UR)                  S5      (       a  [        S[         S35      e[+        US S9n[-        U5      S:w  a  [        [         S35      eUS   u  nnUb  [        [         S35      eOGU(       d  UR)                  S5      b  [        S5      eU(       d  U(       a  [        S5      e[+        UUS9n[/        UU5        UU	U
UUUUS.$ )NFpythonzThe "dnspython" module must be installed to use mongodb+srv:// URIs. To fix this error install pymongo again:
 %s -m pip install pymongo>=4.3Tz)Invalid URI scheme: URI must begin with 'z' or ''z(Must provide at least one hostname or IP?/.rS   zBad database name "%s"rQ   z;Any '/' in a unix domain socket must be percent-encoded: %sr5   r   z*Cannot specify directConnection=true with z URIs)rb   z. URIs must include one, and only one, hostnamer   z$ URIs must not include a port numberr6   zDThe srvServiceName option is only allowed with 'mongodb+srv://' URIszAThe srvMaxHosts option is only allowed with 'mongodb+srv://' URIs)nodelistusernamepassworddatabase
collectionr   fqdn)
startswithSCHEME
SCHEME_LEN
SRV_SCHEMEr   sys
executabler   SRV_SCHEME_LENr   r   rU   r   rp   _BAD_DB_CHARSsearchupdater   
rpartitionrZ   r   r   rI   r   )urirb   r   r   r   srv_max_hostsis_srvscheme_freepython_pathrW   rY   dbaser   r   host_plus_db_partrX   r   	host_partrV   r   r   r   rw   s                          rM   _validate_urir     s    ~~f*+&	
	#	#  ..4HK$1 5@A  ./*DVHFS]R^^_`aaCDDDFEJ(*G!,!6!6s!;$
/99#>	1e%	U#%< %C 3E&&5=>> ' }T89EF
i&11#6!U%h/f
e|VYbbccED!?W[[%?M;;)**$'QR\Q]]b%cddE5u:?
|+YZ[[1X
d
|+OPQQ $45A R
 	
  O
 	
 E=5'"   rO   c                    0 n[          H0  nUR                  5       U ;   d  M  X   X'   U R                  U5        M2     U R                  5        H	  u  p4XAU'   M     U$ rh   )URI_OPTIONSru   r   r   )r   case_sensitiveoptionkvs        rM   _make_options_case_sensitiver   ^  sW    N<<>W$%,_N"KK  q  rO   )rJ   rr   r   r   )rV   rr   r   ztuple[str, str])ra   rr   rb   Optional[int]r   z%tuple[str, Optional[Union[str, int]]])ra   rr   rb   r   r   r   )r   rr   r   zOptional[str]r   r   )r   r   r   r   )F)r   Mapping[str, Any]r   r   r   MutableMapping[str, Any])TFT)
r   rr   r   r   r   r   r   r   r   r   )r   rr   rb   r   r   zlist[_Address])r   r	   r   r   r   None)r   zOptional[Mapping[str, Any]]r   r   r   zdict[str, SSLContext])r   rr   rb   r   r   r   r   r   r   r   r   r   r   dict[str, Any])r   r   r   r   )=__doc__
__future__r   rer   r   typingr   r   r   r   r   r	   r
   r   urllib.parser   !pymongo.asynchronous.srv_resolverr   pymongo.client_optionsr   pymongo.commonr   r   r   r   pymongo.errorsr   r   pymongo.typingsr   pymongo.pyopenssl_contextr   r   rI   r   r   r   DEFAULT_PORT	frozensetr   rN   rZ   rc   rx   r   r   r   r   r   r   r   r   compileescaper   _ALLOWED_TXT_OPTSr   r   r   r    rO   rM   <module>r     s    # 	 
 	 	 	 & = 5  : $4	[

Z/1h 40((,(*(. ;G 0h ,2j$N,-  MQ*
**,0*EI**Z ;G 4 

37!33c9:\ 
Y!0!! !L #/#']	]] ] 	]
 ] !] ]@rO   