
    iSt              
         % S r SSKJr  SSKJ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  SS	K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#   " S S\5      r$\$" \%" S5      6 r&\&RN                  \&RP                  4r)S\*S'   \\\   /\\   4   r+ " S S5      r,\!RZ                  \&RP                  \!R\                  \&R^                  \!R`                  \&Rb                  \!Rd                  \&Rb                  \!Rf                  \&Rb                  0r4      SS jr5      SS jr6            SS jr7        SS jr8        S S jr9S!S jr:g)"zRepresent a deployment of MongoDB servers.

.. seealso:: This module is compatible with both the synchronous and asynchronous PyMongo APIs.
    )annotations)sample)AnyCallableListMappingMutableMapping
NamedTupleOptionalcastMinKey)ObjectId)common)ConfigurationErrorPyMongoError)PrimaryReadPreference_AggWritePref_ServerMode)ServerDescription)	Selection)SERVER_TYPE)_Addressc                  R    \ rS rSr% S\S'   S\S'   S\S'   S\S'   S\S'   S\S'   S	rg
)_TopologyType-   intSingleReplicaSetNoPrimaryReplicaSetWithPrimaryShardedUnknownLoadBalanced N)__name__
__module____qualname____firstlineno____annotations____static_attributes__r%       I/app/mltbenv/lib/python3.13/site-packages/pymongo/topology_description.pyr   r   -   s#    KLLr,   r      ztuple[int, int]SRV_POLLING_TOPOLOGIESc                     \ rS rSr              SS jrSS jrSS jrS S jrS!S jrS"S jr	S#S jr
\S$S	 j5       r\S%S
 j5       r\S&S j5       r\S'S j5       r\S(S j5       r\S'S j5       r\S)S j5       r\S*S j5       r\S)S j5       r\S)S j5       r\S'S j5       r\S$S j5       r\S$S j5       rS+S jr S,   S-S jjr   S.         S/S jjr\R:                  4S0S jjrS*S jrS%S jr Sr!g)1TopologyDescription?   c                   Xl         X0l        X l        X@l        XPl        [        U R                  R                  5       5      U l        X`l        SU l	        U R                   [        R                  :w  a  U R                  5         U R                  nU(       d  SU l        g[        S U 5       5      (       a  SU l        g[!        S U 5       5      U l        g)a  Representation of a deployment of MongoDB servers.

:param topology_type: initial type
:param server_descriptions: dict of (address, ServerDescription) for
    all seeds
:param replica_set_name: replica set name or None
:param max_set_version: greatest setVersion seen from a primary, or None
:param max_election_id: greatest electionId seen from a primary, or None
:param topology_settings: a TopologySettings
Nc              3  <   #    U  H  oR                   S L v   M     g 7fNlogical_session_timeout_minutes.0ss     r-   	<genexpr>/TopologyDescription.__init__.<locals>.<genexpr>l   s     UDTq22d:DTs   c              3  8   #    U  H  oR                   v   M     g 7fr5   r6   r8   s     r-   r;   r<   o   s      +;Ka11;K   )_topology_type_replica_set_name_server_descriptions_max_set_version_max_election_idlistvalues_candidate_servers_topology_settings_incompatible_errTOPOLOGY_TYPEr$   _init_incompatible_errreadable_servers_ls_timeout_minutesanymin)selftopology_typeserver_descriptionsreplica_set_namemax_set_versionmax_election_idtopology_settingsrK   s           r-   __init__TopologyDescription.__init__@   s    & ,!1$7! / /"&t'@'@'G'G'I"J #4 "&-"<"<<'')  00'+D$UDTUUU'+D$'* +;K+ (D$r,   c                   U R                   R                  5        GH-  nUR                  (       d  M  UR                  SL=(       a    UR                  [        R
                  :  nUR                  SL=(       a    UR                  [        R                  :  nU(       aK  SUR                  S   UR                  S   =(       d    SUR                  [        R
                  4-  U l	        M  U(       d  M  SUR                  S   UR                  S   =(       d    SUR                  [        R                  [        R                  4-  U l	          g   g)z>Internal compatibility check for non-load balanced topologies.Nz]Server at %s:%d requires wire version %d, but this version of PyMongo only supports up to %d.r      zgServer at %s:%d reports wire version %d, but this version of PyMongo requires at least %d (MongoDB %s).)rA   rE   is_server_type_knownmin_wire_versionr   MAX_SUPPORTED_WIRE_VERSIONmax_wire_versionMIN_SUPPORTED_WIRE_VERSIONaddressrH   MIN_SUPPORTED_SERVER_VERSION)rO   r:   server_too_newserver_too_olds       r-   rJ   *TopologyDescription._init_incompatible_errs   s.   **113A)) ""$. K&&)J)JJ  ""$. K&&)J)JJ  A 		!		!)**99	 &  L 		!		!)**99;; & W 4r,   c                P    U R                   (       a  [        U R                   5      eg)zRaise ConfigurationError if any server is incompatible.

A server is incompatible if its wire protocol version range does not
overlap with PyMongo's.
N)rH   r   rO   s    r-   check_compatible$TopologyDescription.check_compatible   s#     !!$T%;%;<< "r,   c                    XR                   ;   $ r5   )rA   )rO   r_   s     r-   
has_serverTopologyDescription.has_server   s    3333r,   c                R    U R                   U   R                  5       n[        X5      $ )z;A copy of this description, with one server marked Unknown.)rA   
to_unknownupdated_topology_description)rO   r_   
unknown_sds      r-   reset_server TopologyDescription.reset_server   s&    ..w7BBD
+D==r,   c                <   U R                   [        R                  :X  a  [        R                  nOU R                   nU R                   Vs0 s H  o"[        U5      _M     nn[        UUU R                  U R                  U R                  U R                  5      $ s  snf )z<A copy of this description, with all servers marked Unknown.)r?   rI   r!   r    rA   r   r1   r@   rB   rC   rG   )rO   rP   r_   sdss       r-   resetTopologyDescription.reset   s    -"E"EE)==M //M CGB[B[\B[w)'22B[\"""!!!!##
 	
 ]s   
Bc                6    U R                   R                  5       $ )zKdict of (address,
:class:`~pymongo.server_description.ServerDescription`).
)rA   copyre   s    r-   rQ   'TopologyDescription.server_descriptions   s     ((--//r,   c                    U R                   $ )zThe type of this topology.)r?   re   s    r-   rP   !TopologyDescription.topology_type   s     """r,   c                <    [         R                  U R                     $ )zEThe topology type as a human readable string.

.. versionadded:: 3.4
)rI   _fieldsr?   re   s    r-   topology_type_name&TopologyDescription.topology_type_name   s     $$T%8%899r,   c                    U R                   $ )zThe replica set name.)r@   re   s    r-   rR   $TopologyDescription.replica_set_name   s     %%%r,   c                    U R                   $ )z1Greatest setVersion seen from a primary, or None.)rB   re   s    r-   rS   #TopologyDescription.max_set_version        $$$r,   c                    U R                   $ )z1Greatest electionId seen from a primary, or None.)rC   re   s    r-   rT   #TopologyDescription.max_election_id   r   r,   c                    U R                   $ )z)Minimum logical session timeout, or None.)rL   re   s    r-   r7   3TopologyDescription.logical_session_timeout_minutes   s     '''r,   c                    U R                   R                  5        Vs/ s H  oR                  (       d  M  UPM     sn$ s  snf )z)List of Servers of types besides Unknown.)rA   rE   rZ   rO   r:   s     r-   known_servers!TopologyDescription.known_servers   s3      44;;=X=aAWAW=XXX   >>c                V    [        S U R                  R                  5        5       5      $ )z7Whether there are any Servers of types besides Unknown.c              3  J   #    U  H  oR                   (       d  M  Uv   M     g 7fr5   )rZ   r8   s     r-   r;   8TopologyDescription.has_known_servers.<locals>.<genexpr>   s     [@DZDZ11@s   #	#)rM   rA   rE   re   s    r-   has_known_servers%TopologyDescription.has_known_servers   s$     [d77>>@[[[r,   c                    U R                   R                  5        Vs/ s H  oR                  (       d  M  UPM     sn$ s  snf )zList of readable Servers.)rA   rE   is_readabler   s     r-   rK   $TopologyDescription.readable_servers   s1      44;;=O=a=OOOr   c                    U R                   $ )z0List of Servers excluding deprioritized servers.)rF   re   s    r-   candidate_servers%TopologyDescription.candidate_servers   s     &&&r,   c                b    U R                   nU(       a  [        S U R                    5       5      $ g)z3Minimum of all servers' max wire versions, or None.c              3  8   #    U  H  oR                   v   M     g 7fr5   )r]   r8   s     r-   r;   :TopologyDescription.common_wire_version.<locals>.<genexpr>  s     F3Ea))3Er>   N)r   rN   rO   serverss     r-   common_wire_version'TopologyDescription.common_wire_version  s,     $$F43E3EFFFr,   c                .    U R                   R                  $ r5   )rG   heartbeat_frequencyre   s    r-   r   'TopologyDescription.heartbeat_frequency
  s    &&:::r,   c                .    U R                   R                  $ r5   )rG   _srv_max_hostsre   s    r-   srv_max_hosts!TopologyDescription.srv_max_hosts  s    &&555r,   c                   U(       d  / $ / nUR                    HU  nUR                  c*  SUR                   SU  SUR                    3n[        U5      eUR	                  UR                  5        MW     [        U5      nU R                  R                  S-  nUR                    Vs/ s H(  n[        [        UR                  5      U-
  U::  d  M&  UPM*     sn$ s  snf )Nzround_trip_time for server z is unexpectedly None: z, servers: g     @@)
rQ   round_trip_timer_   r   appendrN   rG   local_threshold_msr   float)rO   	selectionround_trip_timesserverconfig_err_msgfastest	thresholdr:   s           r-   _apply_local_threshold*TopologyDescription._apply_local_threshold  s    I(*33F%%-#>v~~>NNefjekkv  xA  xU  xU  wV  "W(88##F$:$:;	 4 &'++>>G	 22
2UA--.8YF 2
 	
 
s   #%CCNc                   U(       d  U R                   U l        gU Vs1 s H  o"R                  iM     nnU R                    Vs/ s H  nUR                  U;  d  M  UPM     nnU=(       d    U R                   U l        gs  snf s  snf )zBFilter out deprioritized servers from a list of server candidates.N)r   rF   r_   )rO   deprioritized_serverssddeprioritized_addressesr   filtereds         r-   _filter_servers#TopologyDescription._filter_servers$  s     %&*&8&8D#<Q&R<Qbzz<Q#&R #000F>>)@@ 0  
 '/&D$2D2DD# 'Ss   A>BBc                *   [        USS5      (       a<  U R                  nU(       a)  XQR                  :  a  [        SXR                  U4-  5      e[	        U[
        5      (       a  UR                  U 5        U R                  [        R                  :X  a  / $ U R                  [        R                  [        R                  4;   a  U R                  $ U(       a<  U R                  5       R                  U5      nU(       a  UR                  (       a  U/$ / $ U R!                  U5        U R                  [        R"                  :X  a  [%        U5      [&        L a  U R(                   H7  nUR*                  [,        R.                  :X  d  M#  U/nU(       a  U" U5      nUs  $    U(       a=  U H7  nUR*                  [,        R.                  :X  d  M#  U/nU(       a  U" U5      nUs  $    / $ [0        R2                  " U 5      n	U R                  [        R4                  :w  aE  U" U	5      n	U	(       d6  U(       a/  U R!                  S5        [0        R2                  " U 5      n	U" U	5      n	Ub(  U	(       a!  U	R7                  U" U	R                  5      5      n	U R9                  U	5      $ )aD  List of servers matching the provided selector(s).

:param selector: a callable that takes a Selection as input and returns
    a Selection as output. For example, an instance of a read
    preference from :mod:`~pymongo.read_preferences`.
:param address: A server address to select.
:param custom_selector: A callable that augments server
    selection rules. Accepts a list of
    :class:`~pymongo.server_description.ServerDescription` objects and
    return a list of server descriptions that should be considered
    suitable for the desired operation.

.. versionadded:: 3.4
r[   r   zF%s requires min wire version %d, but topology's min wire version is %dN)getattrr   r[   r   
isinstancer   selection_hookrP   rI   r#   r   r$   r   rQ   getrZ   r   r!   typer   rF   server_typer   	RSPrimaryr   from_topology_descriptionr"   with_server_descriptionsr   )
rO   selectorr_   custom_selectorr   	common_wvdescriptionr   rr   r   s
             r-   apply_selector"TopologyDescription.apply_selector3  s+   * 8/3300IY)B)BB(*-57P7PR[,\] 
 h..##D)!6!66IM$8$8-:T:T#UU%%%22488AK$/K4T4TK=\Z\\23!D!DDh[bIb-->>[%:%::$C&-c2J . %/B~~)>)>>!d*"1#"6C"
 0 I77=	!6!66 +I!6$$T*%??E	$Y/	 &9!::	 = =>I **955r,   c                d    [         R                  " SU5        [        U R                  U5      5      $ )a~  Does this topology have any readable servers available matching the
given read preference?

:param read_preference: an instance of a read preference from
    :mod:`~pymongo.read_preferences`. Defaults to
    :attr:`~pymongo.read_preferences.ReadPreference.PRIMARY`.

.. note:: When connected directly to a single server this method
  always returns ``True``.

.. versionadded:: 3.4
read_preference)r   validate_read_preferencerM   r   )rO   r   s     r-   has_readable_server'TopologyDescription.has_readable_server  s+     	''(9?K4&&788r,   c                @    U R                  [        R                  5      $ )zDoes this topology have a writable server available?

.. note:: When connected directly to a single server this method
  always returns ``True``.

.. versionadded:: 3.4
)r   r   PRIMARYre   s    r-   has_writable_server'TopologyDescription.has_writable_server  s     ''(>(>??r,   c                    [        U R                  R                  5       S S9nSR                  U R                  R
                  U R                  R                  U R                  U5      $ )Nc                    U R                   $ r5   )r_   )r   s    r-   <lambda>.TopologyDescription.__repr__.<locals>.<lambda>  s    BJJr,   )keyz-<{} id: {}, topology_type: {}, servers: {!r}>)	sortedrA   rE   format	__class__r&   rG   _topology_idr|   r   s     r-   __repr__TopologyDescription.__repr__  sY    2299;AVW>EENN####00##	
 	
r,   )	rF   rH   rL   rC   rB   r@   rA   rG   r?   )rP   r   rQ   !dict[_Address, ServerDescription]rR   Optional[str]rS   Optional[int]rT   Optional[ObjectId]rU   r   returnNone)r   r   )r_   r   r   bool)r_   r   r   r1   )r   r1   )r   r   )r   r   )r   str)r   r   )r   r   )r   r   )r   list[ServerDescription])r   r   )r   zOptional[Selection]r   r   r5   )r   !Optional[list[ServerDescription]]r   r   )NNN)
r   r   r_   zOptional[_Address]r   zOptional[_ServerSelector]r   r   r   r   )r   r   r   r   )"r&   r'   r(   r)   rV   rJ   rf   ri   ro   rs   rQ   propertyrP   r|   rR   rS   rT   r7   r   r   rK   r   r   r   r   r   r   r   r   r   r   r   r   r+   r%   r,   r-   r1   r1   ?   s   11 ?1 (	1
 '1 ,1 1 
1f-^=4>

&0 # # : : & & % % % % ( ( Y Y \ \ P P ' '   ; ; 6 6
& JNE%FE	E$ '+59CGM6M6 $M6 3	M6
  AM6 
!M6^ BPAWAW 9 @
r,   r1   c                   UR                   nU R                  nU R                  nU R                  nU R                  nUR
                  nU R                  5       nXU'   U[        R                  :X  ao  UbD  XAR                  :w  a5  [        SR                  XAR                  5      5      n	UR                  U	S9X'   [        [        R                  UUUUU R                  5      $ U[        R                  :X  a  U[        R                   [        R"                  4;   aF  [%        U R                  R&                  5      S:X  a  [        R                  nO?UR)                  U5        O-U[        R                  [        R*                  4;  a	  [,        U   nU[        R.                  :X  a7  U[        R0                  [        R                  4;  a  UR)                  U5        GOxU[        R2                  :X  a  U[        R                   [        R0                  4;   a  UR)                  U5        GO-U[        R4                  :X  a  [7        XXU5      u  p4pVGOU[        R8                  [        R:                  [        R<                  4;   a  [?        XU5      u  p4OU[        R@                  :X  a  U[        R                   [        R0                  4;   a  UR)                  U5        [C        U5      nOpU[        R4                  :X  a  [7        XXU5      u  p4pVOKU[        R8                  [        R:                  [        R<                  4;   a  [E        XU5      nO[C        U5      n[        UUUUUU R                  5      $ )aV  Return an updated copy of a TopologyDescription.

:param topology_description: the current TopologyDescription
:param server_description: a new ServerDescription that resulted from
    a hello call

Called after attempting (successfully or not) to call hello on the
server at server_description.address. Does not modify topology_description.
zeclient is configured to connect to a replica set named '{}' but this node belongs to a set named '{}')errorrY   )#r_   rP   rR   rS   rT   r   rQ   rI   r   r   r   rl   r1   rG   r#   r   
StandaloneLoadBalancerlenseedspopRSGhost_SERVER_TYPE_TO_TOPOLOGY_TYPEr"   Mongosr    r   _update_rs_from_primaryRSSecondary	RSArbiterRSOther!_update_rs_no_primary_from_memberr!   _check_has_primary#_update_rs_with_primary_from_member)
topology_descriptionserver_descriptionr_   rP   set_namerS   rT   r   rr   r   s
             r-   rm   rm     s    !((G )66M#44H*::O*::O$00K 
2
2
4C &L,,,H0S0S$S&AAGAABE .88u8ECL"   33
 	
 ---;11;3K3KLL'::@@AQF - 4 4  !4!4k6I6I JJ9+FM---{11;3F3FGGGGG	-;;	;;11;3E3EFFGGGK111Ja1OKG]o [44k6K6K[M`M`aa&G1'#M 
-==	=;11;3E3EFFGGG.s3MK111Ja1OKG]o [44k6K6K[M`M`aa?OabM /s3M // r,   c           	        U R                   [        ;   d   eU R                  5       n[        UR	                  5       5      [        U5      :X  a  U $ [        UR	                  5       5       H  nX1;  d  M
  UR                  U5        M     U R                  S:w  an  [        U5      [        UR	                  5       5      -
  nU R                  [        U5      -
  nUS:  a)  [        [        U5      [        U[        U5      5      5      nO/ nU H  nX2;  d  M
  [        U5      X#'   M     [        U R                   UU R                  U R                  U R                   U R"                  5      $ )zReturn an updated copy of a TopologyDescription.

:param topology_description: the current TopologyDescription
:param seedlist: a list of new seeds new ServerDescription that resulted from
    a hello call
r   )rP   r/   rQ   setkeysrD   r   r   r   r   r   rN   r   r1   rR   rS   rT   rG   )r   seedlistrr   r_   	new_hostsn_to_adds         r-   )_updated_topology_description_srv_pollingr    s-     --1GGGG

2
2
4C 388:#h-'## 
#"GGG $ ))Q.MC
O3	'55C@a<fY/Xs9~1NOHH,W5CL  **--,,,,// r,   c                   Uc  UR                   nO8XR                   :w  a)  U R                  UR                  5        [        U 5      XU4$ UR                  b  UR                  S:  a  UR
                  UR                  4nX44nSU;  aQ  SU;  a?  XV:  a:  UR                  [        SU SU 35      5      XR                  '   [        U 5      XU4$ UR                  nUR
                  b  Ub  UR
                  U:  a  UR
                  nOUR                  UR
                  4nXC4n[        S U 5       5      n[        S U 5       5      nXx:  a:  UR                  [        SU SU 35      5      XR                  '   [        U 5      XU4$ UR                  nUR
                  nU R                  5        Hd  n	U	R                  [        R                  L d  M"  U	R                  UR                  :w  d  M>  U	R                  [        S5      5      X	R                  '     O   UR                   H  n
X;  d  M
  [        U
5      X
'   M     [!        U 5      UR                  -
   H  nU R                  U5        M     [        U 5      XU4$ )aO  Update topology description from a primary's hello response.

Pass in a dict of ServerDescriptions, current replica set name, the
ServerDescription we are processing, and the TopologyDescription's
max_set_version and max_election_id if any.

Returns (new topology type, new replica_set_name, new max_set_version,
new max_election_id).
N   z<primary marked stale due to electionId/setVersion mismatch, z is stale compared to c              3  >   #    U  H  oc
  [        5       OUv   M     g 7fr5   r   r9   is     r-   r;   *_update_rs_from_primary.<locals>.<genexpr>t       ![HZ1i&(Q">HZ   c              3  >   #    U  H  oc
  [        5       OUv   M     g 7fr5   r   r  s     r-   r;   r  u  r	  r
  z6primary marked stale due to discovery of newer primary)rR   r   r_   r   r]   set_versionelection_idrl   r   tuplerE   r   r   r   	all_hostsr   r   )rr   rR   r   rS   rT   new_election_tuplemax_election_tuplenew_election_safemax_election_safer   new_addressaddrs               r-   r   r   F  s     ->>	@@	@ 	"**+!#&(8?ZZ**26H6Y6Y\^6^%7%C%CEWEcEc$d%4$F))--2D2Y2D2O2O VWiVj  kA  BT  AU  V3../
 *#.0@Sbbb0<<O))5#'9'E'E'W0<<O/;;=O=[=[[,=!![HZ![[!![HZ![[0.@.K.KRSeRff|  ~P  }Q  R/C**+
 &c*,<^^0<<O0<<O **,+"7"77"4"<"<< #)"3"3UV#C
   *33!0=C 4
 C-777 8
 s#%5XXr,   c                   Uc   eXR                   :w  a  U R                  UR                  5        OFUR                  (       a5  UR                  UR                  :w  a  U R                  UR                  5        [	        U 5      $ )zRS with known primary. Process a response from a non-primary.

Pass in a dict of ServerDescriptions, current replica set name, and the
ServerDescription we are processing.

Returns new topology type.
)rR   r   r_   mer   )rr   rR   r   s      r-   r   r     sm     '''>>>"**+			#5#=#=ASAVAV#V"**+ c""r,   c                |   [         R                  nUc  UR                  nO-XR                  :w  a  U R                  UR                  5        X14$ UR
                   H  nX@;  d  M
  [        U5      X'   M     UR                  (       a5  UR                  UR                  :w  a  U R                  UR                  5        X14$ )zRS without known primary. Update from a non-primary's response.

Pass in a dict of ServerDescriptions, current replica set name, and the
ServerDescription we are processing.

Returns (new topology type, new replica_set_name).
)rI   r    rR   r   r_   r  r   r  )rr   rR   r   rP   r_   s        r-   r   r     s     "55M->>	@@	@"**+.. &//,W5CL 0 !3!;!;?Q?T?T!T"**+**r,   c                    U R                  5        H3  nUR                  [        R                  :X  d  M#  [        R
                  s  $    [        R                  $ )zCurrent topology type is ReplicaSetWithPrimary. Is primary still known?

Pass in a dict of ServerDescriptions.

Returns new topology type.
)rE   r   r   r   rI   r!   r    )rr   r:   s     r-   r   r     s@     ZZ\==K111 666  000r,   N)r   r1   r   r   r   r1   )r   r1   r   zlist[tuple[str, Any]]r   r1   )rr   +MutableMapping[_Address, ServerDescription]rR   r   r   r   rS   r   rT   r   r   z<tuple[int, Optional[str], Optional[int], Optional[ObjectId]])rr   r  rR   r   r   r   r   r   )rr   r  rR   r   r   r   r   ztuple[int, Optional[str]])rr   z$Mapping[_Address, ServerDescription]r   r   );__doc__
__future__r   randomr   typingr   r   r   r   r	   r
   r   r   bson.min_keyr   bson.objectidr   pymongor   pymongo.errorsr   r   pymongo.read_preferencesr   r   r   r   pymongo.server_descriptionr   pymongo.server_selectorsr   pymongo.server_typer   pymongo.typingsr   r   rangerI   r#   r"   r/   r*   _ServerSelectorr1   r   r   r!   r   r    r   r   r   rm   r  r   r   r   r   r%   r,   r-   <module>r*     s   # 	 	 	   "  ; X X 8 . + $J  uQx( ,9+@+@-BWBW*X  X D!234d;L6MMNe
 e
V --=>>]>>=<<::! e-eCTeeP(-(9N((VUY	4UY#UY *UY #	UY
 (UY BUYp#	4### *# 		#.+	4+#+ *+ 	+@1r,   