[Python-checkins] r54013 - in python/branches/p3yk_no_args_on_exc: Include/pyerrors.h Lib/test/test_exception_variations.py Lib/test/test_exceptions.py Lib/test/test_pep352.py Misc/NEWS Objects/exceptions.c

brett.cannon python-checkins at python.org
Wed Feb 28 02:04:24 CET 2007


Author: brett.cannon
Date: Wed Feb 28 02:04:17 2007
New Revision: 54013

Modified:
   python/branches/p3yk_no_args_on_exc/Include/pyerrors.h
   python/branches/p3yk_no_args_on_exc/Lib/test/test_exception_variations.py
   python/branches/p3yk_no_args_on_exc/Lib/test/test_exceptions.py
   python/branches/p3yk_no_args_on_exc/Lib/test/test_pep352.py
   python/branches/p3yk_no_args_on_exc/Misc/NEWS
   python/branches/p3yk_no_args_on_exc/Objects/exceptions.c
Log:
Checkpoint of PyCon work done in local copy of p3yk.


Modified: python/branches/p3yk_no_args_on_exc/Include/pyerrors.h
==============================================================================
--- python/branches/p3yk_no_args_on_exc/Include/pyerrors.h	(original)
+++ python/branches/p3yk_no_args_on_exc/Include/pyerrors.h	Wed Feb 28 02:04:17 2007
@@ -9,14 +9,12 @@
 typedef struct {
     PyObject_HEAD
     PyObject *dict;
-    PyObject *args;
     PyObject *message;
 } PyBaseExceptionObject;
 
 typedef struct {
     PyObject_HEAD
     PyObject *dict;
-    PyObject *args;
     PyObject *message;
     PyObject *msg;
     PyObject *filename;
@@ -30,7 +28,6 @@
 typedef struct {
     PyObject_HEAD
     PyObject *dict;
-    PyObject *args;
     PyObject *message;
     PyObject *encoding;
     PyObject *object;
@@ -43,7 +40,6 @@
 typedef struct {
     PyObject_HEAD
     PyObject *dict;
-    PyObject *args;
     PyObject *message;
     PyObject *code;
 } PySystemExitObject;
@@ -51,7 +47,6 @@
 typedef struct {
     PyObject_HEAD
     PyObject *dict;
-    PyObject *args;
     PyObject *message;
     PyObject *myerrno;
     PyObject *strerror;
@@ -62,7 +57,6 @@
 typedef struct {
     PyObject_HEAD
     PyObject *dict;
-    PyObject *args;
     PyObject *message;
     PyObject *myerrno;
     PyObject *strerror;

Modified: python/branches/p3yk_no_args_on_exc/Lib/test/test_exception_variations.py
==============================================================================
--- python/branches/p3yk_no_args_on_exc/Lib/test/test_exception_variations.py	(original)
+++ python/branches/p3yk_no_args_on_exc/Lib/test/test_exception_variations.py	Wed Feb 28 02:04:17 2007
@@ -1,4 +1,3 @@
-
 from test.test_support import run_unittest
 import unittest
 

Modified: python/branches/p3yk_no_args_on_exc/Lib/test/test_exceptions.py
==============================================================================
--- python/branches/p3yk_no_args_on_exc/Lib/test/test_exceptions.py	(original)
+++ python/branches/p3yk_no_args_on_exc/Lib/test/test_exceptions.py	Wed Feb 28 02:04:17 2007
@@ -203,71 +203,51 @@
         # test that exception attributes are happy
 
         exceptionList = [
-            (BaseException, (), {'message' : '', 'args' : ()}),
-            (BaseException, (1, ), {'message' : 1, 'args' : (1,)}),
+            (BaseException, (), {'message' : ''}),
+            (BaseException, (1, ), {'message' : 1}),
             (BaseException, ('foo',),
-                {'message' : 'foo', 'args' : ('foo',)}),
-            (BaseException, ('foo', 1),
-                {'message' : '', 'args' : ('foo', 1)}),
+                {'message' : 'foo'}),
             (SystemExit, ('foo',),
-                {'message' : 'foo', 'args' : ('foo',), 'code' : 'foo'}),
+                {'message' : 'foo', 'code' : 'foo'}),
             (IOError, ('foo',),
-                {'message' : 'foo', 'args' : ('foo',), 'filename' : None,
-                 'errno' : None, 'strerror' : None}),
+                {'message' : 'foo', 'filename' : None, 'errno' : 'foo',
+                    'strerror' : None}),
             (IOError, ('foo', 'bar'),
-                {'message' : '', 'args' : ('foo', 'bar'), 'filename' : None,
-                 'errno' : 'foo', 'strerror' : 'bar'}),
+                {'message' : 'foo', 'filename' : None, 'errno' : 'foo',
+                    'strerror' : 'bar'}),
             (IOError, ('foo', 'bar', 'baz'),
-                {'message' : '', 'args' : ('foo', 'bar'), 'filename' : 'baz',
-                 'errno' : 'foo', 'strerror' : 'bar'}),
-            (IOError, ('foo', 'bar', 'baz', 'quux'),
-                {'message' : '', 'args' : ('foo', 'bar', 'baz', 'quux')}),
+                {'message' : 'foo', 'filename' : 'baz', 'errno' : 'foo',
+                    'strerror' : 'bar'}),
             (EnvironmentError, ('errnoStr', 'strErrorStr', 'filenameStr'),
-                {'message' : '', 'args' : ('errnoStr', 'strErrorStr'),
-                 'strerror' : 'strErrorStr', 'errno' : 'errnoStr',
-                 'filename' : 'filenameStr'}),
+                {'message' : 'errnoStr', 'strerror' : 'strErrorStr',
+                    'errno' : 'errnoStr', 'filename' : 'filenameStr'}),
             (EnvironmentError, (1, 'strErrorStr', 'filenameStr'),
-                {'message' : '', 'args' : (1, 'strErrorStr'), 'errno' : 1,
-                 'strerror' : 'strErrorStr', 'filename' : 'filenameStr'}),
+                {'message' : 1, 'errno' : 1, 'strerror' : 'strErrorStr',
+                    'filename' : 'filenameStr'}),
             (SyntaxError, ('msgStr',),
-                {'message' : 'msgStr', 'args' : ('msgStr',), 'text' : None,
-                 'print_file_and_line' : None, 'msg' : 'msgStr',
+                {'message' : 'msgStr', 'text' : None,
+                    'print_file_and_line' : None, 'msg' : 'msgStr',
                  'filename' : None, 'lineno' : None, 'offset' : None}),
             (SyntaxError, ('msgStr', ('filenameStr', 'linenoStr', 'offsetStr',
                            'textStr')),
-                {'message' : '', 'offset' : 'offsetStr', 'text' : 'textStr',
-                 'args' : ('msgStr', ('filenameStr', 'linenoStr',
-                                      'offsetStr', 'textStr')),
+                {'message' : 'msgStr', 'offset' : 'offsetStr', 'text' : 'textStr',
                  'print_file_and_line' : None, 'msg' : 'msgStr',
                  'filename' : 'filenameStr', 'lineno' : 'linenoStr'}),
-            (SyntaxError, ('msgStr', 'filenameStr', 'linenoStr', 'offsetStr',
-                           'textStr', 'print_file_and_lineStr'),
-                {'message' : '', 'text' : None,
-                 'args' : ('msgStr', 'filenameStr', 'linenoStr', 'offsetStr',
-                           'textStr', 'print_file_and_lineStr'),
-                 'print_file_and_line' : None, 'msg' : 'msgStr',
-                 'filename' : None, 'lineno' : None, 'offset' : None}),
-            (UnicodeError, (), {'message' : '', 'args' : (),}),
+            (UnicodeError, (), {'message' : ''}),
             (UnicodeEncodeError, ('ascii', u'a', 0, 1, 'ordinal not in range'),
-                {'message' : '', 'args' : ('ascii', u'a', 0, 1,
-                                           'ordinal not in range'),
-                 'encoding' : 'ascii', 'object' : u'a',
+                {'message' : 'ascii', 'encoding' : 'ascii', 'object' : u'a',
                  'start' : 0, 'reason' : 'ordinal not in range'}),
             (UnicodeDecodeError, ('ascii', '\xff', 0, 1, 'ordinal not in range'),
-                {'message' : '', 'args' : ('ascii', '\xff', 0, 1,
-                                           'ordinal not in range'),
-                 'encoding' : 'ascii', 'object' : '\xff',
+                {'message' : 'ascii', 'encoding' : 'ascii', 'object' : '\xff',
                  'start' : 0, 'reason' : 'ordinal not in range'}),
             (UnicodeTranslateError, (u"\u3042", 0, 1, "ouch"),
-                {'message' : '', 'args' : (u'\u3042', 0, 1, 'ouch'),
-                 'object' : u'\u3042', 'reason' : 'ouch',
+                {'message' : u"\u3042", 'object' : u'\u3042', 'reason' : 'ouch',
                  'start' : 0, 'end' : 1}),
         ]
         try:
             exceptionList.append(
                 (WindowsError, (1, 'strErrorStr', 'filenameStr'),
-                    {'message' : '', 'args' : (1, 'strErrorStr'),
-                     'strerror' : 'strErrorStr', 'winerror' : 1,
+                    {'message' : 1, 'strerror' : 'strErrorStr', 'winerror' : 1,
                      'errno' : 22, 'filename' : 'filenameStr'})
             )
         except NameError:
@@ -279,15 +259,17 @@
             except BaseException as e:
                 if type(e) is not exc:
                     raise
+                print(repr(e), ':', args)
                 # Verify module name
                 self.assertEquals(type(e).__module__, '__builtin__')
                 # Verify no ref leaks in Exc_str()
                 s = str(e)
                 for checkArgName in expected:
-                    self.assertEquals(repr(getattr(e, checkArgName)),
-                                      repr(expected[checkArgName]),
-                                      'exception "%s", attribute "%s"' %
-                                       (repr(e), checkArgName))
+                    got = repr(getattr(e, checkArgName))
+                    want = repr(expected[checkArgName])
+                    self.assertEquals(got, want,
+                                      'exception "%s", attribute %s: %r != %r' %
+                                       (repr(e), checkArgName, got, want))
 
                 # test for pickling support
                 for p in pickle, cPickle:
@@ -299,8 +281,9 @@
                             got = repr(getattr(new, checkArgName))
                             want = repr(expected[checkArgName])
                             self.assertEquals(got, want,
-                                              'pickled "%r", attribute "%s' %
-                                              (e, checkArgName))
+                                                'pickled "%r", attribute %s: '
+                                                '%r != %r' %
+                                              (e, checkArgName, got, want))
 
     def testKeywordArgs(self):
         # test that builtin exception don't take keyword args,

Modified: python/branches/p3yk_no_args_on_exc/Lib/test/test_pep352.py
==============================================================================
--- python/branches/p3yk_no_args_on_exc/Lib/test/test_pep352.py	(original)
+++ python/branches/p3yk_no_args_on_exc/Lib/test/test_pep352.py	Wed Feb 28 02:04:17 2007
@@ -14,7 +14,7 @@
         self.failUnless(issubclass(Exception, object))
 
     def verify_instance_interface(self, ins):
-        for attr in ("args", "message", "__str__", "__repr__"):
+        for attr in ("message", "__str__", "__repr__"):
             self.failUnless(hasattr(ins, attr), "%s missing %s attribute" %
                     (ins.__class__.__name__, attr))
 
@@ -27,7 +27,6 @@
                     exc_set.add(object_.__name__)
             except TypeError:
                 pass
-
         inheritance_tree = open(os.path.join(os.path.split(__file__)[0],
                                                 'exception_hierarchy.txt'))
         try:
@@ -78,39 +77,37 @@
             inheritance_tree.close()
         self.failUnlessEqual(len(exc_set), 0, "%s not accounted for" % exc_set)
 
-    interface_tests = ("length", "args", "message", "str", "unicode", "repr")
+    interface_tests = ("message", "str", "unicode", "repr")
 
     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 make_repr(self, exc, message=None):
+        """Generate the expected str/repr of an exception based on the message
+        and a converter function."""
+        name = exc.__class__.__name__
+        if message:
+            args = '(%r)' % message
+        else:
+            args = '()'
+        return name + args
+
     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)])
-        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)])
+        results = ([exc.message, arg], [str(exc), str(arg)],
+                    [unicode(exc), unicode(arg)],
+                    [repr(exc), self.make_repr(exc, arg)])
         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__ + '()'])
+        results = ([exc.message, ''], [str(exc), ''], [unicode(exc), u''],
+                [repr(exc), self.make_repr(exc)])
         self.interface_test_driver(results)
 
 class UsageTests(unittest.TestCase):

Modified: python/branches/p3yk_no_args_on_exc/Misc/NEWS
==============================================================================
--- python/branches/p3yk_no_args_on_exc/Misc/NEWS	(original)
+++ python/branches/p3yk_no_args_on_exc/Misc/NEWS	Wed Feb 28 02:04:17 2007
@@ -28,7 +28,13 @@
 Core and Builtins
 -----------------
 
-- Removing indexing/slicing on BaseException.
+- SyntaxError now enforces the requirement of having two arguments, second of
+  which is a four-item tuple.
+
+- EnvironmentError always binds its first argument to 'message' and 'errno'.
+  Also don't call with no more than 3 arguments.
+
+- Remove indexing/slicing on BaseException.
 
 - Remove the exceptions module, all the exceptions are already builtin.
 

Modified: python/branches/p3yk_no_args_on_exc/Objects/exceptions.c
==============================================================================
--- python/branches/p3yk_no_args_on_exc/Objects/exceptions.c	(original)
+++ python/branches/p3yk_no_args_on_exc/Objects/exceptions.c	Wed Feb 28 02:04:17 2007
@@ -9,8 +9,6 @@
 #include "structmember.h"
 #include "osdefs.h"
 
-#define MAKE_IT_NONE(x) (x) = Py_None; Py_INCREF(Py_None);
-
 /* NOTE: If the exception class hierarchy changes, don't forget to update
  * Lib/test/exception_hierarchy.txt
  */
@@ -27,12 +25,6 @@
     /* the dict is created on the fly in PyObject_GenericSetAttr */
     self->message = self->dict = NULL;
 
-    self->args = PyTuple_New(0);
-    if (!self->args) {
-        Py_DECREF(self);
-        return NULL;
-    }
-
     self->message = PyString_FromString("");
     if (!self->message) {
         Py_DECREF(self);
@@ -45,26 +37,50 @@
 static int
 BaseException_init(PyBaseExceptionObject *self, PyObject *args, PyObject *kwds)
 {
+    PyObject *message = NULL;
+
     if (!_PyArg_NoKeywords(self->ob_type->tp_name, kwds))
         return -1;
 
-    Py_DECREF(self->args);
-    self->args = args;
-    Py_INCREF(self->args);
-
-    if (PyTuple_GET_SIZE(self->args) == 1) {
-        Py_CLEAR(self->message);
-        self->message = PyTuple_GET_ITEM(self->args, 0);
-        Py_INCREF(self->message);
+    if (!PyArg_ParseTuple(args, "|O", &message))
+	    return -1;
+
+    if (message) {
+	Py_CLEAR(self->message);
+        self->message = message;
+	Py_INCREF(self->message);
     }
+
     return 0;
 }
 
 static int
+BaseException_super_init(PyBaseExceptionObject *self, PyObject *args,
+				PyObject *kwds)
+{
+    PyObject *short_tuple = NULL;
+    PyObject *tuple_item = NULL;
+    int ret;
+
+    /* BaseException.__init__ can handle an argument tuple of length 0 or 1. */
+    if (PyTuple_GET_SIZE(args) <= 1)
+        return BaseException_init(self, args, kwds);
+ 
+    short_tuple = PyTuple_New(1);
+    if (!short_tuple)
+	    return -1;
+    tuple_item = PyTuple_GET_ITEM(args, 0);
+    PyTuple_SET_ITEM(short_tuple, 0, tuple_item);
+    Py_INCREF(tuple_item);
+    ret = BaseException_init(self, short_tuple, kwds);
+    Py_DECREF(short_tuple);
+    return ret;
+}
+
+static int
 BaseException_clear(PyBaseExceptionObject *self)
 {
     Py_CLEAR(self->dict);
-    Py_CLEAR(self->args);
     Py_CLEAR(self->message);
     return 0;
 }
@@ -81,7 +97,6 @@
 BaseException_traverse(PyBaseExceptionObject *self, visitproc visit, void *arg)
 {
     Py_VISIT(self->dict);
-    Py_VISIT(self->args);
     Py_VISIT(self->message);
     return 0;
 }
@@ -89,34 +104,34 @@
 static PyObject *
 BaseException_str(PyBaseExceptionObject *self)
 {
-    PyObject *out;
-
-    switch (PyTuple_GET_SIZE(self->args)) {
-    case 0:
-        out = PyString_FromString("");
-        break;
-    case 1:
-        out = PyObject_Str(PyTuple_GET_ITEM(self->args, 0));
-        break;
-    default:
-        out = PyObject_Str(self->args);
-        break;
-    }
-
-    return out;
+    return PyObject_Str(self->message);
 }
 
 static PyObject *
 BaseException_repr(PyBaseExceptionObject *self)
 {
     PyObject *repr_suffix;
+    PyObject *message_repr;
     PyObject *repr;
     char *name;
     char *dot;
 
-    repr_suffix = PyObject_Repr(self->args);
-    if (!repr_suffix)
-        return NULL;
+    if (PyString_Check(self->message) && PyString_Size(self->message) == 0) {
+        repr_suffix = PyString_FromString("()");
+    }
+    else {
+        message_repr = PyObject_Repr(self->message);
+        if (!message_repr)
+            return NULL;
+
+        repr_suffix = PyString_FromFormat("(%s)",
+                                            PyString_AS_STRING(message_repr));
+        if (!repr_suffix) {
+            Py_DECREF(message_repr);
+            return NULL;
+        }
+        Py_DECREF(message_repr);
+    }
 
     name = (char *)self->ob_type->tp_name;
     dot = strrchr(name, '.');
@@ -136,10 +151,11 @@
 static PyObject *
 BaseException_reduce(PyBaseExceptionObject *self)
 {
-    if (self->args && self->dict)
-        return PyTuple_Pack(3, self->ob_type, self->args, self->dict);
+    if (self->dict)
+        return Py_BuildValue("(O, (O), O)", self->ob_type, self->message,
+				self->dict);
     else
-        return PyTuple_Pack(2, self->ob_type, self->args);
+        return Py_BuildValue("(O, (O))", self->ob_type, self->message);
 }
 
 /*
@@ -210,35 +226,9 @@
     return 0;
 }
 
-static PyObject *
-BaseException_get_args(PyBaseExceptionObject *self)
-{
-    if (self->args == NULL) {
-        Py_INCREF(Py_None);
-        return Py_None;
-    }
-    Py_INCREF(self->args);
-    return self->args;
-}
-
-static int
-BaseException_set_args(PyBaseExceptionObject *self, PyObject *val)
-{
-    PyObject *seq;
-    if (val == NULL) {
-        PyErr_SetString(PyExc_TypeError, "args may not be deleted");
-        return -1;
-    }
-    seq = PySequence_Tuple(val);
-    if (!seq) return -1;
-    Py_CLEAR(self->args);
-    self->args = seq;
-    return 0;
-}
 
 static PyGetSetDef BaseException_getset[] = {
     {"__dict__", (getter)BaseException_get_dict, (setter)BaseException_set_dict},
-    {"args", (getter)BaseException_get_args, (setter)BaseException_set_args},
     {NULL},
 };
 
@@ -388,7 +378,8 @@
 {
     Py_ssize_t size = PyTuple_GET_SIZE(args);
 
-    if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
+    if (BaseException_super_init((PyBaseExceptionObject *)self, args, kwds) ==
+       	-1)
         return -1;
 
     if (size == 0)
@@ -453,29 +444,26 @@
 /*
  *    EnvironmentError extends StandardError
  */
-
-/* Where a function has a single filename, such as open() or some
- * of the os module functions, PyErr_SetFromErrnoWithFilename() is
- * called, giving a third argument which is the filename.  But, so
- * that old code using in-place unpacking doesn't break, e.g.:
- *
- * except IOError, (errno, strerror):
- *
- * we hack args so that it only contains two items.  This also
- * means we need our own __str__() which prints out the filename
- * when it was supplied.
- */
 static int
 EnvironmentError_init(PyEnvironmentErrorObject *self, PyObject *args,
     PyObject *kwds)
 {
     PyObject *myerrno = NULL, *strerror = NULL, *filename = NULL;
-    PyObject *subslice = NULL;
+    Py_ssize_t args_len = 0;
 
-    if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
+    if (BaseException_super_init((PyBaseExceptionObject *)self, args, kwds) ==
+		    -1)
         return -1;
 
-    if (PyTuple_GET_SIZE(args) <= 1 || PyTuple_GET_SIZE(args) > 3) {
+    args_len = PyTuple_GET_SIZE(args);
+
+    if (args_len == 0 || args_len == 1) {
+        Py_INCREF(self->message);
+        self->myerrno = self->message;
+        Py_INCREF(Py_None);
+        self->strerror = Py_None;
+        Py_INCREF(Py_None);
+        self->filename = Py_None;
         return 0;
     }
 
@@ -496,13 +484,10 @@
         Py_CLEAR(self->filename);      /* replacing */
         self->filename = filename;
         Py_INCREF(self->filename);
-
-        subslice = PyTuple_GetSlice(args, 0, 2);
-        if (!subslice)
-            return -1;
-
-        Py_DECREF(self->args);  /* replacing args */
-        self->args = subslice;
+    }
+    else {
+        Py_INCREF(Py_None);
+        self->filename = Py_None;
     }
     return 0;
 }
@@ -560,22 +545,11 @@
             return NULL;
         }
 
-        if (self->myerrno) {
-            Py_INCREF(self->myerrno);
-            PyTuple_SET_ITEM(tuple, 0, self->myerrno);
-        }
-        else {
-            Py_INCREF(Py_None);
-            PyTuple_SET_ITEM(tuple, 0, Py_None);
-        }
-        if (self->strerror) {
-            Py_INCREF(self->strerror);
-            PyTuple_SET_ITEM(tuple, 1, self->strerror);
-        }
-        else {
-            Py_INCREF(Py_None);
-            PyTuple_SET_ITEM(tuple, 1, Py_None);
-        }
+        Py_INCREF(self->myerrno);
+        PyTuple_SET_ITEM(tuple, 0, self->myerrno);
+        
+        Py_INCREF(self->strerror);
+        PyTuple_SET_ITEM(tuple, 1, self->strerror);
 
         PyTuple_SET_ITEM(tuple, 2, repr);
 
@@ -642,27 +616,26 @@
 static PyObject *
 EnvironmentError_reduce(PyEnvironmentErrorObject *self)
 {
-    PyObject *args = self->args;
-    PyObject *res = NULL, *tmp;
+    PyObject *args = PyTuple_New(3);
+    PyObject *res = NULL;
+
+    if (!args)
+        return NULL;
+
+        if (self->myerrno == Py_None) {
+            Py_INCREF(self->message);
+            PyTuple_SET_ITEM(args, 0, self->message);
+        }
+        else {
+            Py_INCREF(self->myerrno);
+            PyTuple_SET_ITEM(args, 0, self->myerrno);
+        }
 
-    /* self->args is only the first two real arguments if there was a
-     * file name given to EnvironmentError. */
-    if (PyTuple_GET_SIZE(args) == 2 && self->filename) {
-        args = PyTuple_New(3);
-        if (!args) return NULL;
-
-        tmp = PyTuple_GET_ITEM(self->args, 0);
-        Py_INCREF(tmp);
-        PyTuple_SET_ITEM(args, 0, tmp);
-
-        tmp = PyTuple_GET_ITEM(self->args, 1);
-        Py_INCREF(tmp);
-        PyTuple_SET_ITEM(args, 1, tmp);
+        Py_INCREF(self->strerror);
+        PyTuple_SET_ITEM(args, 1, self->strerror);
 
         Py_INCREF(self->filename);
         PyTuple_SET_ITEM(args, 2, self->filename);
-    } else
-        Py_INCREF(args);
 
     if (self->dict)
         res = PyTuple_Pack(3, self->ob_type, args, self->dict);
@@ -938,15 +911,25 @@
     PyObject *info = NULL;
     Py_ssize_t lenargs = PyTuple_GET_SIZE(args);
 
-    if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
+    if (BaseException_super_init((PyBaseExceptionObject *)self, args, kwds) ==
+		    -1)
         return -1;
 
-    if (lenargs >= 1) {
-        Py_CLEAR(self->msg);
-        self->msg = PyTuple_GET_ITEM(args, 0);
-        Py_INCREF(self->msg);
+    Py_CLEAR(self->msg);
+    self->msg = self->message;
+    Py_INCREF(self->msg);
+
+    if (lenargs == 1) {
+        Py_INCREF(Py_None);
+        self->filename = Py_None;
+        Py_INCREF(Py_None);
+        self->lineno = Py_None;
+        Py_INCREF(Py_None);
+        self->offset = Py_None;
+        Py_INCREF(Py_None);
+        self->text = Py_None;
     }
-    if (lenargs == 2) {
+    else if (lenargs == 2) {
         info = PyTuple_GET_ITEM(args, 1);
         info = PySequence_Tuple(info);
         if (!info) return -1;
@@ -976,6 +959,10 @@
 
         Py_DECREF(info);
     }
+    else {
+        PyErr_SetString(PyExc_TypeError, "expect either 0, 1, or 2 arguments");
+        return -1;
+    }
     return 0;
 }
 
@@ -1091,6 +1078,26 @@
     return result;
 }
 
+
+static PyObject *
+SyntaxError_reduce(PySyntaxErrorObject *self)
+{
+    if (self->dict)
+        return Py_BuildValue("(O, (O, (O, O, O, O)), O)", self->ob_type,
+                self->message, self->filename, self->lineno,
+                self->offset, self->text, self->dict);
+    else
+        return Py_BuildValue("(O, (O, (O, O, O, O)))", self->ob_type,
+                self->message, self->filename, self->lineno,
+                self->offset, self->text);
+}
+
+
+static PyMethodDef SyntaxError_methods[] = {
+    {"__reduce__", (PyCFunction)SyntaxError_reduce, METH_NOARGS},
+    {NULL}
+};
+
 static PyMemberDef SyntaxError_members[] = {
     {"message", T_OBJECT, offsetof(PySyntaxErrorObject, message), 0,
         PyDoc_STR("exception message")},
@@ -1110,9 +1117,11 @@
     {NULL}  /* Sentinel */
 };
 
+
 ComplexExtendsException(PyExc_StandardError, SyntaxError, SyntaxError,
-                        SyntaxError_dealloc, 0, SyntaxError_members,
-                        SyntaxError_str, "Invalid syntax.");
+                        SyntaxError_dealloc, SyntaxError_methods,
+                        SyntaxError_members, SyntaxError_str,
+                        "Invalid syntax.");
 
 
 /*
@@ -1158,9 +1167,9 @@
        string, that string will be displayed in quotes.  Too bad.
        If args is anything else, use the default BaseException__str__().
     */
-    if (PyTuple_GET_SIZE(self->args) == 1) {
-        return PyObject_Repr(PyTuple_GET_ITEM(self->args, 0));
-    }
+    if (PyString_Check(self->message) && PyString_Size(self->message) == 0)
+        return PyObject_Repr(self->message);
+ 
     return BaseException_str(self);
 }
 
@@ -1549,7 +1558,8 @@
 static int
 UnicodeEncodeError_init(PyObject *self, PyObject *args, PyObject *kwds)
 {
-    if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
+    if (BaseException_super_init((PyBaseExceptionObject *)self, args, kwds) ==
+		    -1)
         return -1;
     return UnicodeError_init((PyUnicodeErrorObject *)self, args,
                              kwds, &PyUnicode_Type);
@@ -1625,7 +1635,8 @@
 static int
 UnicodeDecodeError_init(PyObject *self, PyObject *args, PyObject *kwds)
 {
-    if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
+    if (BaseException_super_init((PyBaseExceptionObject *)self, args, kwds) ==
+		    -1)
         return -1;
     return UnicodeError_init((PyUnicodeErrorObject *)self, args,
                              kwds, &PyString_Type);
@@ -1701,7 +1712,8 @@
 UnicodeTranslateError_init(PyUnicodeErrorObject *self, PyObject *args,
                            PyObject *kwds)
 {
-    if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
+    if (BaseException_super_init((PyBaseExceptionObject *)self, args, kwds) ==
+		    -1)
         return -1;
 
     Py_CLEAR(self->object);


More information about the Python-checkins mailing list