Skip to content

Commit 9f8ad3e

Browse files
author
richard.jones
committed
Conversion of exceptions over from faked-up classes to new-style C types.
git-svn-id: http://svn.python.org/projects/python/trunk@46456 6015fed2-1504-0410-9fe1-9d1591cc4771
1 parent 705a9ad commit 9f8ad3e

16 files changed

Lines changed: 2316 additions & 2163 deletions

File tree

Doc/tut/tut.tex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2711,7 +2711,7 @@ \section{The \function{dir()} Function \label{dir}}
27112711
'FloatingPointError', 'FutureWarning', 'IOError', 'ImportError',
27122712
'IndentationError', 'IndexError', 'KeyError', 'KeyboardInterrupt',
27132713
'LookupError', 'MemoryError', 'NameError', 'None', 'NotImplemented',
2714-
'NotImplementedError', 'OSError', 'OverflowError', 'OverflowWarning',
2714+
'NotImplementedError', 'OSError', 'OverflowError',
27152715
'PendingDeprecationWarning', 'ReferenceError', 'RuntimeError',
27162716
'RuntimeWarning', 'StandardError', 'StopIteration', 'SyntaxError',
27172717
'SyntaxWarning', 'SystemError', 'SystemExit', 'TabError', 'True',

Include/pyerrors.h

Lines changed: 66 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,72 @@
44
extern "C" {
55
#endif
66

7+
/* Error objects */
8+
9+
typedef struct {
10+
PyObject_HEAD
11+
PyObject *dict;
12+
PyObject *args;
13+
PyObject *message;
14+
} PyBaseExceptionObject;
15+
16+
typedef struct {
17+
PyObject_HEAD
18+
PyObject *dict;
19+
PyObject *args;
20+
PyObject *message;
21+
PyObject *msg;
22+
PyObject *filename;
23+
PyObject *lineno;
24+
PyObject *offset;
25+
PyObject *text;
26+
PyObject *print_file_and_line;
27+
} PySyntaxErrorObject;
28+
29+
#ifdef Py_USING_UNICODE
30+
typedef struct {
31+
PyObject_HEAD
32+
PyObject *dict;
33+
PyObject *args;
34+
PyObject *message;
35+
PyObject *encoding;
36+
PyObject *object;
37+
PyObject *start;
38+
PyObject *end;
39+
PyObject *reason;
40+
} PyUnicodeErrorObject;
41+
#endif
42+
43+
typedef struct {
44+
PyObject_HEAD
45+
PyObject *dict;
46+
PyObject *args;
47+
PyObject *message;
48+
PyObject *code;
49+
} PySystemExitObject;
50+
51+
typedef struct {
52+
PyObject_HEAD
53+
PyObject *dict;
54+
PyObject *args;
55+
PyObject *message;
56+
PyObject *myerrno;
57+
PyObject *strerror;
58+
PyObject *filename;
59+
} PyEnvironmentErrorObject;
60+
61+
#ifdef MS_WINDOWS
62+
typedef struct {
63+
PyObject_HEAD
64+
PyObject *dict;
65+
PyObject *args;
66+
PyObject *message;
67+
PyObject *myerrno;
68+
PyObject *strerror;
69+
PyObject *filename;
70+
PyObject *winerror;
71+
} PyWindowsErrorObject;
72+
#endif
773

874
/* Error handling definitions */
975

@@ -104,8 +170,6 @@ PyAPI_DATA(PyObject *) PyExc_UserWarning;
104170
PyAPI_DATA(PyObject *) PyExc_DeprecationWarning;
105171
PyAPI_DATA(PyObject *) PyExc_PendingDeprecationWarning;
106172
PyAPI_DATA(PyObject *) PyExc_SyntaxWarning;
107-
/* PyExc_OverflowWarning will go away for Python 2.5 */
108-
PyAPI_DATA(PyObject *) PyExc_OverflowWarning;
109173
PyAPI_DATA(PyObject *) PyExc_RuntimeWarning;
110174
PyAPI_DATA(PyObject *) PyExc_FutureWarning;
111175
PyAPI_DATA(PyObject *) PyExc_ImportWarning;

Lib/codeop.py

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -95,15 +95,7 @@ def _maybe_compile(compiler, source, filename, symbol):
9595

9696
if code:
9797
return code
98-
try:
99-
e1 = err1.__dict__
100-
except AttributeError:
101-
e1 = err1
102-
try:
103-
e2 = err2.__dict__
104-
except AttributeError:
105-
e2 = err2
106-
if not code1 and e1 == e2:
98+
if not code1 and repr(err1) == repr(err2):
10799
raise SyntaxError, err1
108100

109101
def _compile(source, filename, symbol):

Lib/ctypes/test/test_structures.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -294,20 +294,20 @@ class Person(Structure):
294294
# In Python 2.5, Exception is a new-style class, and the repr changed
295295
if issubclass(Exception, object):
296296
self.failUnlessEqual(msg,
297-
"(Phone) <class 'exceptions.TypeError'>: "
297+
"(Phone) <type 'exceptions.TypeError'>: "
298298
"expected string or Unicode object, int found")
299299
else:
300300
self.failUnlessEqual(msg,
301-
"(Phone) exceptions.TypeError: "
301+
"(Phone) TypeError: "
302302
"expected string or Unicode object, int found")
303303

304304
cls, msg = self.get_except(Person, "Someone", ("a", "b", "c"))
305305
self.failUnlessEqual(cls, RuntimeError)
306306
if issubclass(Exception, object):
307307
self.failUnlessEqual(msg,
308-
"(Phone) <class 'exceptions.ValueError'>: too many initializers")
308+
"(Phone) <type 'exceptions.ValueError'>: too many initializers")
309309
else:
310-
self.failUnlessEqual(msg, "(Phone) exceptions.ValueError: too many initializers")
310+
self.failUnlessEqual(msg, "(Phone) ValueError: too many initializers")
311311

312312

313313
def get_except(self, func, *args):

Lib/test/exception_hierarchy.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ BaseException
1515
| | +-- IOError
1616
| | +-- OSError
1717
| | +-- WindowsError (Windows)
18+
| | +-- VMSError (VMS)
1819
| +-- EOFError
1920
| +-- ImportError
2021
| +-- LookupError
@@ -43,5 +44,4 @@ BaseException
4344
+-- SyntaxWarning
4445
+-- UserWarning
4546
+-- FutureWarning
46-
+-- OverflowWarning [not generated by the interpreter]
4747
+-- ImportWarning

Lib/test/output/test_logging

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -488,12 +488,12 @@ INFO:a.b.c.d:Info 5
488488
-- log_test4 begin ---------------------------------------------------
489489
config0: ok.
490490
config1: ok.
491-
config2: <class 'exceptions.AttributeError'>
492-
config3: <class 'exceptions.KeyError'>
491+
config2: <type 'exceptions.AttributeError'>
492+
config3: <type 'exceptions.KeyError'>
493493
-- log_test4 end ---------------------------------------------------
494494
-- log_test5 begin ---------------------------------------------------
495495
ERROR:root:just testing
496-
<class 'exceptions.KeyError'>... Don't panic!
496+
<type 'exceptions.KeyError'>... Don't panic!
497497
-- log_test5 end ---------------------------------------------------
498498
-- logrecv output begin ---------------------------------------------------
499499
ERR -> CRITICAL: Message 0 (via logrecv.tcp.ERR)

Lib/test/test_codeccallbacks.py

Lines changed: 0 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -18,30 +18,12 @@ def handle(self, exc):
1818
self.pos = len(exc.object)
1919
return (u"<?>", oldpos)
2020

21-
# A UnicodeEncodeError object without a start attribute
22-
class NoStartUnicodeEncodeError(UnicodeEncodeError):
23-
def __init__(self):
24-
UnicodeEncodeError.__init__(self, "ascii", u"", 0, 1, "bad")
25-
del self.start
26-
2721
# A UnicodeEncodeError object with a bad start attribute
2822
class BadStartUnicodeEncodeError(UnicodeEncodeError):
2923
def __init__(self):
3024
UnicodeEncodeError.__init__(self, "ascii", u"", 0, 1, "bad")
3125
self.start = []
3226

33-
# A UnicodeEncodeError object without an end attribute
34-
class NoEndUnicodeEncodeError(UnicodeEncodeError):
35-
def __init__(self):
36-
UnicodeEncodeError.__init__(self, "ascii", u"", 0, 1, "bad")
37-
del self.end
38-
39-
# A UnicodeEncodeError object without an object attribute
40-
class NoObjectUnicodeEncodeError(UnicodeEncodeError):
41-
def __init__(self):
42-
UnicodeEncodeError.__init__(self, "ascii", u"", 0, 1, "bad")
43-
del self.object
44-
4527
# A UnicodeEncodeError object with a bad object attribute
4628
class BadObjectUnicodeEncodeError(UnicodeEncodeError):
4729
def __init__(self):
@@ -477,56 +459,16 @@ def test_badandgoodreplaceexceptions(self):
477459
codecs.replace_errors,
478460
UnicodeError("ouch")
479461
)
480-
self.assertRaises(
481-
AttributeError,
482-
codecs.replace_errors,
483-
NoStartUnicodeEncodeError()
484-
)
485-
self.assertRaises(
486-
TypeError,
487-
codecs.replace_errors,
488-
BadStartUnicodeEncodeError()
489-
)
490-
self.assertRaises(
491-
AttributeError,
492-
codecs.replace_errors,
493-
NoEndUnicodeEncodeError()
494-
)
495-
self.assertRaises(
496-
AttributeError,
497-
codecs.replace_errors,
498-
NoObjectUnicodeEncodeError()
499-
)
500462
self.assertRaises(
501463
TypeError,
502464
codecs.replace_errors,
503465
BadObjectUnicodeEncodeError()
504466
)
505-
self.assertRaises(
506-
AttributeError,
507-
codecs.replace_errors,
508-
NoEndUnicodeDecodeError()
509-
)
510467
self.assertRaises(
511468
TypeError,
512469
codecs.replace_errors,
513470
BadObjectUnicodeDecodeError()
514471
)
515-
self.assertRaises(
516-
AttributeError,
517-
codecs.replace_errors,
518-
NoStartUnicodeTranslateError()
519-
)
520-
self.assertRaises(
521-
AttributeError,
522-
codecs.replace_errors,
523-
NoEndUnicodeTranslateError()
524-
)
525-
self.assertRaises(
526-
AttributeError,
527-
codecs.replace_errors,
528-
NoObjectUnicodeTranslateError()
529-
)
530472
# With the correct exception, "replace" returns an "?" or u"\ufffd" replacement
531473
self.assertEquals(
532474
codecs.replace_errors(UnicodeEncodeError("ascii", u"\u3042", 0, 1, "ouch")),
@@ -565,21 +507,6 @@ def test_badandgoodxmlcharrefreplaceexceptions(self):
565507
codecs.xmlcharrefreplace_errors,
566508
UnicodeTranslateError(u"\u3042", 0, 1, "ouch")
567509
)
568-
self.assertRaises(
569-
AttributeError,
570-
codecs.xmlcharrefreplace_errors,
571-
NoStartUnicodeEncodeError()
572-
)
573-
self.assertRaises(
574-
AttributeError,
575-
codecs.xmlcharrefreplace_errors,
576-
NoEndUnicodeEncodeError()
577-
)
578-
self.assertRaises(
579-
AttributeError,
580-
codecs.xmlcharrefreplace_errors,
581-
NoObjectUnicodeEncodeError()
582-
)
583510
# Use the correct exception
584511
cs = (0, 1, 9, 10, 99, 100, 999, 1000, 9999, 10000, 0x3042)
585512
s = "".join(unichr(c) for c in cs)

Lib/test/test_exceptions.py

Lines changed: 85 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -81,14 +81,6 @@ def r(thing):
8181
except NameError: pass
8282

8383
r(OverflowError)
84-
# XXX
85-
# Obscure: in 2.2 and 2.3, this test relied on changing OverflowWarning
86-
# into an error, in order to trigger OverflowError. In 2.4, OverflowWarning
87-
# should no longer be generated, so the focus of the test shifts to showing
88-
# that OverflowError *isn't* generated. OverflowWarning should be gone
89-
# in Python 2.5, and then the filterwarnings() call, and this comment,
90-
# should go away.
91-
warnings.filterwarnings("error", "", OverflowWarning, __name__)
9284
x = 1
9385
for dummy in range(128):
9486
x += x # this simply shouldn't blow up
@@ -206,3 +198,88 @@ def test_capi2():
206198
test_capi2()
207199

208200
unlink(TESTFN)
201+
202+
# test that exception attributes are happy.
203+
try: str(u'Hello \u00E1')
204+
except Exception, e: sampleUnicodeEncodeError = e
205+
try: unicode('\xff')
206+
except Exception, e: sampleUnicodeDecodeError = e
207+
exceptionList = [
208+
( BaseException, (), { 'message' : '', 'args' : () }),
209+
( BaseException, (1, ), { 'message' : 1, 'args' : ( 1, ) }),
210+
( BaseException, ('foo', ), { 'message' : 'foo', 'args' : ( 'foo', ) }),
211+
( BaseException, ('foo', 1), { 'message' : '', 'args' : ( 'foo', 1 ) }),
212+
( SystemExit, ('foo',), { 'message' : 'foo', 'args' : ( 'foo', ),
213+
'code' : 'foo' }),
214+
( IOError, ('foo',), { 'message' : 'foo', 'args' : ( 'foo', ), }),
215+
( IOError, ('foo', 'bar'), { 'message' : '',
216+
'args' : ('foo', 'bar'), }),
217+
( IOError, ('foo', 'bar', 'baz'),
218+
{ 'message' : '', 'args' : ('foo', 'bar'), }),
219+
( EnvironmentError, ('errnoStr', 'strErrorStr', 'filenameStr'),
220+
{ 'message' : '', 'args' : ('errnoStr', 'strErrorStr'),
221+
'strerror' : 'strErrorStr',
222+
'errno' : 'errnoStr', 'filename' : 'filenameStr' }),
223+
( EnvironmentError, (1, 'strErrorStr', 'filenameStr'),
224+
{ 'message' : '', 'args' : (1, 'strErrorStr'),
225+
'strerror' : 'strErrorStr', 'errno' : 1,
226+
'filename' : 'filenameStr' }),
227+
( SyntaxError, ('msgStr',),
228+
{ 'message' : 'msgStr', 'args' : ('msgStr', ),
229+
'print_file_and_line' : None, 'msg' : 'msgStr',
230+
'filename' : None, 'lineno' : None, 'offset' : None,
231+
'text' : None }),
232+
( SyntaxError, ('msgStr', ('filenameStr', 'linenoStr', 'offsetStr',
233+
'textStr')),
234+
{ 'message' : '', 'args' : ('msgStr', ('filenameStr',
235+
'linenoStr', 'offsetStr', 'textStr' )),
236+
'print_file_and_line' : None, 'msg' : 'msgStr',
237+
'filename' : 'filenameStr', 'lineno' : 'linenoStr',
238+
'offset' : 'offsetStr', 'text' : 'textStr' }),
239+
( SyntaxError, ('msgStr', 'filenameStr', 'linenoStr', 'offsetStr',
240+
'textStr', 'print_file_and_lineStr'),
241+
{ 'message' : '', 'args' : ('msgStr', 'filenameStr',
242+
'linenoStr', 'offsetStr', 'textStr',
243+
'print_file_and_lineStr'),
244+
'print_file_and_line' : None, 'msg' : 'msgStr',
245+
'filename' : None, 'lineno' : None, 'offset' : None,
246+
'text' : None }),
247+
( UnicodeError, (),
248+
{ 'message' : '', 'args' : (), }),
249+
( sampleUnicodeEncodeError,
250+
{ 'message' : '', 'args' : ('ascii', u'Hello \xe1', 6, 7,
251+
'ordinal not in range(128)'),
252+
'encoding' : 'ascii', 'object' : u'Hello \xe1',
253+
'start' : 6, 'reason' : 'ordinal not in range(128)' }),
254+
( sampleUnicodeDecodeError,
255+
{ 'message' : '', 'args' : ('ascii', '\xff', 0, 1,
256+
'ordinal not in range(128)'),
257+
'encoding' : 'ascii', 'object' : '\xff',
258+
'start' : 0, 'reason' : 'ordinal not in range(128)' }),
259+
( UnicodeTranslateError, (u"\u3042", 0, 1, "ouch"),
260+
{ 'message' : '', 'args' : (u'\u3042', 0, 1, 'ouch'),
261+
'object' : u'\u3042', 'reason' : 'ouch',
262+
'start' : 0, 'end' : 1 }),
263+
]
264+
try:
265+
exceptionList.append(
266+
( WindowsError, (1, 'strErrorStr', 'filenameStr'),
267+
{ 'message' : '', 'args' : (1, 'strErrorStr'),
268+
'strerror' : 'strErrorStr',
269+
'errno' : 22, 'filename' : 'filenameStr',
270+
'winerror' : 1 }))
271+
except NameError: pass
272+
273+
for args in exceptionList:
274+
expected = args[-1]
275+
try:
276+
if len(args) == 2: raise args[0]
277+
else: raise apply(args[0], args[1])
278+
except BaseException, e:
279+
for checkArgName in expected.keys():
280+
if repr(getattr(e, checkArgName)) != repr(expected[checkArgName]):
281+
raise TestFailed('Checking exception arguments, exception '
282+
'"%s", attribute "%s" expected %s got %s.' %
283+
( repr(e), checkArgName,
284+
repr(expected[checkArgName]),
285+
repr(getattr(e, checkArgName)) ))

Lib/warnings.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,4 @@ def _getcategory(category):
261261

262262
# Module initialization
263263
_processoptions(sys.warnoptions)
264-
# XXX OverflowWarning should go away for Python 2.5.
265-
simplefilter("ignore", category=OverflowWarning, append=1)
266264
simplefilter("ignore", category=PendingDeprecationWarning, append=1)

Makefile.pre.in

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,6 @@ PYTHON_OBJS= \
240240
Python/asdl.o \
241241
Python/ast.o \
242242
Python/bltinmodule.o \
243-
Python/exceptions.o \
244243
Python/ceval.o \
245244
Python/compile.o \
246245
Python/codecs.o \
@@ -289,6 +288,7 @@ OBJECT_OBJS= \
289288
Objects/complexobject.o \
290289
Objects/descrobject.o \
291290
Objects/enumobject.o \
291+
Objects/exceptions.o \
292292
Objects/genobject.o \
293293
Objects/fileobject.o \
294294
Objects/floatobject.o \

0 commit comments

Comments
 (0)