This commit is contained in:
Raymond Hettinger 2012-04-23 00:22:48 -07:00
commit 016878aea6
10 changed files with 81 additions and 15 deletions

View file

@ -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::

View file

@ -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::

View file

@ -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)

View file

@ -260,6 +260,16 @@ text
('starttag', 'a', [('foo', None), ('=', None), ('bar', None)])
]
self._run_check(html, expected)
#see issue #14538
html = ('<meta><meta / ><meta // ><meta / / >'
'<meta/><meta /><meta //><meta//>')
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("<!DOCTYPE foo $ >", [('decl', 'DOCTYPE foo $ ')])

View file

@ -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 = {}

View file

@ -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):

View file

@ -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()

View file

@ -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.
@ -48,6 +50,12 @@ 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 '/'.
- Issue #14452: SysLogHandler no longer inserts a UTF-8 BOM into the message.
- Issue #13496: Fix potential overflow in bisect.bisect algorithm when applied

View file

@ -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;

View file

@ -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);