
    IiTi              
         % 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  SS	K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$\$RJ                  \$RL                  4r'S\(S'   \\\   /\\   4   r) " S S5      r*\RV                  \$RL                  \RX                  \$RZ                  \R\                  \$R^                  \R`                  \$R^                  \Rb                  \$R^                  0r2      SS jr3      SS jr4            SS jr5        SS jr6        S S jr7S!S jr8g)"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)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#       B/venv/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r  S*       S+S jjr\R6                  4S,S jjrS(S jrS#S jrSrg)-TopologyDescription?   c                X   Xl         X0l        X l        X@l        XPl        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>k   s     UDTq22d:DTs   c              3  8   #    U  H  oR                   v   M     g 7fr3   r4   r6   s     r+   r9   r:   n   s      +;Ka11;K   )_topology_type_replica_set_name_server_descriptions_max_set_version_max_election_id_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_settingsrF   s           r+   __init__TopologyDescription.__init__@   s    & ,!1$7! / / #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).)r?   valuesis_server_type_knownmin_wire_versionr   MAX_SUPPORTED_WIRE_VERSIONmax_wire_versionMIN_SUPPORTED_WIRE_VERSIONaddressrC   MIN_SUPPORTED_SERVER_VERSION)rJ   r8   server_too_newserver_too_olds       r+   rE   *TopologyDescription._init_incompatible_errr   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)rC   r   rJ   s    r+   check_compatible$TopologyDescription.check_compatible   s#     !!$T%;%;<< "r*   c                    XR                   ;   $ r3   )r?   )rJ   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.)r?   
to_unknownupdated_topology_description)rJ   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=   rD   r   r   r?   r   r/   r>   r@   rA   rB   )rJ   rK   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`).
)r?   copyra   s    r+   rL   'TopologyDescription.server_descriptions   s     ((--//r*   c                    U R                   $ )zThe type of this topology.)r=   ra   s    r+   rK   !TopologyDescription.topology_type   s     """r*   c                <    [         R                  U R                     $ )zEThe topology type as a human readable string.

.. versionadded:: 3.4
)rD   _fieldsr=   ra   s    r+   topology_type_name&TopologyDescription.topology_type_name   s     $$T%8%899r*   c                    U R                   $ )zThe replica set name.)r>   ra   s    r+   rM   $TopologyDescription.replica_set_name   s     %%%r*   c                    U R                   $ )z1Greatest setVersion seen from a primary, or None.)r@   ra   s    r+   rN   #TopologyDescription.max_set_version        $$$r*   c                    U R                   $ )z1Greatest electionId seen from a primary, or None.)rA   ra   s    r+   rO   #TopologyDescription.max_election_id   r~   r*   c                    U R                   $ )z)Minimum logical session timeout, or None.)rG   ra   s    r+   r5   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.)r?   rU   rV   rJ   r8   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r3   )rV   r6   s     r+   r9   8TopologyDescription.has_known_servers.<locals>.<genexpr>   s     [@DZDZ11@s   #	#)rH   r?   rU   ra   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.)r?   rU   is_readabler   s     r+   rF   $TopologyDescription.readable_servers   s1      44;;=O=a=OOOr   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r3   )rY   r6   s     r+   r9   :TopologyDescription.common_wire_version.<locals>.<genexpr>   s     F3Ea))3Er<   N)r   rI   rJ   serverss     r+   common_wire_version'TopologyDescription.common_wire_version   s,     $$F43E3EFFFr*   c                .    U R                   R                  $ r3   )rB   heartbeat_frequencyra   s    r+   r   'TopologyDescription.heartbeat_frequency  s    &&:::r*   c                .    U R                   R                  $ r3   )rB   _srv_max_hostsra   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     @@)
rL   round_trip_timer[   r   appendrI   rB   local_threshold_msr   float)rJ   	selectionround_trip_timesserverconfig_err_msgfastest	thresholdr8   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SS5      (       a<  U R                  nU(       a)  XAR                  :  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                   " U 5      nU R                  [        R"                  :w  a  U" U5      nUb(  U(       a!  UR%                  U" UR                  5      5      nU R'                  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
rW   r   zF%s requires min wire version %d, but topology's min wire version is %d)getattrr   rW   r   
isinstancer   selection_hookrK   rD   r!   r   r"   r   rL   getr   from_topology_descriptionr    with_server_descriptionsr   )rJ   selectorr[   custom_selector	common_wvdescriptionr   s          r+   apply_selector"TopologyDescription.apply_selector  sI   ( 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$/K=7R777=	!6!66 +I &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_preferencerH   r   )rJ   r   s     r+   has_readable_server'TopologyDescription.has_readable_serverS  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   PRIMARYra   s    r+   has_writable_server'TopologyDescription.has_writable_serverc  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                   $ r3   )r[   )sds    r+   <lambda>.TopologyDescription.__repr__.<locals>.<lambda>o  s    BJJr*   )keyz-<{} id: {}, topology_type: {}, servers: {!r}>)	sortedr?   rU   format	__class__r$   rB   _topology_idrx   r   s     r+   __repr__TopologyDescription.__repr__m  sY    2299;AVW>EENN####00##	
 	
r*   )rC   rG   rA   r@   r>   r?   rB   r=   )rK   r   rL   !dict[_Address, ServerDescription]rM   Optional[str]rN   Optional[int]rO   Optional[ObjectId]rP   r   returnNone)r   r   )r[   r   r   bool)r[   r   r   r/   )r   r/   )r   r   )r   r   )r   str)r   r   )r   r   )r   r   )r   list[ServerDescription])r   r   )r   zOptional[Selection]r   r   )NN)r   r   r[   zOptional[_Address]r   zOptional[_ServerSelector]r   r   )r   r   r   r   ) r$   r%   r&   r'   rQ   rE   rb   re   rk   ro   rL   propertyrK   rx   rM   rN   rO   r5   r   r   rF   r   r   r   r   r   r   r   r   r   r   r)   r#   r*   r+   r/   r/   ?   s   00 ?0 (	0
 '0 ,0 0 
0d-^=4>

&0 # # : : & & % % % % ( ( Y Y \ \ P P   ; ; 6 6
* '+59	3636 $36 3	36
 
!36j BPAWAW 9 @
r*   r/   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 '{}')errorrT   )#r[   rK   rM   rN   rO   server_typerL   rD   r   r   r   rh   r/   rB   r!   r   
StandaloneLoadBalancerlenseedspopRSGhost_SERVER_TYPE_TO_TOPOLOGY_TYPEr    Mongosr   	RSPrimary_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[   rK   set_namerN   rO   r   rn   r   s
             r+   ri   ri     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   )rK   r-   rL   setkeyslistr   r   r   r   r   rI   r   r/   rM   rN   rO   rB   )r   seedlistrn   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;  aA  SU;  a/  XV:  a*  UR                  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                  5       XR                  '   [        U 5      XU4$ UR                  nUR
                  nU R                  5        HZ  n	U	R                  [        R                  L d  M"  U	R                  UR                  :w  d  M>  U	R                  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   c              3  >   #    U  H  oc
  [        5       OUv   M     g 7fr3   r   r7   is     r+   r9   *_update_rs_from_primary.<locals>.<genexpr>A       ![HZ1i&(Q">HZ   c              3  >   #    U  H  oc
  [        5       OUv   M     g 7fr3   r   r   s     r+   r9   r   B  r   r   )rM   r   r[   r   rY   set_versionelection_idrh   tuplerU   r   r   r   	all_hostsr   r   )rn   rM   r   rN   rO   new_election_tuplemax_election_tuplenew_election_safemax_election_safer   new_addressaddrs               r+   r   r     sA     ->>	@@	@ 	"**+!#&(8?ZZ**26H6Y6Y\^6^%7%C%CEWEcEc$d%4$F))--2D2Y2D2O2O2Q../)#.0@Sbbb0<<O))5#'9'E'E'W0<<O/;;=O=[=[[,=!![HZ![[!![HZ![[0.@.K.K.MC**+%c*,<^^0<<O0<<O **,+"7"77"4"<"<< #)"3"3"5C   *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.
)rM   r   r[   mer   )rn   rM   r   s      r+   r   r   e  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).
)rD   r   rM   r   r[   r  r   r	  )rn   rM   r   rK   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.
)rU   r   r   r   rD   r   r   )rn   r8   s     r+   r   r     s@     ZZ\==K111 666  000r*   N)r   r/   r   r   r   r/   )r   r/   r   zlist[tuple[str, Any]]r   r/   )rn   +MutableMapping[_Address, ServerDescription]rM   r   r   r   rN   r   rO   r   r   z<tuple[int, Optional[str], Optional[int], Optional[ObjectId]])rn   r  rM   r   r   r   r   r   )rn   r  rM   r   r   r   r   ztuple[int, Optional[str]])rn   z$Mapping[_Address, ServerDescription]r   r   )9__doc__
__future__r   randomr   typingr   r   r   r   r	   r
   r   r   bson.min_keyr   bson.objectidr   pymongor   pymongo.errorsr   pymongo.read_preferencesr   r   r   pymongo.server_descriptionr   pymongo.server_selectorsr   pymongo.server_typer   pymongo.typingsr   r   rangerD   r!   r    r-   r(   _ServerSelectorr/   r   r   r   r   r   r   r   r   ri   r   r   r   r   r   r#   r*   r+   <module>r     s   # 	 	 	   "  - O O 8 . + $J  uQx( ,9+@+@-BWBW*X  X D!234d;L6MMNv
 v
x	 --=>>]>>=<<::! e-eCTeeP(-(9N((VKY	4KY#KY *KY #	KY
 (KY BKY\#	4### *# 		#.+	4+#+ *+ 	+@1r*   