o
    'huk                  
   @  s~  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 dd
lmZ ddlmZ ddlm Z  ddl!m"Z" G d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 dZ+e j,e%j'e j-e%j.e j/e%j0e j1e%j0e j2e%j0iZ3d4ddZ4d5ddZ5d6d(d)Z6d7d+d,Z7d8d.d/Z8d9d1d2Z9d3S ):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)ReadPreference_AggWritePref_ServerModeServerDescription)	Selection)SERVER_TYPE)_Addressc                   @  s>   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__ r&   r&   X/var/www/html/olx_land/venv/lib/python3.10/site-packages/pymongo/topology_description.pyr   -   s   
 r      ztuple[int, int]SRV_POLLING_TOPOLOGIESc                   @  s8  e Zd ZdMddZdNddZdNddZdOddZdPddZdQddZdRddZ	e
dSd d!Ze
dTd#d$Ze
dUd%d&Ze
dVd'd(Ze
dWd)d*Ze
dVd+d,Ze
dXd.d/Ze
dYd0d1Ze
dXd2d3Ze
dVd4d5Ze
dSd6d7Ze
dSd8d9ZdZd<d=Z	>	>d[d\dCdDZejfd]dGdHZdYdIdJZdTdKdLZd>S )^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                 C  s   || _ || _|| _|| _|| _|| _d| _| j tjkr| 	  | j
}|s)d| _dS tdd |D r7d| _dS td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                 s  s    | ]}|j d u V  qd S Nlogical_session_timeout_minutes.0sr&   r&   r'   	<genexpr>k       z/TopologyDescription.__init__.<locals>.<genexpr>c                 s      | ]}|j V  qd S r7   r8   r:   r&   r&   r'   r=   n   s    
)_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)selfr+   r,   r.   r0   r2   r4   rI   r&   r&   r'   __init__@   s"   	

zTopologyDescription.__init__c                 C  s   | j  D ]L}|jsq|jduo|jtjk}|jduo |jtjk }|r7d|jd |jd p.d|jtjf | _	q|rQd|jd |jd pDd|jtjtj
f | _	 dS q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).)rB   valuesis_server_type_knownmin_wire_versionr   MAX_SUPPORTED_WIRE_VERSIONmax_wire_versionMIN_SUPPORTED_WIRE_VERSIONaddressrF   MIN_SUPPORTED_SERVER_VERSION)rM   r<   server_too_newserver_too_oldr&   r&   r'   rH   r   s>   



z*TopologyDescription._init_incompatible_errc                 C  s   | 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)rF   r   rM   r&   r&   r'   check_compatible   s   
z$TopologyDescription.check_compatiblerV   r   boolc                 C  s
   || j v S r7   )rB   )rM   rV   r&   r&   r'   
has_server   s   
zTopologyDescription.has_serverc                 C  s   | j |  }t| |S )z;A copy of this description, with one server marked Unknown.)rB   
to_unknownupdated_topology_description)rM   rV   
unknown_sdr&   r&   r'   reset_server   s   
z TopologyDescription.reset_serverc                 C  sD   | j tjkr
tj}n| j }dd | jD }t||| j| j| j| j	S )z<A copy of this description, with all servers marked Unknown.c                 S  s   i | ]}|t |qS r&   r   )r;   rV   r&   r&   r'   
<dictcomp>       z-TopologyDescription.reset.<locals>.<dictcomp>)
r@   rG   r   r   rB   r*   rA   rC   rD   rE   )rM   r+   sdsr&   r&   r'   reset   s   zTopologyDescription.resetc                 C  s
   | j  S )z[dict of (address,
        :class:`~pymongo.server_description.ServerDescription`).
        )rB   copyrZ   r&   r&   r'   r,      s   
z'TopologyDescription.server_descriptionsc                 C     | j S )zThe type of this topology.)r@   rZ   r&   r&   r'   r+         z!TopologyDescription.topology_typestrc                 C  s   t j| j S )zUThe topology type as a human readable string.

        .. versionadded:: 3.4
        )rG   _fieldsr@   rZ   r&   r&   r'   topology_type_name   s   z&TopologyDescription.topology_type_namec                 C  rg   )zThe replica set name.)rA   rZ   r&   r&   r'   r.      rh   z$TopologyDescription.replica_set_namec                 C  rg   )z1Greatest setVersion seen from a primary, or None.)rC   rZ   r&   r&   r'   r0      rh   z#TopologyDescription.max_set_versionc                 C  rg   )z1Greatest electionId seen from a primary, or None.)rD   rZ   r&   r&   r'   r2      rh   z#TopologyDescription.max_election_idc                 C  rg   )z)Minimum logical session timeout, or None.)rJ   rZ   r&   r&   r'   r9      rh   z3TopologyDescription.logical_session_timeout_minuteslist[ServerDescription]c                 C     dd | j  D S )z)List of Servers of types besides Unknown.c                 S     g | ]}|j r|qS r&   rQ   r:   r&   r&   r'   
<listcomp>   rc   z5TopologyDescription.known_servers.<locals>.<listcomp>rB   rP   rZ   r&   r&   r'   known_servers      z!TopologyDescription.known_serversc                 C  s   t dd | j D S )z7Whether there are any Servers of types besides Unknown.c                 s  s    | ]}|j r|V  qd S r7   ro   r:   r&   r&   r'   r=      r>   z8TopologyDescription.has_known_servers.<locals>.<genexpr>)rK   rB   rP   rZ   r&   r&   r'   has_known_servers   s   z%TopologyDescription.has_known_serversc                 C  rm   )zList of readable Servers.c                 S  rn   r&   )is_readabler:   r&   r&   r'   rp      rc   z8TopologyDescription.readable_servers.<locals>.<listcomp>rq   rZ   r&   r&   r'   rI      rs   z$TopologyDescription.readable_serversc                 C  s"   | j }|rtdd | j D S dS )z3Minimum of all servers' max wire versions, or None.c                 s  r?   r7   )rT   r:   r&   r&   r'   r=      s    z:TopologyDescription.common_wire_version.<locals>.<genexpr>N)rr   rL   rM   serversr&   r&   r'   common_wire_version   s   z'TopologyDescription.common_wire_versionc                 C     | j jS r7   )rE   heartbeat_frequencyrZ   r&   r&   r'   rz        z'TopologyDescription.heartbeat_frequencyc                 C  ry   r7   )rE   _srv_max_hostsrZ   r&   r&   r'   srv_max_hosts  r{   z!TopologyDescription.srv_max_hosts	selectionOptional[Selection]c                   sz   |sg S g }|j D ]}|jd u r!d|j d|  d|j  }t|||j q	t| | jjd  fdd|j D S )Nzround_trip_time for server z is unexpectedly None: z, servers: g     @@c                   s$   g | ]}t t|j  kr|qS r&   )r   floatround_trip_timer:   fastest	thresholdr&   r'   rp     s
    z>TopologyDescription._apply_local_threshold.<locals>.<listcomp>)r,   r   rV   r   appendrL   rE   local_threshold_ms)rM   r~   round_trip_timesserverconfig_err_msgr&   r   r'   _apply_local_threshold  s   

z*TopologyDescription._apply_local_thresholdNselectorOptional[_Address]custom_selectorOptional[_ServerSelector]c                 C  s   t |ddr| j}|r||jk rtd||j|f t|tr$||  | jtj	kr,g S | jtj
tjfv r8| jS |rH|  |}|rF|gS g S t| }| jtjkrW||}|dure|re|||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
        rR   r   zF%s requires min wire version %d, but topology's min wire version is %dN)getattrrx   rR   r   
isinstancer   selection_hookr+   rG   r    r   r!   rr   r,   getr   from_topology_descriptionr   with_server_descriptionsr   )rM   r   rV   r   	common_wvdescriptionr~   r&   r&   r'   apply_selector  s2   




z"TopologyDescription.apply_selectorread_preferencer   c                 C  s   t 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_preferencerK   r   )rM   r   r&   r&   r'   has_readable_serverS  s   z'TopologyDescription.has_readable_serverc                 C  s   |  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   PRIMARYrZ   r&   r&   r'   has_writable_serverc  s   z'TopologyDescription.has_writable_serverc                 C  s0   t | j dd d}d| jj| jj| j|S )Nc                 S  rg   r7   )rV   )sdr&   r&   r'   <lambda>o  s    z.TopologyDescription.__repr__.<locals>.<lambda>)keyz-<{} id: {}, topology_type: {}, servers: {!r}>)	sortedrB   rP   format	__class__r"   rE   _topology_idrk   rv   r&   r&   r'   __repr__m  s   zTopologyDescription.__repr__)r+   r   r,   r-   r.   r/   r0   r1   r2   r3   r4   r   r5   r6   )r5   r6   )rV   r   r5   r\   )rV   r   r5   r*   )r5   r*   )r5   r-   )r5   r   )r5   ri   )r5   r/   )r5   r1   )r5   r3   )r5   rl   )r5   r\   )r~   r   r5   rl   )NN)r   r   rV   r   r   r   r5   rl   )r   r   r5   r\   )r"   r#   r$   rN   rH   r[   r]   ra   re   r,   propertyr+   rk   r.   r0   r2   r9   rr   rt   rI   rx   rz   r}   r   r   r   r   r   r   r   r&   r&   r&   r'   r*   ?   sN    

2
/
	



5

r*   topology_descriptionserver_descriptionr   r5   c           
      C  s  |j }| j}| j}| j}| j}|j}|  }|||< |tjkrD|dur9||jkr9t	d
||j}	|j|	d||< ttj||||| jS |tjkro|tjtjfv rct| jjdkr]tj}n|| n|tjtjfvrot| }|tjkr|tjtjfvr|| nv|tjkr|tjtjfv r|| nc|tjkrt|||||\}}}}nQ|tjtjtjfv rt|||\}}n>|tj kr|tjtjfv r|| t!|}n'|tjkrt|||||\}}}}n|tjtjtjfv rt"|||}nt!|}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 '{}')errorrO   )#rV   r+   r.   r0   r2   server_typer,   rG   r   r   r   r^   r*   rE   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)
r   r   rV   r+   set_namer0   r2   r   rd   r   r&   r&   r'   r_     s   

	









r_   seedlistlist[tuple[str, Any]]c                 C  s   | j tv sJ |  }t| t|kr| S t| D ]}||vr(|| q| jdkrRt|t|  }| jt| }|dkrPt	t
|t|t|}ng }|D ]}||vr`t|||< qTt| 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   )r+   r)   r,   setkeyslistr   r}   r   r   r   rL   r   r*   r.   r0   r2   rE   )r   r   rd   rV   	new_hostsn_to_addr&   r&   r'   )_updated_topology_description_srv_polling  s4   	

r   rd   +MutableMapping[_Address, ServerDescription]r.   r/   r0   r1   r2   r3   <tuple[int, Optional[str], Optional[int], Optional[ObjectId]]c                 C  s  |du r|j }n||j kr| |j t| |||fS |jdu s%|jdk rh|j|jf}||f}d|vrVd|vrS||k rS|td| d| | |j< t| |||fS |j}|jdurg|du sd|j|krg|j}n>|j|jf}||f}t	dd |D }t	dd |D }||k r|td| d| | |j< t| |||fS |j}|j}| 
 D ]}	|	jtju r|	j|jkr|	td| |	j<  nq|jD ]}
|
| vrt|
| |
< qt| |j D ]}| | qt| |||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                 s  "    | ]}|d u rt  n|V  qd S r7   r   r;   ir&   r&   r'   r=   E       z*_update_rs_from_primary.<locals>.<genexpr>c                 s  r   r7   r   r   r&   r&   r'   r=   F  r   z6primary marked stale due to discovery of newer primary)r.   r   rV   r   rT   set_versionelection_idr^   r   tuplerP   r   r   r   	all_hostsr   r   )rd   r.   r   r0   r2   new_election_tuplemax_election_tuplenew_election_safemax_election_safer   new_addressaddrr&   r&   r'   r     sb   





r   r   c                 C  sP   |dusJ ||j kr| |j t| S |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.
    N)r.   r   rV   mer   )rd   r.   r   r&   r&   r'   r   o  s   
r   tuple[int, Optional[str]]c                 C  sz   t j}|du r|j}n||jkr| |j ||fS |jD ]}|| vr)t|| |< q|jr9|j|jkr9| |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).
    N)rG   r   r.   r   rV   r   r   r   )rd   r.   r   r+   rV   r&   r&   r'   r     s   

r   $Mapping[_Address, ServerDescription]c                 C  s*   |   D ]}|jtjkrtj  S qtjS )zCurrent topology type is ReplicaSetWithPrimary. Is primary still known?

    Pass in a dict of ServerDescriptions.

    Returns new topology type.
    )rP   r   r   r   rG   r   r   )rd   r<   r&   r&   r'   r     s
   
r   N)r   r*   r   r   r5   r*   )r   r*   r   r   r5   r*   )rd   r   r.   r/   r   r   r0   r1   r2   r3   r5   r   )rd   r   r.   r/   r   r   r5   r   )rd   r   r.   r/   r   r   r5   r   )rd   r   r5   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   pymongo.server_descriptionr   pymongo.server_selectorsr   pymongo.server_typer   pymongo.typingsr   r   rangerG   r    r   r)   r%   _ServerSelectorr*   r   r   r   r   r   r   r   r   r_   r   r   r   r   r   r&   r&   r&   r'   <module>   s@   (	  >


h
+
X
 