o
    sDiSt                  
   @  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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!j0e&j1e!j2e&j1e!j3e&j1iZ4d4ddZ5d5ddZ6d6d(d)Z7d7d+d,Z8d8d.d/Z9d9d1d2Z:d3S ):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                   @  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'   Z/home/alumno/antzosa8961/venv/lib/python3.10/site-packages/pymongo/topology_description.pyr   -   s   
 r      ztuple[int, int]SRV_POLLING_TOPOLOGIESc                   @  sV  e Zd ZdSddZdTddZdTddZdUddZdVddZdWddZdXddZ	e
dYd d!Ze
dZd#d$Ze
d[d%d&Ze
d\d'd(Ze
d]d)d*Ze
d\d+d,Ze
d^d.d/Ze
d_d0d1Ze
d^d2d3Ze
d^d4d5Ze
d\d6d7Ze
dYd8d9Ze
dYd:d;Zd`d>d?Z	@dadbdCdDZ	@	@	@dcdddIdJZejfdedMdNZd_dOdPZdZdQdR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                 C  s   || _ || _|| _|| _|| _t| j | _|| _d| _	| j t
jkr'|   | j}|s1d| _dS tdd |D r?d| _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>l       z/TopologyDescription.__init__.<locals>.<genexpr>c                 s      | ]}|j V  qd S r8   r9   r;   r'   r'   r(   r>   o   s    
)_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)selfr,   r-   r/   r1   r3   r5   rM   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).)rC   rG   is_server_type_knownmin_wire_versionr   MAX_SUPPORTED_WIRE_VERSIONmax_wire_versionMIN_SUPPORTED_WIRE_VERSIONaddressrJ   MIN_SUPPORTED_SERVER_VERSION)rQ   r=   server_too_newserver_too_oldr'   r'   r(   rL   s   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)rJ   r   rQ   r'   r'   r(   check_compatible   s   
z$TopologyDescription.check_compatiblerY   r   boolc                 C  s
   || j v S r8   )rC   )rQ   rY   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.)rC   
to_unknownupdated_topology_description)rQ   rY   
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<   rY   r'   r'   r(   
<dictcomp>       z-TopologyDescription.reset.<locals>.<dictcomp>)
rA   rK   r   r   rC   r+   rB   rD   rE   rI   )rQ   r,   sdsr'   r'   r(   reset   s   zTopologyDescription.resetc                 C  s
   | j  S )z[dict of (address,
        :class:`~pymongo.server_description.ServerDescription`).
        )rC   copyr]   r'   r'   r(   r-      s   
z'TopologyDescription.server_descriptionsc                 C     | j S )zThe type of this topology.)rA   r]   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
        )rK   _fieldsrA   r]   r'   r'   r(   topology_type_name   s   z&TopologyDescription.topology_type_namec                 C  rj   )zThe replica set name.)rB   r]   r'   r'   r(   r/      rk   z$TopologyDescription.replica_set_namec                 C  rj   )z1Greatest setVersion seen from a primary, or None.)rD   r]   r'   r'   r(   r1      rk   z#TopologyDescription.max_set_versionc                 C  rj   )z1Greatest electionId seen from a primary, or None.)rE   r]   r'   r'   r(   r3      rk   z#TopologyDescription.max_election_idc                 C  rj   )z)Minimum logical session timeout, or None.)rN   r]   r'   r'   r(   r:      rk   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'   rT   r;   r'   r'   r(   
<listcomp>   rf   z5TopologyDescription.known_servers.<locals>.<listcomp>rC   rG   r]   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 r8   rr   r;   r'   r'   r(   r>      r?   z8TopologyDescription.has_known_servers.<locals>.<genexpr>)rO   rC   rG   r]   r'   r'   r(   has_known_servers   s   z%TopologyDescription.has_known_serversc                 C  rp   )zList of readable Servers.c                 S  rq   r'   )is_readabler;   r'   r'   r(   rs      rf   z8TopologyDescription.readable_servers.<locals>.<listcomp>rt   r]   r'   r'   r(   rM      rv   z$TopologyDescription.readable_serversc                 C  rj   )z0List of Servers excluding deprioritized servers.)rH   r]   r'   r'   r(   candidate_servers   rk   z%TopologyDescription.candidate_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@   r8   )rW   r;   r'   r'   r(   r>     s    z:TopologyDescription.common_wire_version.<locals>.<genexpr>N)ru   rP   rQ   serversr'   r'   r(   common_wire_version  s   z'TopologyDescription.common_wire_versionc                 C     | j jS r8   )rI   heartbeat_frequencyr]   r'   r'   r(   r~   
     z'TopologyDescription.heartbeat_frequencyc                 C  r}   r8   )rI   _srv_max_hostsr]   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(   rs     s
    z>TopologyDescription._apply_local_threshold.<locals>.<listcomp>)r-   r   rY   r   appendrP   rI   local_threshold_ms)rQ   r   round_trip_timesserverconfig_err_msgr'   r   r(   _apply_local_threshold  s   

z*TopologyDescription._apply_local_thresholdNdeprioritized_servers!Optional[list[ServerDescription]]c                   sB   |s| j | _dS dd |D   fdd| j D }|p| j | _dS )zBFilter out deprioritized servers from a list of server candidates.c                 S  s   h | ]}|j qS r'   rY   )r<   sdr'   r'   r(   	<setcomp>+  s    z6TopologyDescription._filter_servers.<locals>.<setcomp>c                   s   g | ]	}|j  vr|qS r'   r   )r<   r   deprioritized_addressesr'   r(   rs   ,  s
    
z7TopologyDescription._filter_servers.<locals>.<listcomp>N)ru   rH   )rQ   r   filteredr'   r   r(   _filter_servers$  s   
z#TopologyDescription._filter_servers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 |rK|  |}|rI|jrI|gS g S | | | jtjkrt|tu r| jD ]}|jtjkrt|g}|rp||}|  S q_|r|D ]}|jtjkr|g}|r||}|  S qyg S t| }	| jtjkr||	}	|	s|r| d t| }	||	}	|du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
        rU   r   zF%s requires min wire version %d, but topology's min wire version is %dN)getattrr|   rU   r   
isinstancer   selection_hookr,   rK   r!   r   r"   ru   r-   getrT   r   r   typer   rH   server_typer   	RSPrimaryr   from_topology_descriptionr    with_server_descriptionsr   )
rQ   r   rY   r   r   	common_wvdescriptionr   rg   r   r'   r'   r(   apply_selector3  s^   








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_preferencerO   r   )rQ   r   r'   r'   r(   has_readable_server  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   PRIMARYr]   r'   r'   r(   has_writable_server  s   z'TopologyDescription.has_writable_serverc                 C  s0   t | j dd d}d| jj| jj| j|S )Nc                 S  rj   r8   r   )r   r'   r'   r(   <lambda>  s    z.TopologyDescription.__repr__.<locals>.<lambda>)keyz-<{} id: {}, topology_type: {}, servers: {!r}>)	sortedrC   rG   format	__class__r#   rI   _topology_idrn   rz   r'   r'   r(   __repr__  s   zTopologyDescription.__repr__)r,   r   r-   r.   r/   r0   r1   r2   r3   r4   r5   r   r6   r7   )r6   r7   )rY   r   r6   r_   )rY   r   r6   r+   )r6   r+   )r6   r.   )r6   r   )r6   rl   )r6   r0   )r6   r2   )r6   r4   )r6   ro   )r6   r_   )r   r   r6   ro   r8   )r   r   r6   r7   )NNN)
r   r   rY   r   r   r   r   r   r6   ro   )r   r   r6   r_   ) r#   r$   r%   rR   rL   r^   r`   rd   rh   r-   propertyr,   rn   r/   r1   r3   r:   ru   rw   rM   ry   r|   r~   r   r   r   r   r   r   r   r   r   r'   r'   r'   r(   r+   ?   sX    

3
/
	



O

r+   topology_descriptionserver_descriptionr   r6   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 '{}')errorrS   )#rY   r,   r/   r1   r3   r   r-   rK   r   r   r   ra   r+   rI   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   rY   r,   set_namer1   r3   r   rg   r   r'   r'   r(   rb     s   

	









rb   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keysrF   r   r   r   r   r   rP   r   r+   r/   r1   r3   rI   )r   r   rg   rY   	new_hostsn_to_addr'   r'   r(   )_updated_topology_description_srv_polling  s4   	

r   rg   +MutableMapping[_Address, ServerDescription]r/   r0   r1   r2   r3   r4   <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 r8   r   r<   ir'   r'   r(   r>   t       z*_update_rs_from_primary.<locals>.<genexpr>c                 s  r   r8   r   r   r'   r'   r(   r>   u  r   z6primary marked stale due to discovery of newer primary)r/   r   rY   r   rW   set_versionelection_idra   r   tuplerG   r   r   r   	all_hostsr   r   )rg   r/   r   r1   r3   new_election_tuplemax_election_tuplenew_election_safemax_election_safer   new_addressaddrr'   r'   r(   r   F  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   rY   mer   )rg   r/   r   r'   r'   r(   r     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)rK   r   r/   r   rY   r   r   r   )rg   r/   r   r,   rY   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.
    )rG   r   r   r   rK   r   r   )rg   r=   r'   r'   r(   r     s
   
r   N)r   r+   r   r   r6   r+   )r   r+   r   r   r6   r+   )rg   r   r/   r0   r   r   r1   r2   r3   r4   r6   r   )rg   r   r/   r0   r   r   r6   r   )rg   r   r/   r0   r   r   r6   r   )rg   r   r6   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   rangerK   r!   r    r*   r&   _ServerSelectorr+   r   r   r   r   r   r   r   r   rb   r   r   r   r   r   r'   r'   r'   r(   <module>   s@   (	  m


h
+
X
 