@@ -763,32 +763,40 @@ def command(
763
763
unacknowledged = write_concern and not write_concern .acknowledged
764
764
if self .op_msg_enabled :
765
765
self ._raise_if_not_writable (unacknowledged )
766
+ args = (
767
+ self ,
768
+ dbname ,
769
+ spec ,
770
+ self .is_mongos ,
771
+ read_preference ,
772
+ codec_options ,
773
+ session ,
774
+ client ,
775
+ check ,
776
+ allowable_errors ,
777
+ self .address ,
778
+ listeners ,
779
+ self .max_bson_size ,
780
+ read_concern ,
781
+ )
782
+ kwargs = dict (
783
+ parse_write_concern_error = parse_write_concern_error ,
784
+ collation = collation ,
785
+ compression_ctx = self .compression_context ,
786
+ use_op_msg = self .op_msg_enabled ,
787
+ unacknowledged = unacknowledged ,
788
+ user_fields = user_fields ,
789
+ exhaust_allowed = exhaust_allowed ,
790
+ write_concern = write_concern ,
791
+ )
766
792
try :
767
- return command (
768
- self ,
769
- dbname ,
770
- spec ,
771
- self .is_mongos ,
772
- read_preference ,
773
- codec_options ,
774
- session ,
775
- client ,
776
- check ,
777
- allowable_errors ,
778
- self .address ,
779
- listeners ,
780
- self .max_bson_size ,
781
- read_concern ,
782
- parse_write_concern_error = parse_write_concern_error ,
783
- collation = collation ,
784
- compression_ctx = self .compression_context ,
785
- use_op_msg = self .op_msg_enabled ,
786
- unacknowledged = unacknowledged ,
787
- user_fields = user_fields ,
788
- exhaust_allowed = exhaust_allowed ,
789
- write_concern = write_concern ,
790
- )
791
- except (OperationFailure , NotPrimaryError ):
793
+ return command (* args , ** kwargs )
794
+ except OperationFailure as exc :
795
+ if exc .code == helpers ._REAUTHENTICATION_REQUIRED_CODE :
796
+ self .authenticate (True )
797
+ return command (* args , ** kwargs )
798
+ raise
799
+ except NotPrimaryError :
792
800
raise
793
801
# Catch socket.error, KeyboardInterrupt, etc. and close ourselves.
794
802
except BaseException as error :
@@ -864,7 +872,12 @@ def authenticate(self, reauthenticate=False):
864
872
"""
865
873
# CMAP spec says to publish the ready event only after authenticating
866
874
# the connection.
867
- if not self .ready or reauthenticate :
875
+ if reauthenticate :
876
+ self .ready = False
877
+ if self .performed_handshake :
878
+ # Existing auth_ctx is stale, remove it.
879
+ self .auth_ctx = None
880
+ if not self .ready :
868
881
creds = self .opts ._credentials
869
882
if creds :
870
883
auth .authenticate (creds , self , reauthenticate = reauthenticate )
@@ -927,12 +940,6 @@ def idle_time_seconds(self):
927
940
"""Seconds since this socket was last checked into its pool."""
928
941
return time .monotonic () - self .last_checkin_time
929
942
930
- def handle_reauthenticate (self ):
931
- """Handle a reauthentication."""
932
- if self .performed_handshake :
933
- # Existing auth_ctx is stale, remove it.
934
- self .auth_ctx = None
935
-
936
943
def _raise_connection_failure (self , error ):
937
944
# Catch *all* exceptions from socket methods and close the socket. In
938
945
# regular Python, socket operations only raise socket.error, even if
0 commit comments