Skip to content

Commit fdca6d8

Browse files
committed
Demand version 2.5.1 since 2.5 has a bug with codecs.open context managers.
1 parent 1bb124a commit fdca6d8

4 files changed

Lines changed: 60 additions & 9 deletions

File tree

Doc/tools/sphinx-build.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@
1111

1212
if __name__ == '__main__':
1313

14-
if sys.version_info[:3] < (2, 5, 0):
14+
if sys.version_info[:3] < (2, 5, 1):
1515
print >>sys.stderr, """\
16-
Error: Sphinx needs to be executed with Python 2.5 or newer
16+
Error: Sphinx needs to be executed with Python 2.5.1 or newer
1717
(If you run this from the Makefile, you can set the PYTHON variable
1818
to the path of an alternative interpreter executable, e.g.,
1919
``make html PYTHON=python2.5``).

Lib/test/test_exceptions.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,16 @@
99
catch_warning)
1010
from test.test_pep352 import ignore_message_warning
1111

12+
class NaiveException(Exception):
13+
def __init__(self, x):
14+
self.x = x
15+
16+
class SomewhatNaiveException(Exception):
17+
def __init__(self, x):
18+
self.x = x
19+
Exception.__init__(self)
20+
21+
1222
# XXX This is not really enough, each *operation* should be tested!
1323

1424
class ExceptionTests(unittest.TestCase):
@@ -263,6 +273,10 @@ def testAttributes(self):
263273
{'message' : '', 'args' : (u'\u3042', 0, 1, 'ouch'),
264274
'object' : u'\u3042', 'reason' : 'ouch',
265275
'start' : 0, 'end' : 1}),
276+
(NaiveException, ('foo',),
277+
{'message': '', 'args': ('foo',), 'x': 'foo'}),
278+
(SomewhatNaiveException, ('foo',),
279+
{'message': '', 'args': (), 'x': 'foo'}),
266280
]
267281
try:
268282
exceptionList.append(
@@ -283,7 +297,8 @@ def testAttributes(self):
283297
if type(e) is not exc:
284298
raise
285299
# Verify module name
286-
self.assertEquals(type(e).__module__, 'exceptions')
300+
if not type(e).__name__.endswith('NaiveException'):
301+
self.assertEquals(type(e).__module__, 'exceptions')
287302
# Verify no ref leaks in Exc_str()
288303
s = str(e)
289304
for checkArgName in expected:

Objects/exceptions.c

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,18 +38,31 @@ BaseException_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
3838
/* the dict is created on the fly in PyObject_GenericSetAttr */
3939
self->message = self->dict = NULL;
4040

41-
self->args = PyTuple_New(0);
42-
if (!self->args) {
41+
if (!args) {
42+
/* MemoryError instantiation */
43+
args = PyTuple_New(0);
44+
if (!args) {
45+
Py_DECREF(self);
46+
return NULL;
47+
}
48+
} else {
49+
Py_INCREF(args);
50+
}
51+
52+
self->args = args;
53+
54+
/* Since the args can be overwritten in __init__, we have to store
55+
the original args somewhere for pickling. */
56+
if (PyObject_SetAttrString((PyObject *)self, "__newargs__", args) < 0) {
4357
Py_DECREF(self);
4458
return NULL;
4559
}
46-
60+
4761
self->message = PyString_FromString("");
4862
if (!self->message) {
4963
Py_DECREF(self);
5064
return NULL;
5165
}
52-
5366
return (PyObject *)self;
5467
}
5568

@@ -147,10 +160,23 @@ BaseException_repr(PyBaseExceptionObject *self)
147160
static PyObject *
148161
BaseException_reduce(PyBaseExceptionObject *self)
149162
{
163+
PyObject *result;
164+
PyObject *newargs = PyObject_GetAttrString((PyObject *)self, "__newargs__");
165+
if (!newargs) {
166+
if (PyErr_ExceptionMatches(PyExc_AttributeError)) {
167+
PyErr_SetString(PyExc_AttributeError,
168+
"To pickle exceptions via BaseException.__reduce__, "
169+
"you need to set the __newargs__ attribute in your "
170+
"custom __new__ method.");
171+
}
172+
return NULL;
173+
}
150174
if (self->args && self->dict)
151-
return PyTuple_Pack(3, Py_Type(self), self->args, self->dict);
175+
result = PyTuple_Pack(3, Py_Type(self), newargs, self->dict);
152176
else
153-
return PyTuple_Pack(2, Py_Type(self), self->args);
177+
result = PyTuple_Pack(2, Py_Type(self), newargs);
178+
Py_DECREF(newargs);
179+
return result;
154180
}
155181

156182
/*

Python/import.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1395,6 +1395,7 @@ find_module(char *fullname, char *subname, PyObject *path, char *buf,
13951395
filemode = fdp->mode;
13961396
if (filemode[0] == 'U')
13971397
filemode = "r" PY_STDIOTEXTMODE;
1398+
errno = 0;
13981399
fp = fopen(buf, filemode);
13991400
if (fp != NULL) {
14001401
if (case_ok(buf, len, namelen, name))
@@ -1404,6 +1405,15 @@ find_module(char *fullname, char *subname, PyObject *path, char *buf,
14041405
fp = NULL;
14051406
}
14061407
}
1408+
/* issue a warning if the file is there */
1409+
/*if (errno != ENOENT) {
1410+
char warnstr[MAXPATHLEN+80];
1411+
sprintf(warnstr, "Not importing '%.*s': ");
1412+
1413+
if (PyErr_Warn(PyExc_ImportWarning,
1414+
warnstr)) {
1415+
1416+
}*/
14071417
#if defined(PYOS_OS2)
14081418
/* restore the saved snapshot */
14091419
strcpy(buf, saved_buf);

0 commit comments

Comments
 (0)