diff -r d1cbf0347eb4 -r c43e264256e4 Doc/whatsnew/3.2.rst --- a/Doc/whatsnew/3.2.rst Fri Mar 25 22:06:04 2011 +0100 +++ b/Doc/whatsnew/3.2.rst Fri Mar 25 22:15:57 2011 +0100 @@ -1499,11 +1499,11 @@ >>> os.fsencode(filename) b'Sehensw\xc3\xbcrdigkeiten' -Some operating systems allow direct access to the unencoded bytes in the +Some operating systems allow direct access to encoded bytes in the environment. If so, the :attr:`os.supports_bytes_environ` constant will be true. -For direct access to unencoded environment variables (if available), +For direct access to encoded environment variables (if available), use the new :func:`os.getenvb` function or use :data:`os.environb` which is a bytes version of :data:`os.environ`. diff -r d1cbf0347eb4 -r c43e264256e4 Lib/email/header.py --- a/Lib/email/header.py Fri Mar 25 22:06:04 2011 +0100 +++ b/Lib/email/header.py Fri Mar 25 22:15:57 2011 +0100 @@ -66,9 +66,15 @@ otherwise a lower-case string containing the name of the character set specified in the encoded string. + header may be a string that may or may not contain RFC2047 encoded words, + or it may be a Header object. + An email.errors.HeaderParseError may be raised when certain decoding error occurs (e.g. a base64 decoding exception). """ + # If it is a Header object, we can just return the chunks. + if hasattr(header, '_chunks'): + return list(header._chunks) # If no encoding, just return the header with no charset. if not ecre.search(header): return [(header, None)] diff -r d1cbf0347eb4 -r c43e264256e4 Lib/test/test_email/test_email.py --- a/Lib/test/test_email/test_email.py Fri Mar 25 22:06:04 2011 +0100 +++ b/Lib/test/test_email/test_email.py Fri Mar 25 22:15:57 2011 +0100 @@ -3925,6 +3925,20 @@ h.append(x, errors='replace') eq(str(h), e) + def test_escaped_8bit_header(self): + x = b'Ynwp4dUEbay Auction Semiar- No Charge \x96 Earn Big' + x = x.decode('ascii', 'surrogateescape') + h = Header(x, charset=email.charset.UNKNOWN8BIT) + self.assertEqual(str(h), + 'Ynwp4dUEbay Auction Semiar- No Charge \uFFFD Earn Big') + self.assertEqual(email.header.decode_header(h), [(x, 'unknown-8bit')]) + + def test_modify_returned_list_does_not_change_header(self): + h = Header('test') + chunks = email.header.decode_header(h) + chunks.append(('ascii', 'test2')) + self.assertEqual(str(h), 'test') + def test_encoded_adjacent_nonencoded(self): eq = self.assertEqual h = Header() diff -r d1cbf0347eb4 -r c43e264256e4 Lib/test/test_mailbox.py --- a/Lib/test/test_mailbox.py Fri Mar 25 22:06:04 2011 +0100 +++ b/Lib/test/test_mailbox.py Fri Mar 25 22:15:57 2011 +0100 @@ -869,8 +869,6 @@ self.assertFalse((perms & 0o111)) # Execute bits should all be off. def test_reread(self): - # Wait for 2 seconds - time.sleep(2) # Initially, the mailbox has not been read and the time is null. assert getattr(self._box, '_last_read', None) is None @@ -879,15 +877,21 @@ self._box._refresh() assert getattr(self._box, '_last_read', None) is not None - # Try calling _refresh() again; the modification times shouldn't have - # changed, so the mailbox should not be re-reading. Re-reading causes - # the ._toc attribute to be assigned a new dictionary object, so - # we'll check that the ._toc attribute isn't a different object. + # Put the last modified times more than one second into the past + # (because mtime has a one second granularity, a refresh is done + # unconditionally if called for within the same second, just in case + # the mbox has changed). + for subdir in ('cur', 'new'): + os.utime(os.path.join(self._box._path, subdir), + (time.time()-5,)*2) + + # Re-reading causes the ._toc attribute to be assigned a new dictionary + # object, so we'll check that the ._toc attribute isn't a different + # object. orig_toc = self._box._toc def refreshed(): return self._box._toc is not orig_toc - time.sleep(1) # Wait 1sec to ensure time.time()'s value changes self._box._refresh() assert not refreshed()