diff --git a/Lib/test/test_exceptions.py b/Lib/test/test_exceptions.py index 59f77f91d85e5c..482edd3c92efd6 100644 --- a/Lib/test/test_exceptions.py +++ b/Lib/test/test_exceptions.py @@ -20,6 +20,7 @@ from test.support.os_helper import TESTFN, unlink from test.support.warnings_helper import check_warnings from test import support +import timeit try: import _testcapi @@ -2002,6 +2003,14 @@ def blech(self): # Note: name suggestion tests live in `test_traceback`. +class ImportErrorBenchmark(unittest.TestCase): + def test_benchmark(self): + stmt = "repr(ImportError('Cannot import some_missing_module', name='some_missing_module', path='/this/is/a/fake/path/that/is/quite/long/and/descriptive'))" + + iterations = 1_000_000 + total_time = timeit.timeit(stmt, number=iterations) + + print(f"Total time for creating ImportError: {total_time:.10f} seconds") class ImportErrorTests(unittest.TestCase): diff --git a/Objects/exceptions.c b/Objects/exceptions.c index c41a8a0b37037f..a573ae7176cda7 100644 --- a/Objects/exceptions.c +++ b/Objects/exceptions.c @@ -1868,54 +1868,80 @@ static PyObject * ImportError_repr(PyObject *self) { int hasargs = PyTuple_GET_SIZE(((PyBaseExceptionObject *)self)->args) != 0; - PyImportErrorObject *exc = PyImportErrorObject_CAST(self); - PyUnicodeWriter *writer = PyUnicodeWriter_Create(0); - if (writer == NULL) { - goto error; - } PyObject *r = BaseException_repr(self); - if (r == NULL) { - goto error; - } - if (PyUnicodeWriter_WriteSubstring( - writer, r, 0, PyUnicode_GET_LENGTH(r) - 1) < 0) - { - Py_XDECREF(r); - goto error; - } - Py_XDECREF(r); - if (exc->name) { - if (hasargs) { - if (PyUnicodeWriter_WriteASCII(writer, ", ", 2) < 0) { - goto error; - } - } - if (PyUnicodeWriter_Format(writer, "name=%R", exc->name) < 0) { - goto error; + PyImportErrorObject *exc = PyImportErrorObject_CAST(self); + + if (r && (exc->name || exc->path)) { + /* remove ')' */ + Py_SETREF(r, PyUnicode_Substring(r, 0, PyUnicode_GET_LENGTH(r) - 1)); + if (r && exc->name) { + Py_SETREF(r, PyUnicode_FromFormat("%U%sname=%R", + r, hasargs ? ", " : "", exc->name)); + hasargs = 1; } - hasargs = 1; - } - if (exc->path) { - if (hasargs) { - if (PyUnicodeWriter_WriteASCII(writer, ", ", 2) < 0) { - goto error; - } + if (r && exc->path) { + Py_SETREF(r, PyUnicode_FromFormat("%U%spath=%R", + r, hasargs ? ", " : "", exc->path)); } - if (PyUnicodeWriter_Format(writer, "path=%R", exc->path) < 0) { - goto error; + if (r) { + Py_SETREF(r, PyUnicode_FromFormat("%U)", r)); } } - - if (PyUnicodeWriter_WriteChar(writer, ')') < 0) { - goto error; - } - - return PyUnicodeWriter_Finish(writer); - -error: - PyUnicodeWriter_Discard(writer); - return NULL; -} + return r; +} + +// static PyObject * +// ImportError_repr(PyObject *self) +// { +// int hasargs = PyTuple_GET_SIZE(((PyBaseExceptionObject *)self)->args) != 0; +// PyImportErrorObject *exc = PyImportErrorObject_CAST(self); +// PyUnicodeWriter *writer = PyUnicodeWriter_Create(0); +// if (writer == NULL) { +// goto error; +// } +// PyObject *r = BaseException_repr(self); +// if (r == NULL) { +// goto error; +// } +// if (PyUnicodeWriter_WriteSubstring( +// writer, r, 0, PyUnicode_GET_LENGTH(r) - 1) < 0) +// { +// Py_XDECREF(r); +// goto error; +// } +// Py_XDECREF(r); +// if (exc->name) { +// if (hasargs) { +// if (PyUnicodeWriter_WriteASCII(writer, ", ", 2) < 0) { +// goto error; +// } +// } +// if (PyUnicodeWriter_Format(writer, "name=%R", exc->name) < 0) { +// goto error; +// } +// hasargs = 1; +// } +// if (exc->path) { +// if (hasargs) { +// if (PyUnicodeWriter_WriteASCII(writer, ", ", 2) < 0) { +// goto error; +// } +// } +// if (PyUnicodeWriter_Format(writer, "path=%R", exc->path) < 0) { +// goto error; +// } +// } + +// if (PyUnicodeWriter_WriteChar(writer, ')') < 0) { +// goto error; +// } + +// return PyUnicodeWriter_Finish(writer); + +// error: +// PyUnicodeWriter_Discard(writer); +// return NULL; +// } static PyMemberDef ImportError_members[] = { {"msg", _Py_T_OBJECT, offsetof(PyImportErrorObject, msg), 0,