PEP 352 implementation. Creates a new base class, BaseException, which has an
added message attribute compared to the previous version of Exception. It is also a new-style class, making all exceptions now new-style. KeyboardInterrupt and SystemExit inherit from BaseException directly. String exceptions now raise DeprecationWarning. Applies patch 1104669, and closes bugs 1012952 and 518846.
This commit is contained in:
parent
762467475d
commit
bf36409e2a
|
@ -26,9 +26,32 @@ PyAPI_FUNC(int) PyErr_GivenExceptionMatches(PyObject *, PyObject *);
|
||||||
PyAPI_FUNC(int) PyErr_ExceptionMatches(PyObject *);
|
PyAPI_FUNC(int) PyErr_ExceptionMatches(PyObject *);
|
||||||
PyAPI_FUNC(void) PyErr_NormalizeException(PyObject**, PyObject**, PyObject**);
|
PyAPI_FUNC(void) PyErr_NormalizeException(PyObject**, PyObject**, PyObject**);
|
||||||
|
|
||||||
|
/* */
|
||||||
|
|
||||||
|
#define PyExceptionClass_Check(x) \
|
||||||
|
(PyClass_Check((x)) \
|
||||||
|
|| (PyType_Check((x)) && PyType_IsSubtype( \
|
||||||
|
(PyTypeObject*)(x), (PyTypeObject*)PyExc_BaseException)))
|
||||||
|
|
||||||
|
|
||||||
|
#define PyExceptionInstance_Check(x) \
|
||||||
|
(PyInstance_Check((x)) || \
|
||||||
|
(PyType_IsSubtype((x)->ob_type, (PyTypeObject*)PyExc_BaseException)))
|
||||||
|
|
||||||
|
#define PyExceptionClass_Name(x) \
|
||||||
|
(PyClass_Check((x)) \
|
||||||
|
? PyString_AS_STRING(((PyClassObject*)(x))->cl_name) \
|
||||||
|
: (char *)(((PyTypeObject*)(x))->tp_name))
|
||||||
|
|
||||||
|
#define PyExceptionInstance_Class(x) \
|
||||||
|
((PyInstance_Check((x)) \
|
||||||
|
? (PyObject*)((PyInstanceObject*)(x))->in_class \
|
||||||
|
: (PyObject*)((x)->ob_type)))
|
||||||
|
|
||||||
|
|
||||||
/* Predefined exceptions */
|
/* Predefined exceptions */
|
||||||
|
|
||||||
|
PyAPI_DATA(PyObject *) PyExc_BaseException;
|
||||||
PyAPI_DATA(PyObject *) PyExc_Exception;
|
PyAPI_DATA(PyObject *) PyExc_Exception;
|
||||||
PyAPI_DATA(PyObject *) PyExc_StopIteration;
|
PyAPI_DATA(PyObject *) PyExc_StopIteration;
|
||||||
PyAPI_DATA(PyObject *) PyExc_GeneratorExit;
|
PyAPI_DATA(PyObject *) PyExc_GeneratorExit;
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
BaseException
|
||||||
|
+-- SystemExit
|
||||||
|
+-- KeyboardInterrupt
|
||||||
|
+-- Exception
|
||||||
|
+-- GeneratorExit
|
||||||
|
+-- StopIteration
|
||||||
|
+-- StandardError
|
||||||
|
| +-- ArithmeticError
|
||||||
|
| | +-- FloatingPointError
|
||||||
|
| | +-- OverflowError
|
||||||
|
| | +-- ZeroDivisionError
|
||||||
|
| +-- AssertionError
|
||||||
|
| +-- AttributeError
|
||||||
|
| +-- EnvironmentError
|
||||||
|
| | +-- IOError
|
||||||
|
| | +-- OSError
|
||||||
|
| | +-- WindowsError (Windows)
|
||||||
|
| +-- EOFError
|
||||||
|
| +-- ImportError
|
||||||
|
| +-- LookupError
|
||||||
|
| | +-- IndexError
|
||||||
|
| | +-- KeyError
|
||||||
|
| +-- MemoryError
|
||||||
|
| +-- NameError
|
||||||
|
| | +-- UnboundLocalError
|
||||||
|
| +-- ReferenceError
|
||||||
|
| +-- RuntimeError
|
||||||
|
| | +-- NotImplementedError
|
||||||
|
| +-- SyntaxError
|
||||||
|
| | +-- IndentationError
|
||||||
|
| | +-- TabError
|
||||||
|
| +-- SystemError
|
||||||
|
| +-- TypeError
|
||||||
|
| +-- ValueError
|
||||||
|
| | +-- UnicodeError
|
||||||
|
| | +-- UnicodeDecodeError
|
||||||
|
| | +-- UnicodeEncodeError
|
||||||
|
| | +-- UnicodeTranslateError
|
||||||
|
+-- Warning
|
||||||
|
+-- DeprecationWarning
|
||||||
|
+-- PendingDeprecationWarning
|
||||||
|
+-- RuntimeWarning
|
||||||
|
+-- SyntaxWarning
|
||||||
|
+-- UserWarning
|
||||||
|
+-- FutureWarning
|
||||||
|
+-- OverflowWarning [not generated by the interpreter]
|
|
@ -488,12 +488,12 @@ INFO:a.b.c.d:Info 5
|
||||||
-- log_test4 begin ---------------------------------------------------
|
-- log_test4 begin ---------------------------------------------------
|
||||||
config0: ok.
|
config0: ok.
|
||||||
config1: ok.
|
config1: ok.
|
||||||
config2: exceptions.AttributeError
|
config2: <class 'exceptions.AttributeError'>
|
||||||
config3: exceptions.KeyError
|
config3: <class 'exceptions.KeyError'>
|
||||||
-- log_test4 end ---------------------------------------------------
|
-- log_test4 end ---------------------------------------------------
|
||||||
-- log_test5 begin ---------------------------------------------------
|
-- log_test5 begin ---------------------------------------------------
|
||||||
ERROR:root:just testing
|
ERROR:root:just testing
|
||||||
exceptions.KeyError... Don't panic!
|
<class 'exceptions.KeyError'>... Don't panic!
|
||||||
-- log_test5 end ---------------------------------------------------
|
-- log_test5 end ---------------------------------------------------
|
||||||
-- logrecv output begin ---------------------------------------------------
|
-- logrecv output begin ---------------------------------------------------
|
||||||
ERR -> CRITICAL: Message 0 (via logrecv.tcp.ERR)
|
ERR -> CRITICAL: Message 0 (via logrecv.tcp.ERR)
|
||||||
|
|
|
@ -96,7 +96,7 @@ def do_infix_binops():
|
||||||
x = eval('a %s b' % op)
|
x = eval('a %s b' % op)
|
||||||
except:
|
except:
|
||||||
error = sys.exc_info()[:2]
|
error = sys.exc_info()[:2]
|
||||||
print '... %s' % error[0]
|
print '... %s.%s' % (error[0].__module__, error[0].__name__)
|
||||||
else:
|
else:
|
||||||
print '=', format_result(x)
|
print '=', format_result(x)
|
||||||
try:
|
try:
|
||||||
|
@ -108,7 +108,7 @@ def do_infix_binops():
|
||||||
exec('z %s= b' % op)
|
exec('z %s= b' % op)
|
||||||
except:
|
except:
|
||||||
error = sys.exc_info()[:2]
|
error = sys.exc_info()[:2]
|
||||||
print '... %s' % error[0]
|
print '... %s.%s' % (error[0].__module__, error[0].__name__)
|
||||||
else:
|
else:
|
||||||
print '=>', format_result(z)
|
print '=>', format_result(z)
|
||||||
|
|
||||||
|
@ -121,7 +121,7 @@ def do_prefix_binops():
|
||||||
x = eval('%s(a, b)' % op)
|
x = eval('%s(a, b)' % op)
|
||||||
except:
|
except:
|
||||||
error = sys.exc_info()[:2]
|
error = sys.exc_info()[:2]
|
||||||
print '... %s' % error[0]
|
print '... %s.%s' % (error[0].__module__, error[0].__name__)
|
||||||
else:
|
else:
|
||||||
print '=', format_result(x)
|
print '=', format_result(x)
|
||||||
|
|
||||||
|
|
|
@ -3355,31 +3355,6 @@ def docdescriptor():
|
||||||
vereq(NewClass.__doc__, 'object=None; type=NewClass')
|
vereq(NewClass.__doc__, 'object=None; type=NewClass')
|
||||||
vereq(NewClass().__doc__, 'object=NewClass instance; type=NewClass')
|
vereq(NewClass().__doc__, 'object=NewClass instance; type=NewClass')
|
||||||
|
|
||||||
def string_exceptions():
|
|
||||||
if verbose:
|
|
||||||
print "Testing string exceptions ..."
|
|
||||||
|
|
||||||
# Ensure builtin strings work OK as exceptions.
|
|
||||||
astring = "An exception string."
|
|
||||||
try:
|
|
||||||
raise astring
|
|
||||||
except astring:
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
raise TestFailed, "builtin string not usable as exception"
|
|
||||||
|
|
||||||
# Ensure string subclass instances do not.
|
|
||||||
class MyStr(str):
|
|
||||||
pass
|
|
||||||
|
|
||||||
newstring = MyStr("oops -- shouldn't work")
|
|
||||||
try:
|
|
||||||
raise newstring
|
|
||||||
except TypeError:
|
|
||||||
pass
|
|
||||||
except:
|
|
||||||
raise TestFailed, "string subclass allowed as exception"
|
|
||||||
|
|
||||||
def copy_setstate():
|
def copy_setstate():
|
||||||
if verbose:
|
if verbose:
|
||||||
print "Testing that copy.*copy() correctly uses __setstate__..."
|
print "Testing that copy.*copy() correctly uses __setstate__..."
|
||||||
|
@ -4172,7 +4147,6 @@ def test_main():
|
||||||
funnynew()
|
funnynew()
|
||||||
imulbug()
|
imulbug()
|
||||||
docdescriptor()
|
docdescriptor()
|
||||||
string_exceptions()
|
|
||||||
copy_setstate()
|
copy_setstate()
|
||||||
slices()
|
slices()
|
||||||
subtype_resurrection()
|
subtype_resurrection()
|
||||||
|
|
|
@ -29,10 +29,7 @@ def test_raise_catch(exc):
|
||||||
|
|
||||||
def r(thing):
|
def r(thing):
|
||||||
test_raise_catch(thing)
|
test_raise_catch(thing)
|
||||||
if isinstance(thing, ClassType):
|
print getattr(thing, '__name__', thing)
|
||||||
print thing.__name__
|
|
||||||
else:
|
|
||||||
print thing
|
|
||||||
|
|
||||||
r(AttributeError)
|
r(AttributeError)
|
||||||
import sys
|
import sys
|
||||||
|
|
|
@ -0,0 +1,182 @@
|
||||||
|
import unittest
|
||||||
|
import __builtin__
|
||||||
|
import exceptions
|
||||||
|
import warnings
|
||||||
|
from test.test_support import run_unittest
|
||||||
|
import os
|
||||||
|
from platform import system as platform_system
|
||||||
|
|
||||||
|
class ExceptionClassTests(unittest.TestCase):
|
||||||
|
|
||||||
|
"""Tests for anything relating to exception objects themselves (e.g.,
|
||||||
|
inheritance hierarchy)"""
|
||||||
|
|
||||||
|
def test_builtins_new_style(self):
|
||||||
|
self.failUnless(issubclass(Exception, object))
|
||||||
|
|
||||||
|
def verify_instance_interface(self, ins):
|
||||||
|
for attr in ("args", "message", "__str__", "__unicode__", "__repr__",
|
||||||
|
"__getitem__"):
|
||||||
|
self.failUnless(hasattr(ins, attr), "%s missing %s attribute" %
|
||||||
|
(ins.__class__.__name__, attr))
|
||||||
|
|
||||||
|
def test_inheritance(self):
|
||||||
|
# Make sure the inheritance hierarchy matches the documentation
|
||||||
|
exc_set = set(x for x in dir(exceptions) if not x.startswith('_'))
|
||||||
|
inheritance_tree = open(os.path.join(os.path.split(__file__)[0],
|
||||||
|
'exception_hierarchy.txt'))
|
||||||
|
try:
|
||||||
|
superclass_name = inheritance_tree.readline().rstrip()
|
||||||
|
try:
|
||||||
|
last_exc = getattr(__builtin__, superclass_name)
|
||||||
|
except AttributeError:
|
||||||
|
self.fail("base class %s not a built-in" % superclass_name)
|
||||||
|
self.failUnless(superclass_name in exc_set)
|
||||||
|
exc_set.discard(superclass_name)
|
||||||
|
superclasses = [] # Loop will insert base exception
|
||||||
|
last_depth = 0
|
||||||
|
for exc_line in inheritance_tree:
|
||||||
|
exc_line = exc_line.rstrip()
|
||||||
|
depth = exc_line.rindex('-')
|
||||||
|
exc_name = exc_line[depth+2:] # Slice past space
|
||||||
|
if '(' in exc_name:
|
||||||
|
paren_index = exc_name.index('(')
|
||||||
|
platform_name = exc_name[paren_index+1:-1]
|
||||||
|
if platform_system() != platform_name:
|
||||||
|
exc_set.discard(exc_name)
|
||||||
|
continue
|
||||||
|
if '[' in exc_name:
|
||||||
|
left_bracket = exc_name.index('[')
|
||||||
|
exc_name = exc_name[:left_bracket-1] # cover space
|
||||||
|
try:
|
||||||
|
exc = getattr(__builtin__, exc_name)
|
||||||
|
except AttributeError:
|
||||||
|
self.fail("%s not a built-in exception" % exc_name)
|
||||||
|
if last_depth < depth:
|
||||||
|
superclasses.append((last_depth, last_exc))
|
||||||
|
elif last_depth > depth:
|
||||||
|
while superclasses[-1][0] >= depth:
|
||||||
|
superclasses.pop()
|
||||||
|
self.failUnless(issubclass(exc, superclasses[-1][1]),
|
||||||
|
"%s is not a subclass of %s" % (exc.__name__,
|
||||||
|
superclasses[-1][1].__name__))
|
||||||
|
try: # Some exceptions require arguments; just skip them
|
||||||
|
self.verify_instance_interface(exc())
|
||||||
|
except TypeError:
|
||||||
|
pass
|
||||||
|
self.failUnless(exc_name in exc_set)
|
||||||
|
exc_set.discard(exc_name)
|
||||||
|
last_exc = exc
|
||||||
|
last_depth = depth
|
||||||
|
finally:
|
||||||
|
inheritance_tree.close()
|
||||||
|
self.failUnlessEqual(len(exc_set), 0, "%s not accounted for" % exc_set)
|
||||||
|
|
||||||
|
interface_tests = ("length", "args", "message", "str", "unicode", "repr",
|
||||||
|
"indexing")
|
||||||
|
|
||||||
|
def interface_test_driver(self, results):
|
||||||
|
for test_name, (given, expected) in zip(self.interface_tests, results):
|
||||||
|
self.failUnlessEqual(given, expected, "%s: %s != %s" % (test_name,
|
||||||
|
given, expected))
|
||||||
|
|
||||||
|
def test_interface_single_arg(self):
|
||||||
|
# Make sure interface works properly when given a single argument
|
||||||
|
arg = "spam"
|
||||||
|
exc = Exception(arg)
|
||||||
|
results = ([len(exc.args), 1], [exc.args[0], arg], [exc.message, arg],
|
||||||
|
[str(exc), str(arg)], [unicode(exc), unicode(arg)],
|
||||||
|
[repr(exc), exc.__class__.__name__ + repr(exc.args)], [exc[0], arg])
|
||||||
|
self.interface_test_driver(results)
|
||||||
|
|
||||||
|
def test_interface_multi_arg(self):
|
||||||
|
# Make sure interface correct when multiple arguments given
|
||||||
|
arg_count = 3
|
||||||
|
args = tuple(range(arg_count))
|
||||||
|
exc = Exception(*args)
|
||||||
|
results = ([len(exc.args), arg_count], [exc.args, args],
|
||||||
|
[exc.message, ''], [str(exc), str(args)],
|
||||||
|
[unicode(exc), unicode(args)],
|
||||||
|
[repr(exc), exc.__class__.__name__ + repr(exc.args)],
|
||||||
|
[exc[-1], args[-1]])
|
||||||
|
self.interface_test_driver(results)
|
||||||
|
|
||||||
|
def test_interface_no_arg(self):
|
||||||
|
# Make sure that with no args that interface is correct
|
||||||
|
exc = Exception()
|
||||||
|
results = ([len(exc.args), 0], [exc.args, tuple()], [exc.message, ''],
|
||||||
|
[str(exc), ''], [unicode(exc), u''],
|
||||||
|
[repr(exc), exc.__class__.__name__ + '()'], [True, True])
|
||||||
|
self.interface_test_driver(results)
|
||||||
|
|
||||||
|
class UsageTests(unittest.TestCase):
|
||||||
|
|
||||||
|
"""Test usage of exceptions"""
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
self._filters = warnings.filters[:]
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
warnings.filters = self._filters[:]
|
||||||
|
|
||||||
|
def test_raise_classic(self):
|
||||||
|
class ClassicClass:
|
||||||
|
pass
|
||||||
|
try:
|
||||||
|
raise ClassicClass
|
||||||
|
except ClassicClass:
|
||||||
|
pass
|
||||||
|
except:
|
||||||
|
self.fail("unable to raise classic class")
|
||||||
|
try:
|
||||||
|
raise ClassicClass()
|
||||||
|
except ClassicClass:
|
||||||
|
pass
|
||||||
|
except:
|
||||||
|
self.fail("unable to raise class class instance")
|
||||||
|
|
||||||
|
def test_raise_new_style_non_exception(self):
|
||||||
|
class NewStyleClass(object):
|
||||||
|
pass
|
||||||
|
try:
|
||||||
|
raise NewStyleClass
|
||||||
|
except TypeError:
|
||||||
|
pass
|
||||||
|
except:
|
||||||
|
self.fail("unable to raise new-style class")
|
||||||
|
try:
|
||||||
|
raise NewStyleClass()
|
||||||
|
except TypeError:
|
||||||
|
pass
|
||||||
|
except:
|
||||||
|
self.fail("unable to raise new-style class instance")
|
||||||
|
|
||||||
|
def test_raise_string(self):
|
||||||
|
warnings.resetwarnings()
|
||||||
|
warnings.filterwarnings("error")
|
||||||
|
try:
|
||||||
|
raise "spam"
|
||||||
|
except DeprecationWarning:
|
||||||
|
pass
|
||||||
|
except:
|
||||||
|
self.fail("raising a string did not cause a DeprecationWarning")
|
||||||
|
|
||||||
|
def test_catch_string(self):
|
||||||
|
# Test will be pertinent when catching exceptions raises a
|
||||||
|
# DeprecationWarning
|
||||||
|
warnings.filterwarnings("ignore", "raising")
|
||||||
|
str_exc = "spam"
|
||||||
|
try:
|
||||||
|
raise str_exc
|
||||||
|
except str_exc:
|
||||||
|
pass
|
||||||
|
except:
|
||||||
|
self.fail("catching a string exception failed")
|
||||||
|
|
||||||
|
def test_main():
|
||||||
|
run_unittest(ExceptionClassTests, UsageTests)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
test_main()
|
|
@ -157,7 +157,8 @@ def format_exception_only(etype, value):
|
||||||
which exception occurred is the always last string in the list.
|
which exception occurred is the always last string in the list.
|
||||||
"""
|
"""
|
||||||
list = []
|
list = []
|
||||||
if type(etype) == types.ClassType:
|
if (type(etype) == types.ClassType
|
||||||
|
or (isinstance(etype, type) and issubclass(etype, Exception))):
|
||||||
stype = etype.__name__
|
stype = etype.__name__
|
||||||
else:
|
else:
|
||||||
stype = etype
|
stype = etype
|
||||||
|
|
|
@ -145,7 +145,8 @@ def filterwarnings(action, message="", category=Warning, module="", lineno=0,
|
||||||
assert action in ("error", "ignore", "always", "default", "module",
|
assert action in ("error", "ignore", "always", "default", "module",
|
||||||
"once"), "invalid action: %r" % (action,)
|
"once"), "invalid action: %r" % (action,)
|
||||||
assert isinstance(message, basestring), "message must be a string"
|
assert isinstance(message, basestring), "message must be a string"
|
||||||
assert isinstance(category, types.ClassType), "category must be a class"
|
assert isinstance(category, (type, types.ClassType)), \
|
||||||
|
"category must be a class"
|
||||||
assert issubclass(category, Warning), "category must be a Warning subclass"
|
assert issubclass(category, Warning), "category must be a Warning subclass"
|
||||||
assert isinstance(module, basestring), "module must be a string"
|
assert isinstance(module, basestring), "module must be a string"
|
||||||
assert isinstance(lineno, int) and lineno >= 0, \
|
assert isinstance(lineno, int) and lineno >= 0, \
|
||||||
|
|
|
@ -12,6 +12,11 @@ What's New in Python 2.5 alpha 1?
|
||||||
Core and builtins
|
Core and builtins
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
|
- PEP 352, patch #1104669: Make exceptions new-style objects. Introduced the
|
||||||
|
new exception base class, BaseException, which has a new message attribute.
|
||||||
|
KeyboardInterrupt and SystemExit to directly inherit from BaseException now.
|
||||||
|
Raising a string exception now raises a DeprecationWarning.
|
||||||
|
|
||||||
- Patch #1438387, PEP 328: relative and absolute imports. Imports can now be
|
- Patch #1438387, PEP 328: relative and absolute imports. Imports can now be
|
||||||
explicitly relative, using 'from .module import name' to mean 'from the same
|
explicitly relative, using 'from .module import name' to mean 'from the same
|
||||||
package as this module is in. Imports without dots still default to the
|
package as this module is in. Imports without dots still default to the
|
||||||
|
|
|
@ -230,11 +230,11 @@ gen_throw(PyGenObject *gen, PyObject *args)
|
||||||
Py_XINCREF(val);
|
Py_XINCREF(val);
|
||||||
Py_XINCREF(tb);
|
Py_XINCREF(tb);
|
||||||
|
|
||||||
if (PyClass_Check(typ)) {
|
if (PyExceptionClass_Check(typ)) {
|
||||||
PyErr_NormalizeException(&typ, &val, &tb);
|
PyErr_NormalizeException(&typ, &val, &tb);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (PyInstance_Check(typ)) {
|
else if (PyExceptionInstance_Check(typ)) {
|
||||||
/* Raising an instance. The value should be a dummy. */
|
/* Raising an instance. The value should be a dummy. */
|
||||||
if (val && val != Py_None) {
|
if (val && val != Py_None) {
|
||||||
PyErr_SetString(PyExc_TypeError,
|
PyErr_SetString(PyExc_TypeError,
|
||||||
|
@ -245,7 +245,7 @@ gen_throw(PyGenObject *gen, PyObject *args)
|
||||||
/* Normalize to raise <class>, <instance> */
|
/* Normalize to raise <class>, <instance> */
|
||||||
Py_XDECREF(val);
|
Py_XDECREF(val);
|
||||||
val = typ;
|
val = typ;
|
||||||
typ = (PyObject*) ((PyInstanceObject*)typ)->in_class;
|
typ = PyExceptionInstance_Class(typ);
|
||||||
Py_INCREF(typ);
|
Py_INCREF(typ);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1685,7 +1685,7 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throw)
|
||||||
why == WHY_CONTINUE)
|
why == WHY_CONTINUE)
|
||||||
retval = POP();
|
retval = POP();
|
||||||
}
|
}
|
||||||
else if (PyClass_Check(v) || PyString_Check(v)) {
|
else if (PyExceptionClass_Check(v) || PyString_Check(v)) {
|
||||||
w = POP();
|
w = POP();
|
||||||
u = POP();
|
u = POP();
|
||||||
PyErr_Restore(v, w, u);
|
PyErr_Restore(v, w, u);
|
||||||
|
@ -3026,14 +3026,14 @@ do_raise(PyObject *type, PyObject *value, PyObject *tb)
|
||||||
/* Raising builtin string is deprecated but still allowed --
|
/* Raising builtin string is deprecated but still allowed --
|
||||||
* do nothing. Raising an instance of a new-style str
|
* do nothing. Raising an instance of a new-style str
|
||||||
* subclass is right out. */
|
* subclass is right out. */
|
||||||
if (-1 == PyErr_Warn(PyExc_PendingDeprecationWarning,
|
if (PyErr_Warn(PyExc_DeprecationWarning,
|
||||||
"raising a string exception is deprecated"))
|
"raising a string exception is deprecated"))
|
||||||
goto raise_error;
|
goto raise_error;
|
||||||
}
|
}
|
||||||
else if (PyClass_Check(type))
|
else if (PyExceptionClass_Check(type))
|
||||||
PyErr_NormalizeException(&type, &value, &tb);
|
PyErr_NormalizeException(&type, &value, &tb);
|
||||||
|
|
||||||
else if (PyInstance_Check(type)) {
|
else if (PyExceptionInstance_Check(type)) {
|
||||||
/* Raising an instance. The value should be a dummy. */
|
/* Raising an instance. The value should be a dummy. */
|
||||||
if (value != Py_None) {
|
if (value != Py_None) {
|
||||||
PyErr_SetString(PyExc_TypeError,
|
PyErr_SetString(PyExc_TypeError,
|
||||||
|
@ -3044,7 +3044,7 @@ do_raise(PyObject *type, PyObject *value, PyObject *tb)
|
||||||
/* Normalize to raise <class>, <instance> */
|
/* Normalize to raise <class>, <instance> */
|
||||||
Py_DECREF(value);
|
Py_DECREF(value);
|
||||||
value = type;
|
value = type;
|
||||||
type = (PyObject*) ((PyInstanceObject*)type)->in_class;
|
type = PyExceptionInstance_Class(type);
|
||||||
Py_INCREF(type);
|
Py_INCREF(type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -448,9 +448,8 @@ static void wrong_exception_type(PyObject *exc)
|
||||||
|
|
||||||
PyObject *PyCodec_StrictErrors(PyObject *exc)
|
PyObject *PyCodec_StrictErrors(PyObject *exc)
|
||||||
{
|
{
|
||||||
if (PyInstance_Check(exc))
|
if (PyExceptionInstance_Check(exc))
|
||||||
PyErr_SetObject((PyObject*)((PyInstanceObject*)exc)->in_class,
|
PyErr_SetObject(PyExceptionInstance_Class(exc), exc);
|
||||||
exc);
|
|
||||||
else
|
else
|
||||||
PyErr_SetString(PyExc_TypeError, "codec must pass exception instance");
|
PyErr_SetString(PyExc_TypeError, "codec must pass exception instance");
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
@ -97,11 +97,14 @@ PyErr_GivenExceptionMatches(PyObject *err, PyObject *exc)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/* err might be an instance, so check its class. */
|
/* err might be an instance, so check its class. */
|
||||||
if (PyInstance_Check(err))
|
if (PyExceptionInstance_Check(err))
|
||||||
err = (PyObject*)((PyInstanceObject*)err)->in_class;
|
err = PyExceptionInstance_Class(err);
|
||||||
|
|
||||||
if (PyClass_Check(err) && PyClass_Check(exc))
|
if (PyExceptionClass_Check(err) && PyExceptionClass_Check(exc)) {
|
||||||
return PyClass_IsSubclass(err, exc);
|
/* problems here!? not sure PyObject_IsSubclass expects to
|
||||||
|
be called with an exception pending... */
|
||||||
|
return PyObject_IsSubclass(err, exc);
|
||||||
|
}
|
||||||
|
|
||||||
return err == exc;
|
return err == exc;
|
||||||
}
|
}
|
||||||
|
@ -138,19 +141,19 @@ PyErr_NormalizeException(PyObject **exc, PyObject **val, PyObject **tb)
|
||||||
Py_INCREF(value);
|
Py_INCREF(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PyInstance_Check(value))
|
if (PyExceptionInstance_Check(value))
|
||||||
inclass = (PyObject*)((PyInstanceObject*)value)->in_class;
|
inclass = PyExceptionInstance_Class(value);
|
||||||
|
|
||||||
/* Normalize the exception so that if the type is a class, the
|
/* Normalize the exception so that if the type is a class, the
|
||||||
value will be an instance.
|
value will be an instance.
|
||||||
*/
|
*/
|
||||||
if (PyClass_Check(type)) {
|
if (PyExceptionClass_Check(type)) {
|
||||||
/* if the value was not an instance, or is not an instance
|
/* if the value was not an instance, or is not an instance
|
||||||
whose class is (or is derived from) type, then use the
|
whose class is (or is derived from) type, then use the
|
||||||
value as an argument to instantiation of the type
|
value as an argument to instantiation of the type
|
||||||
class.
|
class.
|
||||||
*/
|
*/
|
||||||
if (!inclass || !PyClass_IsSubclass(inclass, type)) {
|
if (!inclass || !PyObject_IsSubclass(inclass, type)) {
|
||||||
PyObject *args, *res;
|
PyObject *args, *res;
|
||||||
|
|
||||||
if (value == Py_None)
|
if (value == Py_None)
|
||||||
|
@ -282,7 +285,7 @@ PyErr_SetFromErrnoWithFilenameObject(PyObject *exc, PyObject *filenameObject)
|
||||||
{
|
{
|
||||||
/* Note that the Win32 errors do not lineup with the
|
/* Note that the Win32 errors do not lineup with the
|
||||||
errno error. So if the error is in the MSVC error
|
errno error. So if the error is in the MSVC error
|
||||||
table, we use it, otherwise we assume it really _is_
|
table, we use it, otherwise we assume it really _is_
|
||||||
a Win32 error code
|
a Win32 error code
|
||||||
*/
|
*/
|
||||||
if (i > 0 && i < _sys_nerr) {
|
if (i > 0 && i < _sys_nerr) {
|
||||||
|
@ -302,7 +305,7 @@ PyErr_SetFromErrnoWithFilenameObject(PyObject *exc, PyObject *filenameObject)
|
||||||
0, /* size not used */
|
0, /* size not used */
|
||||||
NULL); /* no args */
|
NULL); /* no args */
|
||||||
if (len==0) {
|
if (len==0) {
|
||||||
/* Only ever seen this in out-of-mem
|
/* Only ever seen this in out-of-mem
|
||||||
situations */
|
situations */
|
||||||
sprintf(s_small_buf, "Windows Error 0x%X", i);
|
sprintf(s_small_buf, "Windows Error 0x%X", i);
|
||||||
s = s_small_buf;
|
s = s_small_buf;
|
||||||
|
@ -345,8 +348,8 @@ PyErr_SetFromErrnoWithFilename(PyObject *exc, char *filename)
|
||||||
PyObject *
|
PyObject *
|
||||||
PyErr_SetFromErrnoWithUnicodeFilename(PyObject *exc, Py_UNICODE *filename)
|
PyErr_SetFromErrnoWithUnicodeFilename(PyObject *exc, Py_UNICODE *filename)
|
||||||
{
|
{
|
||||||
PyObject *name = filename ?
|
PyObject *name = filename ?
|
||||||
PyUnicode_FromUnicode(filename, wcslen(filename)) :
|
PyUnicode_FromUnicode(filename, wcslen(filename)) :
|
||||||
NULL;
|
NULL;
|
||||||
PyObject *result = PyErr_SetFromErrnoWithFilenameObject(exc, name);
|
PyObject *result = PyErr_SetFromErrnoWithFilenameObject(exc, name);
|
||||||
Py_XDECREF(name);
|
Py_XDECREF(name);
|
||||||
|
@ -360,7 +363,7 @@ PyErr_SetFromErrno(PyObject *exc)
|
||||||
return PyErr_SetFromErrnoWithFilenameObject(exc, NULL);
|
return PyErr_SetFromErrnoWithFilenameObject(exc, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MS_WINDOWS
|
#ifdef MS_WINDOWS
|
||||||
/* Windows specific error code handling */
|
/* Windows specific error code handling */
|
||||||
PyObject *PyErr_SetExcFromWindowsErrWithFilenameObject(
|
PyObject *PyErr_SetExcFromWindowsErrWithFilenameObject(
|
||||||
PyObject *exc,
|
PyObject *exc,
|
||||||
|
@ -415,8 +418,8 @@ PyObject *PyErr_SetExcFromWindowsErrWithFilename(
|
||||||
const char *filename)
|
const char *filename)
|
||||||
{
|
{
|
||||||
PyObject *name = filename ? PyString_FromString(filename) : NULL;
|
PyObject *name = filename ? PyString_FromString(filename) : NULL;
|
||||||
PyObject *ret = PyErr_SetExcFromWindowsErrWithFilenameObject(exc,
|
PyObject *ret = PyErr_SetExcFromWindowsErrWithFilenameObject(exc,
|
||||||
ierr,
|
ierr,
|
||||||
name);
|
name);
|
||||||
Py_XDECREF(name);
|
Py_XDECREF(name);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -428,11 +431,11 @@ PyObject *PyErr_SetExcFromWindowsErrWithUnicodeFilename(
|
||||||
int ierr,
|
int ierr,
|
||||||
const Py_UNICODE *filename)
|
const Py_UNICODE *filename)
|
||||||
{
|
{
|
||||||
PyObject *name = filename ?
|
PyObject *name = filename ?
|
||||||
PyUnicode_FromUnicode(filename, wcslen(filename)) :
|
PyUnicode_FromUnicode(filename, wcslen(filename)) :
|
||||||
NULL;
|
NULL;
|
||||||
PyObject *ret = PyErr_SetExcFromWindowsErrWithFilenameObject(exc,
|
PyObject *ret = PyErr_SetExcFromWindowsErrWithFilenameObject(exc,
|
||||||
ierr,
|
ierr,
|
||||||
name);
|
name);
|
||||||
Py_XDECREF(name);
|
Py_XDECREF(name);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -466,8 +469,8 @@ PyObject *PyErr_SetFromWindowsErrWithUnicodeFilename(
|
||||||
int ierr,
|
int ierr,
|
||||||
const Py_UNICODE *filename)
|
const Py_UNICODE *filename)
|
||||||
{
|
{
|
||||||
PyObject *name = filename ?
|
PyObject *name = filename ?
|
||||||
PyUnicode_FromUnicode(filename, wcslen(filename)) :
|
PyUnicode_FromUnicode(filename, wcslen(filename)) :
|
||||||
NULL;
|
NULL;
|
||||||
PyObject *result = PyErr_SetExcFromWindowsErrWithFilenameObject(
|
PyObject *result = PyErr_SetExcFromWindowsErrWithFilenameObject(
|
||||||
PyExc_WindowsError,
|
PyExc_WindowsError,
|
||||||
|
@ -574,7 +577,24 @@ PyErr_WriteUnraisable(PyObject *obj)
|
||||||
if (f != NULL) {
|
if (f != NULL) {
|
||||||
PyFile_WriteString("Exception ", f);
|
PyFile_WriteString("Exception ", f);
|
||||||
if (t) {
|
if (t) {
|
||||||
PyFile_WriteObject(t, f, Py_PRINT_RAW);
|
char* className = PyExceptionClass_Name(t);
|
||||||
|
PyObject* moduleName =
|
||||||
|
PyObject_GetAttrString(t, "__module__");
|
||||||
|
|
||||||
|
if (moduleName == NULL)
|
||||||
|
PyFile_WriteString("<unknown>", f);
|
||||||
|
else {
|
||||||
|
char* modstr = PyString_AsString(moduleName);
|
||||||
|
if (modstr)
|
||||||
|
{
|
||||||
|
PyFile_WriteString(modstr, f);
|
||||||
|
PyFile_WriteString(".", f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (className == NULL)
|
||||||
|
PyFile_WriteString("<unknown>", f);
|
||||||
|
else
|
||||||
|
PyFile_WriteString(className, f);
|
||||||
if (v && v != Py_None) {
|
if (v && v != Py_None) {
|
||||||
PyFile_WriteString(": ", f);
|
PyFile_WriteString(": ", f);
|
||||||
PyFile_WriteObject(v, f, 0);
|
PyFile_WriteObject(v, f, 0);
|
||||||
|
@ -726,7 +746,7 @@ PyErr_SyntaxLocation(const char *filename, int lineno)
|
||||||
|
|
||||||
/* com_fetch_program_text will attempt to load the line of text that
|
/* com_fetch_program_text will attempt to load the line of text that
|
||||||
the exception refers to. If it fails, it will return NULL but will
|
the exception refers to. If it fails, it will return NULL but will
|
||||||
not set an exception.
|
not set an exception.
|
||||||
|
|
||||||
XXX The functionality of this function is quite similar to the
|
XXX The functionality of this function is quite similar to the
|
||||||
functionality in tb_displayline() in traceback.c.
|
functionality in tb_displayline() in traceback.c.
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
* 98-08-19 fl created (for pyexe)
|
* 98-08-19 fl created (for pyexe)
|
||||||
* 00-02-08 fl updated for 1.5.2
|
* 00-02-08 fl updated for 1.5.2
|
||||||
* 26-May-2000 baw vetted for Python 1.6
|
* 26-May-2000 baw vetted for Python 1.6
|
||||||
|
* XXX
|
||||||
*
|
*
|
||||||
* written by Fredrik Lundh
|
* written by Fredrik Lundh
|
||||||
* modifications, additions, cleanups, and proofreading by Barry Warsaw
|
* modifications, additions, cleanups, and proofreading by Barry Warsaw
|
||||||
|
@ -33,99 +34,19 @@
|
||||||
PyDoc_STRVAR(module__doc__,
|
PyDoc_STRVAR(module__doc__,
|
||||||
"Python's standard exception class hierarchy.\n\
|
"Python's standard exception class hierarchy.\n\
|
||||||
\n\
|
\n\
|
||||||
Before Python 1.5, the standard exceptions were all simple string objects.\n\
|
Exceptions found here are defined both in the exceptions module and the \n\
|
||||||
In Python 1.5, the standard exceptions were converted to classes organized\n\
|
built-in namespace. It is recommended that user-defined exceptions inherit \n\
|
||||||
into a relatively flat hierarchy. String-based standard exceptions were\n\
|
from Exception.\n\
|
||||||
optional, or used as a fallback if some problem occurred while importing\n\
|
"
|
||||||
the exception module. With Python 1.6, optional string-based standard\n\
|
|
||||||
exceptions were removed (along with the -X command line flag).\n\
|
|
||||||
\n\
|
|
||||||
The class exceptions were implemented in such a way as to be almost\n\
|
|
||||||
completely backward compatible. Some tricky uses of IOError could\n\
|
|
||||||
potentially have broken, but by Python 1.6, all of these should have\n\
|
|
||||||
been fixed. As of Python 1.6, the class-based standard exceptions are\n\
|
|
||||||
now implemented in C, and are guaranteed to exist in the Python\n\
|
|
||||||
interpreter.\n\
|
|
||||||
\n\
|
|
||||||
Here is a rundown of the class hierarchy. The classes found here are\n\
|
|
||||||
inserted into both the exceptions module and the `built-in' module. It is\n\
|
|
||||||
recommended that user defined class based exceptions be derived from the\n\
|
|
||||||
`Exception' class, although this is currently not enforced.\n"
|
|
||||||
/* keep string pieces "small" */
|
/* keep string pieces "small" */
|
||||||
"\n\
|
/* XXX exception hierarchy from Lib/test/exception_hierarchy.txt */
|
||||||
Exception\n\
|
|
||||||
|\n\
|
|
||||||
+-- SystemExit\n\
|
|
||||||
+-- StopIteration\n\
|
|
||||||
+-- GeneratorExit\n\
|
|
||||||
+-- StandardError\n\
|
|
||||||
| |\n\
|
|
||||||
| +-- KeyboardInterrupt\n\
|
|
||||||
| +-- ImportError\n\
|
|
||||||
| +-- EnvironmentError\n\
|
|
||||||
| | |\n\
|
|
||||||
| | +-- IOError\n\
|
|
||||||
| | +-- OSError\n\
|
|
||||||
| | |\n\
|
|
||||||
| | +-- WindowsError\n\
|
|
||||||
| | +-- VMSError\n\
|
|
||||||
| |\n\
|
|
||||||
| +-- EOFError\n\
|
|
||||||
| +-- RuntimeError\n\
|
|
||||||
| | |\n\
|
|
||||||
| | +-- NotImplementedError\n\
|
|
||||||
| |\n\
|
|
||||||
| +-- NameError\n\
|
|
||||||
| | |\n\
|
|
||||||
| | +-- UnboundLocalError\n\
|
|
||||||
| |\n\
|
|
||||||
| +-- AttributeError\n\
|
|
||||||
| +-- SyntaxError\n\
|
|
||||||
| | |\n\
|
|
||||||
| | +-- IndentationError\n\
|
|
||||||
| | |\n\
|
|
||||||
| | +-- TabError\n\
|
|
||||||
| |\n\
|
|
||||||
| +-- TypeError\n\
|
|
||||||
| +-- AssertionError\n\
|
|
||||||
| +-- LookupError\n\
|
|
||||||
| | |\n\
|
|
||||||
| | +-- IndexError\n\
|
|
||||||
| | +-- KeyError\n\
|
|
||||||
| |\n\
|
|
||||||
| +-- ArithmeticError\n\
|
|
||||||
| | |\n\
|
|
||||||
| | +-- OverflowError\n\
|
|
||||||
| | +-- ZeroDivisionError\n\
|
|
||||||
| | +-- FloatingPointError\n\
|
|
||||||
| |\n\
|
|
||||||
| +-- ValueError\n\
|
|
||||||
| | |\n\
|
|
||||||
| | +-- UnicodeError\n\
|
|
||||||
| | |\n\
|
|
||||||
| | +-- UnicodeEncodeError\n\
|
|
||||||
| | +-- UnicodeDecodeError\n\
|
|
||||||
| | +-- UnicodeTranslateError\n\
|
|
||||||
| |\n\
|
|
||||||
| +-- ReferenceError\n\
|
|
||||||
| +-- SystemError\n\
|
|
||||||
| +-- MemoryError\n\
|
|
||||||
|\n\
|
|
||||||
+---Warning\n\
|
|
||||||
|\n\
|
|
||||||
+-- UserWarning\n\
|
|
||||||
+-- DeprecationWarning\n\
|
|
||||||
+-- PendingDeprecationWarning\n\
|
|
||||||
+-- SyntaxWarning\n\
|
|
||||||
+-- OverflowWarning\n\
|
|
||||||
+-- RuntimeWarning\n\
|
|
||||||
+-- FutureWarning"
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
/* Helper function for populating a dictionary with method wrappers. */
|
/* Helper function for populating a dictionary with method wrappers. */
|
||||||
static int
|
static int
|
||||||
populate_methods(PyObject *klass, PyObject *dict, PyMethodDef *methods)
|
populate_methods(PyObject *klass, PyMethodDef *methods)
|
||||||
{
|
{
|
||||||
PyObject *module;
|
PyObject *module;
|
||||||
int status = -1;
|
int status = -1;
|
||||||
|
@ -151,7 +72,7 @@ populate_methods(PyObject *klass, PyObject *dict, PyMethodDef *methods)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* add method to dictionary */
|
/* add method to dictionary */
|
||||||
status = PyDict_SetItemString(dict, methods->ml_name, meth);
|
status = PyObject_SetAttrString(klass, methods->ml_name, meth);
|
||||||
Py_DECREF(meth);
|
Py_DECREF(meth);
|
||||||
Py_DECREF(func);
|
Py_DECREF(func);
|
||||||
|
|
||||||
|
@ -196,7 +117,7 @@ make_class(PyObject **klass, PyObject *base,
|
||||||
if (!(*klass = PyErr_NewException(name, base, dict)))
|
if (!(*klass = PyErr_NewException(name, base, dict)))
|
||||||
goto finally;
|
goto finally;
|
||||||
|
|
||||||
if (populate_methods(*klass, dict, methods)) {
|
if (populate_methods(*klass, methods)) {
|
||||||
Py_DECREF(*klass);
|
Py_DECREF(*klass);
|
||||||
*klass = NULL;
|
*klass = NULL;
|
||||||
goto finally;
|
goto finally;
|
||||||
|
@ -232,47 +153,81 @@ get_self(PyObject *args)
|
||||||
/* Notes on bootstrapping the exception classes.
|
/* Notes on bootstrapping the exception classes.
|
||||||
*
|
*
|
||||||
* First thing we create is the base class for all exceptions, called
|
* First thing we create is the base class for all exceptions, called
|
||||||
* appropriately enough: Exception. Creation of this class makes no
|
* appropriately BaseException. Creation of this class makes no
|
||||||
* assumptions about the existence of any other exception class -- except
|
* assumptions about the existence of any other exception class -- except
|
||||||
* for TypeError, which can conditionally exist.
|
* for TypeError, which can conditionally exist.
|
||||||
*
|
*
|
||||||
* Next, StandardError is created (which is quite simple) followed by
|
* Next, Exception is created since it is the common subclass for the rest of
|
||||||
|
* the needed exceptions for this bootstrapping to work. StandardError is
|
||||||
|
* created (which is quite simple) followed by
|
||||||
* TypeError, because the instantiation of other exceptions can potentially
|
* TypeError, because the instantiation of other exceptions can potentially
|
||||||
* throw a TypeError. Once these exceptions are created, all the others
|
* throw a TypeError. Once these exceptions are created, all the others
|
||||||
* can be created in any order. See the static exctable below for the
|
* can be created in any order. See the static exctable below for the
|
||||||
* explicit bootstrap order.
|
* explicit bootstrap order.
|
||||||
*
|
*
|
||||||
* All classes after Exception can be created using PyErr_NewException().
|
* All classes after BaseException can be created using PyErr_NewException().
|
||||||
*/
|
*/
|
||||||
|
|
||||||
PyDoc_STRVAR(Exception__doc__, "Common base class for all exceptions.");
|
PyDoc_STRVAR(BaseException__doc__, "Common base class for all exceptions");
|
||||||
|
|
||||||
|
/*
|
||||||
|
Set args and message attributes.
|
||||||
|
|
||||||
|
Assumes self and args have already been set properly with set_self, etc.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
set_args_and_message(PyObject *self, PyObject *args)
|
||||||
|
{
|
||||||
|
PyObject *message_val;
|
||||||
|
Py_ssize_t args_len = PySequence_Length(args);
|
||||||
|
|
||||||
|
if (args_len < 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* set args */
|
||||||
|
if (PyObject_SetAttrString(self, "args", args) < 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* set message */
|
||||||
|
if (args_len == 1)
|
||||||
|
message_val = PySequence_GetItem(args, 0);
|
||||||
|
else
|
||||||
|
message_val = PyString_FromString("");
|
||||||
|
if (!message_val)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (PyObject_SetAttrString(self, "message", message_val) < 0) {
|
||||||
|
Py_DECREF(message_val);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Py_DECREF(message_val);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
Exception__init__(PyObject *self, PyObject *args)
|
BaseException__init__(PyObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
int status;
|
|
||||||
|
|
||||||
if (!(self = get_self(args)))
|
if (!(self = get_self(args)))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* set args attribute */
|
/* set args and message attribute */
|
||||||
/* XXX size is only a hint */
|
args = PySequence_GetSlice(args, 1, PySequence_Length(args));
|
||||||
args = PySequence_GetSlice(args, 1, PySequence_Size(args));
|
|
||||||
if (!args)
|
if (!args)
|
||||||
return NULL;
|
return NULL;
|
||||||
status = PyObject_SetAttrString(self, "args", args);
|
|
||||||
Py_DECREF(args);
|
|
||||||
if (status < 0)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
Py_INCREF(Py_None);
|
if (!set_args_and_message(self, args)) {
|
||||||
return Py_None;
|
Py_DECREF(args);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
Py_DECREF(args);
|
||||||
|
Py_RETURN_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
Exception__str__(PyObject *self, PyObject *args)
|
BaseException__str__(PyObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
PyObject *out;
|
PyObject *out;
|
||||||
|
|
||||||
|
@ -310,9 +265,116 @@ Exception__str__(PyObject *self, PyObject *args)
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef Py_USING_UNICODE
|
||||||
|
static PyObject *
|
||||||
|
BaseException__unicode__(PyObject *self, PyObject *args)
|
||||||
|
{
|
||||||
|
Py_ssize_t args_len;
|
||||||
|
|
||||||
|
if (!PyArg_ParseTuple(args, "O:__unicode__", &self))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
args = PyObject_GetAttrString(self, "args");
|
||||||
|
if (!args)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
args_len = PySequence_Size(args);
|
||||||
|
if (args_len < 0) {
|
||||||
|
Py_DECREF(args);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args_len == 0) {
|
||||||
|
Py_DECREF(args);
|
||||||
|
return PyUnicode_FromUnicode(NULL, 0);
|
||||||
|
}
|
||||||
|
else if (args_len == 1) {
|
||||||
|
PyObject *temp = PySequence_GetItem(args, 0);
|
||||||
|
if (!temp) {
|
||||||
|
Py_DECREF(args);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
Py_DECREF(args);
|
||||||
|
return PyObject_Unicode(temp);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Py_DECREF(args);
|
||||||
|
return PyObject_Unicode(args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* Py_USING_UNICODE */
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
Exception__getitem__(PyObject *self, PyObject *args)
|
BaseException__repr__(PyObject *self, PyObject *args)
|
||||||
|
{
|
||||||
|
PyObject *args_attr;
|
||||||
|
Py_ssize_t args_len;
|
||||||
|
PyObject *repr_suffix;
|
||||||
|
PyObject *repr;
|
||||||
|
|
||||||
|
if (!PyArg_ParseTuple(args, "O:__repr__", &self))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
args_attr = PyObject_GetAttrString(self, "args");
|
||||||
|
if (!args_attr)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
args_len = PySequence_Length(args_attr);
|
||||||
|
if (args_len < 0) {
|
||||||
|
Py_DECREF(args_attr);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args_len == 0) {
|
||||||
|
Py_DECREF(args_attr);
|
||||||
|
repr_suffix = PyString_FromString("()");
|
||||||
|
if (!repr_suffix)
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
PyObject *args_repr;
|
||||||
|
/*PyObject *right_paren;
|
||||||
|
|
||||||
|
repr_suffix = PyString_FromString("(*");
|
||||||
|
if (!repr_suffix) {
|
||||||
|
Py_DECREF(args_attr);
|
||||||
|
return NULL;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
args_repr = PyObject_Repr(args_attr);
|
||||||
|
Py_DECREF(args_attr);
|
||||||
|
if (!args_repr)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
repr_suffix = args_repr;
|
||||||
|
|
||||||
|
/*PyString_ConcatAndDel(&repr_suffix, args_repr);
|
||||||
|
if (!repr_suffix)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
right_paren = PyString_FromString(")");
|
||||||
|
if (!right_paren) {
|
||||||
|
Py_DECREF(repr_suffix);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
PyString_ConcatAndDel(&repr_suffix, right_paren);
|
||||||
|
if (!repr_suffix)
|
||||||
|
return NULL;*/
|
||||||
|
}
|
||||||
|
|
||||||
|
repr = PyString_FromString(self->ob_type->tp_name);
|
||||||
|
if (!repr) {
|
||||||
|
Py_DECREF(repr_suffix);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
PyString_ConcatAndDel(&repr, repr_suffix);
|
||||||
|
return repr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
BaseException__getitem__(PyObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
PyObject *out;
|
PyObject *out;
|
||||||
PyObject *index;
|
PyObject *index;
|
||||||
|
@ -331,21 +393,27 @@ Exception__getitem__(PyObject *self, PyObject *args)
|
||||||
|
|
||||||
|
|
||||||
static PyMethodDef
|
static PyMethodDef
|
||||||
Exception_methods[] = {
|
BaseException_methods[] = {
|
||||||
/* methods for the Exception class */
|
/* methods for the BaseException class */
|
||||||
{ "__getitem__", Exception__getitem__, METH_VARARGS},
|
{"__getitem__", BaseException__getitem__, METH_VARARGS},
|
||||||
{ "__str__", Exception__str__, METH_VARARGS},
|
{"__repr__", BaseException__repr__, METH_VARARGS},
|
||||||
{ "__init__", Exception__init__, METH_VARARGS},
|
{"__str__", BaseException__str__, METH_VARARGS},
|
||||||
{ NULL, NULL }
|
#ifdef Py_USING_UNICODE
|
||||||
|
{"__unicode__", BaseException__unicode__, METH_VARARGS},
|
||||||
|
#endif /* Py_USING_UNICODE */
|
||||||
|
{"__init__", BaseException__init__, METH_VARARGS},
|
||||||
|
{NULL, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
make_Exception(char *modulename)
|
make_BaseException(char *modulename)
|
||||||
{
|
{
|
||||||
PyObject *dict = PyDict_New();
|
PyObject *dict = PyDict_New();
|
||||||
PyObject *str = NULL;
|
PyObject *str = NULL;
|
||||||
PyObject *name = NULL;
|
PyObject *name = NULL;
|
||||||
|
PyObject *emptytuple = NULL;
|
||||||
|
PyObject *argstuple = NULL;
|
||||||
int status = -1;
|
int status = -1;
|
||||||
|
|
||||||
if (!dict)
|
if (!dict)
|
||||||
|
@ -360,20 +428,28 @@ make_Exception(char *modulename)
|
||||||
if (PyDict_SetItemString(dict, "__module__", str))
|
if (PyDict_SetItemString(dict, "__module__", str))
|
||||||
goto finally;
|
goto finally;
|
||||||
Py_DECREF(str);
|
Py_DECREF(str);
|
||||||
if (!(str = PyString_FromString(Exception__doc__)))
|
|
||||||
|
if (!(str = PyString_FromString(BaseException__doc__)))
|
||||||
goto finally;
|
goto finally;
|
||||||
if (PyDict_SetItemString(dict, "__doc__", str))
|
if (PyDict_SetItemString(dict, "__doc__", str))
|
||||||
goto finally;
|
goto finally;
|
||||||
|
|
||||||
if (!(name = PyString_FromString("Exception")))
|
if (!(name = PyString_FromString("BaseException")))
|
||||||
goto finally;
|
goto finally;
|
||||||
|
|
||||||
if (!(PyExc_Exception = PyClass_New(NULL, dict, name)))
|
if (!(emptytuple = PyTuple_New(0)))
|
||||||
|
goto finally;
|
||||||
|
|
||||||
|
if (!(argstuple = PyTuple_Pack(3, name, emptytuple, dict)))
|
||||||
|
goto finally;
|
||||||
|
|
||||||
|
if (!(PyExc_BaseException = PyType_Type.tp_new(&PyType_Type, argstuple,
|
||||||
|
NULL)))
|
||||||
goto finally;
|
goto finally;
|
||||||
|
|
||||||
/* Now populate the dictionary with the method suite */
|
/* Now populate the dictionary with the method suite */
|
||||||
if (populate_methods(PyExc_Exception, dict, Exception_methods))
|
if (populate_methods(PyExc_BaseException, BaseException_methods))
|
||||||
/* Don't need to reclaim PyExc_Exception here because that'll
|
/* Don't need to reclaim PyExc_BaseException here because that'll
|
||||||
* happen during interpreter shutdown.
|
* happen during interpreter shutdown.
|
||||||
*/
|
*/
|
||||||
goto finally;
|
goto finally;
|
||||||
|
@ -384,13 +460,18 @@ make_Exception(char *modulename)
|
||||||
Py_XDECREF(dict);
|
Py_XDECREF(dict);
|
||||||
Py_XDECREF(str);
|
Py_XDECREF(str);
|
||||||
Py_XDECREF(name);
|
Py_XDECREF(name);
|
||||||
|
Py_XDECREF(emptytuple);
|
||||||
|
Py_XDECREF(argstuple);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
PyDoc_STRVAR(Exception__doc__, "Common base class for all non-exit exceptions.");
|
||||||
|
|
||||||
PyDoc_STRVAR(StandardError__doc__,
|
PyDoc_STRVAR(StandardError__doc__,
|
||||||
"Base class for all standard Python exceptions.");
|
"Base class for all standard Python exceptions that do not represent"
|
||||||
|
"interpreter exiting.");
|
||||||
|
|
||||||
PyDoc_STRVAR(TypeError__doc__, "Inappropriate argument type.");
|
PyDoc_STRVAR(TypeError__doc__, "Inappropriate argument type.");
|
||||||
|
|
||||||
|
@ -411,14 +492,12 @@ SystemExit__init__(PyObject *self, PyObject *args)
|
||||||
if (!(self = get_self(args)))
|
if (!(self = get_self(args)))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* Set args attribute. */
|
|
||||||
if (!(args = PySequence_GetSlice(args, 1, PySequence_Size(args))))
|
if (!(args = PySequence_GetSlice(args, 1, PySequence_Size(args))))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
status = PyObject_SetAttrString(self, "args", args);
|
if (!set_args_and_message(self, args)) {
|
||||||
if (status < 0) {
|
Py_DECREF(args);
|
||||||
Py_DECREF(args);
|
return NULL;
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* set code attribute */
|
/* set code attribute */
|
||||||
|
@ -445,8 +524,7 @@ SystemExit__init__(PyObject *self, PyObject *args)
|
||||||
if (status < 0)
|
if (status < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
Py_INCREF(Py_None);
|
Py_RETURN_NONE;
|
||||||
return Py_None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -482,8 +560,12 @@ EnvironmentError__init__(PyObject *self, PyObject *args)
|
||||||
if (!(args = PySequence_GetSlice(args, 1, PySequence_Size(args))))
|
if (!(args = PySequence_GetSlice(args, 1, PySequence_Size(args))))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (PyObject_SetAttrString(self, "args", args) ||
|
if (!set_args_and_message(self, args)) {
|
||||||
PyObject_SetAttrString(self, "errno", Py_None) ||
|
Py_DECREF(args);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PyObject_SetAttrString(self, "errno", Py_None) ||
|
||||||
PyObject_SetAttrString(self, "strerror", Py_None) ||
|
PyObject_SetAttrString(self, "strerror", Py_None) ||
|
||||||
PyObject_SetAttrString(self, "filename", Py_None))
|
PyObject_SetAttrString(self, "filename", Py_None))
|
||||||
{
|
{
|
||||||
|
@ -624,9 +706,9 @@ EnvironmentError__str__(PyObject *self, PyObject *args)
|
||||||
* return StandardError.__str__(self)
|
* return StandardError.__str__(self)
|
||||||
*
|
*
|
||||||
* but there is no StandardError__str__() function; we happen to
|
* but there is no StandardError__str__() function; we happen to
|
||||||
* know that's just a pass through to Exception__str__().
|
* know that's just a pass through to BaseException__str__().
|
||||||
*/
|
*/
|
||||||
rtnval = Exception__str__(originalself, args);
|
rtnval = BaseException__str__(originalself, args);
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
Py_XDECREF(filename);
|
Py_XDECREF(filename);
|
||||||
|
@ -712,8 +794,10 @@ SyntaxError__init__(PyObject *self, PyObject *args)
|
||||||
if (!(args = PySequence_GetSlice(args, 1, PySequence_Size(args))))
|
if (!(args = PySequence_GetSlice(args, 1, PySequence_Size(args))))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (PyObject_SetAttrString(self, "args", args))
|
if (!set_args_and_message(self, args)) {
|
||||||
goto finally;
|
Py_DECREF(args);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
lenargs = PySequence_Size(args);
|
lenargs = PySequence_Size(args);
|
||||||
if (lenargs >= 1) {
|
if (lenargs >= 1) {
|
||||||
|
@ -879,8 +963,9 @@ KeyError__str__(PyObject *self, PyObject *args)
|
||||||
if (!PyArg_ParseTuple(args, "O:__str__", &self))
|
if (!PyArg_ParseTuple(args, "O:__str__", &self))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (!(argsattr = PyObject_GetAttrString(self, "args")))
|
argsattr = PyObject_GetAttrString(self, "args");
|
||||||
return NULL;
|
if (!argsattr)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
/* If args is a tuple of exactly one item, apply repr to args[0].
|
/* If args is a tuple of exactly one item, apply repr to args[0].
|
||||||
This is done so that e.g. the exception raised by {}[''] prints
|
This is done so that e.g. the exception raised by {}[''] prints
|
||||||
|
@ -889,14 +974,14 @@ KeyError__str__(PyObject *self, PyObject *args)
|
||||||
KeyError
|
KeyError
|
||||||
alone. The downside is that if KeyError is raised with an explanatory
|
alone. The downside is that if KeyError is raised with an explanatory
|
||||||
string, that string will be displayed in quotes. Too bad.
|
string, that string will be displayed in quotes. Too bad.
|
||||||
If args is anything else, use the default Exception__str__().
|
If args is anything else, use the default BaseException__str__().
|
||||||
*/
|
*/
|
||||||
if (PyTuple_Check(argsattr) && PyTuple_GET_SIZE(argsattr) == 1) {
|
if (PyTuple_Check(argsattr) && PyTuple_GET_SIZE(argsattr) == 1) {
|
||||||
PyObject *key = PyTuple_GET_ITEM(argsattr, 0);
|
PyObject *key = PyTuple_GET_ITEM(argsattr, 0);
|
||||||
result = PyObject_Repr(key);
|
result = PyObject_Repr(key);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
result = Exception__str__(self, args);
|
result = BaseException__str__(self, args);
|
||||||
|
|
||||||
Py_DECREF(argsattr);
|
Py_DECREF(argsattr);
|
||||||
return result;
|
return result;
|
||||||
|
@ -1193,6 +1278,11 @@ UnicodeError__init__(PyObject *self, PyObject *args, PyTypeObject *objecttype)
|
||||||
if (!(args = PySequence_GetSlice(args, 1, PySequence_Size(args))))
|
if (!(args = PySequence_GetSlice(args, 1, PySequence_Size(args))))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
if (!set_args_and_message(self, args)) {
|
||||||
|
Py_DECREF(args);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "O!O!O!O!O!",
|
if (!PyArg_ParseTuple(args, "O!O!O!O!O!",
|
||||||
&PyString_Type, &encoding,
|
&PyString_Type, &encoding,
|
||||||
objecttype, &object,
|
objecttype, &object,
|
||||||
|
@ -1201,9 +1291,6 @@ UnicodeError__init__(PyObject *self, PyObject *args, PyTypeObject *objecttype)
|
||||||
&PyString_Type, &reason))
|
&PyString_Type, &reason))
|
||||||
goto finally;
|
goto finally;
|
||||||
|
|
||||||
if (PyObject_SetAttrString(self, "args", args))
|
|
||||||
goto finally;
|
|
||||||
|
|
||||||
if (PyObject_SetAttrString(self, "encoding", encoding))
|
if (PyObject_SetAttrString(self, "encoding", encoding))
|
||||||
goto finally;
|
goto finally;
|
||||||
if (PyObject_SetAttrString(self, "object", object))
|
if (PyObject_SetAttrString(self, "object", object))
|
||||||
|
@ -1405,6 +1492,11 @@ UnicodeTranslateError__init__(PyObject *self, PyObject *args)
|
||||||
if (!(args = PySequence_GetSlice(args, 1, PySequence_Size(args))))
|
if (!(args = PySequence_GetSlice(args, 1, PySequence_Size(args))))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
if (!set_args_and_message(self, args)) {
|
||||||
|
Py_DECREF(args);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "O!O!O!O!",
|
if (!PyArg_ParseTuple(args, "O!O!O!O!",
|
||||||
&PyUnicode_Type, &object,
|
&PyUnicode_Type, &object,
|
||||||
&PyInt_Type, &start,
|
&PyInt_Type, &start,
|
||||||
|
@ -1412,9 +1504,6 @@ UnicodeTranslateError__init__(PyObject *self, PyObject *args)
|
||||||
&PyString_Type, &reason))
|
&PyString_Type, &reason))
|
||||||
goto finally;
|
goto finally;
|
||||||
|
|
||||||
if (PyObject_SetAttrString(self, "args", args))
|
|
||||||
goto finally;
|
|
||||||
|
|
||||||
if (PyObject_SetAttrString(self, "object", object))
|
if (PyObject_SetAttrString(self, "object", object))
|
||||||
goto finally;
|
goto finally;
|
||||||
if (PyObject_SetAttrString(self, "start", start))
|
if (PyObject_SetAttrString(self, "start", start))
|
||||||
|
@ -1424,8 +1513,8 @@ UnicodeTranslateError__init__(PyObject *self, PyObject *args)
|
||||||
if (PyObject_SetAttrString(self, "reason", reason))
|
if (PyObject_SetAttrString(self, "reason", reason))
|
||||||
goto finally;
|
goto finally;
|
||||||
|
|
||||||
Py_INCREF(Py_None);
|
|
||||||
rtnval = Py_None;
|
rtnval = Py_None;
|
||||||
|
Py_INCREF(rtnval);
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
Py_DECREF(args);
|
Py_DECREF(args);
|
||||||
|
@ -1591,6 +1680,7 @@ static PyMethodDef functions[] = {
|
||||||
|
|
||||||
/* Global C API defined exceptions */
|
/* Global C API defined exceptions */
|
||||||
|
|
||||||
|
PyObject *PyExc_BaseException;
|
||||||
PyObject *PyExc_Exception;
|
PyObject *PyExc_Exception;
|
||||||
PyObject *PyExc_StopIteration;
|
PyObject *PyExc_StopIteration;
|
||||||
PyObject *PyExc_GeneratorExit;
|
PyObject *PyExc_GeneratorExit;
|
||||||
|
@ -1636,7 +1726,7 @@ PyObject *PyExc_VMSError;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Pre-computed MemoryError instance. Best to create this as early as
|
/* Pre-computed MemoryError instance. Best to create this as early as
|
||||||
* possibly and not wait until a MemoryError is actually raised!
|
* possible and not wait until a MemoryError is actually raised!
|
||||||
*/
|
*/
|
||||||
PyObject *PyExc_MemoryErrorInst;
|
PyObject *PyExc_MemoryErrorInst;
|
||||||
|
|
||||||
|
@ -1663,9 +1753,10 @@ static struct {
|
||||||
int (*classinit)(PyObject *);
|
int (*classinit)(PyObject *);
|
||||||
} exctable[] = {
|
} exctable[] = {
|
||||||
/*
|
/*
|
||||||
* The first three classes MUST appear in exactly this order
|
* The first four classes MUST appear in exactly this order
|
||||||
*/
|
*/
|
||||||
{"Exception", &PyExc_Exception},
|
{"BaseException", &PyExc_BaseException},
|
||||||
|
{"Exception", &PyExc_Exception, &PyExc_BaseException, Exception__doc__},
|
||||||
{"StopIteration", &PyExc_StopIteration, &PyExc_Exception,
|
{"StopIteration", &PyExc_StopIteration, &PyExc_Exception,
|
||||||
StopIteration__doc__},
|
StopIteration__doc__},
|
||||||
{"GeneratorExit", &PyExc_GeneratorExit, &PyExc_Exception,
|
{"GeneratorExit", &PyExc_GeneratorExit, &PyExc_Exception,
|
||||||
|
@ -1676,9 +1767,10 @@ static struct {
|
||||||
/*
|
/*
|
||||||
* The rest appear in depth-first order of the hierarchy
|
* The rest appear in depth-first order of the hierarchy
|
||||||
*/
|
*/
|
||||||
{"SystemExit", &PyExc_SystemExit, &PyExc_Exception, SystemExit__doc__,
|
{"SystemExit", &PyExc_SystemExit, &PyExc_BaseException, SystemExit__doc__,
|
||||||
SystemExit_methods},
|
SystemExit_methods},
|
||||||
{"KeyboardInterrupt", &PyExc_KeyboardInterrupt, 0, KeyboardInterrupt__doc__},
|
{"KeyboardInterrupt", &PyExc_KeyboardInterrupt, &PyExc_BaseException,
|
||||||
|
KeyboardInterrupt__doc__},
|
||||||
{"ImportError", &PyExc_ImportError, 0, ImportError__doc__},
|
{"ImportError", &PyExc_ImportError, 0, ImportError__doc__},
|
||||||
{"EnvironmentError", &PyExc_EnvironmentError, 0, EnvironmentError__doc__,
|
{"EnvironmentError", &PyExc_EnvironmentError, 0, EnvironmentError__doc__,
|
||||||
EnvironmentError_methods},
|
EnvironmentError_methods},
|
||||||
|
@ -1786,11 +1878,11 @@ _PyExc_Init(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This is the base class of all exceptions, so make it first. */
|
/* This is the base class of all exceptions, so make it first. */
|
||||||
if (make_Exception(modulename) ||
|
if (make_BaseException(modulename) ||
|
||||||
PyDict_SetItemString(mydict, "Exception", PyExc_Exception) ||
|
PyDict_SetItemString(mydict, "BaseException", PyExc_BaseException) ||
|
||||||
PyDict_SetItemString(bdict, "Exception", PyExc_Exception))
|
PyDict_SetItemString(bdict, "BaseException", PyExc_BaseException))
|
||||||
{
|
{
|
||||||
Py_FatalError("Base class `Exception' could not be created.");
|
Py_FatalError("Base class `BaseException' could not be created.");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now we can programmatically create all the remaining exceptions.
|
/* Now we can programmatically create all the remaining exceptions.
|
||||||
|
|
|
@ -976,7 +976,7 @@ handle_system_exit(void)
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
if (value == NULL || value == Py_None)
|
if (value == NULL || value == Py_None)
|
||||||
goto done;
|
goto done;
|
||||||
if (PyInstance_Check(value)) {
|
if (PyExceptionInstance_Check(value)) {
|
||||||
/* The error code should be in the `code' attribute. */
|
/* The error code should be in the `code' attribute. */
|
||||||
PyObject *code = PyObject_GetAttrString(value, "code");
|
PyObject *code = PyObject_GetAttrString(value, "code");
|
||||||
if (code) {
|
if (code) {
|
||||||
|
@ -1106,11 +1106,10 @@ void PyErr_Display(PyObject *exception, PyObject *value, PyObject *tb)
|
||||||
if (err) {
|
if (err) {
|
||||||
/* Don't do anything else */
|
/* Don't do anything else */
|
||||||
}
|
}
|
||||||
else if (PyClass_Check(exception)) {
|
else if (PyExceptionClass_Check(exception)) {
|
||||||
PyClassObject* exc = (PyClassObject*)exception;
|
char* className = PyExceptionClass_Name(exception);
|
||||||
PyObject* className = exc->cl_name;
|
|
||||||
PyObject* moduleName =
|
PyObject* moduleName =
|
||||||
PyDict_GetItemString(exc->cl_dict, "__module__");
|
PyObject_GetAttrString(exception, "__module__");
|
||||||
|
|
||||||
if (moduleName == NULL)
|
if (moduleName == NULL)
|
||||||
err = PyFile_WriteString("<unknown>", f);
|
err = PyFile_WriteString("<unknown>", f);
|
||||||
|
@ -1126,8 +1125,7 @@ void PyErr_Display(PyObject *exception, PyObject *value, PyObject *tb)
|
||||||
if (className == NULL)
|
if (className == NULL)
|
||||||
err = PyFile_WriteString("<unknown>", f);
|
err = PyFile_WriteString("<unknown>", f);
|
||||||
else
|
else
|
||||||
err = PyFile_WriteObject(className, f,
|
err = PyFile_WriteString(className, f);
|
||||||
Py_PRINT_RAW);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
Loading…
Reference in New Issue