
    i)im              
         U d Z ddlmZ ddlmZ ddlmZmZmZm	Z	m
Z
mZmZmZ ddlmZ ddlmZ ddlmZ ddlmZmZ dd	lmZmZmZmZ dd
lmZ ddlmZ ddl m!Z! ddl"m#Z#  G d de          Z$ e$ e%d           Z&e&j'        e&j(        fZ)de*d<   eee         gee         f         Z+ G d d          Z,e!j-        e&j(        e!j.        e&j/        e!j0        e&j1        e!j2        e&j1        e!j3        e&j1        iZ4d.dZ5d/dZ6d0d&Z7d1d(Z8d2d*Z9d3d,Z:d-S )4zRepresent 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                  L    e Zd ZU ded<   ded<   ded<   ded<   ded<   ded<   dS )	_TopologyTypeintSingleReplicaSetNoPrimaryReplicaSetWithPrimaryShardedUnknownLoadBalancedN)__name__
__module____qualname____annotations__     n/Users/user/workspace/sujinbaek/cqa-test-app/venv/lib/python3.11/site-packages/pymongo/topology_description.pyr   r   -   sQ         KKKLLLLLLr*   r      ztuple[int, int]SRV_POLLING_TOPOLOGIESc                     e Zd Zd5dZd6dZd6dZd7dZd8dZd9dZd:dZ	e
d;d            Ze
d<d            Ze
d=d            Ze
d>d            Ze
d?d            Ze
d>d            Ze
d@d!            Ze
dAd"            Ze
d@d#            Ze
d>d$            Ze
d;d%            Ze
d;d&            ZdBd)Z	 	 dCdDd/Zej        fdEd2ZdAd3Zd<d4Zd*S )FTopologyDescriptiontopology_typer   server_descriptions!dict[_Address, ServerDescription]replica_set_nameOptional[str]max_set_versionOptional[int]max_election_idOptional[ObjectId]topology_settingsr   returnNonec                ^   || _         || _        || _        || _        || _        || _        d| _        | j         t          j        k    r| 	                                 | j
        }|s	d| _        dS t          d |D                       r	d| _        dS t          d |D                       | _        dS )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  (   K   | ]}|j         d u V  d S Nlogical_session_timeout_minutes.0ss     r+   	<genexpr>z/TopologyDescription.__init__.<locals>.<genexpr>k   s*      UUq2d:UUUUUUr*   c              3  $   K   | ]}|j         V  d S r>   r?   rA   s     r+   rD   z/TopologyDescription.__init__.<locals>.<genexpr>n   s6       + +671+ + + + + +r*   )_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)selfr0   r1   r3   r5   r7   r9   rO   s           r+   __init__zTopologyDescription.__init__@   s    & ,!1$7! / / #4 "&-"<<<'')))  0 	'+D$$$UUDTUUUUU 	'+D$$$'* + +;K+ + + ( (D$$$r*   c                   | j                                         D ]}|j        s
|j        duo|j        t          j        k    }|j        duo|j        t          j        k     }|r6d|j        d         |j        d         pd|j        t          j        fz  | _	        ~|rCd|j        d         |j        d         pd|j        t          j        t          j
        fz  | _	         dS dS )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).)rH   valuesis_server_type_knownmin_wire_versionr   MAX_SUPPORTED_WIRE_VERSIONmax_wire_versionMIN_SUPPORTED_WIRE_VERSIONaddressrL   MIN_SUPPORTED_SERVER_VERSION)rS   rC   server_too_newserver_too_olds       r+   rN   z*TopologyDescription._init_incompatible_errr   s)   *1133 +	 +	A)  "$. K&)JJ  "$. K&)JJ   A 	!	!)*9	 &&   L 	!	!)*9; & =+	 +	r*   c                <    | j         rt          | j                   dS )zRaise ConfigurationError if any server is incompatible.

        A server is incompatible if its wire protocol version range does not
        overlap with PyMongo's.
        N)rL   r   rS   s    r+   check_compatiblez$TopologyDescription.check_compatible   s*     ! 	=$T%;<<<	= 	=r*   r]   r   boolc                    || j         v S r>   )rH   )rS   r]   s     r+   
has_serverzTopologyDescription.has_server   s    $333r*   c                `    | j         |                                         }t          | |          S )z;A copy of this description, with one server marked Unknown.)rH   
to_unknownupdated_topology_description)rS   r]   
unknown_sds      r+   reset_serverz TopologyDescription.reset_server   s+    .w7BBDD
+D*===r*   c                    | j         t          j        k    rt          j        }n| j         }d | j        D             }t          ||| j        | j        | j        | j	                  S )z<A copy of this description, with all servers marked Unknown.c                .    i | ]}|t          |          S r)   r   )rB   r]   s     r+   
<dictcomp>z-TopologyDescription.reset.<locals>.<dictcomp>   s#    \\\ww)'22\\\r*   )
rF   rM   r!   r    rH   r/   rG   rI   rJ   rK   )rS   r0   sdss      r+   resetzTopologyDescription.reset   sn    -"EEE)=MM /M ]\$B[\\\""!!#
 
 	
r*   c                4    | j                                         S )z[dict of (address,
        :class:`~pymongo.server_description.ServerDescription`).
        )rH   copyrb   s    r+   r1   z'TopologyDescription.server_descriptions   s     (--///r*   c                    | j         S )zThe type of this topology.)rF   rb   s    r+   r0   z!TopologyDescription.topology_type   s     ""r*   strc                0    t           j        | j                 S )zUThe topology type as a human readable string.

        .. versionadded:: 3.4
        )rM   _fieldsrF   rb   s    r+   topology_type_namez&TopologyDescription.topology_type_name   s     $T%899r*   c                    | j         S )zThe replica set name.)rG   rb   s    r+   r3   z$TopologyDescription.replica_set_name   s     %%r*   c                    | j         S )z1Greatest setVersion seen from a primary, or None.)rI   rb   s    r+   r5   z#TopologyDescription.max_set_version        $$r*   c                    | j         S )z1Greatest electionId seen from a primary, or None.)rJ   rb   s    r+   r7   z#TopologyDescription.max_election_id   rz   r*   c                    | j         S )z)Minimum logical session timeout, or None.)rP   rb   s    r+   r@   z3TopologyDescription.logical_session_timeout_minutes   s     ''r*   list[ServerDescription]c                H    d | j                                         D             S )z)List of Servers of types besides Unknown.c                     g | ]}|j         	|S r)   rX   rA   s     r+   
<listcomp>z5TopologyDescription.known_servers.<locals>.<listcomp>   s     XXXaAWXXXXr*   rH   rW   rb   s    r+   known_serversz!TopologyDescription.known_servers   s(     YX44;;==XXXXr*   c                b    t          d | j                                        D                       S )z7Whether there are any Servers of types besides Unknown.c              3  (   K   | ]}|j         	|V  d S r>   r   rA   s     r+   rD   z8TopologyDescription.has_known_servers.<locals>.<genexpr>   s*      [[ADZ[1[[[[[[r*   )rQ   rH   rW   rb   s    r+   has_known_serversz%TopologyDescription.has_known_servers   s0     [[d7>>@@[[[[[[r*   c                H    d | j                                         D             S )zList of readable Servers.c                     g | ]}|j         	|S r)   )is_readablerA   s     r+   r   z8TopologyDescription.readable_servers.<locals>.<listcomp>   s    OOOaOOOOr*   r   rb   s    r+   rO   z$TopologyDescription.readable_servers   s(     PO44;;==OOOOr*   c                T    | j         }|rt          d | j         D                       S dS )z3Minimum of all servers' max wire versions, or None.c              3  $   K   | ]}|j         V  d S r>   )r[   rA   s     r+   rD   z:TopologyDescription.common_wire_version.<locals>.<genexpr>   s%      FFaq)FFFFFFr*   N)r   rR   rS   serverss     r+   common_wire_versionz'TopologyDescription.common_wire_version   s:     $ 	GFF43EFFFFFFtr*   c                    | j         j        S r>   )rK   heartbeat_frequencyrb   s    r+   r   z'TopologyDescription.heartbeat_frequency  s    &::r*   c                    | j         j        S r>   )rK   _srv_max_hostsrb   s    r+   srv_max_hostsz!TopologyDescription.srv_max_hosts  s    &55r*   	selectionOptional[Selection]c                   |sg S g }|j         D ]G}|j        $d|j         d|  d|j          }t          |          |                    |j                   Ht          |          | j        j        dz  fd|j         D             S )Nzround_trip_time for server z is unexpectedly None: z, servers: g     @@c                V    g | ]%}t          t          |j                  z
  k    #|&S r)   )r   floatround_trip_time)rB   rC   fastest	thresholds     r+   r   z>TopologyDescription._apply_local_threshold.<locals>.<listcomp>  s@     
 
 
UA-..8YFF FFFr*   )r1   r   r]   r   appendrR   rK   local_threshold_ms)rS   r   round_trip_timesserverconfig_err_msgr   r   s        @@r+   _apply_local_thresholdz*TopologyDescription._apply_local_threshold  s     	I(*3 	< 	<F%- "Wv~  "W  "Wfj  "W  "W  xA  xU  "W  "W(888##F$:;;;;&''+>G	
 
 
 
 
2
 
 
 	
r*   NselectorOptional[_Address]custom_selectorOptional[_ServerSelector]c                r   t          |dd          r.| j        }|r%||j        k     rt          d||j        |fz            t	          |t
                    r|                    |            | j        t          j	        k    rg S | j        t          j
        t          j        fv r| j        S |r.|                                                     |          }|r|gng S | j        t          j        k    r]t!          |          t"          u rG| j                                        D ]+}|j        t*          j        k    r|g}|r ||          }|c S ,g S t/          j        |           }| j        t          j        k    r ||          }|%|r#|                     ||j                            }|                     |          S )a  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
        rY   r   zF%s requires min wire version %d, but topology's min wire version is %d)getattrr   rY   r   
isinstancer   selection_hookr0   rM   r#   r   r$   r   r1   getr!   typer   rH   rW   server_typer   	RSPrimaryr   from_topology_descriptionr"   with_server_descriptionsr   )	rS   r   r]   r   	common_wvdescriptionsdro   r   s	            r+   apply_selectorz"TopologyDescription.apply_selector  s   ( 8/33 	0I Y)BBB(*-5x7PR[,\]  
 h.. 	*##D)))!666IM$8-:T#UUU%% 	8224488AAK$/7K==R7 !DDDh[bIbIb/6688  >[%:::$C& 3-oc22JJJ	 ; I7==	!666 ++I &9&!::	 =>> I **9555r*   read_preferencer   c                p    t          j        d|           t          |                     |                    S )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
        r   )r   validate_read_preferencerQ   r   )rS   r   s     r+   has_readable_serverz'TopologyDescription.has_readable_server^  s4     	'(9?KKK4&&77888r*   c                @    |                      t          j                  S )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   PRIMARYrb   s    r+   has_writable_serverz'TopologyDescription.has_writable_servern  s     ''(>???r*   c                    t          | j                                        d           }d                    | j        j        | j        j        | j        |          S )Nc                    | j         S r>   )r]   )r   s    r+   <lambda>z.TopologyDescription.__repr__.<locals>.<lambda>z  s    BJ r*   )keyz-<{} id: {}, topology_type: {}, servers: {!r}>)	sortedrH   rW   format	__class__r%   rK   _topology_idrw   r   s     r+   __repr__zTopologyDescription.__repr__x  sY    299;;AVAVWWW>EEN##0#	
 
 	
r*   )r0   r   r1   r2   r3   r4   r5   r6   r7   r8   r9   r   r:   r;   )r:   r;   )r]   r   r:   rd   )r]   r   r:   r/   )r:   r/   )r:   r2   )r:   r   )r:   rt   )r:   r4   )r:   r6   )r:   r8   )r:   r}   )r:   rd   )r   r   r:   r}   )NN)r   r   r]   r   r   r   r:   r}   )r   r   r:   rd   )r%   r&   r'   rT   rN   rc   rf   rk   rp   r1   propertyr0   rw   r3   r5   r7   r@   r   r   rO   r   r   r   r   r   r   r   r   r   r   r)   r*   r+   r/   r/   ?   s       0 0 0 0d- - - -^= = = =4 4 4 4> > > >

 
 
 
&0 0 0 0 # # # X# : : : X: & & & X& % % % X% % % % X% ( ( ( X( Y Y Y XY \ \ \ X\ P P P XP    X ; ; ; X; 6 6 6 X6
 
 
 
* '+59	>6 >6 >6 >6 >6@ BPAW 9 9 9 9 9 @ @ @ @
 
 
 
 
 
r*   r/   topology_descriptionserver_descriptionr   r:   c                $   |j         }| j        }| j        }| j        }| j        }|j        }|                                 }|||<   |t          j        k    rq|L||j        k    rAt          d
                    ||j                            }	|                    |	          ||<   t          t          j        ||||| j                  S |t          j        k    r|t          j        t          j        fv r@t%          | j        j                  dk    rt          j        }n=|                    |           n'|t          j        t          j        fvrt,          |         }|t          j        k    r1|t          j        t          j        fvr|                    |           nb|t          j        k    r|t          j        t          j        fv r|                    |           n!|t          j        k    rt7          |||||          \  }}}}n|t          j        t          j        t          j        fv rt?          |||          \  }}n|t          j         k    r|t          j        t          j        fv r%|                    |           tC          |          }no|t          j        k    rt7          |||||          \  }}}}nF|t          j        t          j        t          j        fv rtE          |||          }ntC          |          }t          |||||| j                  S )an  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.
    Nzeclient is configured to connect to a replica set named '{}' but this node belongs to a set named '{}')errorrV   )#r]   r0   r3   r5   r7   r   r1   rM   r   r   r   rh   r/   rK   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)
r   r   r]   r0   set_namer5   r7   r   ro   r   s
             r+   ri   ri     s2    !(G )6M#4H*:O*:O$0K 
2
2
4
4C &CL,,,H0B0S$S$S&AAG0AB B E .88u8EECL"  3
 
 	
 ---;1;3KLLL':@AAQFF - 4     !4k6I JJJ9+FM---{1;3FGGGGGG	-;	;	;;1;3EFFFGGGK111JaX1?OK KG]Ho [4k6K[M`aaa&GX1' '#M8 
-=	=	=;1;3EFFFGGG.s33MMK111JaX1?OK KG]Ho [4k6K[M`aaa?XOabbMM /s33M /  r*   seedlistlist[tuple[str, Any]]c           	        | j         t          v sJ |                                 }t          |                                          t          |          k    r| S t          |                                          D ]}||vr|                    |           | j        dk    rt          |          t          |                                          z
  }| j        t          |          z
  }|dk    r9t          t          |          t          |t          |                              }ng }|D ]}||vrt          |          ||<   t          | j         || j        | j        | j        | j                  S )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   )r0   r-   r1   setkeyslistr   r   r   r   r   rR   r   r/   r3   r5   r7   rK   )r   r   ro   r]   	new_hostsn_to_adds         r+   )_updated_topology_description_srv_pollingr     se     -1GGGGG

2
2
4
4C 388::#h--''## 

##  (""GGG)Q..MMC

OO3	'5C@a<<fY//Xs9~~1N1NOOHHH 6 6#,W55CL*-,,/  r*   ro   +MutableMapping[_Address, ServerDescription]r3   r4   r5   r6   r7   r8   <tuple[int, Optional[str], Optional[int], Optional[ObjectId]]c                |   ||j         }n8||j         k    r-|                     |j                   t          |           |||fS |j        |j        dk     r|j        |j        f}||f}d|vrTd|vrI||k     rC|                    t          d| d|                     | |j        <   t          |           |||fS |j        }|j        ||j        |k    r|j        }n|j        |j        f}||f}t          d |D                       }t          d |D                       }||k     rC|                    t          d| d|                     | |j        <   t          |           |||fS |j        }|j        }| 
                                D ]Q}	|	j        t          j        u r<|	j        |j        k    r,|	                    t          d                    | |	j        <    nR|j        D ]}
|
| vrt          |
          | |
<   t!          |           |j        z
  D ]}|                     |           t          |           |||fS )ag  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  :   K   | ]}|t                      n|V  d S r>   r   rB   is     r+   rD   z*_update_rs_from_primary.<locals>.<genexpr>P  .      ![![1ai&(((Q![![![![![![r*   c              3  :   K   | ]}|t                      n|V  d S r>   r   r   s     r+   rD   z*_update_rs_from_primary.<locals>.<genexpr>Q  r   r*   z6primary marked stale due to discovery of newer primary)r3   r   r]   r   r[   set_versionelection_idrh   r   tuplerW   r   r   r   	all_hostsr   r   )ro   r3   r   r5   r7   new_election_tuplemax_election_tuplenew_election_safemax_election_safer   new_addressaddrs               r+   r   r   "  s     ->	/@	@	@ 	"*+++!#&&(8/?ZZ*26H6Y\^6^6^%7%CEWEc$d%4o$F)))---2DGY2Y2Y2D2O2O  VWi  V  V  BT  V  V 3 3&./
 *#..0@/Sbbb0<O)5#'9'E'W'W0<O/;=O=[[,o=!![![HZ![![![[[!![![HZ![![![[[000.@.K.K RSe  R  R  ~P  R  R / /C"*+
 &c**,<o^^0<O0<O **,,  +"777"4"<<< #)"3"3UVV# #C
 E *3 > >c!!0==C C-77   s##%5XXr*   r   c                    |J ||j         k    r|                     |j                   n1|j        r*|j        |j        k    r|                     |j                   t	          |           S )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.
    )r3   r   r]   mer   )ro   r3   r   s      r+   r   r   z  s{     '''->>>"*++++		 ,#5#=ASAV#V#V"*+++ c"""r*   tuple[int, Optional[str]]c                *   t           j        }||j        }n)||j        k    r|                     |j                   ||fS |j        D ]}|| vrt          |          | |<   |j        r*|j        |j        k    r|                     |j                   ||fS )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).
    )rM   r    r3   r   r]   r   r   r   )ro   r3   r   r0   r]   s        r+   r   r     s     "5M->	/@	@	@"*+++... &/ 6 6#,W55CL ,!3!;?Q?T!T!T"*+++***r*   $Mapping[_Address, ServerDescription]c                    |                                  D ]%}|j        t          j        k    rt          j        c S &t          j        S )zCurrent topology type is ReplicaSetWithPrimary. Is primary still known?

    Pass in a dict of ServerDescriptions.

    Returns new topology type.
    )rW   r   r   r   rM   r!   r    )ro   rC   s     r+   r   r     sJ     ZZ\\ 1 1=K111 6666 2 00r*   N)r   r/   r   r   r:   r/   )r   r/   r   r   r:   r/   )ro   r   r3   r4   r   r   r5   r6   r7   r8   r:   r   )ro   r   r3   r4   r   r   r:   r   )ro   r   r3   r4   r   r   r:   r   )ro   r   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   rangerM   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     # " " " " "      	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	        " " " " " "       ; ; ; ; ; ; ; ; X X X X X X X X X X X X 8 8 8 8 8 8 . . . . . . + + + + + + $ $ $ $ $ $    J    uuQxx( ,9+@-BW*X  X X X X D!234d;L6MMNA
 A
 A
 A
 A
 A
 A
 A
N
 -=>]>=<:! e e e eP( ( ( (VUY UY UY UYp# # # #.+ + + +@1 1 1 1 1 1r*   