From solipsis at pitrou.net Thu Jul 1 01:23:55 2010 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Thu, 1 Jul 2010 01:23:55 +0200 (CEST) Subject: [Python-checkins] Daily py3k reference leaks (r82407): sum=0 Message-ID: <20100630232355.4AB2A1770A@ns6635.ovh.net> py3k results for svn r82407 (hg cset 40435013f940) -------------------------------------------------- Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflogluNgCL', '-x'] From python-checkins at python.org Thu Jul 1 01:58:07 2010 From: python-checkins at python.org (ezio.melotti) Date: Thu, 1 Jul 2010 01:58:07 +0200 (CEST) Subject: [Python-checkins] r82412 - in tracker/instances/python-dev/html: issue.item.html issue.item.js Message-ID: <20100630235807.73769EEA48@mail.python.org> Author: ezio.melotti Date: Thu Jul 1 01:58:07 2010 New Revision: 82412 Log: Avoid using display:block -- the resize works with display:inline too. Also close the span properly in issue.item.html. Modified: tracker/instances/python-dev/html/issue.item.html tracker/instances/python-dev/html/issue.item.js Modified: tracker/instances/python-dev/html/issue.item.html ============================================================================== --- tracker/instances/python-dev/html/issue.item.html (original) +++ tracker/instances/python-dev/html/issue.item.html Thu Jul 1 01:58:07 2010 @@ -145,7 +145,7 @@ tal:define="current_user request/user/username" tal:condition="python:request.user.username != 'anonymous' and current_user not in str(context.nosy).replace(' ','').split(',')" tal:attributes="onclick string:add_to_nosy('$current_user')" - onclick="add_to_nosy(the_current_username)" /> + onclick="add_to_nosy(the_current_username)"> Modified: tracker/instances/python-dev/html/issue.item.js ============================================================================== --- tracker/instances/python-dev/html/issue.item.js (original) +++ tracker/instances/python-dev/html/issue.item.js Thu Jul 1 01:58:07 2010 @@ -38,6 +38,6 @@ // hide the button and resize the list to fill the void var new_width = nosy.offsetWidth + add_me_button.offsetWidth; add_me_button.style.display = 'none'; - nosy.style.display = 'block'; + nosy.style.display = 'inline'; nosy.style.width = new_width + "px"; } From python-checkins at python.org Thu Jul 1 09:32:02 2010 From: python-checkins at python.org (ezio.melotti) Date: Thu, 1 Jul 2010 09:32:02 +0200 (CEST) Subject: [Python-checkins] r82413 - in python/branches/py3k: Lib/test/test_codeccallbacks.py Lib/test/test_unicode.py Misc/NEWS Objects/unicodeobject.c Message-ID: <20100701073202.76D7CEEAEF@mail.python.org> Author: ezio.melotti Date: Thu Jul 1 09:32:02 2010 New Revision: 82413 Log: Update PyUnicode_DecodeUTF8 from RFC 2279 to RFC 3629. 1) #8271: when a byte sequence is invalid, only the start byte and all the valid continuation bytes are now replaced by U+FFFD, instead of replacing the number of bytes specified by the start byte. See http://www.unicode.org/versions/Unicode5.2.0/ch03.pdf (pages 94-95); 2) 5- and 6-bytes-long UTF-8 sequences are now considered invalid (no changes in behavior); 3) Change the error messages "unexpected code byte" to "invalid start byte" and "invalid data" to "invalid continuation byte"; 4) Add an extensive set of tests in test_unicode; 5) Fix test_codeccallbacks because it was failing after this change. Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/test/test_codeccallbacks.py python/branches/py3k/Lib/test/test_unicode.py python/branches/py3k/Misc/NEWS python/branches/py3k/Objects/unicodeobject.c Modified: python/branches/py3k/Lib/test/test_codeccallbacks.py ============================================================================== --- python/branches/py3k/Lib/test/test_codeccallbacks.py (original) +++ python/branches/py3k/Lib/test/test_codeccallbacks.py Thu Jul 1 09:32:02 2010 @@ -153,28 +153,30 @@ sout += bytes("\\U%08x" % sys.maxunicode, "ascii") self.assertEqual(sin.encode("iso-8859-15", "backslashreplace"), sout) - def test_decoderelaxedutf8(self): - # This is the test for a decoding callback handler, - # that relaxes the UTF-8 minimal encoding restriction. - # A null byte that is encoded as "\xc0\x80" will be - # decoded as a null byte. All other illegal sequences - # will be handled strictly. + def test_decoding_callbacks(self): + # This is a test for a decoding callback handler + # that allows the decoding of the invalid sequence + # "\xc0\x80" and returns "\x00" instead of raising an error. + # All other illegal sequences will be handled strictly. def relaxedutf8(exc): if not isinstance(exc, UnicodeDecodeError): raise TypeError("don't know how to handle %r" % exc) - if exc.object[exc.start:exc.end].startswith(b"\xc0\x80"): + if exc.object[exc.start:exc.start+2] == b"\xc0\x80": return ("\x00", exc.start+2) # retry after two bytes else: raise exc - codecs.register_error( - "test.relaxedutf8", relaxedutf8) + codecs.register_error("test.relaxedutf8", relaxedutf8) + # all the "\xc0\x80" will be decoded to "\x00" sin = b"a\x00b\xc0\x80c\xc3\xbc\xc0\x80\xc0\x80" sout = "a\x00b\x00c\xfc\x00\x00" self.assertEqual(sin.decode("utf-8", "test.relaxedutf8"), sout) + + # "\xc0\x81" is not valid and a UnicodeDecodeError will be raised sin = b"\xc0\x80\xc0\x81" - self.assertRaises(UnicodeError, sin.decode, "utf-8", "test.relaxedutf8") + self.assertRaises(UnicodeDecodeError, sin.decode, + "utf-8", "test.relaxedutf8") def test_charmapencode(self): # For charmap encodings the replacement string will be Modified: python/branches/py3k/Lib/test/test_unicode.py ============================================================================== --- python/branches/py3k/Lib/test/test_unicode.py (original) +++ python/branches/py3k/Lib/test/test_unicode.py Thu Jul 1 09:32:02 2010 @@ -942,6 +942,159 @@ # * strict decoding testing for all of the # UTF8_ERROR cases in PyUnicode_DecodeUTF8 + def test_utf8_decode_valid_sequences(self): + sequences = [ + # single byte + (b'\x00', '\x00'), (b'a', 'a'), (b'\x7f', '\x7f'), + # 2 bytes + (b'\xc2\x80', '\x80'), (b'\xdf\xbf', '\u07ff'), + # 3 bytes + (b'\xe0\xa0\x80', '\u0800'), (b'\xed\x9f\xbf', '\ud7ff'), + (b'\xee\x80\x80', '\uE000'), (b'\xef\xbf\xbf', '\uffff'), + # 4 bytes + (b'\xF0\x90\x80\x80', '\U00010000'), + (b'\xf4\x8f\xbf\xbf', '\U0010FFFF') + ] + for seq, res in sequences: + self.assertEqual(seq.decode('utf-8'), res) + + + def test_utf8_decode_invalid_sequences(self): + # continuation bytes in a sequence of 2, 3, or 4 bytes + continuation_bytes = [bytes([x]) for x in range(0x80, 0xC0)] + # start bytes of a 2-byte sequence equivalent to codepoints < 0x7F + invalid_2B_seq_start_bytes = [bytes([x]) for x in range(0xC0, 0xC2)] + # start bytes of a 4-byte sequence equivalent to codepoints > 0x10FFFF + invalid_4B_seq_start_bytes = [bytes([x]) for x in range(0xF5, 0xF8)] + invalid_start_bytes = ( + continuation_bytes + invalid_2B_seq_start_bytes + + invalid_4B_seq_start_bytes + [bytes([x]) for x in range(0xF7, 0x100)] + ) + + for byte in invalid_start_bytes: + self.assertRaises(UnicodeDecodeError, byte.decode, 'utf-8') + + for sb in invalid_2B_seq_start_bytes: + for cb in continuation_bytes: + self.assertRaises(UnicodeDecodeError, (sb+cb).decode, 'utf-8') + + for sb in invalid_4B_seq_start_bytes: + for cb1 in continuation_bytes[:3]: + for cb3 in continuation_bytes[:3]: + self.assertRaises(UnicodeDecodeError, + (sb+cb1+b'\x80'+cb3).decode, 'utf-8') + + for cb in [bytes([x]) for x in range(0x80, 0xA0)]: + self.assertRaises(UnicodeDecodeError, + (b'\xE0'+cb+b'\x80').decode, 'utf-8') + self.assertRaises(UnicodeDecodeError, + (b'\xE0'+cb+b'\xBF').decode, 'utf-8') + # surrogates + for cb in [bytes([x]) for x in range(0xA0, 0xC0)]: + self.assertRaises(UnicodeDecodeError, + (b'\xED'+cb+b'\x80').decode, 'utf-8') + self.assertRaises(UnicodeDecodeError, + (b'\xED'+cb+b'\xBF').decode, 'utf-8') + for cb in [bytes([x]) for x in range(0x80, 0x90)]: + self.assertRaises(UnicodeDecodeError, + (b'\xF0'+cb+b'\x80\x80').decode, 'utf-8') + self.assertRaises(UnicodeDecodeError, + (b'\xF0'+cb+b'\xBF\xBF').decode, 'utf-8') + for cb in [bytes([x]) for x in range(0x90, 0xC0)]: + self.assertRaises(UnicodeDecodeError, + (b'\xF4'+cb+b'\x80\x80').decode, 'utf-8') + self.assertRaises(UnicodeDecodeError, + (b'\xF4'+cb+b'\xBF\xBF').decode, 'utf-8') + + def test_issue8271(self): + # Issue #8271: during the decoding of an invalid UTF-8 byte sequence, + # only the start byte and the continuation byte(s) are now considered + # invalid, instead of the number of bytes specified by the start byte. + # See http://www.unicode.org/versions/Unicode5.2.0/ch03.pdf (page 95, + # table 3-8, Row 2) for more information about the algorithm used. + FFFD = '\ufffd' + sequences = [ + # invalid start bytes + (b'\x80', FFFD), # continuation byte + (b'\x80\x80', FFFD*2), # 2 continuation bytes + (b'\xc0', FFFD), + (b'\xc0\xc0', FFFD*2), + (b'\xc1', FFFD), + (b'\xc1\xc0', FFFD*2), + (b'\xc0\xc1', FFFD*2), + # with start byte of a 2-byte sequence + (b'\xc2', FFFD), # only the start byte + (b'\xc2\xc2', FFFD*2), # 2 start bytes + (b'\xc2\xc2\xc2', FFFD*3), # 2 start bytes + (b'\xc2\x41', FFFD+'A'), # invalid continuation byte + # with start byte of a 3-byte sequence + (b'\xe1', FFFD), # only the start byte + (b'\xe1\xe1', FFFD*2), # 2 start bytes + (b'\xe1\xe1\xe1', FFFD*3), # 3 start bytes + (b'\xe1\xe1\xe1\xe1', FFFD*4), # 4 start bytes + (b'\xe1\x80', FFFD), # only 1 continuation byte + (b'\xe1\x41', FFFD+'A'), # invalid continuation byte + (b'\xe1\x41\x80', FFFD+'A'+FFFD), # invalid cb followed by valid cb + (b'\xe1\x41\x41', FFFD+'AA'), # 2 invalid continuation bytes + (b'\xe1\x80\x41', FFFD+'A'), # only 1 valid continuation byte + (b'\xe1\x80\xe1\x41', FFFD*2+'A'), # 1 valid and the other invalid + (b'\xe1\x41\xe1\x80', FFFD+'A'+FFFD), # 1 invalid and the other valid + # with start byte of a 4-byte sequence + (b'\xf1', FFFD), # only the start byte + (b'\xf1\xf1', FFFD*2), # 2 start bytes + (b'\xf1\xf1\xf1', FFFD*3), # 3 start bytes + (b'\xf1\xf1\xf1\xf1', FFFD*4), # 4 start bytes + (b'\xf1\xf1\xf1\xf1\xf1', FFFD*5), # 5 start bytes + (b'\xf1\x80', FFFD), # only 1 continuation bytes + (b'\xf1\x80\x80', FFFD), # only 2 continuation bytes + (b'\xf1\x80\x41', FFFD+'A'), # 1 valid cb and 1 invalid + (b'\xf1\x80\x41\x41', FFFD+'AA'), # 1 valid cb and 1 invalid + (b'\xf1\x80\x80\x41', FFFD+'A'), # 2 valid cb and 1 invalid + (b'\xf1\x41\x80', FFFD+'A'+FFFD), # 1 invalid cv and 1 valid + (b'\xf1\x41\x80\x80', FFFD+'A'+FFFD*2), # 1 invalid cb and 2 invalid + (b'\xf1\x41\x80\x41', FFFD+'A'+FFFD+'A'), # 2 invalid cb and 1 invalid + (b'\xf1\x41\x41\x80', FFFD+'AA'+FFFD), # 1 valid cb and 1 invalid + (b'\xf1\x41\xf1\x80', FFFD+'A'+FFFD), + (b'\xf1\x41\x80\xf1', FFFD+'A'+FFFD*2), + (b'\xf1\xf1\x80\x41', FFFD*2+'A'), + (b'\xf1\x41\xf1\xf1', FFFD+'A'+FFFD*2), + # with invalid start byte of a 4-byte sequence (rfc2279) + (b'\xf5', FFFD), # only the start byte + (b'\xf5\xf5', FFFD*2), # 2 start bytes + (b'\xf5\x80', FFFD*2), # only 1 continuation byte + (b'\xf5\x80\x80', FFFD*3), # only 2 continuation byte + (b'\xf5\x80\x80\x80', FFFD*4), # 3 continuation bytes + (b'\xf5\x80\x41', FFFD*2+'A'), # 1 valid cb and 1 invalid + (b'\xf5\x80\x41\xf5', FFFD*2+'A'+FFFD), + (b'\xf5\x41\x80\x80\x41', FFFD+'A'+FFFD*2+'A'), + # with invalid start byte of a 5-byte sequence (rfc2279) + (b'\xf8', FFFD), # only the start byte + (b'\xf8\xf8', FFFD*2), # 2 start bytes + (b'\xf8\x80', FFFD*2), # only one continuation byte + (b'\xf8\x80\x41', FFFD*2 + 'A'), # 1 valid cb and 1 invalid + (b'\xf8\x80\x80\x80\x80', FFFD*5), # invalid 5 bytes seq with 5 bytes + # with invalid start byte of a 6-byte sequence (rfc2279) + (b'\xfc', FFFD), # only the start byte + (b'\xfc\xfc', FFFD*2), # 2 start bytes + (b'\xfc\x80\x80', FFFD*3), # only 2 continuation bytes + (b'\xfc\x80\x80\x80\x80\x80', FFFD*6), # 6 continuation bytes + # invalid start byte + (b'\xfe', FFFD), + (b'\xfe\x80\x80', FFFD*3), + # other sequences + (b'\xf1\x80\x41\x42\x43', '\ufffd\x41\x42\x43'), + (b'\xf1\x80\xff\x42\x43', '\ufffd\ufffd\x42\x43'), + (b'\xf1\x80\xc2\x81\x43', '\ufffd\x81\x43'), + (b'\x61\xF1\x80\x80\xE1\x80\xC2\x62\x80\x63\x80\xBF\x64', + '\x61\uFFFD\uFFFD\uFFFD\x62\uFFFD\x63\uFFFD\uFFFD\x64'), + ] + for n, (seq, res) in enumerate(sequences): + self.assertRaises(UnicodeDecodeError, seq.decode, 'utf-8', 'strict') + self.assertEqual(seq.decode('utf-8', 'replace'), res) + self.assertEqual((seq+b'b').decode('utf-8', 'replace'), res+'b') + self.assertEqual(seq.decode('utf-8', 'ignore'), + res.replace('\uFFFD', '')) + def test_codecs_idna(self): # Test whether trailing dot is preserved self.assertEqual("www.python.org.".encode("idna"), b"www.python.org.") Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Thu Jul 1 09:32:02 2010 @@ -12,6 +12,14 @@ Core and Builtins ----------------- +- Issue #8271: during the decoding of an invalid UTF-8 byte sequence, only the + start byte and the continuation byte(s) are now considered invalid, instead + of the number of bytes specified by the start byte. + E.g.: '\xf1\x80AB'.decode('utf-8', 'replace') now returns u'\ufffdAB' and + replaces with U+FFFD only the start byte ('\xf1') and the continuation byte + ('\x80') even if '\xf1' is the start byte of a 4-bytes sequence. + Previous versions returned a single u'\ufffd'. + - Issue #9011: A negated imaginary literal (e.g., "-7j") now has real part -0.0 rather than 0.0. So "-7j" is now exactly equivalent to "-(7j)". Modified: python/branches/py3k/Objects/unicodeobject.c ============================================================================== --- python/branches/py3k/Objects/unicodeobject.c (original) +++ python/branches/py3k/Objects/unicodeobject.c Thu Jul 1 09:32:02 2010 @@ -2285,24 +2285,24 @@ static char utf8_code_length[256] = { - /* Map UTF-8 encoded prefix byte to sequence length. zero means - illegal prefix. see RFC 2279 for details */ + /* Map UTF-8 encoded prefix byte to sequence length. Zero means + illegal prefix. See RFC 3629 for details */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 00-0F */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 70-7F */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 80-8F */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* B0-BF */ + 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* C0-C1 + C2-CF */ + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* D0-DF */ + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* E0-EF */ + 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /* F0-F4 + F5-FF */ }; PyObject *PyUnicode_DecodeUTF8(const char *s, @@ -2332,6 +2332,7 @@ { const char *starts = s; int n; + int k; Py_ssize_t startinpos; Py_ssize_t endinpos; Py_ssize_t outpos; @@ -2415,7 +2416,9 @@ else { errmsg = "unexpected end of data"; startinpos = s-starts; - endinpos = size; + endinpos = startinpos+1; + for (k=1; (k < size-startinpos) && ((s[k]&0xC0) == 0x80); k++) + endinpos++; goto utf8Error; } } @@ -2423,7 +2426,7 @@ switch (n) { case 0: - errmsg = "unexpected code byte"; + errmsg = "invalid start byte"; startinpos = s-starts; endinpos = startinpos+1; goto utf8Error; @@ -2436,63 +2439,67 @@ case 2: if ((s[1] & 0xc0) != 0x80) { - errmsg = "invalid data"; + errmsg = "invalid continuation byte"; startinpos = s-starts; - endinpos = startinpos+2; + endinpos = startinpos + 1; goto utf8Error; } ch = ((s[0] & 0x1f) << 6) + (s[1] & 0x3f); - if (ch < 0x80) { - startinpos = s-starts; - endinpos = startinpos+2; - errmsg = "illegal encoding"; - goto utf8Error; - } - else - *p++ = (Py_UNICODE)ch; + assert ((ch > 0x007F) && (ch <= 0x07FF)); + *p++ = (Py_UNICODE)ch; break; case 3: + /* XXX: surrogates shouldn't be valid UTF-8! + see http://www.unicode.org/versions/Unicode5.2.0/ch03.pdf + (table 3-7) and http://www.rfc-editor.org/rfc/rfc3629.txt + Uncomment the 2 lines below to make them invalid, + codepoints: d800-dfff; UTF-8: \xed\xa0\x80-\xed\xbf\xbf. */ if ((s[1] & 0xc0) != 0x80 || - (s[2] & 0xc0) != 0x80) { - errmsg = "invalid data"; + (s[2] & 0xc0) != 0x80 || + ((unsigned char)s[0] == 0xE0 && + (unsigned char)s[1] < 0xA0) || + ((unsigned char)s[0] == 0xED && + (unsigned char)s[1] > 0x9F)) { + errmsg = "invalid continuation byte"; startinpos = s-starts; - endinpos = startinpos+3; + endinpos = startinpos + 1; + + /* if s[1] first two bits are 1 and 0, then the invalid + continuation byte is s[2], so increment endinpos by 1, + if not, s[1] is invalid and endinpos doesn't need to + be incremented. */ + if ((s[1] & 0xC0) == 0x80) + endinpos++; goto utf8Error; } ch = ((s[0] & 0x0f) << 12) + ((s[1] & 0x3f) << 6) + (s[2] & 0x3f); - if (ch < 0x0800 || (ch >= 0xd800 && ch <= 0xDFFF)) { - errmsg = "illegal encoding"; - startinpos = s-starts; - endinpos = startinpos+3; - goto utf8Error; - } - else - *p++ = (Py_UNICODE)ch; + assert ((ch > 0x07FF) && (ch <= 0xFFFF)); + *p++ = (Py_UNICODE)ch; break; case 4: if ((s[1] & 0xc0) != 0x80 || (s[2] & 0xc0) != 0x80 || - (s[3] & 0xc0) != 0x80) { - errmsg = "invalid data"; + (s[3] & 0xc0) != 0x80 || + ((unsigned char)s[0] == 0xF0 && + (unsigned char)s[1] < 0x90) || + ((unsigned char)s[0] == 0xF4 && + (unsigned char)s[1] > 0x8F)) { + errmsg = "invalid continuation byte"; startinpos = s-starts; - endinpos = startinpos+4; + endinpos = startinpos + 1; + if ((s[1] & 0xC0) == 0x80) { + endinpos++; + if ((s[2] & 0xC0) == 0x80) + endinpos++; + } goto utf8Error; } ch = ((s[0] & 0x7) << 18) + ((s[1] & 0x3f) << 12) + - ((s[2] & 0x3f) << 6) + (s[3] & 0x3f); - /* validate and convert to UTF-16 */ - if ((ch < 0x10000) /* minimum value allowed for 4 - byte encoding */ - || (ch > 0x10ffff)) /* maximum value allowed for - UTF-16 */ - { - errmsg = "illegal encoding"; - startinpos = s-starts; - endinpos = startinpos+4; - goto utf8Error; - } + ((s[2] & 0x3f) << 6) + (s[3] & 0x3f); + assert ((ch > 0xFFFF) && (ch <= 0x10ffff)); + #ifdef Py_UNICODE_WIDE *p++ = (Py_UNICODE)ch; #else @@ -2508,13 +2515,6 @@ *p++ = (Py_UNICODE)(0xDC00 + (ch & 0x03FF)); #endif break; - - default: - /* Other sizes are only needed for UCS-4 */ - errmsg = "unsupported Unicode code range"; - startinpos = s-starts; - endinpos = startinpos+n; - goto utf8Error; } s += n; continue; From python-checkins at python.org Thu Jul 1 17:07:15 2010 From: python-checkins at python.org (benjamin.peterson) Date: Thu, 1 Jul 2010 17:07:15 +0200 (CEST) Subject: [Python-checkins] r82415 - python/trunk/Doc/library/math.rst Message-ID: <20100701150715.51429F6915@mail.python.org> Author: benjamin.peterson Date: Thu Jul 1 17:07:15 2010 New Revision: 82415 Log: remove docs about delegating to special methods; it does no such thing Modified: python/trunk/Doc/library/math.rst Modified: python/trunk/Doc/library/math.rst ============================================================================== --- python/trunk/Doc/library/math.rst (original) +++ python/trunk/Doc/library/math.rst Thu Jul 1 17:07:15 2010 @@ -57,9 +57,6 @@ Return the floor of *x* as a float, the largest integer value less than or equal to *x*. - .. versionchanged:: 2.6 - Added :meth:`__floor__` delegation. - .. function:: fmod(x, y) @@ -137,7 +134,7 @@ .. function:: trunc(x) Return the :class:`Real` value *x* truncated to an :class:`Integral` (usually - a long integer). Delegates to ``x.__trunc__()``. + a long integer). .. versionadded:: 2.6 From python-checkins at python.org Thu Jul 1 17:09:15 2010 From: python-checkins at python.org (benjamin.peterson) Date: Thu, 1 Jul 2010 17:09:15 +0200 (CEST) Subject: [Python-checkins] r82416 - python/branches/py3k Message-ID: <20100701150915.09235EEB64@mail.python.org> Author: benjamin.peterson Date: Thu Jul 1 17:09:14 2010 New Revision: 82416 Log: Blocked revisions 82415 via svnmerge ........ r82415 | benjamin.peterson | 2010-07-01 10:07:15 -0500 (Thu, 01 Jul 2010) | 1 line remove docs about delegating to special methods; it does no such thing ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Thu Jul 1 17:16:55 2010 From: python-checkins at python.org (benjamin.peterson) Date: Thu, 1 Jul 2010 17:16:55 +0200 (CEST) Subject: [Python-checkins] r82417 - in python/branches/py3k: Lib/test/test_descr.py Misc/NEWS Modules/mathmodule.c Message-ID: <20100701151655.6E378EEBB1@mail.python.org> Author: benjamin.peterson Date: Thu Jul 1 17:16:55 2010 New Revision: 82417 Log: correctly lookup __trunc__ and __floor__ Modified: python/branches/py3k/Lib/test/test_descr.py python/branches/py3k/Misc/NEWS python/branches/py3k/Modules/mathmodule.c Modified: python/branches/py3k/Lib/test/test_descr.py ============================================================================== --- python/branches/py3k/Lib/test/test_descr.py (original) +++ python/branches/py3k/Lib/test/test_descr.py Thu Jul 1 17:16:55 2010 @@ -1,6 +1,7 @@ import builtins import sys import types +import math import unittest from copy import deepcopy @@ -1578,6 +1579,8 @@ ("__exit__", run_context, swallow, set(), {"__enter__" : iden}), ("__complex__", complex, complex_num, set(), {}), ("__format__", format, format_impl, set(), {}), + ("__floor__", math.floor, zero, set(), {}), + ("__trunc__", math.trunc, zero, set(), {}), ] class Checker(object): Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Thu Jul 1 17:16:55 2010 @@ -1374,6 +1374,9 @@ Extension Modules ----------------- +- In the math module, correctly lookup __trunc__ and __floor__ as special + methods. + - Issue #9005: Prevent utctimetuple() from producing year 0 or year 10,000. Prior to this change, timezone adjustment in utctimetuple() could produce tm_year value of 0 or 10,000. Now an OverflowError is Modified: python/branches/py3k/Modules/mathmodule.c ============================================================================== --- python/branches/py3k/Modules/mathmodule.c (original) +++ python/branches/py3k/Modules/mathmodule.c Thu Jul 1 17:16:55 2010 @@ -883,17 +883,13 @@ static PyObject *floor_str = NULL; PyObject *method; - if (floor_str == NULL) { - floor_str = PyUnicode_InternFromString("__floor__"); - if (floor_str == NULL) + method = _PyObject_LookupSpecial(number, "__floor__", &floor_str); + if (method == NULL) { + if (PyErr_Occurred()) return NULL; - } - - method = _PyType_Lookup(Py_TYPE(number), floor_str); - if (method == NULL) return math_1_to_int(number, floor, 0); - else - return PyObject_CallFunction(method, "O", number); + } + return PyObject_CallFunctionObjArgs(method, NULL); } PyDoc_STRVAR(math_floor_doc, @@ -1427,20 +1423,15 @@ return NULL; } - if (trunc_str == NULL) { - trunc_str = PyUnicode_InternFromString("__trunc__"); - if (trunc_str == NULL) - return NULL; - } - - trunc = _PyType_Lookup(Py_TYPE(number), trunc_str); + trunc = _PyObject_LookupSpecial(number, "__trunc__", &trunc_str); if (trunc == NULL) { - PyErr_Format(PyExc_TypeError, - "type %.100s doesn't define __trunc__ method", - Py_TYPE(number)->tp_name); + if (!PyErr_Occurred()) + PyErr_Format(PyExc_TypeError, + "type %.100s doesn't define __trunc__ method", + Py_TYPE(number)->tp_name); return NULL; } - return PyObject_CallFunctionObjArgs(trunc, number, NULL); + return PyObject_CallFunctionObjArgs(trunc, NULL); } PyDoc_STRVAR(math_trunc_doc, From python-checkins at python.org Thu Jul 1 18:16:24 2010 From: python-checkins at python.org (benjamin.peterson) Date: Thu, 1 Jul 2010 18:16:24 +0200 (CEST) Subject: [Python-checkins] r82418 - in python/branches/release26-maint: Doc/library/math.rst Message-ID: <20100701161624.EE662F692F@mail.python.org> Author: benjamin.peterson Date: Thu Jul 1 18:16:24 2010 New Revision: 82418 Log: Merged revisions 82415 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r82415 | benjamin.peterson | 2010-07-01 10:07:15 -0500 (Thu, 01 Jul 2010) | 1 line remove docs about delegating to special methods; it does no such thing ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Doc/library/math.rst Modified: python/branches/release26-maint/Doc/library/math.rst ============================================================================== --- python/branches/release26-maint/Doc/library/math.rst (original) +++ python/branches/release26-maint/Doc/library/math.rst Thu Jul 1 18:16:24 2010 @@ -57,9 +57,6 @@ Return the floor of *x* as a float, the largest integer value less than or equal to *x*. - .. versionchanged:: 2.6 - Added :meth:`__floor__` delegation. - .. function:: fmod(x, y) @@ -137,7 +134,7 @@ .. function:: trunc(x) Return the :class:`Real` value *x* truncated to an :class:`Integral` (usually - a long integer). Delegates to ``x.__trunc__()``. + a long integer). .. versionadded:: 2.6 From python-checkins at python.org Thu Jul 1 18:16:35 2010 From: python-checkins at python.org (alexander.belopolsky) Date: Thu, 1 Jul 2010 18:16:35 +0200 (CEST) Subject: [Python-checkins] r82419 - in sandbox/branches/py3k-datetime: datetime.py test_datetime.py Message-ID: <20100701161635.88A6CEED3A@mail.python.org> Author: alexander.belopolsky Date: Thu Jul 1 18:16:35 2010 New Revision: 82419 Log: Fixed pickling to pass a more rigid test suit. Modified: sandbox/branches/py3k-datetime/datetime.py sandbox/branches/py3k-datetime/test_datetime.py Modified: sandbox/branches/py3k-datetime/datetime.py ============================================================================== --- sandbox/branches/py3k-datetime/datetime.py (original) +++ sandbox/branches/py3k-datetime/datetime.py Thu Jul 1 18:16:35 2010 @@ -269,6 +269,8 @@ raise ValueError("%s()=%d, must be in -1439..1439" % (name, offset)) def _check_date_fields(year, month, day): + if not isinstance(year, int): + raise TypeError('int expected') if not MINYEAR <= year <= MAXYEAR: raise ValueError('year must be in %d..%d' % (MINYEAR, MAXYEAR), year) if not 1 <= month <= 12: @@ -278,6 +280,8 @@ raise ValueError('day must be in 1..%d' % dim, day) def _check_time_fields(hour, minute, second, microsecond): + if not isinstance(hour, int): + raise TypeError('int expected') if not 0 <= hour <= 23: raise ValueError('hour must be in 0..23', hour) if not 0 <= minute <= 59: @@ -660,7 +664,7 @@ year, month, day (required, base 1) """ - if isinstance(year, bytes): + if isinstance(year, bytes) and len(year) == 4: # Pickle support self = object.__new__(cls) self.__setstate(year) @@ -1008,7 +1012,7 @@ tzinfo (default to None) """ self = object.__new__(cls) - if isinstance(hour, str): + if isinstance(hour, bytes) and len(hour) == 6: # Pickle support self.__setstate(hour, minute or None) return self @@ -1256,18 +1260,18 @@ def __getstate(self): us2, us3 = divmod(self.__microsecond, 256) us1, us2 = divmod(us2, 256) - basestate = ("%c" * 6) % (self.__hour, self.__minute, self.__second, - us1, us2, us3) + basestate = bytes([self.__hour, self.__minute, self.__second, + us1, us2, us3]) if self._tzinfo is None: return (basestate,) else: return (basestate, self._tzinfo) def __setstate(self, string, tzinfo): - if len(string) != 6 or ord(string[0]) >= 24: + if len(string) != 6 or string[0] >= 24: raise TypeError("an integer is required") - self.__hour, self.__minute, self.__second, us1, us2, us3 = \ - map(ord, string) + (self.__hour, self.__minute, self.__second, + us1, us2, us3) = string self.__microsecond = (((us1 << 8) | us2) << 8) | us3 self._tzinfo = tzinfo @@ -1287,7 +1291,7 @@ def __new__(cls, year, month=None, day=None, hour=0, minute=0, second=0, microsecond=0, tzinfo=None): - if isinstance(year, bytes): + if isinstance(year, bytes) and len(year) == 10: # Pickle support self = date.__new__(cls, year[:4]) self.__setstate(year, month) Modified: sandbox/branches/py3k-datetime/test_datetime.py ============================================================================== --- sandbox/branches/py3k-datetime/test_datetime.py (original) +++ sandbox/branches/py3k-datetime/test_datetime.py Thu Jul 1 18:16:35 2010 @@ -261,6 +261,33 @@ t.replace(tzinfo=tz).dst()) ############################################################################# +# Base clase for testing pickling state of timedelta, time, date and +# datetime instances. + +class ReduceStructure: + initargs = 1, 1, 1 + statetype = (bytes, tzinfo) + def test_reduce(self): + obj = self.theclass(*self.initargs) + factory, state = obj.__reduce__()[:2] + self.assertIs(factory, self.theclass) + for v, t in zip(state, self.statetype): + self.assertIsInstance(v, t) + + def test_construct_from_state(self): + obj = self.theclass(*self.initargs) + factory, state = obj.__reduce__()[:2] + initbytes = state[0] + # This test should be overriden in tests for classes that + # don't produce their state as bytes. Curently, timedelta + # and timezone + assert isinstance(initbytes, bytes) + obj = factory(initbytes) + self.assertIs(type(obj), self.theclass) + self.assertRaises(TypeError, factory, initbytes[:-1]) + self.assertRaises(TypeError, factory, initbytes + b'x') + +############################################################################# # Base clase for testing a particular aspect of timedelta, time, date and # datetime comparisons. @@ -297,10 +324,10 @@ ############################################################################# # timedelta tests -class TestTimeDelta(HarmlessMixedComparison, unittest.TestCase): +class TestTimeDelta(HarmlessMixedComparison, ReduceStructure, unittest.TestCase): theclass = timedelta - + statetype = (int, int, int) def test_constructor(self): eq = self.assertEqual td = timedelta @@ -326,6 +353,9 @@ eq(td(seconds=0.001), td(milliseconds=1)) eq(td(milliseconds=0.001), td(microseconds=1)) + def test_construct_from_state(self): + pass + def test_computations(self): eq = self.assertEqual td = timedelta @@ -758,11 +788,12 @@ class SubclassDate(date): sub_var = 1 -class TestDate(HarmlessMixedComparison, unittest.TestCase): +class TestDate(HarmlessMixedComparison, ReduceStructure, unittest.TestCase): # Tests here should pass for both dates and datetimes, except for a # few tests that TestDateTime overrides. theclass = date + statetype = (bytes,) def test_basic_attributes(self): dt = self.theclass(2002, 3, 1) @@ -1387,6 +1418,7 @@ class TestDateTime(TestDate): theclass = datetime + statetype = (bytes, tzinfo) def test_basic_attributes(self): dt = self.theclass(2002, 3, 1, 12, 0) @@ -1735,6 +1767,8 @@ # than one microsecond smaller than an integer. self.assertEqual(self.theclass.fromtimestamp(0.9999999), self.theclass.fromtimestamp(1)) + self.assertEqual(self.theclass.utcfromtimestamp(0.9999999), + self.theclass.utcfromtimestamp(1)) def test_insane_fromtimestamp(self): # It's possible that some platform maps time_t to double, @@ -1962,7 +1996,7 @@ class SubclassTime(time): sub_var = 1 -class TestTime(HarmlessMixedComparison, unittest.TestCase): +class TestTime(HarmlessMixedComparison, ReduceStructure, unittest.TestCase): theclass = time From python-checkins at python.org Thu Jul 1 19:45:52 2010 From: python-checkins at python.org (benjamin.peterson) Date: Thu, 1 Jul 2010 19:45:52 +0200 (CEST) Subject: [Python-checkins] r82420 - python/trunk/Doc/library/2to3.rst Message-ID: <20100701174552.DC93FEEB23@mail.python.org> Author: benjamin.peterson Date: Thu Jul 1 19:45:52 2010 New Revision: 82420 Log: fix fixer name Modified: python/trunk/Doc/library/2to3.rst Modified: python/trunk/Doc/library/2to3.rst ============================================================================== --- python/trunk/Doc/library/2to3.rst (original) +++ python/trunk/Doc/library/2to3.rst Thu Jul 1 19:45:52 2010 @@ -276,7 +276,7 @@ Converts the :keyword:`print` statement to the :func:`print` function. -.. 2to3fixer:: raises +.. 2to3fixer:: raise Converts ``raise E, V`` to ``raise E(V)``, and ``raise E, V, T`` to ``raise E(V).with_traceback(T)``. If ``E`` is a tuple, the translation will be From python-checkins at python.org Thu Jul 1 19:48:17 2010 From: python-checkins at python.org (benjamin.peterson) Date: Thu, 1 Jul 2010 19:48:17 +0200 (CEST) Subject: [Python-checkins] r82421 - in python/branches/release26-maint: Doc/library/2to3.rst Message-ID: <20100701174817.2423AEE9F4@mail.python.org> Author: benjamin.peterson Date: Thu Jul 1 19:48:16 2010 New Revision: 82421 Log: Merged revisions 82420 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r82420 | benjamin.peterson | 2010-07-01 12:45:52 -0500 (Thu, 01 Jul 2010) | 1 line fix fixer name ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Doc/library/2to3.rst Modified: python/branches/release26-maint/Doc/library/2to3.rst ============================================================================== --- python/branches/release26-maint/Doc/library/2to3.rst (original) +++ python/branches/release26-maint/Doc/library/2to3.rst Thu Jul 1 19:48:16 2010 @@ -276,7 +276,7 @@ Converts the :keyword:`print` statement to the :func:`print` function. -.. 2to3fixer:: raises +.. 2to3fixer:: raise Converts ``raise E, V`` to ``raise E(V)``, and ``raise E, V, T`` to ``raise E(V).with_traceback(T)``. If ``E`` is a tuple, the translation will be From python-checkins at python.org Thu Jul 1 19:49:01 2010 From: python-checkins at python.org (benjamin.peterson) Date: Thu, 1 Jul 2010 19:49:01 +0200 (CEST) Subject: [Python-checkins] r82422 - in python/branches/py3k: Doc/library/2to3.rst Message-ID: <20100701174901.61836EEA84@mail.python.org> Author: benjamin.peterson Date: Thu Jul 1 19:49:01 2010 New Revision: 82422 Log: Merged revisions 82420 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r82420 | benjamin.peterson | 2010-07-01 12:45:52 -0500 (Thu, 01 Jul 2010) | 1 line fix fixer name ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/library/2to3.rst Modified: python/branches/py3k/Doc/library/2to3.rst ============================================================================== --- python/branches/py3k/Doc/library/2to3.rst (original) +++ python/branches/py3k/Doc/library/2to3.rst Thu Jul 1 19:49:01 2010 @@ -276,7 +276,7 @@ Converts the :keyword:`print` statement to the :func:`print` function. -.. 2to3fixer:: raises +.. 2to3fixer:: raise Converts ``raise E, V`` to ``raise E(V)``, and ``raise E, V, T`` to ``raise E(V).with_traceback(T)``. If ``E`` is a tuple, the translation will be From python-checkins at python.org Thu Jul 1 19:51:42 2010 From: python-checkins at python.org (benjamin.peterson) Date: Thu, 1 Jul 2010 19:51:42 +0200 (CEST) Subject: [Python-checkins] r82423 - in python/branches/release31-maint: Doc/library/2to3.rst Message-ID: <20100701175142.879D4EEA65@mail.python.org> Author: benjamin.peterson Date: Thu Jul 1 19:51:42 2010 New Revision: 82423 Log: Merged revisions 82422 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r82422 | benjamin.peterson | 2010-07-01 12:49:01 -0500 (Thu, 01 Jul 2010) | 9 lines Merged revisions 82420 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r82420 | benjamin.peterson | 2010-07-01 12:45:52 -0500 (Thu, 01 Jul 2010) | 1 line fix fixer name ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Doc/library/2to3.rst Modified: python/branches/release31-maint/Doc/library/2to3.rst ============================================================================== --- python/branches/release31-maint/Doc/library/2to3.rst (original) +++ python/branches/release31-maint/Doc/library/2to3.rst Thu Jul 1 19:51:42 2010 @@ -276,7 +276,7 @@ Converts the :keyword:`print` statement to the :func:`print` function. -.. 2to3fixer:: raises +.. 2to3fixer:: raise Converts ``raise E, V`` to ``raise E(V)``, and ``raise E, V, T`` to ``raise E(V).with_traceback(T)``. If ``E`` is a tuple, the translation will be From python-checkins at python.org Thu Jul 1 21:16:58 2010 From: python-checkins at python.org (alexander.belopolsky) Date: Thu, 1 Jul 2010 21:16:58 +0200 (CEST) Subject: [Python-checkins] r82424 - sandbox/branches/py3k-datetime/datetime.py Message-ID: <20100701191658.3B67CEE9A4@mail.python.org> Author: alexander.belopolsky Date: Thu Jul 1 21:16:58 2010 New Revision: 82424 Log: added __slots__ specifications Modified: sandbox/branches/py3k-datetime/datetime.py Modified: sandbox/branches/py3k-datetime/datetime.py ============================================================================== --- sandbox/branches/py3k-datetime/datetime.py (original) +++ sandbox/branches/py3k-datetime/datetime.py Thu Jul 1 21:16:58 2010 @@ -316,6 +316,7 @@ Representation: (days, seconds, microseconds). Why? Because I felt like it. """ + __slots__ = '__days', '__seconds', '__microseconds' def __new__(cls, days=0, seconds=0, microseconds=0, # XXX The following should only be used as keyword args: @@ -656,6 +657,7 @@ Properties (readonly): year, month, day """ + __slots__ = '__year', '__month', '__day' def __new__(cls, year, month=None, day=None): """Constructor. @@ -916,7 +918,7 @@ Subclasses must override the name(), utcoffset() and dst() methods. """ - + __slots__ = () def tzname(self, dt): "datetime -> string name of time zone." raise NotImplementedError("tzinfo subclass must override tzname()") @@ -1289,6 +1291,9 @@ # XXX needs docstrings # See http://www.zope.org/Members/fdrake/DateTimeWiki/TimeZoneInfo + __slots__ = date.__slots__ + ( + '__hour', '__minute', '__second', + '__microsecond', '_tzinfo') def __new__(cls, year, month=None, day=None, hour=0, minute=0, second=0, microsecond=0, tzinfo=None): if isinstance(year, bytes) and len(year) == 10: @@ -1765,6 +1770,8 @@ return week1monday class timezone(tzinfo): + __slots__ = '__offset', '__name' + def __init__(self, offset, *args): # Reproduce C behavior n = len(args) From python-checkins at python.org Thu Jul 1 22:10:47 2010 From: python-checkins at python.org (ezio.melotti) Date: Thu, 1 Jul 2010 22:10:47 +0200 (CEST) Subject: [Python-checkins] r82425 - in tracker/instances/python-dev/html: issue.item.html issue.search.html page.html Message-ID: <20100701201047.DA893EE98A@mail.python.org> Author: ezio.melotti Date: Thu Jul 1 22:10:47 2010 New Revision: 82425 Log: #343: Remove the "(list)" for superseder and dependencies. Modified: tracker/instances/python-dev/html/issue.item.html tracker/instances/python-dev/html/issue.search.html tracker/instances/python-dev/html/page.html Modified: tracker/instances/python-dev/html/issue.item.html ============================================================================== --- tracker/instances/python-dev/html/issue.item.html (original) +++ tracker/instances/python-dev/html/issue.item.html Thu Jul 1 22:10:47 2010 @@ -93,8 +93,8 @@ Dependencies: - + @@ -104,8 +104,8 @@ Superseder: - + Modified: tracker/instances/python-dev/html/issue.search.html ============================================================================== --- tracker/instances/python-dev/html/issue.search.html (original) +++ tracker/instances/python-dev/html/issue.search.html Thu Jul 1 22:10:47 2010 @@ -42,6 +42,15 @@   + + Ignore attachments: + +   +   +   + + Title: Modified: tracker/instances/python-dev/html/page.html ============================================================================== --- tracker/instances/python-dev/html/page.html (original) +++ tracker/instances/python-dev/html/page.html Thu Jul 1 22:10:47 2010 @@ -42,6 +42,7 @@ + @@ -145,7 +146,8 @@ })" i18n:translate="">Show Having Patch
  • - Search + Search
  • From python-checkins at python.org Thu Jul 1 22:16:23 2010 From: python-checkins at python.org (ezio.melotti) Date: Thu, 1 Jul 2010 22:16:23 +0200 (CEST) Subject: [Python-checkins] r82426 - in tracker/instances/python-dev/html: issue.search.html page.html Message-ID: <20100701201623.64B72EE98A@mail.python.org> Author: ezio.melotti Date: Thu Jul 1 22:16:23 2010 New Revision: 82426 Log: Revert accidental changes in two files that were unrelated. Modified: tracker/instances/python-dev/html/issue.search.html tracker/instances/python-dev/html/page.html Modified: tracker/instances/python-dev/html/issue.search.html ============================================================================== --- tracker/instances/python-dev/html/issue.search.html (original) +++ tracker/instances/python-dev/html/issue.search.html Thu Jul 1 22:16:23 2010 @@ -42,15 +42,6 @@   - - Ignore attachments: - -   -   -   - - Title: Modified: tracker/instances/python-dev/html/page.html ============================================================================== --- tracker/instances/python-dev/html/page.html (original) +++ tracker/instances/python-dev/html/page.html Thu Jul 1 22:16:23 2010 @@ -42,7 +42,6 @@ - @@ -146,8 +145,7 @@ })" i18n:translate="">Show Having Patch
  • - Search + Search
  • From python-checkins at python.org Thu Jul 1 22:23:17 2010 From: python-checkins at python.org (ezio.melotti) Date: Thu, 1 Jul 2010 22:23:17 +0200 (CEST) Subject: [Python-checkins] r82427 - tracker/instances/python-dev/html/issue.item.html Message-ID: <20100701202317.8EDC5D2CC@mail.python.org> Author: ezio.melotti Date: Thu Jul 1 22:23:17 2010 New Revision: 82427 Log: #251: Remove the nosy count from the issue page. Modified: tracker/instances/python-dev/html/issue.item.html Modified: tracker/instances/python-dev/html/issue.item.html ============================================================================== --- tracker/instances/python-dev/html/issue.item.html (original) +++ tracker/instances/python-dev/html/issue.item.html Thu Jul 1 22:23:17 2010 @@ -135,7 +135,7 @@ - Nosy List: + Nosy List: From python-checkins at python.org Thu Jul 1 22:26:54 2010 From: python-checkins at python.org (ezio.melotti) Date: Thu, 1 Jul 2010 22:26:54 +0200 (CEST) Subject: [Python-checkins] r82428 - tracker/instances/python-dev/html/issue.item.html Message-ID: <20100701202654.A3D90EDB4@mail.python.org> Author: ezio.melotti Date: Thu Jul 1 22:26:54 2010 New Revision: 82428 Log: Remove trailing whitespace and add a missing colon after "Keywords". Modified: tracker/instances/python-dev/html/issue.item.html Modified: tracker/instances/python-dev/html/issue.item.html ============================================================================== --- tracker/instances/python-dev/html/issue.item.html (original) +++ tracker/instances/python-dev/html/issue.item.html Thu Jul 1 22:26:54 2010 @@ -116,8 +116,8 @@ tal:attributes="href string:issue${sup/id}; title sup/title;"> -->
    View: -
    + tal:attributes="href string:issue${context/superseder/id}; title context/superseder/title;"> +
    @@ -126,7 +126,7 @@