Skip to content

Commit 5cdc09f

Browse files
committed
Avoid using sys.exc_info
In Python 3 it's better to handle exception objects directly, they now carry their traceback.
1 parent c0f794a commit 5cdc09f

File tree

6 files changed

+40
-48
lines changed

6 files changed

+40
-48
lines changed

src/execnet/gateway.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
import inspect
66
import linecache
77
import os
8-
import sys
98
import textwrap
109
import types
1110

@@ -56,10 +55,9 @@ def exit(self):
5655
self._send(Message.GATEWAY_TERMINATE)
5756
self._trace("--> io.close_write")
5857
self._io.close_write()
59-
except (ValueError, EOFError, OSError):
60-
v = sys.exc_info()[1]
58+
except (ValueError, EOFError, OSError) as exc:
6159
self._trace("io-error: could not send termination sequence")
62-
self._trace(" exception: %r" % v)
60+
self._trace(" exception: %r" % exc)
6361

6462
def reconfigure(self, py2str_as_py3str=True, py3str_as_py2str=False):
6563
"""

src/execnet/gateway_base.py

Lines changed: 27 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@ def get(self, timeout=None):
283283
try:
284284
return self._result
285285
except AttributeError:
286-
raise self._excinfo[1].with_traceback(self._excinfo[2])
286+
raise self._exc
287287

288288
def waitfinish(self, timeout=None):
289289
if not self._result_ready.wait(timeout):
@@ -294,10 +294,8 @@ def run(self):
294294
try:
295295
try:
296296
self._result = func(*args, **kwargs)
297-
except BaseException:
298-
# sys may be already None when shutting down the interpreter
299-
if sys is not None:
300-
self._excinfo = sys.exc_info()
297+
except BaseException as exc:
298+
self._exc = exc
301299
finally:
302300
self._result_ready.set()
303301
self.running = False
@@ -437,10 +435,9 @@ def trace(*msg):
437435
line = " ".join(map(str, msg))
438436
debugfile.write(line + "\n")
439437
debugfile.flush()
440-
except Exception:
438+
except Exception as exc:
441439
try:
442-
v = sys.exc_info()[1]
443-
sys.stderr.write(f"[{pid}] exception during tracing: {v!r}\n")
440+
sys.stderr.write(f"[{pid}] exception during tracing: {exc!r}\n")
444441
except Exception:
445442
pass # nothing we can do, likely interpreter-shutdown
446443

@@ -507,8 +504,7 @@ def from_io(io):
507504
header = io.read(9) # type 1, channel 4, payload 4
508505
if not header:
509506
raise EOFError("empty read")
510-
except EOFError:
511-
e = sys.exc_info()[1]
507+
except EOFError as e:
512508
raise EOFError("couldn't load message header, " + e.args[0])
513509
msgtype, channel, payload = struct.unpack("!bii", header)
514510
return Message(msgtype, channel, io.read(payload))
@@ -594,14 +590,20 @@ class GatewayReceivedTerminate(Exception):
594590
"""Receiverthread got termination message."""
595591

596592

597-
def geterrortext(excinfo, format_exception=traceback.format_exception, sysex=sysex):
593+
def geterrortext(
594+
exc: BaseException,
595+
format_exception=traceback.format_exception,
596+
sysex=sysex,
597+
) -> str:
598598
try:
599-
l = format_exception(*excinfo) # noqa:E741
599+
# In py310, can change this to:
600+
# l = format_exception(exc)
601+
l = format_exception(type(exc), exc, exc.__traceback__)
600602
errortext = "".join(l)
601603
except sysex:
602604
raise
603605
except BaseException:
604-
errortext = f"{excinfo[0].__name__}: {excinfo[1]}"
606+
errortext = f"{type(exc).__name__}: {exc}"
605607
return errortext
606608

607609

@@ -937,10 +939,9 @@ def _local_receive(self, id, data):
937939
try:
938940
data = loads_internal(data, channel, strconfig)
939941
callback(data) # even if channel may be already closed
940-
except Exception:
941-
excinfo = sys.exc_info()
942-
self.gateway._trace("exception during callback: %s" % excinfo[1])
943-
errortext = self.gateway._geterrortext(excinfo)
942+
except Exception as exc:
943+
self.gateway._trace("exception during callback: %s" % exc)
944+
errortext = self.gateway._geterrortext(exc)
944945
self.gateway._send(
945946
Message.CHANNEL_CLOSE_ERROR, id, dumps_internal(errortext)
946947
)
@@ -1017,7 +1018,6 @@ def readline(self):
10171018

10181019

10191020
class BaseGateway:
1020-
exc_info = sys.exc_info
10211021
_sysex = sysex
10221022
id = "<worker>"
10231023

@@ -1054,11 +1054,11 @@ def log(*msg):
10541054
del msg
10551055
except (KeyboardInterrupt, GatewayReceivedTerminate):
10561056
pass
1057-
except EOFError:
1057+
except EOFError as exc:
10581058
log("EOF without prior gateway termination message")
1059-
self._error = self.exc_info()[1]
1060-
except Exception:
1061-
log(self._geterrortext(self.exc_info()))
1059+
self._error = exc
1060+
except Exception as exc:
1061+
log(self._geterrortext(exc))
10621062
log("finishing receiving thread")
10631063
# wake up and terminate any execution waiting to receive
10641064
self._channelfactory._finished_receiving()
@@ -1079,8 +1079,7 @@ def _send(self, msgcode, channelid=0, data=b""):
10791079
try:
10801080
message.to_io(self._io)
10811081
self._trace("sent", message)
1082-
except (OSError, ValueError):
1083-
e = sys.exc_info()[1]
1082+
except (OSError, ValueError) as e:
10841083
self._trace("failed to send", message, e)
10851084
# ValueError might be because the IO is already closed
10861085
raise OSError("cannot send (already closed?)")
@@ -1166,12 +1165,11 @@ def executetask(self, item):
11661165
except KeyboardInterrupt:
11671166
channel.close(INTERRUPT_TEXT)
11681167
raise
1169-
except BaseException:
1170-
excinfo = self.exc_info()
1171-
if not isinstance(excinfo[1], EOFError):
1168+
except BaseException as exc:
1169+
if not isinstance(exc, EOFError):
11721170
if not channel.gateway._channelfactory.finished:
1173-
self._trace(f"got exception: {excinfo[1]!r}")
1174-
errortext = self._geterrortext(excinfo)
1171+
self._trace(f"got exception: {exc!r}")
1172+
errortext = self._geterrortext(exc)
11751173
channel.close(errortext)
11761174
return
11771175
self._trace("ignoring EOFError because receiving finished")

src/execnet/gateway_socket.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,6 @@ def create_io(spec, group, execmodel):
8484
io.remoteaddress = "%s:%d" % (host, port)
8585
try:
8686
sock.connect((host, port))
87-
except execmodel.socket.gaierror:
88-
raise HostNotFound(str(sys.exc_info()[1]))
87+
except execmodel.socket.gaierror as e:
88+
raise HostNotFound() from e
8989
return io

src/execnet/multi.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
(c) 2008-2014, Holger Krekel and others
55
"""
66
import atexit
7-
import sys
87
from functools import partial
98
from threading import Lock
109

@@ -285,11 +284,11 @@ def waitclose(self):
285284
for ch in self._channels:
286285
try:
287286
ch.waitclose()
288-
except ch.RemoteError:
287+
except ch.RemoteError as exc:
289288
if first is None:
290-
first = sys.exc_info()
289+
first = exc
291290
if first:
292-
raise first[1].with_traceback(first[2])
291+
raise first
293292

294293

295294
def safe_terminate(execmodel, timeout, list_of_paired_functions):

src/execnet/script/socketserver.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,14 +94,13 @@ def startserver(serversock, loop=False):
9494
exec_from_one_connection(serversock)
9595
except (KeyboardInterrupt, SystemExit):
9696
raise
97-
except BaseException:
97+
except BaseException as exc:
9898
if debug:
9999
import traceback
100100

101101
traceback.print_exc()
102102
else:
103-
excinfo = sys.exc_info()
104-
print_("got exception", excinfo[1])
103+
print_("got exception", exc)
105104
os.chdir(execute_path)
106105
if not loop:
107106
break

testing/test_basics.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -229,16 +229,14 @@ def test_geterrortext(checker):
229229
out = checker.run_check(
230230
inspect.getsource(gateway_base)
231231
+ """
232-
class Arg:
232+
class Arg(Exception):
233233
pass
234-
errortext = geterrortext((Arg, "1", 4))
234+
errortext = geterrortext(Arg())
235235
assert "Arg" in errortext
236-
import sys
237236
try:
238237
raise ValueError("17")
239-
except ValueError:
240-
excinfo = sys.exc_info()
241-
s = geterrortext(excinfo)
238+
except ValueError as exc:
239+
s = geterrortext(exc)
242240
assert "17" in s
243241
print ("all passed")
244242
"""

0 commit comments

Comments
 (0)