summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Doc/bugs.rst10
-rw-r--r--Doc/whatsnew/2.6.rst14
-rw-r--r--Lib/test/test_fnmatch.py10
-rw-r--r--Lib/test/test_strftime.py11
-rw-r--r--Misc/NEWS3
-rw-r--r--Modules/selectmodule.c31
6 files changed, 41 insertions, 38 deletions
diff --git a/Doc/bugs.rst b/Doc/bugs.rst
index dc7d388..4db2433 100644
--- a/Doc/bugs.rst
+++ b/Doc/bugs.rst
@@ -23,10 +23,9 @@ In the case of documentation bugs, look at the most recent development docs at
http://docs.python.org/dev to see if the bug has been fixed.
If the problem you're reporting is not already in the bug tracker, go back to
-the Python Bug Tracker. If you don't already have a tracker account, select the
-"Register" link in the sidebar and undergo the registration procedure.
-Otherwise, if you're not logged in, enter your credentials and select "Login".
-It is not possible to submit a bug report anonymously.
+the Python Bug Tracker and log in. If you don't already have a tracker account,
+select the "Register" link or, if you use OpenID, one of the OpenID provider
+logos in the sidebar. It is not possible to submit a bug report anonymously.
Being now logged in, you can submit a bug. Select the "Create New" link in the
sidebar to open the bug reporting form.
@@ -43,7 +42,8 @@ were using (including version information as appropriate).
Each bug report will be assigned to a developer who will determine what needs to
be done to correct the problem. You will receive an update each time action is
-taken on the bug.
+taken on the bug. See http://www.python.org/dev/workflow/ for a detailed
+description of the issue workflow.
.. seealso::
diff --git a/Doc/whatsnew/2.6.rst b/Doc/whatsnew/2.6.rst
index 7c59022..1952032 100644
--- a/Doc/whatsnew/2.6.rst
+++ b/Doc/whatsnew/2.6.rst
@@ -350,9 +350,10 @@ A high-level explanation of the context management protocol is:
* The code in *BLOCK* is executed.
-* If *BLOCK* raises an exception, the :meth:`__exit__(type, value, traceback)`
- is called with the exception details, the same values returned by
- :func:`sys.exc_info`. The method's return value controls whether the exception
+* If *BLOCK* raises an exception, the context manager's :meth:`__exit__` method
+ is called with three arguments, the exception details (``type, value, traceback``,
+ the same values returned by :func:`sys.exc_info`, which can also be ``None``
+ if no exception occurred). The method's return value controls whether an exception
is re-raised: any false value re-raises the exception, and ``True`` will result
in suppressing it. You'll only rarely want to suppress the exception, because
if you do the author of the code containing the ':keyword:`with`' statement will
@@ -463,7 +464,7 @@ could be written as::
with db_transaction(db) as cursor:
...
-The :mod:`contextlib` module also has a :func:`nested(mgr1, mgr2, ...)` function
+The :mod:`contextlib` module also has a ``nested(mgr1, mgr2, ...)`` function
that combines a number of context managers so you don't need to write nested
':keyword:`with`' statements. In this example, the single ':keyword:`with`'
statement both starts a database transaction and acquires a thread lock::
@@ -472,8 +473,9 @@ statement both starts a database transaction and acquires a thread lock::
with nested (db_transaction(db), lock) as (cursor, locked):
...
-Finally, the :func:`closing(object)` function returns *object* so that it can be
-bound to a variable, and calls ``object.close`` at the end of the block. ::
+Finally, the :func:`closing` function returns its argument so that it can be
+bound to a variable, and calls the argument's ``.close()`` method at the end
+of the block. ::
import urllib, sys
from contextlib import closing
diff --git a/Lib/test/test_fnmatch.py b/Lib/test/test_fnmatch.py
index 2b51099..6d2f9ad 100644
--- a/Lib/test/test_fnmatch.py
+++ b/Lib/test/test_fnmatch.py
@@ -7,13 +7,13 @@ from fnmatch import fnmatch, fnmatchcase
class FnmatchTestCase(unittest.TestCase):
- def check_match(self, filename, pattern, should_match=1):
+ def check_match(self, filename, pattern, should_match=1, fn=fnmatch):
if should_match:
- self.assertTrue(fnmatch(filename, pattern),
+ self.assertTrue(fn(filename, pattern),
"expected %r to match pattern %r"
% (filename, pattern))
else:
- self.assertTrue(not fnmatch(filename, pattern),
+ self.assertTrue(not fn(filename, pattern),
"expected %r not to match pattern %r"
% (filename, pattern))
@@ -52,8 +52,8 @@ class FnmatchTestCase(unittest.TestCase):
def test_fnmatchcase(self):
check = self.check_match
- check('AbC', 'abc', 0)
- check('abc', 'AbC', 0)
+ check('AbC', 'abc', 0, fnmatchcase)
+ check('abc', 'AbC', 0, fnmatchcase)
def test_bytes(self):
self.check_match(b'test', b'te*')
diff --git a/Lib/test/test_strftime.py b/Lib/test/test_strftime.py
index 41144b7..14057eb 100644
--- a/Lib/test/test_strftime.py
+++ b/Lib/test/test_strftime.py
@@ -116,16 +116,15 @@ class StrftimeTest(unittest.TestCase):
try:
result = time.strftime(e[0], now)
except ValueError as error:
- print("Standard '%s' format gaver error:" % (e[0], error))
- continue
+ self.fail("strftime '%s' format gave error: %s" % (e[0], error))
if re.match(escapestr(e[1], self.ampm), result):
continue
if not result or result[0] == '%':
- print("Does not support standard '%s' format (%s)" % \
- (e[0], e[2]))
+ self.fail("strftime does not support standard '%s' format (%s)"
+ % (e[0], e[2]))
else:
- print("Conflict for %s (%s):" % (e[0], e[2]))
- print(" Expected %s, but got %s" % (e[1], result))
+ self.fail("Conflict for %s (%s): expected %s, but got %s"
+ % (e[0], e[2], e[1], result))
def strftest2(self, now):
nowsecs = str(int(now))[:-1]
diff --git a/Misc/NEWS b/Misc/NEWS
index 8651d1f..b8c098c 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -781,6 +781,9 @@ Library
Extension Modules
-----------------
+- Issue #6544: fix a reference leak in the kqueue implementation's error
+ handling.
+
- Stop providing crtassem.h symbols when compiling with Visual Studio 2010, as
msvcr100.dll is not a platform assembly anymore.
diff --git a/Modules/selectmodule.c b/Modules/selectmodule.c
index 9f1b968..c13bab9 100644
--- a/Modules/selectmodule.c
+++ b/Modules/selectmodule.c
@@ -1241,6 +1241,7 @@ static struct PyMemberDef kqueue_event_members[] = {
#undef KQ_OFF
static PyObject *
+
kqueue_event_repr(kqueue_event_Object *s)
{
char buf[1024];
@@ -1526,19 +1527,6 @@ kqueue_queue_control(kqueue_queue_Object *self, PyObject *args)
return NULL;
}
- if (ch != NULL && ch != Py_None) {
- it = PyObject_GetIter(ch);
- if (it == NULL) {
- PyErr_SetString(PyExc_TypeError,
- "changelist is not iterable");
- return NULL;
- }
- nchanges = PyObject_Size(ch);
- if (nchanges < 0) {
- return NULL;
- }
- }
-
if (otimeout == Py_None || otimeout == NULL) {
ptimeoutspec = NULL;
}
@@ -1574,11 +1562,22 @@ kqueue_queue_control(kqueue_queue_Object *self, PyObject *args)
return NULL;
}
- if (nchanges) {
+ if (ch != NULL && ch != Py_None) {
+ it = PyObject_GetIter(ch);
+ if (it == NULL) {
+ PyErr_SetString(PyExc_TypeError,
+ "changelist is not iterable");
+ return NULL;
+ }
+ nchanges = PyObject_Size(ch);
+ if (nchanges < 0) {
+ goto error;
+ }
+
chl = PyMem_New(struct kevent, nchanges);
if (chl == NULL) {
PyErr_NoMemory();
- return NULL;
+ goto error;
}
i = 0;
while ((ei = PyIter_Next(it)) != NULL) {
@@ -1601,7 +1600,7 @@ kqueue_queue_control(kqueue_queue_Object *self, PyObject *args)
evl = PyMem_New(struct kevent, nevents);
if (evl == NULL) {
PyErr_NoMemory();
- return NULL;
+ goto error;
}
}