Skip to content

Commit 44e0374

Browse files
committed
Improved printing of Python exceptions in PL/Python
Mimic the Python interpreter's own logic for printing exceptions instead of just using the straight str() call, so that you get plpy.SPIError instead of <class 'plpy.SPIError'> and for built-in exceptions merely UnicodeEncodeError Besides looking better this cuts down on the endless version differences in the regression test expected files.
1 parent 2edc31c commit 44e0374

File tree

7 files changed

+46
-208
lines changed

7 files changed

+46
-208
lines changed

src/pl/plpython/expected/README

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,8 @@
11
Guide to alternative expected files:
22

3-
plpython_error_2.out Python 2.2, 2.3, 2.4
4-
plpython_error.out Python 2.5, 2.6
5-
63
plpython_unicode.out any version, when server encoding != SQL_ASCII and client encoding = UTF8; else ...
74
plpython_unicode_0.out any version, when server encoding != SQL_ASCII and client encoding != UTF8; else ...
85
plpython_unicode_2.out Python 2.2
9-
plpython_unicode_3.out Python 2.3, 2.4
10-
plpython_unicode_5.out Python 2.5, 2.6
6+
plpython_unicode_3.out Python 2.3, 2.4, 2.5, 2.6
117

128
plpython_types_3.out Python 3.1

src/pl/plpython/expected/plpython_error.out

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ CREATE FUNCTION sql_syntax_error() RETURNS text
88
'plpy.execute("syntax error")'
99
LANGUAGE plpythonu;
1010
SELECT sql_syntax_error();
11-
WARNING: PL/Python: <class 'plpy.SPIError'>: unrecognized error in PLy_spi_execute_query
11+
WARNING: PL/Python: plpy.SPIError: unrecognized error in PLy_spi_execute_query
1212
CONTEXT: PL/Python function "sql_syntax_error"
1313
ERROR: syntax error at or near "syntax"
1414
LINE 1: syntax error
@@ -23,7 +23,7 @@ CREATE FUNCTION exception_index_invalid(text) RETURNS text
2323
LANGUAGE plpythonu;
2424
SELECT exception_index_invalid('test');
2525
ERROR: PL/Python: PL/Python function "exception_index_invalid" failed
26-
DETAIL: <type 'exceptions.IndexError'>: list index out of range
26+
DETAIL: IndexError: list index out of range
2727
CONTEXT: PL/Python function "exception_index_invalid"
2828
/* check handling of nested exceptions
2929
*/
@@ -33,7 +33,7 @@ CREATE FUNCTION exception_index_invalid_nested() RETURNS text
3333
return rv[0]'
3434
LANGUAGE plpythonu;
3535
SELECT exception_index_invalid_nested();
36-
WARNING: PL/Python: <class 'plpy.SPIError'>: unrecognized error in PLy_spi_execute_query
36+
WARNING: PL/Python: plpy.SPIError: unrecognized error in PLy_spi_execute_query
3737
CONTEXT: PL/Python function "exception_index_invalid_nested"
3838
ERROR: function test5(unknown) does not exist
3939
LINE 1: SELECT test5('foo')
@@ -55,7 +55,7 @@ return None
5555
'
5656
LANGUAGE plpythonu;
5757
SELECT invalid_type_uncaught('rick');
58-
WARNING: PL/Python: <class 'plpy.SPIError'>: unrecognized error in PLy_spi_prepare
58+
WARNING: PL/Python: plpy.SPIError: unrecognized error in PLy_spi_prepare
5959
CONTEXT: PL/Python function "invalid_type_uncaught"
6060
ERROR: type "test" does not exist
6161
CONTEXT: PL/Python function "invalid_type_uncaught"
@@ -78,7 +78,7 @@ return None
7878
'
7979
LANGUAGE plpythonu;
8080
SELECT invalid_type_caught('rick');
81-
WARNING: PL/Python: <class 'plpy.SPIError'>: unrecognized error in PLy_spi_prepare
81+
WARNING: PL/Python: plpy.SPIError: unrecognized error in PLy_spi_prepare
8282
CONTEXT: PL/Python function "invalid_type_caught"
8383
ERROR: type "test" does not exist
8484
CONTEXT: PL/Python function "invalid_type_caught"
@@ -100,7 +100,7 @@ return None
100100
'
101101
LANGUAGE plpythonu;
102102
SELECT invalid_type_reraised('rick');
103-
WARNING: PL/Python: <class 'plpy.SPIError'>: unrecognized error in PLy_spi_prepare
103+
WARNING: PL/Python: plpy.SPIError: unrecognized error in PLy_spi_prepare
104104
CONTEXT: PL/Python function "invalid_type_reraised"
105105
ERROR: type "test" does not exist
106106
CONTEXT: PL/Python function "invalid_type_reraised"

src/pl/plpython/expected/plpython_error_2.out

Lines changed: 0 additions & 124 deletions
This file was deleted.

src/pl/plpython/expected/plpython_unicode_2.out

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,12 @@ return rv[0]["testvalue"]
2525
' LANGUAGE plpythonu;
2626
SELECT unicode_return();
2727
ERROR: PL/Python: could not convert Python Unicode object to PostgreSQL server encoding
28-
DETAIL: exceptions.UnicodeError: ASCII encoding error: ordinal not in range(128)
28+
DETAIL: UnicodeError: ASCII encoding error: ordinal not in range(128)
2929
CONTEXT: while creating return value
3030
PL/Python function "unicode_return"
3131
INSERT INTO unicode_test (testvalue) VALUES ('test');
3232
ERROR: PL/Python: could not convert Python Unicode object to PostgreSQL server encoding
33-
DETAIL: exceptions.UnicodeError: ASCII encoding error: ordinal not in range(128)
33+
DETAIL: UnicodeError: ASCII encoding error: ordinal not in range(128)
3434
CONTEXT: while modifying trigger row
3535
PL/Python function "unicode_trigger"
3636
SELECT * FROM unicode_test;
@@ -42,7 +42,7 @@ SELECT unicode_plan1();
4242
WARNING: PL/Python: plpy.Error: unrecognized error in PLy_spi_execute_plan
4343
CONTEXT: PL/Python function "unicode_plan1"
4444
ERROR: PL/Python: could not convert Python Unicode object to PostgreSQL server encoding
45-
DETAIL: exceptions.UnicodeError: ASCII encoding error: ordinal not in range(128)
45+
DETAIL: UnicodeError: ASCII encoding error: ordinal not in range(128)
4646
CONTEXT: PL/Python function "unicode_plan1"
4747
SELECT unicode_plan2();
4848
unicode_plan2

src/pl/plpython/expected/plpython_unicode_3.out

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,12 @@ return rv[0]["testvalue"]
2525
' LANGUAGE plpythonu;
2626
SELECT unicode_return();
2727
ERROR: PL/Python: could not convert Python Unicode object to PostgreSQL server encoding
28-
DETAIL: exceptions.UnicodeEncodeError: 'ascii' codec can't encode character u'\x80' in position 0: ordinal not in range(128)
28+
DETAIL: UnicodeEncodeError: 'ascii' codec can't encode character u'\x80' in position 0: ordinal not in range(128)
2929
CONTEXT: while creating return value
3030
PL/Python function "unicode_return"
3131
INSERT INTO unicode_test (testvalue) VALUES ('test');
3232
ERROR: PL/Python: could not convert Python Unicode object to PostgreSQL server encoding
33-
DETAIL: exceptions.UnicodeEncodeError: 'ascii' codec can't encode character u'\x80' in position 0: ordinal not in range(128)
33+
DETAIL: UnicodeEncodeError: 'ascii' codec can't encode character u'\x80' in position 0: ordinal not in range(128)
3434
CONTEXT: while modifying trigger row
3535
PL/Python function "unicode_trigger"
3636
SELECT * FROM unicode_test;
@@ -42,7 +42,7 @@ SELECT unicode_plan1();
4242
WARNING: PL/Python: plpy.Error: unrecognized error in PLy_spi_execute_plan
4343
CONTEXT: PL/Python function "unicode_plan1"
4444
ERROR: PL/Python: could not convert Python Unicode object to PostgreSQL server encoding
45-
DETAIL: exceptions.UnicodeEncodeError: 'ascii' codec can't encode character u'\x80' in position 0: ordinal not in range(128)
45+
DETAIL: UnicodeEncodeError: 'ascii' codec can't encode character u'\x80' in position 0: ordinal not in range(128)
4646
CONTEXT: PL/Python function "unicode_plan1"
4747
SELECT unicode_plan2();
4848
unicode_plan2

src/pl/plpython/expected/plpython_unicode_5.out

Lines changed: 0 additions & 52 deletions
This file was deleted.

src/pl/plpython/plpython.c

Lines changed: 33 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/**********************************************************************
22
* plpython.c - python as a procedural language for PostgreSQL
33
*
4-
* $PostgreSQL: pgsql/src/pl/plpython/plpython.c,v 1.134 2009/12/15 22:59:54 petere Exp $
4+
* $PostgreSQL: pgsql/src/pl/plpython/plpython.c,v 1.135 2010/01/16 11:03:51 petere Exp $
55
*
66
*********************************************************************
77
*/
@@ -3453,10 +3453,12 @@ PLy_traceback(int *xlevel)
34533453
PyObject *e,
34543454
*v,
34553455
*tb;
3456-
PyObject *eob,
3457-
*vob = NULL;
3458-
char *vstr,
3459-
*estr;
3456+
PyObject *e_type_o;
3457+
PyObject *e_module_o;
3458+
char *e_type_s = NULL;
3459+
char *e_module_s = NULL;
3460+
PyObject *vob = NULL;
3461+
char *vstr;
34603462
StringInfoData xstr;
34613463

34623464
/*
@@ -3476,23 +3478,39 @@ PLy_traceback(int *xlevel)
34763478
PyErr_NormalizeException(&e, &v, &tb);
34773479
Py_XDECREF(tb);
34783480

3479-
eob = PyObject_Str(e);
3481+
e_type_o = PyObject_GetAttrString(e, "__name__");
3482+
e_module_o = PyObject_GetAttrString(e, "__module__");
3483+
if (e_type_o)
3484+
e_type_s = PyString_AsString(e_type_o);
3485+
if (e_type_s)
3486+
e_module_s = PyString_AsString(e_module_o);
3487+
34803488
if (v && ((vob = PyObject_Str(v)) != NULL))
34813489
vstr = PyString_AsString(vob);
34823490
else
34833491
vstr = "unknown";
34843492

3485-
/*
3486-
* I'm not sure what to do if eob is NULL here -- we can't call PLy_elog
3487-
* because that function calls us, so we could end up with infinite
3488-
* recursion. I'm not even sure if eob could be NULL here -- would an
3489-
* Assert() be more appropriate?
3490-
*/
3491-
estr = eob ? PyString_AsString(eob) : "unrecognized exception";
34923493
initStringInfo(&xstr);
3493-
appendStringInfo(&xstr, "%s: %s", estr, vstr);
3494+
if (!e_type_s || !e_module_s)
3495+
{
3496+
if (PyString_Check(e))
3497+
/* deprecated string exceptions */
3498+
appendStringInfoString(&xstr, PyString_AsString(e));
3499+
else
3500+
/* shouldn't happen */
3501+
appendStringInfoString(&xstr, "unrecognized exception");
3502+
}
3503+
/* mimics behavior of traceback.format_exception_only */
3504+
else if (strcmp(e_module_s, "builtins") == 0
3505+
|| strcmp(e_module_s, "__main__") == 0
3506+
|| strcmp(e_module_s, "exceptions") == 0)
3507+
appendStringInfo(&xstr, "%s", e_type_s);
3508+
else
3509+
appendStringInfo(&xstr, "%s.%s", e_module_s, e_type_s);
3510+
appendStringInfo(&xstr, ": %s", vstr);
34943511

3495-
Py_DECREF(eob);
3512+
Py_XDECREF(e_type_o);
3513+
Py_XDECREF(e_module_o);
34963514
Py_XDECREF(vob);
34973515
Py_XDECREF(v);
34983516

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy