Skip to content

Commit 9225336

Browse files
authored
Handle case when HTTPConnection socket is wrapped with pyopenssl (patroni#3425)
It happens when `pyopenssl` is installed, because `python-etcd` module enforces its usage. In this case we need to use `WrappedSocket.socket` to shutdown and close connection. Not doing so results in an error: ```python TypeError('WrappedSocket.shutdown() takes 1 positional argument but 2 were given') ``` Close patroni#3420
1 parent 3a4ace2 commit 9225336

File tree

1 file changed

+9
-4
lines changed

1 file changed

+9
-4
lines changed

patroni/dcs/etcd3.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -583,16 +583,21 @@ def run(self) -> None:
583583
time.sleep(1)
584584

585585
def kill_stream(self) -> None:
586-
sock = None
586+
conn_sock: Any = None
587587
with self._response_lock:
588588
if isinstance(self._response, urllib3.response.HTTPResponse):
589589
try:
590-
sock = self._response.connection.sock if self._response.connection else None
590+
conn_sock = self._response.connection.sock if self._response.connection else None
591591
except Exception:
592-
sock = None
592+
conn_sock = None
593593
else:
594594
self._response = False
595-
if sock:
595+
if conn_sock:
596+
# python-etcd forces usage of pyopenssl if the last one is available.
597+
# In this case HTTPConnection.socket is not inherited from socket.socket, but urllib3 uses custom
598+
# class `WrappedSocket`, which shutdown() method could be incompatible with socket.shutdown().
599+
# Therefore we use WrappedSocket.socket, which points to original `socket` object.
600+
sock: socket.socket = conn_sock.socket if conn_sock.__class__.__name__ == 'WrappedSocket' else conn_sock
596601
try:
597602
sock.shutdown(socket.SHUT_RDWR)
598603
sock.close()

0 commit comments

Comments
 (0)