Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 035574d

Browse files
committed
Added Py_UseClassExceptionsFlag, the variable containing the state of
the -X command line option. Py_Initialize(): Handle the two phase initialization of the built-in module. Py_Finalize(): Handle the two phase finalization of the built-in module. parse_syntax_error(): New function which parses syntax errors that PyErr_Print() will catch. This correctly parses such errors regardless of whether PyExc_SyntaxError is an old-style string exception or new-fangled class exception. PyErr_Print(): Many changes: 1. Normalize the exception. 2. Handle SystemExit exceptions which might be class based. Digs the exit code out of the "code" attribute. String based SystemExit is handled the same as before. 3. Handle SyntaxError exceptions which might be class based. Digs the various information bits out of the instance's attributes (see parse_syntax_error() for details). String based SyntaxError still works too. 4. Don't write the `:' after the exception if the exception is class based and has an empty string str() value.
1 parent d5a0ff9 commit 035574d

1 file changed

Lines changed: 106 additions & 5 deletions

File tree

Python/pythonrun.c

Lines changed: 106 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ static void call_ll_exitfuncs Py_PROTO((void));
7575
int Py_DebugFlag; /* Needed by parser.c */
7676
int Py_VerboseFlag; /* Needed by import.c */
7777
int Py_InteractiveFlag; /* Needed by Py_FdIsInteractive() below */
78+
int Py_UseClassExceptionsFlag; /* Needed by bltinmodule.c */
7879

7980
static int initialized = 0;
8081

@@ -127,7 +128,7 @@ Py_Initialize()
127128
if (interp->modules == NULL)
128129
Py_FatalError("Py_Initialize: can't make modules dictionary");
129130

130-
bimod = _PyBuiltin_Init();
131+
bimod = _PyBuiltin_Init_1();
131132
if (bimod == NULL)
132133
Py_FatalError("Py_Initialize: can't initialize __builtin__");
133134
interp->builtins = PyModule_GetDict(bimod);
@@ -144,6 +145,9 @@ Py_Initialize()
144145
PyDict_SetItemString(interp->sysdict, "modules",
145146
interp->modules);
146147

148+
/* phase 2 of builtins */
149+
_PyBuiltin_Init_2(interp->builtins);
150+
147151
_PyImport_Init();
148152

149153
initsigs(); /* Signal handling stuff, including initintr() */
@@ -178,6 +182,12 @@ Py_Finalize()
178182
if (initialized < 0)
179183
Py_FatalError("Py_Finalize: not initialized");
180184

185+
/* We must call this before the current thread gets removed because
186+
it decrefs class instances, which in turn save and restore the
187+
current error state, which is a per thread data structure.
188+
*/
189+
_PyBuiltin_Fini_1();
190+
181191
tstate = PyThreadState_Get();
182192
interp = tstate->interp;
183193

@@ -188,7 +198,13 @@ Py_Finalize()
188198

189199
finisigs();
190200
_PyImport_Fini();
191-
_PyBuiltin_Fini();
201+
202+
/* Now we decref the exception classes. After this point nothing
203+
can raise an exception. That's okay, because each Fini() method
204+
below has been checked to make sure no exceptions are ever
205+
raised.
206+
*/
207+
_PyBuiltin_Fini_2();
192208
PyMethod_Fini();
193209
PyFrame_Fini();
194210
PyCFunction_Fini();
@@ -522,19 +538,99 @@ PyRun_SimpleString(command)
522538
return 0;
523539
}
524540

541+
static int
542+
parse_syntax_error(err, message, filename, lineno, offset, text)
543+
PyObject* err;
544+
PyObject** message;
545+
char** filename;
546+
int* lineno;
547+
int* offset;
548+
char** text;
549+
{
550+
long hold;
551+
PyObject *v;
552+
553+
/* old style errors */
554+
if (PyTuple_Check(err))
555+
return PyArg_Parse(err, "(O(ziiz))", message, filename,
556+
lineno, offset, text);
557+
558+
/* new style errors. `err' is an instance */
559+
560+
if (! (v = PyObject_GetAttrString(err, "msg")))
561+
goto finally;
562+
*message = v;
563+
564+
if (!(v = PyObject_GetAttrString(err, "filename")))
565+
goto finally;
566+
if (v == Py_None)
567+
*filename = NULL;
568+
else if (! (*filename = PyString_AsString(v)))
569+
goto finally;
570+
571+
Py_DECREF(v);
572+
if (!(v = PyObject_GetAttrString(err, "lineno")))
573+
goto finally;
574+
hold = PyInt_AsLong(v);
575+
Py_DECREF(v);
576+
v = NULL;
577+
if (hold < 0 && PyErr_Occurred())
578+
goto finally;
579+
*lineno = (int)hold;
580+
581+
if (!(v = PyObject_GetAttrString(err, "offset")))
582+
goto finally;
583+
hold = PyInt_AsLong(v);
584+
Py_DECREF(v);
585+
v = NULL;
586+
if (hold < 0 && PyErr_Occurred())
587+
goto finally;
588+
*offset = (int)hold;
589+
590+
if (!(v = PyObject_GetAttrString(err, "text")))
591+
goto finally;
592+
if (v == Py_None)
593+
*text = NULL;
594+
else if (! (*text = PyString_AsString(v)))
595+
goto finally;
596+
Py_DECREF(v);
597+
return 1;
598+
599+
finally:
600+
Py_XDECREF(v);
601+
return 0;
602+
}
603+
525604
void
526605
PyErr_Print()
527606
{
528607
int err = 0;
529608
PyObject *exception, *v, *tb, *f;
530609
PyErr_Fetch(&exception, &v, &tb);
610+
PyErr_NormalizeException(&exception, &v, &tb);
611+
531612
if (exception == NULL)
532613
return;
614+
533615
if (PyErr_GivenExceptionMatches(exception, PyExc_SystemExit)) {
534616
err = Py_FlushLine();
535617
fflush(stdout);
536618
if (v == NULL || v == Py_None)
537619
Py_Exit(0);
620+
if (PyInstance_Check(v)) {
621+
/* we expect the error code to be store in the
622+
`code' attribute
623+
*/
624+
PyObject *code = PyObject_GetAttrString(v, "code");
625+
if (code) {
626+
Py_DECREF(v);
627+
v = code;
628+
}
629+
/* if we failed to dig out the "code" attribute,
630+
then just let the else clause below print the
631+
error
632+
*/
633+
}
538634
if (PyInt_Check(v))
539635
Py_Exit((int)PyInt_AsLong(v));
540636
else {
@@ -561,8 +657,8 @@ PyErr_Print()
561657
PyObject *message;
562658
char *filename, *text;
563659
int lineno, offset;
564-
if (!PyArg_Parse(v, "(O(ziiz))", &message,
565-
&filename, &lineno, &offset, &text))
660+
if (!parse_syntax_error(v, &message, &filename,
661+
&lineno, &offset, &text))
566662
PyErr_Clear();
567663
else {
568664
char buf[10];
@@ -630,7 +726,12 @@ PyErr_Print()
630726
err = PyFile_WriteObject(exception, f, Py_PRINT_RAW);
631727
if (err == 0) {
632728
if (v != NULL && v != Py_None) {
633-
err = PyFile_WriteString(": ", f);
729+
PyObject *s = PyObject_Str(v);
730+
/* only print colon if the str() of the
731+
object is not the empty string
732+
*/
733+
if (s && strcmp(PyString_AsString(s), ""))
734+
err = PyFile_WriteString(": ", f);
634735
if (err == 0)
635736
err = PyFile_WriteObject(v, f, Py_PRINT_RAW);
636737
}

0 commit comments

Comments
 (0)