From 76605557ea800ae72ec8296b80287ad5fae0e9e7 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Wed, 18 Apr 2012 11:14:31 -0400 Subject: [PATCH 1/6] SETUP_WITH acts like SETUP_FINALLY for the purposes of setting f_lineno (closes #14612) --- Lib/test/test_sys_settrace.py | 11 +++++++++++ Misc/NEWS | 2 ++ Objects/frameobject.c | 6 ++++-- 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_sys_settrace.py b/Lib/test/test_sys_settrace.py index 1f77f9b16bb..57a78391895 100644 --- a/Lib/test/test_sys_settrace.py +++ b/Lib/test/test_sys_settrace.py @@ -670,6 +670,14 @@ def no_jump_to_non_integers(output): no_jump_to_non_integers.jump = (2, "Spam") no_jump_to_non_integers.output = [True] +def jump_across_with(output): + with open(test_support.TESTFN, "wb") as fp: + pass + with open(test_support.TESTFN, "wb") as fp: + pass +jump_across_with.jump = (1, 3) +jump_across_with.output = [] + # This verifies that you can't set f_lineno via _getframe or similar # trickery. def no_jump_without_trace_function(): @@ -739,6 +747,9 @@ class JumpTestCase(unittest.TestCase): self.run_test(no_jump_to_non_integers) def test_19_no_jump_without_trace_function(self): no_jump_without_trace_function() + def test_jump_across_with(self): + self.addCleanup(test_support.unlink, test_support.TESTFN) + self.run_test(jump_across_with) def test_20_large_function(self): d = {} diff --git a/Misc/NEWS b/Misc/NEWS index 71218d7f4a4..6b278bd8b7d 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -9,6 +9,8 @@ What's New in Python 2.7.4 Core and Builtins ----------------- +- Issue #14612: Fix jumping around with blocks by setting f_lineno. + - Issue #13889: Check and (if necessary) set FPU control word before calling any of the dtoa.c string <-> float conversion functions, on MSVC builds of Python. This fixes issues when embedding Python in a Delphi app. diff --git a/Objects/frameobject.c b/Objects/frameobject.c index a3476cfff12..f9e4a0ead6e 100644 --- a/Objects/frameobject.c +++ b/Objects/frameobject.c @@ -214,6 +214,7 @@ frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno) case SETUP_LOOP: case SETUP_EXCEPT: case SETUP_FINALLY: + case SETUP_WITH: blockstack[blockstack_top++] = addr; in_finally[blockstack_top-1] = 0; break; @@ -221,7 +222,7 @@ frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno) case POP_BLOCK: assert(blockstack_top > 0); setup_op = code[blockstack[blockstack_top-1]]; - if (setup_op == SETUP_FINALLY) { + if (setup_op == SETUP_FINALLY || setup_op == SETUP_WITH) { in_finally[blockstack_top-1] = 1; } else { @@ -236,7 +237,7 @@ frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno) * be seeing such an END_FINALLY.) */ if (blockstack_top > 0) { setup_op = code[blockstack[blockstack_top-1]]; - if (setup_op == SETUP_FINALLY) { + if (setup_op == SETUP_FINALLY || setup_op == SETUP_WITH) { blockstack_top--; } } @@ -298,6 +299,7 @@ frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno) case SETUP_LOOP: case SETUP_EXCEPT: case SETUP_FINALLY: + case SETUP_WITH: delta_iblock++; break; From 9b5952d7cd64712dd68aebd577ce9cb0a67ca76c Mon Sep 17 00:00:00 2001 From: Ned Deily Date: Wed, 18 Apr 2012 12:48:09 -0700 Subject: [PATCH 2/6] Remove webbrowser doc reference to the previously removed internet-config option. --- Doc/library/webbrowser.rst | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/Doc/library/webbrowser.rst b/Doc/library/webbrowser.rst index 05de5894f4d..b978777bd4d 100644 --- a/Doc/library/webbrowser.rst +++ b/Doc/library/webbrowser.rst @@ -138,11 +138,9 @@ for the controller classes, all defined in this module. +-----------------------+-----------------------------------------+-------+ | ``'windows-default'`` | :class:`WindowsDefault` | \(2) | +-----------------------+-----------------------------------------+-------+ -| ``'internet-config'`` | :class:`InternetConfig` | \(3) | +| ``'macosx'`` | :class:`MacOSX('default')` | \(3) | +-----------------------+-----------------------------------------+-------+ -| ``'macosx'`` | :class:`MacOSX('default')` | \(4) | -+-----------------------+-----------------------------------------+-------+ -| ``'safari'`` | :class:`MacOSX('safari')` | \(4) | +| ``'safari'`` | :class:`MacOSX('safari')` | \(3) | +-----------------------+-----------------------------------------+-------+ Notes: @@ -158,9 +156,6 @@ Notes: Only on Windows platforms. (3) - Only on Mac OS platforms; requires the standard MacPython :mod:`ic` module. - -(4) Only on Mac OS X platform. Here are some simple examples:: From a72aa843b66e80cc6f97a5e3571952d941e82404 Mon Sep 17 00:00:00 2001 From: "Gregory P. Smith" Date: Wed, 18 Apr 2012 16:41:56 -0700 Subject: [PATCH 3/6] Fix compiler warning related to issue #14331. harmless. --- Python/import.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Python/import.c b/Python/import.c index 4d8a610c3dd..108a1e1b074 100644 --- a/Python/import.c +++ b/Python/import.c @@ -1267,7 +1267,8 @@ find_module(char *fullname, char *subname, PyObject *path, char *buf, } name = PyMem_MALLOC(MAXPATHLEN+1); if (name == NULL) { - return PyErr_NoMemory(); + PyErr_NoMemory(); + return NULL; } strcpy(name, subname); From c45868ec697a70a80d1cf8a511894f073fda3a27 Mon Sep 17 00:00:00 2001 From: Ezio Melotti Date: Wed, 18 Apr 2012 19:08:41 -0600 Subject: [PATCH 4/6] #14538: HTMLParser can now parse correctly start tags that contain a bare /. --- Lib/HTMLParser.py | 6 +++--- Lib/test/test_htmlparser.py | 10 ++++++++++ Misc/NEWS | 3 +++ 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/Lib/HTMLParser.py b/Lib/HTMLParser.py index d4e14d43876..b336a4c31df 100644 --- a/Lib/HTMLParser.py +++ b/Lib/HTMLParser.py @@ -22,13 +22,13 @@ charref = re.compile('&#(?:[0-9]+|[xX][0-9a-fA-F]+)[^0-9a-fA-F]') starttagopen = re.compile('<[a-zA-Z]') piclose = re.compile('>') commentclose = re.compile(r'--\s*>') -tagfind = re.compile('[a-zA-Z][-.a-zA-Z0-9:_]*') +tagfind = re.compile('([a-zA-Z][-.a-zA-Z0-9:_]*)(?:\s|/(?!>))*') # see http://www.w3.org/TR/html5/tokenization.html#tag-open-state # and http://www.w3.org/TR/html5/tokenization.html#tag-name-state tagfind_tolerant = re.compile('[a-zA-Z][^\t\n\r\f />\x00]*') attrfind = re.compile( - r'[\s/]*((?<=[\'"\s/])[^\s/>][^\s/=>]*)(\s*=+\s*' + r'((?<=[\'"\s/])[^\s/>][^\s/=>]*)(\s*=+\s*' r'(\'[^\']*\'|"[^"]*"|(?![\'"])[^>\s]*))?(?:\s|/(?!>))*') locatestarttagend = re.compile(r""" @@ -289,7 +289,7 @@ class HTMLParser(markupbase.ParserBase): match = tagfind.match(rawdata, i+1) assert match, 'unexpected call to parse_starttag()' k = match.end() - self.lasttag = tag = rawdata[i+1:k].lower() + self.lasttag = tag = match.group(1).lower() while k < endpos: m = attrfind.match(rawdata, k) diff --git a/Lib/test/test_htmlparser.py b/Lib/test/test_htmlparser.py index 41f43408d83..8cc461f1ee3 100644 --- a/Lib/test/test_htmlparser.py +++ b/Lib/test/test_htmlparser.py @@ -260,6 +260,16 @@ text ('starttag', 'a', [('foo', None), ('=', None), ('bar', None)]) ] self._run_check(html, expected) + #see issue #14538 + html = ('' + '') + expected = [ + ('starttag', 'meta', []), ('starttag', 'meta', []), + ('starttag', 'meta', []), ('starttag', 'meta', []), + ('startendtag', 'meta', []), ('startendtag', 'meta', []), + ('startendtag', 'meta', []), ('startendtag', 'meta', []), + ] + self._run_check(html, expected) def test_declaration_junk_chars(self): self._run_check("", [('decl', 'DOCTYPE foo $ ')]) diff --git a/Misc/NEWS b/Misc/NEWS index 6b278bd8b7d..6ae6e53e3a7 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -50,6 +50,9 @@ Core and Builtins Library ------- +- Issue #14538: HTMLParser can now parse correctly start tags that contain + a bare '/'. + - Issue #14452: SysLogHandler no longer inserts a UTF-8 BOM into the message. - Issue #13496: Fix potential overflow in bisect.bisect algorithm when applied From 52849bfaa384f1dcc26a8aa9092379921d835081 Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Thu, 19 Apr 2012 23:55:01 +0200 Subject: [PATCH 5/6] Issue #14308: Fix an exception when a "dummy" thread is in the threading module's active list after a fork(). --- Lib/test/test_threading.py | 29 +++++++++++++++++++++++++++++ Lib/threading.py | 4 ++++ Misc/NEWS | 3 +++ 3 files changed, 36 insertions(+) diff --git a/Lib/test/test_threading.py b/Lib/test/test_threading.py index 1a02ef2e314..ef04cd360a4 100644 --- a/Lib/test/test_threading.py +++ b/Lib/test/test_threading.py @@ -2,6 +2,8 @@ import test.test_support from test.test_support import verbose +from test.script_helper import assert_python_ok + import random import re import sys @@ -414,6 +416,33 @@ class ThreadTests(BaseTestCase): msg=('%d references still around' % sys.getrefcount(weak_raising_cyclic_object()))) + @unittest.skipUnless(hasattr(os, 'fork'), 'test needs fork()') + def test_dummy_thread_after_fork(self): + # Issue #14308: a dummy thread in the active list doesn't mess up + # the after-fork mechanism. + code = """if 1: + import thread, threading, os, time + + def background_thread(evt): + # Creates and registers the _DummyThread instance + threading.current_thread() + evt.set() + time.sleep(10) + + evt = threading.Event() + thread.start_new_thread(background_thread, (evt,)) + evt.wait() + assert threading.active_count() == 2, threading.active_count() + if os.fork() == 0: + assert threading.active_count() == 1, threading.active_count() + os._exit(0) + else: + os.wait() + """ + _, out, err = assert_python_ok("-c", code) + self.assertEqual(out, '') + self.assertEqual(err, '') + class ThreadJoinOnShutdown(BaseTestCase): diff --git a/Lib/threading.py b/Lib/threading.py index ff32dfb41c8..22908550e09 100644 --- a/Lib/threading.py +++ b/Lib/threading.py @@ -605,6 +605,10 @@ class Thread(_Verbose): pass def __stop(self): + # DummyThreads delete self.__block, but they have no waiters to + # notify anyway (join() is forbidden on them). + if not hasattr(self, '_Thread__block'): + return self.__block.acquire() self.__stopped = True self.__block.notify_all() diff --git a/Misc/NEWS b/Misc/NEWS index 6ae6e53e3a7..20ca9684f57 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -50,6 +50,9 @@ Core and Builtins Library ------- +- Issue #14308: Fix an exception when a "dummy" thread is in the threading + module's active list after a fork(). + - Issue #14538: HTMLParser can now parse correctly start tags that contain a bare '/'. From ea17082c25a4835975537373454097b8dd054692 Mon Sep 17 00:00:00 2001 From: Senthil Kumaran Date: Sun, 22 Apr 2012 10:27:22 +0800 Subject: [PATCH 6/6] Update 2.7 docs about legal characters allowed in Cookie name --- Doc/library/cookie.rst | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/Doc/library/cookie.rst b/Doc/library/cookie.rst index 480dffa66e6..52c897579d1 100644 --- a/Doc/library/cookie.rst +++ b/Doc/library/cookie.rst @@ -22,8 +22,14 @@ cookie value. The module formerly strictly applied the parsing rules described in the :rfc:`2109` and :rfc:`2068` specifications. It has since been discovered that -MSIE 3.0x doesn't follow the character rules outlined in those specs. As a -result, the parsing rules used are a bit less strict. +MSIE 3.0x doesn't follow the character rules outlined in those specs and also +many current day browsers and servers have relaxed parsing rules when comes to +Cookie handling. As a result, the parsing rules used are a bit less strict. + +The character set, :data:`string.ascii_letters`, :data:`string.digits` and +``!#$%&'*+-.^_`|~`` denote the set of valid characters allowed by this module +in Cookie name (as :attr:`~Morsel.key`). + .. note::