Handle exit exceptions in connect

This commit is contained in:
Richard Bann 2019-06-18 08:38:46 +02:00
parent bc65c636ae
commit bf01bbcfca
2 changed files with 31 additions and 1 deletions

View File

@ -1395,7 +1395,15 @@ exit:
PyObject *ptype = NULL, *pvalue = NULL, *ptb = NULL; PyObject *ptype = NULL, *pvalue = NULL, *ptb = NULL;
PyErr_Fetch(&ptype, &pvalue, &ptb); PyErr_Fetch(&ptype, &pvalue, &ptb);
obscure_password(self); obscure_password(self);
PyErr_Restore(ptype, pvalue, ptb); // if we got a system exit exception (not a subclass of Exception),
// leave it as is, do not restore
if (PyErr_Occurred() && ! PyErr_ExceptionMatches(PyExc_Exception)) {
Py_XDECREF(ptype);
Py_XDECREF(pvalue);
Py_XDECREF(ptb);
} else {
PyErr_Restore(ptype, pvalue, ptb);
}
} }
return rv; return rv;
} }

View File

@ -35,6 +35,8 @@ import subprocess as sp
from collections import deque from collections import deque
from operator import attrgetter from operator import attrgetter
from weakref import ref from weakref import ref
import multiprocessing
import signal
import psycopg2 import psycopg2
import psycopg2.extras import psycopg2.extras
@ -408,6 +410,26 @@ t.join()
finally: finally:
shutil.rmtree(dir, ignore_errors=True) shutil.rmtree(dir, ignore_errors=True)
@slow
def test_handles_keyboardinterrupt(self):
def conn(queue):
host = "10.255.255.1" # will timeout
queue.put(1)
try:
self.connect(host=host, password="x", connect_timeout=1)
except KeyboardInterrupt:
queue.put("KeyboardInterrupt")
except psycopg2.OperationalError:
queue.put("OperationalError")
queue = multiprocessing.Queue()
process = multiprocessing.Process(target=conn, args=(queue,))
process.start()
queue.get()
os.kill(process.pid, signal.SIGINT)
process.join()
self.assertEqual(queue.get(), "KeyboardInterrupt")
class ParseDsnTestCase(ConnectingTestCase): class ParseDsnTestCase(ConnectingTestCase):
def test_parse_dsn(self): def test_parse_dsn(self):