o
    {g                     @  s
  d Z ddlmZ ddlZddlZddlZddlZddlZddlZddl	Z	ddl
Z
ddlmZ ddlmZmZmZmZmZmZ ddlmZmZ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$m%Z% dd
l&m'Z'm(Z(m)Z)m*Z*m+Z+ ddl,m-Z- ddl.m/Z/ ddl0m1Z1m2Z2m3Z3m4Z4m5Z5 ddl6m7Z7 ddl8m9Z9m:Z: ddl;m<Z< ddl=m>Z> ddl?m@Z@ ddlAmBZBmCZCmDZDmEZEmFZF erddlGmHZH ddlImJZJ ddlKmLZLmMZM dZNeOeePjQZRd2ddZSG dd dZTG d d! d!ZUd3d%d&ZVd4d*d+ZW	d5d6d0d1ZXdS )7z<Internal class to monitor a topology of one or more servers.    )annotationsN)Path)TYPE_CHECKINGAnyCallableMappingOptionalcast)_csotcommonhelpers_shared)ConnectionFailureInvalidOperationNetworkTimeoutNotPrimaryErrorOperationFailurePyMongoErrorServerSelectionTimeoutError
WriteError)Hello)_create_lock_Lock)_SDAM_LOGGER_SERVER_SELECTION_LOGGER
_debug_log_SDAMStatusMessage_ServerSelectionStatusMessage)PoolOptions)ServerDescription)	Selectionany_server_selectorarbiter_server_selectorsecondary_server_selectorwritable_server_selector)periodic_executor)_ServerSession_ServerSessionPool)
SrvMonitor)Pool)Server)SRV_POLLING_TOPOLOGIESTOPOLOGY_TYPETopologyDescription)_updated_topology_description_srv_pollingupdated_topology_description)ObjectId)TopologySettings)ClusterTime_AddressT	queue_ref"weakref.ReferenceType[queue.Queue]returnboolc                 C  sF   |  }|sdS 	 z|  }W n tjy   Y dS w |\}}||  q)NFT)
get_nowaitqueueEmpty)r3   qeventfnargs r>   y/var/www/bot.gig.net.ua/public_html/telegram/P1/HellBot/venv/lib/python3.10/site-packages/pymongo/synchronous/topology.pyprocess_events_queueR   s   r@   c                   @  s  e Zd ZdZdddZddd	ZdddZ			ddddZdddZ				ddd"d#Z					ddd$d%Z
		ddd'd(Z	)	)ddd/d0Z	)	)ddd1d2Zdd5d6Zdd7d8Zdd:d;Zdd<d=Zdd>d?ZddAdBZddCdDZddEdFZddHdIZddLdMZddNdOZdddSdTZddUdVZddWdXZddYdZZedd\d]Zdd_d`ZddcddZ ddfdgZ!ddidjZ"ddkdlZ#ddodpZ$ddqdrZ%ddsdtZ&ddudvZ'ddwdxZ(ddzd{Z)dd|d}Z*dd~dZ+dddZ,dddZ-dddZ.dddZ/dS )Topologyz*Monitor a topology of one or more servers.topology_settingsr0   c                   s  |j | _ |jj| _| jd uo| jj| _| jd uo| jj| _d | _d | _	| js)| jr0t
jdd| _ttjr?tt| j tjd | jrU| jd usIJ | j| jj| j ff || _t| | |jd d |}|| _ttji d d d | j}| jr| jd us~J | j| jj|| j| j ff ttjrtt| j || jtjd |jD ].}| jr| jd usJ | j| jj || j ff ttjrtt| j |d |d tj!d qt"|# | _$d| _%d| _&t' }t(|| _)| j*|| _+i | _,d | _-d | _.t/ | _0| js| jr+| jd us
J d fdd}t1j2t3j4t3j5|dd}t67| j|j8 || _	|9  d | _:| jj;d urC| jj<sEt=| | j| _:d S d S d S )Nd   )maxsize
topologyIdmessagerF   previousDescriptionnewDescriptionrG   r      )rF   
serverHost
serverPortrG   Fr5   r6   c                     s   t  S N)r@   r>   weakr>   r?   target   s   z!Topology.__init__.<locals>.targetpymongo_events_thread)intervalmin_intervalrQ   name)r5   r6   )>_topology_id_pool_options_event_listeners
_listenersenabled_for_server_publish_serverenabled_for_topology_publish_tp_events_Topology__events_executorr8   Queuer   isEnabledForloggingDEBUGr   r   START_TOPOLOGYputpublish_topology_opened	_settingsr,   get_topology_typeget_server_descriptionsreplica_set_name_descriptionr+   Unknown$publish_topology_description_changedTOPOLOGY_CHANGEseedspublish_server_openedSTART_SERVERlistserver_descriptions_seed_addresses_opened_closedr   r   _lockcondition_class
_condition_servers_pid_max_cluster_timer&   _session_poolr$   PeriodicExecutorr   EVENTS_QUEUE_FREQUENCYMIN_HEARTBEAT_INTERVALweakrefrefcloseopen_srv_monitorfqdnload_balancedr'   )selfrB   topology_description
initial_tdseedrw   rQ   executorr>   rO   r?   __init__f   s   
	
	

zTopology.__init__r5   Nonec                 C  s   t  }| jdu r|| _nH|| jkrU|| _tjdd dkr$dtfi}nddi}tj	di | | j | j	
 D ]}|  q:| j  W d   n1 sPw   Y  | j |   W d   dS 1 shw   Y  dS )	a  Start monitoring, or restart after a fork.

        No effect if called multiple times.

        .. warning:: Topology is shared among multiple threads and is protected
          by mutual exclusion. Using Topology from a process other than the one
          that initialized it will emit a warning and may result in deadlock. To
          prevent this from happening, MongoClient must be created after any
          forking.

        N   )      skip_file_prefixes
stacklevel   MongoClient opened before fork. May not be entirely fork-safe, proceed with caution. See PyMongo's documentation for details: https://www.mongodb.com/docs/languages/python/pymongo-driver/current/faq/#is-pymongo-fork-safe-)r   )osgetpidr{   sysversion_info_pymongo_dirwarningswarnrw   rz   valuesr   r}   reset_ensure_opened)r   pidkwargsserverr>   r>   r?   r      s*   



"zTopology.openfloatc                 C  s   t  }|d u r| jjS |S rN   )r
   	remainingrg   server_selection_timeout)r   timeoutr>   r>   r?   get_server_selection_timeout   s   z%Topology.get_server_selection_timeoutNselector Callable[[Selection], Selection]	operationstrr   Optional[float]addressOptional[_Address]operation_idOptional[int]list[Server]c                   sd   |du r	   }n|} j  |||||} fdd|D W  d   S 1 s+w   Y  dS )a  Return a list of Servers matching selector, or time out.

        :param selector: function that takes a list of Servers and returns
            a subset of them.
        :param operation: The name of the operation that the server is being selected for.
        :param server_selection_timeout: maximum seconds to wait.
            If not provided, the default value common.SERVER_SELECTION_TIMEOUT
            is used.
        :param address: optional server address to select.

        Calls self.open() if needed.

        Raises exc:`ServerSelectionTimeoutError` after
        `server_selection_timeout` if no matching servers are found.
        Nc                   s   g | ]}t t |jqS r>   )r	   r)   get_server_by_addressr   .0sdr   r>   r?   
<listcomp>  s    z+Topology.select_servers.<locals>.<listcomp>)r   rw   _select_servers_loop)r   r   r   r   r   r   server_timeoutrs   r>   r   r?   select_servers   s   


$zTopology.select_serversr   list[ServerDescription]c           
      C  sL  t  }|| }d}ttjr tttj|||| j	| j	j
jd | jj||| jjd}	|	s|dks5||kr_ttjrOtttj|||| j	| j	j
j| |d t| | d| d| j	|sztttj|||| j	| j	j
jt|t   d d	}|   |   | jtj | j  t  }| jj||| jjd}	|	r-| j  |	S )
z7select_servers() guts. Hold the lock when calling this.F)rG   r   r   operationIdtopologyDescriptionclientId)custom_selectorr   )rG   r   r   r   r   r   failurez, Timeout: zs, Topology Description: )rG   r   r   r   r   r   remainingTimeMST)time	monotonicr   ra   rb   rc   r   r   STARTEDdescription_topology_settingsrV   rk   apply_selectorrg   server_selectorFAILED_error_messager   WAITINGintr   _request_check_allry   waitr   r   check_compatible)
r   r   r   r   r   r   nowend_timelogged_waitingrs   r>   r>   r?   r   #  sn   	






-zTopology._select_servers_loopdeprioritized_serversOptional[list[Server]]r)   c           
      C  sX   |  |||||}t||}t|dkr|d S t|d\}}	|jj|	jjkr*|S |	S )NrK   r   r   )r   _filter_serverslenrandomsamplepooloperation_count)
r   r   r   r   r   r   r   serversserver1server2r>   r>   r?   _select_servero  s   	

zTopology._select_serverc                 C  sp   | j ||||||d}t rt|jj ttj	r6t
ttj|||| j| jjj|jjd |jjd d	 |S )zALike select_servers, but choose a random server if several match.r   r   rK   )rG   r   r   r   r   r   rL   rM   )r   r
   get_timeoutset_rttr   min_round_trip_timer   ra   rb   rc   r   r   	SUCCEEDEDr   rV   r   )r   r   r   r   r   r   r   r   r>   r>   r?   select_server  s.   


zTopology.select_serverr2   c                 C  s   | j t||||dS )a=  Return a Server for "address", reconnecting if necessary.

        If the server's type is not known, request an immediate check of all
        servers. Time out after "server_selection_timeout" if the server
        cannot be reached.

        :param address: A (host, port) pair.
        :param operation: The name of the operation that the server is being selected for.
        :param server_selection_timeout: maximum seconds to wait.
            If not provided, the default value
            common.SERVER_SELECTION_TIMEOUT is used.
        :param operation_id: The unique id of the current operation being performed. Defaults to None if not provided.

        Calls self.open() if needed.

        Raises exc:`ServerSelectionTimeoutError` after
        `server_selection_timeout` if no matching servers are found.
        r   )r   r    )r   r   r   r   r   r>   r>   r?   select_server_by_address  s   z!Topology.select_server_by_addressFserver_descriptionr   
reset_poolr6   interrupt_connectionsc           	      C  sr  | j }|j|j }t||rdS t| j |}|js"|jr0|jtj	kr0| j
|j}|r0|j  ||k}| jrP|sP| jdus@J | j| jj|||j| jff || _ |   | |j | jrx|sx| jdusiJ | j| jj|| j | jff ttjr|stt| j|| j tjd | j r|jtj!kr| j jt"vr| j #  |r| j
|j}|r|jj$|d | j%&  dS )ziProcess a new ServerDescription on an opened topology.

        Hold the lock when calling this.
        NrH   )r   )'rk   _server_descriptionsr   _is_stale_server_descriptionr.   is_readableis_server_type_knowntopology_typer+   Singlerz   getr   readyr[   r^   re   rY   "publish_server_description_changedrV   _update_servers_receive_cluster_time_no_lockcluster_timer]   rm   r   ra   rb   rc   r   r   rn   r   rl   r*   r   r   ry   
notify_all)	r   r   r   r   td_oldsd_oldnew_tdr   suppress_eventr>   r>   r?   _process_change  s^   





zTopology._process_changec                 C  sn   | j * | jr| j|jr%| ||| W d   dS W d   dS W d   dS 1 s0w   Y  dS )z>Process a new ServerDescription after an hello call completes.N)rw   ru   rk   
has_serverr   r   )r   r   r   r   r>   r>   r?   	on_change  s   			"zTopology.on_changeseedlistlist[tuple[str, Any]]c                 C  s   | j }|jtvr
dS t| j || _ |   | jr.| jdusJ | j| jj	|| j | j
ff ttjrBtt| j
|| j tjd dS dS )z_Process a new seedlist on an opened topology.
        Hold the lock when calling this.
        NrH   )rk   r   r*   r-   r   r]   r^   re   rY   rm   rV   r   ra   rb   rc   r   r   rn   )r   r   r   r>   r>   r?   _process_srv_update%  s*   

zTopology._process_srv_updatec                 C  sL   | j  | jr| | W d   dS W d   dS 1 sw   Y  dS )z?Process a new list of nodes obtained from scanning SRV records.N)rw   ru   r   )r   r   r>   r>   r?   on_srv_updateA  s   "zTopology.on_srv_updateOptional[Server]c                 C     | j |S )aJ  Get a Server or None.

        Returns the current version of the server immediately, even if it's
        Unknown or absent from the topology. Only use this in unittests.
        In driver code, use select_server_by_address, since then you're
        assured a recent view of the server's type and wire protocol version.
        )rz   r   r   r   r>   r>   r?   r   H  s   zTopology.get_server_by_addressc                 C  s
   || j v S rN   )rz   r  r>   r>   r?   r   R  s   
zTopology.has_serverc                 C  s`   | j # | jj}|tjkr	 W d   dS t|  d jW  d   S 1 s)w   Y  dS )z!Return primary's address or None.Nr   )rw   rk   r   r+   ReplicaSetWithPrimaryr#   _new_selectionr   )r   r   r>   r>   r?   get_primaryU  s   
$zTopology.get_primaryset[_Address]c                 C  sp   | j + | jj}|tjtjfvrt W  d   S dd t||  D W  d   S 1 s1w   Y  dS )z+Return set of replica set member addresses.Nc                 S  s   h | ]}|j qS r>   )r   r   r>   r>   r?   	<setcomp>j  s    z4Topology._get_replica_set_members.<locals>.<setcomp>)	rw   rk   r   r+   r  ReplicaSetNoPrimarysetiterr  )r   r   r   r>   r>   r?   _get_replica_set_members_  s   $z!Topology._get_replica_set_membersc                 C  
   |  tS )z"Return set of secondary addresses.)r  r"   r   r>   r>   r?   get_secondariesl     
zTopology.get_secondariesc                 C  r  )z Return set of arbiter addresses.)r  r!   r   r>   r>   r?   get_arbitersp  r  zTopology.get_arbitersOptional[ClusterTime]c                 C     | j S )z1Return a document, the highest seen $clusterTime.r|   r   r>   r>   r?   max_cluster_timet     zTopology.max_cluster_timer   Optional[Mapping[str, Any]]c                 C  s.   |r| j r|d | j d kr|| _ d S d S d S )NclusterTimer  r   r   r>   r>   r?   r   x  s   
z&Topology._receive_cluster_time_no_lockc                 C  s6   | j  | | W d    d S 1 sw   Y  d S rN   )rw   r   r  r>   r>   r?   receive_cluster_time  s   "zTopology.receive_cluster_time   	wait_timer   c                 C  s@   | j  |   | j| W d   dS 1 sw   Y  dS )z=Wake all monitors, wait for at least one to check its server.N)rw   r   ry   r   )r   r  r>   r>   r?   request_check_all  s   "zTopology.request_check_allc                 C  s   | j jtjkr| j jS | j jS )z~Return a list of all data-bearing servers.

        This includes any server that might be selected for an operation.
        )rk   r   r+   r   known_serversreadable_serversr   r>   r>   r?   data_bearing_servers  s   zTopology.data_bearing_serversc                 C  s   g }| j   |  D ]}| j|j }|||jj f q
W d    n1 s(w   Y  |D ])\}}z|j| W q/ t	yX } zt
|d|dd }| |jj|  d }~ww d S )Nr   F)rw   r  rz   r   appendr   genget_overallremove_stale_socketsr   _ErrorContexthandle_errorr   )r   r   r   r   
generationexcctxr>   r>   r?   update_pool  s"   zTopology.update_poolc                 C  sz  | j B | j}| j D ]}|  q| j | _| j  D ]\}}|| jv r/|| j| _q | j	r8| j	  d| _
d| _W d   n1 sHw   Y  | jr| jdusWJ ttji | jj| jj| jj| jj| _| j| jj|| j| jff | j| jj| jff ttjrtt| j|| jtj d tt| jtj!d | j"s| jr| j#  | j#$d t%t&'| j dS dS )zClear pools and terminate monitors. Topology does not reopen on
        demand. Any further operations will raise
        :exc:`~.errors.InvalidOperation`.
        FTNrH   rE   rK   )(rw   rk   rz   r   r   r   rs   itemsr   r   ru   rv   r]   r^   r,   r+   rl   rj   max_set_versionmax_election_idr   re   rY   rm   rV   publish_topology_closedr   ra   rb   rc   r   r   rn   STOP_TOPOLOGYr[   r_   joinr@   r   r   )r   old_tdr   r   r   r>   r>   r?   r     sb   





zTopology.closer,   c                 C  r  rN   )rk   r   r>   r>   r?   r     r  zTopology.descriptionlist[_ServerSession]c                 C  s
   | j  S )z"Pop all session ids from the pool.)r}   pop_allr   r>   r>   r?   pop_all_sessions  r  zTopology.pop_all_sessionssession_timeout_minutesr%   c                 C  r  )z>Start or resume a server session, or raise ConfigurationError.)r}   get_server_session)r   r4  r>   r>   r?   r5    s   zTopology.get_server_sessionserver_sessionc                 C  s   | j | d S rN   )r}   return_server_session)r   r6  r>   r>   r?   r7    s   zTopology.return_server_sessionr   c                 C  s   t | jS )zmA Selection object, initially including all known servers.

        Hold the lock when calling this.
        )r   from_topology_descriptionrk   r   r>   r>   r?   r    s   zTopology._new_selectionc              	   C  s   | j rtd| js@d| _|   | js| jr| j  | jr*| j	j
tv r*| j  | jjr@| t| jd td| jdd | j D ]}|  qEdS )z[Start monitors, or restart after a fork.

        Hold the lock when calling this.
        z"Cannot use MongoClient after closeTr   rK      )ok	serviceIdmaxWireVersionN)rv   r   ru   r   r]   r[   r_   r   r   r   r   r*   rg   r   r   r   rt   r   rV   rz   r   r   r   r>   r>   r?   r      s&   


zTopology._ensure_openederr_ctxr$  c                 C  sp   | j |}|d u rdS |j|j|jrdS |jj}|j}d }|r3t	|dr3t
|jtr3|jd}t||S )NTdetailstopologyVersion)rz   r   _poolstale_generationsock_generation
service_idr   topology_versionerrorhasattr
isinstancer?  dict _is_stale_error_topology_version)r   r   r>  r   cur_tvrF  error_tvr>   r>   r?   _is_stale_error!  s   
zTopology._is_stale_errorc           	      C  sb  |  ||rd S | j| }|j}|j}| jjr|s|jsd S t|tr(|jr(d S t|t	r/d S t|t
tfrt|dr?|j}nt|t
rFdnd }|jd|}|tjv rx|tjv }| jjsf| t||d |sm|jdkrr|| |  d S |js| jjs| t||d || d S d S t|tr| jjs| t||d || |j  d S d S )Ncodei{'  rF     )rM  rz   rF  rD  rg   r   completed_handshakerH  r   r   r   r   rG  rN  r?  r   r   _NOT_PRIMARY_CODES_SHUTDOWN_CODESr   r   max_wire_versionr   request_checkr   _monitorcancel_check)	r   r   r>  r   rF  rD  err_codedefaultis_shutting_downr>   r>   r?   _handle_error5  sD   


	




zTopology._handle_errorc                 C  s8   | j  | || W d   dS 1 sw   Y  dS )zHandle an application error.

        May reset the server to Unknown, clear the pool, and request an
        immediate check depending on the error and the context.
        N)rw   r[  )r   r   r>  r>   r>   r?   r%  w  s   "zTopology.handle_errorc                 C  s   | j  D ]}|  qdS )z3Wake all monitors. Hold the lock when calling this.N)rz   r   rU  r=  r>   r>   r?   r     s   
zTopology._request_check_allc              	   C  s  | j   D ]\\}}|| jvrG| jj|| | || jd}d}| jr.| jdur.t	
| j}t|| ||| j| j|d}|| j|< |  q| j| jj}|| j| _||jkrc| j| j|j qt| j D ]\}}| j |s|  | j| qkdS )zrSync our Servers from TopologyDescription.server_descriptions.

        Hold the lock while calling this.
        )r   topologyr   rB   N)r   r   monitortopology_id	listenersevents)rk   rs   r*  rz   rg   monitor_class_create_pool_for_monitorr[   r^   r   r   r)   _create_pool_for_serverrV   rY   r   r   is_writabler   update_is_writablerr   r   r   pop)r   r   r   r]  rP   r   was_writabler>   r>   r?   r     s@   

	

zTopology._update_serversr(   c                 C  s   | j j|| j j| jdS )N)	client_id)rg   
pool_classpool_optionsrV   r  r>   r>   r?   rc    s   z Topology._create_pool_for_serverc                 C  sH   | j j}t|j|j|j|j|j|j|jd|j	d	}| j j
||d| jdS )NF)	connect_timeoutsocket_timeoutssl_contexttls_allow_invalid_hostnamesevent_listenersappnamedriverpause_enabled
server_api)	handshakerh  )rg   rj  r   rk  _ssl_contextrn  rX   rp  rq  rs  ri  rV   )r   r   optionsmonitor_pool_optionsr>   r>   r?   rb    s   
z!Topology._create_pool_for_monitorc                   s  | j jtjtjfv }|rd}n| j jtjkrd}nd}| j jr4|tu r+|r'dS d| S d| d| dS t| j 	 }t| j 	 
 }|sT|rPd	|| jjS d
| S |d j t fdd|dd D }|r du rrd| S |rt|| jsd| S t S ddd |D S )zeFormat an error message if server selection fails.

        Hold the lock when calling this.
        zreplica set membersmongosesr   zNo primary available for writeszNo %s available for writeszNo z match selector ""z)No {} available for replica set name "{}"zNo %s availabler   c                 3  s    | ]}|j  kV  qd S rN   rO  r   r   rO  r>   r?   	<genexpr>  s    z*Topology._error_message.<locals>.<genexpr>rK   NzNo %s found yetz\Could not reach any servers in %s. Replica set is configured with internal hostnames or IPs?,c                 s  s     | ]}|j rt|j V  qd S rN   )rF  r   rz  r>   r>   r?   r{    s    )rk   r   r+   r  r	  Shardedr  r#   rr   rs   r   formatrg   rj   rF  allr
  intersectionrt   r   r/  )r   r   is_replica_setserver_plural	addressesr   samer>   rO  r?   r     sH   
zTopology._error_messagec                 C  s*   d}| j sd}d| jj d| | jdS )N zCLOSED < >)ru   	__class____name__rk   )r   msgr>   r>   r?   __repr__  s   zTopology.__repr__>tuple[tuple[_Address, ...], Optional[str], Optional[str], str]c                 C  s"   | j }tt|j|j|j|jfS )z?The properties to use for MongoClient/Topology equality checks.)rg   tuplesortedro   rj   r   srv_service_name)r   tsr>   r>   r?   eq_props
  s   zTopology.eq_propsotherobjectc                 C  s    t || jr|  | kS tS rN   )rH  r  r  NotImplemented)r   r  r>   r>   r?   __eq__  s   zTopology.__eq__c                 C  s   t |  S rN   )hashr  r   r>   r>   r?   __hash__  s   zTopology.__hash__)rB   r0   )r5   r   )r5   r   )NNN)r   r   r   r   r   r   r   r   r   r   r5   r   )r   r   r   r   r   r   r   r   r   r   r5   r   )NNNN)r   r   r   r   r   r   r   r   r   r   r   r   r5   r)   )NN)
r   r2   r   r   r   r   r   r   r5   r)   )FF)r   r   r   r6   r   r6   r5   r   )r   r   r5   r   )r   r2   r5   r  )r   r2   r5   r6   )r5   r   )r   r   r5   r  )r5   r  )r5   r  )r   r  r5   r   )r  )r  r   r5   r   )r5   r   )r5   r,   )r5   r1  )r4  r   r5   r%   )r6  r%   r5   r   )r5   r   )r   r2   r>  r$  r5   r6   )r   r2   r>  r$  r5   r   )r   r2   r5   r(   )r   r   r5   r   )r5   r   )r5   r  )r  r  r5   r6   )r5   r   )0r  
__module____qualname____doc__r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r  r  r  r   r  r  r  r)  r   propertyr   r3  r5  r7  r  r   rM  r[  r%  r   r   rc  rb  r   r  r  r  r  r>   r>   r>   r?   rA   c   s~    

h
)
%P&$M














	
?





!

B
	

*


:

rA   c                   @  s   e Zd ZdZdddZdS )r$  z.An error with context for SDAM error handling.rF  BaseExceptionrT  r   rC  rQ  r6   rD  Optional[ObjectId]c                 C  s"   || _ || _|| _|| _|| _d S rN   )rF  rT  rC  rQ  rD  )r   rF  rT  rC  rQ  rD  r>   r>   r?   r     s
   
z_ErrorContext.__init__N)
rF  r  rT  r   rC  r   rQ  r6   rD  r  )r  r  r  r  r   r>   r>   r>   r?   r$    s    r$  
current_tvr  rL  c                 C  s8   | du s|du r
dS | d |d krdS | d |d kS )z9Return True if the error's topologyVersion is <= current.NF	processIdcounterr>   )r  rL  r>   r>   r?   rJ  *  s
   rJ  
current_sdr   new_sdc                 C  sF   | j |j }}|du s|du rdS |d |d krdS |d |d kS )z4Return True if the new topologyVersion is < current.NFr  r  )rE  )r  r  r  new_tvr>   r>   r?   r   5  s   r   
candidatesr   r   r   c                   s"    s| S  fdd| D }|p| S )zBFilter out deprioritized servers from a list of server candidates.c                   s   g | ]}| vr|qS r>   r>   rz  r   r>   r?   r   F  s    z#_filter_servers.<locals>.<listcomp>r>   )r  r   filteredr>   r  r?   r   ?  s   r   )r3   r4   r5   r6   )r  r  rL  r  r5   r6   )r  r   r  r   r5   r6   rN   )r  r   r   r   r5   r   )Yr  
__future__r   rb   r   r8   r   r   r   r   r   pathlibr   typingr   r   r   r   r   r	   pymongor
   r   r   pymongo.errorsr   r   r   r   r   r   r   r   pymongo.hellor   pymongo.lockr   r   pymongo.loggerr   r   r   r   r   pymongo.pool_optionsr   pymongo.server_descriptionr   pymongo.server_selectorsr   r    r!   r"   r#   pymongo.synchronousr$   "pymongo.synchronous.client_sessionr%   r&   pymongo.synchronous.monitorr'   pymongo.synchronous.poolr(   pymongo.synchronous.serverr)   pymongo.topology_descriptionr*   r+   r,   r-   r.   bsonr/   pymongo.synchronous.settingsr0   pymongo.typingsr1   r2   _IS_SYNCr   __file__parentr   r@   rA   r$  rJ  r   r   r>   r>   r>   r?   <module>   s\    (

       <

