summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.bzrignore1
-rw-r--r--.hgignore1
-rw-r--r--Doc/howto/urllib2.rst2
-rw-r--r--Doc/library/cgi.rst15
-rw-r--r--Doc/library/itertools.rst4
-rw-r--r--Lib/_pyio.py4
-rw-r--r--Lib/test/test_asynchat.py2
-rw-r--r--Lib/test/test_curses.py11
-rw-r--r--Lib/test/test_mailbox.py125
-rw-r--r--Lib/test/test_memoryio.py15
-rw-r--r--Lib/test/test_scope.py15
-rw-r--r--Modules/_io/bytesio.c8
-rw-r--r--Modules/_io/stringio.c39
-rw-r--r--Objects/unicodeobject.c4
-rw-r--r--Python/peephole.c15
15 files changed, 149 insertions, 112 deletions
diff --git a/.bzrignore b/.bzrignore
index 52143a9..3407d65 100644
--- a/.bzrignore
+++ b/.bzrignore
@@ -37,6 +37,7 @@ TAGS
.gdb_history
Doc/tools/sphinx
Doc/tools/jinja
+Doc/tools/jinja2
Doc/tools/pygments
Doc/tools/docutils
Misc/python.pc
diff --git a/.hgignore b/.hgignore
index 77def91..df3a52e 100644
--- a/.hgignore
+++ b/.hgignore
@@ -39,6 +39,7 @@ Lib/plat-mac/errors.rsrc.df.rsrc
Doc/tools/sphinx/
Doc/tools/docutils/
Doc/tools/jinja/
+Doc/tools/jinja2/
Doc/tools/pygments/
Misc/python.pc
Modules/Setup
diff --git a/Doc/howto/urllib2.rst b/Doc/howto/urllib2.rst
index 51978fc..fb5b1c3 100644
--- a/Doc/howto/urllib2.rst
+++ b/Doc/howto/urllib2.rst
@@ -492,7 +492,7 @@ than the URL you pass to .add_password() will also match. ::
.. note::
- In the above example we only supplied our ``HHTPBasicAuthHandler`` to
+ In the above example we only supplied our ``HTTPBasicAuthHandler`` to
``build_opener``. By default openers have the handlers for normal situations
-- ``ProxyHandler``, ``UnknownHandler``, ``HTTPHandler``,
``HTTPDefaultErrorHandler``, ``HTTPRedirectHandler``, ``FTPHandler``,
diff --git a/Doc/library/cgi.rst b/Doc/library/cgi.rst
index 55f6509..03dfe2d 100644
--- a/Doc/library/cgi.rst
+++ b/Doc/library/cgi.rst
@@ -88,12 +88,13 @@ input or the environment (depending on the value of various environment
variables set according to the CGI standard). Since it may consume standard
input, it should be instantiated only once.
-The :class:`FieldStorage` instance can be indexed like a Python dictionary, and
-also supports the standard dictionary methods :meth:`__contains__` and
-:meth:`keys`. The built-in :func:`len` is also supported. Form fields
-containing empty strings are ignored and do not appear in the dictionary; to
-keep such values, provide a true value for the optional *keep_blank_values*
-keyword parameter when creating the :class:`FieldStorage` instance.
+The :class:`FieldStorage` instance can be indexed like a Python dictionary.
+It allows membership testing with the :keyword:`in` operator, and also supports
+the standard dictionary method :meth:`keys` and the built-in function
+:func:`len`. Form fields containing empty strings are ignored and do not appear
+in the dictionary; to keep such values, provide a true value for the optional
+*keep_blank_values* keyword parameter when creating the :class:`FieldStorage`
+instance.
For instance, the following code (which assumes that the
:mailheader:`Content-Type` header and blank line have already been printed)
@@ -101,7 +102,7 @@ checks that the fields ``name`` and ``addr`` are both set to a non-empty
string::
form = cgi.FieldStorage()
- if not ("name" in form and "addr" in form):
+ if "name" not in form or "addr" not in form:
print("<H1>Error</H1>")
print("Please fill in the name and addr fields.")
return
diff --git a/Doc/library/itertools.rst b/Doc/library/itertools.rst
index ac3b761..c1f8d9a 100644
--- a/Doc/library/itertools.rst
+++ b/Doc/library/itertools.rst
@@ -49,13 +49,13 @@ Iterator Arguments Results
:func:`chain` p, q, ... p0, p1, ... plast, q0, q1, ... ``chain('ABC', 'DEF') --> A B C D E F``
:func:`compress` data, selectors (d[0] if s[0]), (d[1] if s[1]), ... ``compress('ABCDEF', [1,0,1,0,1,1]) --> A C E F``
:func:`dropwhile` pred, seq seq[n], seq[n+1], starting when pred fails ``dropwhile(lambda x: x<5, [1,4,6,4,1]) --> 6 4 1``
-:func:`filterfalse` pred, seq elements of seq where pred(elem) is False ``ifilterfalse(lambda x: x%2, range(10)) --> 0 2 4 6 8``
+:func:`filterfalse` pred, seq elements of seq where pred(elem) is False ``filterfalse(lambda x: x%2, range(10)) --> 0 2 4 6 8``
:func:`groupby` iterable[, keyfunc] sub-iterators grouped by value of keyfunc(v)
:func:`islice` seq, [start,] stop [, step] elements from seq[start:stop:step] ``islice('ABCDEFG', 2, None) --> C D E F G``
:func:`starmap` func, seq func(\*seq[0]), func(\*seq[1]), ... ``starmap(pow, [(2,5), (3,2), (10,3)]) --> 32 9 1000``
:func:`takewhile` pred, seq seq[0], seq[1], until pred fails ``takewhile(lambda x: x<5, [1,4,6,4,1]) --> 1 4``
:func:`tee` it, n it1, it2 , ... itn splits one iterator into n
-:func:`zip_longest` p, q, ... (p[0], q[0]), (p[1], q[1]), ... ``izip_longest('ABCD', 'xy', fillvalue='-') --> Ax By C- D-``
+:func:`zip_longest` p, q, ... (p[0], q[0]), (p[1], q[1]), ... ``zip_longest('ABCD', 'xy', fillvalue='-') --> Ax By C- D-``
==================== ============================ ================================================= =============================================================
**Combinatoric generators:**
diff --git a/Lib/_pyio.py b/Lib/_pyio.py
index bbf65bc..5458f99 100644
--- a/Lib/_pyio.py
+++ b/Lib/_pyio.py
@@ -1924,8 +1924,10 @@ class StringIO(TextIOWrapper):
# C version, even under Windows.
if newline is None:
self._writetranslate = False
- if initial_value:
+ if initial_value is not None:
if not isinstance(initial_value, str):
+ raise TypeError("initial_value must be str or None, not {0}"
+ .format(type(initial_value).__name__))
initial_value = str(initial_value)
self.write(initial_value)
self.seek(0)
diff --git a/Lib/test/test_asynchat.py b/Lib/test/test_asynchat.py
index 3da5878..f49701f 100644
--- a/Lib/test/test_asynchat.py
+++ b/Lib/test/test_asynchat.py
@@ -214,7 +214,7 @@ class TestAsynchat(unittest.TestCase):
# the server might have been able to send a byte or two back, but this
# at least checks that it received something and didn't just fail
# (which could still result in the client not having received anything)
- self.assertTrue(len(s.buffer) > 0)
+ self.assertGreater(len(s.buffer), 0)
class TestAsynchat_WithPoll(TestAsynchat):
diff --git a/Lib/test/test_curses.py b/Lib/test/test_curses.py
index bf60daa..4be2029 100644
--- a/Lib/test/test_curses.py
+++ b/Lib/test/test_curses.py
@@ -269,16 +269,17 @@ def main(stdscr):
finally:
curses.resetty()
-if __name__ == '__main__':
- curses.wrapper(main)
- unit_tests()
-else:
+def test_main():
# testing setupterm() inside initscr/endwin
# causes terminal breakage
- curses.setupterm(fd=sys.__stdout__.fileno())
+ curses.setupterm(fd=sys.stdout.fileno())
try:
stdscr = curses.initscr()
main(stdscr)
finally:
curses.endwin()
unit_tests()
+
+if __name__ == '__main__':
+ curses.wrapper(main)
+ unit_tests()
diff --git a/Lib/test/test_mailbox.py b/Lib/test/test_mailbox.py
index 8994340..66472d9 100644
--- a/Lib/test/test_mailbox.py
+++ b/Lib/test/test_mailbox.py
@@ -24,13 +24,13 @@ class TestBase(unittest.TestCase):
self.assertTrue(isinstance(msg, email.message.Message))
self.assertTrue(isinstance(msg, mailbox.Message))
for key, value in _sample_headers.items():
- self.assertTrue(value in msg.get_all(key))
+ self.assertIn(value, msg.get_all(key))
self.assertTrue(msg.is_multipart())
self.assertEqual(len(msg.get_payload()), len(_sample_payloads))
for i, payload in enumerate(_sample_payloads):
part = msg.get_payload(i)
self.assertTrue(isinstance(part, email.message.Message))
- self.assertTrue(not isinstance(part, mailbox.Message))
+ self.assertFalse(isinstance(part, mailbox.Message))
self.assertEqual(part.get_payload(), payload)
def _delete_recursively(self, target):
@@ -91,16 +91,14 @@ class TestMailbox(TestBase):
key1 = self._box.add(self._template % 1)
self.assertEqual(len(self._box), 2)
method(key0)
- l = len(self._box)
- self.assertTrue(l == 1, "actual l: %s" % l)
+ self.assertEqual(len(self._box), 1)
self.assertRaises(KeyError, lambda: self._box[key0])
self.assertRaises(KeyError, lambda: method(key0))
self.assertEqual(self._box.get_string(key1), self._template % 1)
key2 = self._box.add(self._template % 2)
self.assertEqual(len(self._box), 2)
method(key2)
- l = len(self._box)
- self.assertTrue(l == 1, "actual l: %s" % l)
+ self.assertEqual(len(self._box), 1)
self.assertRaises(KeyError, lambda: self._box[key2])
self.assertRaises(KeyError, lambda: method(key2))
self.assertEqual(self._box.get_string(key1), self._template % 1)
@@ -127,8 +125,8 @@ class TestMailbox(TestBase):
msg = self._box.get(key0)
self.assertEqual(msg['from'], 'foo')
self.assertEqual(msg.get_payload(), '0')
- self.assertTrue(self._box.get('foo') is None)
- self.assertTrue(self._box.get('foo', False) is False)
+ self.assertIs(self._box.get('foo'), None)
+ self.assertIs(self._box.get('foo', False), False)
self._box.close()
self._box = self._factory(self._path)
key1 = self._box.add(self._template % 1)
@@ -228,29 +226,28 @@ class TestMailbox(TestBase):
count = 0
for value in returned_values:
self.assertEqual(value['from'], 'foo')
- self.assertTrue(int(value.get_payload()) < repetitions)
+ self.assertLess(int(value.get_payload()), repetitions)
count += 1
self.assertEqual(len(values), count)
def test_contains(self):
# Check existence of keys using __contains__()
- method = self._box.__contains__
- self.assertTrue(not method('foo'))
+ self.assertNotIn('foo', self._box)
key0 = self._box.add(self._template % 0)
- self.assertTrue(method(key0))
- self.assertTrue(not method('foo'))
+ self.assertIn(key0, self._box)
+ self.assertNotIn('foo', self._box)
key1 = self._box.add(self._template % 1)
- self.assertTrue(method(key1))
- self.assertTrue(method(key0))
- self.assertTrue(not method('foo'))
+ self.assertIn(key1, self._box)
+ self.assertIn(key0, self._box)
+ self.assertNotIn('foo', self._box)
self._box.remove(key0)
- self.assertTrue(not method(key0))
- self.assertTrue(method(key1))
- self.assertTrue(not method('foo'))
+ self.assertNotIn(key0, self._box)
+ self.assertIn(key1, self._box)
+ self.assertNotIn('foo', self._box)
self._box.remove(key1)
- self.assertTrue(not method(key1))
- self.assertTrue(not method(key0))
- self.assertTrue(not method('foo'))
+ self.assertNotIn(key1, self._box)
+ self.assertNotIn(key0, self._box)
+ self.assertNotIn('foo', self._box)
def test_len(self, repetitions=10):
# Get message count
@@ -297,7 +294,7 @@ class TestMailbox(TestBase):
for i in range(iterations):
self._box.add(self._template % i)
for i, key in enumerate(keys):
- self.assertTrue(self._box.get_string(key) == self._template % i)
+ self.assertEqual(self._box.get_string(key), self._template % i)
self._box.clear()
self.assertEqual(len(self._box), 0)
for i, key in enumerate(keys):
@@ -306,19 +303,19 @@ class TestMailbox(TestBase):
def test_pop(self):
# Get and remove a message using pop()
key0 = self._box.add(self._template % 0)
- self.assertTrue(key0 in self._box)
+ self.assertIn(key0, self._box)
key1 = self._box.add(self._template % 1)
- self.assertTrue(key1 in self._box)
+ self.assertIn(key1, self._box)
self.assertEqual(self._box.pop(key0).get_payload(), '0')
- self.assertTrue(key0 not in self._box)
- self.assertTrue(key1 in self._box)
+ self.assertNotIn(key0, self._box)
+ self.assertIn(key1, self._box)
key2 = self._box.add(self._template % 2)
- self.assertTrue(key2 in self._box)
+ self.assertIn(key2, self._box)
self.assertEqual(self._box.pop(key2).get_payload(), '2')
- self.assertTrue(key2 not in self._box)
- self.assertTrue(key1 in self._box)
+ self.assertNotIn(key2, self._box)
+ self.assertIn(key1, self._box)
self.assertEqual(self._box.pop(key1).get_payload(), '1')
- self.assertTrue(key1 not in self._box)
+ self.assertNotIn(key1, self._box)
self.assertEqual(len(self._box), 0)
def test_popitem(self, iterations=10):
@@ -329,8 +326,8 @@ class TestMailbox(TestBase):
seen = []
for i in range(10):
key, msg = self._box.popitem()
- self.assertTrue(key in keys)
- self.assertTrue(key not in seen)
+ self.assertIn(key, keys)
+ self.assertNotIn(key, seen)
seen.append(key)
self.assertEqual(int(msg.get_payload()), keys.index(key))
self.assertEqual(len(self._box), 0)
@@ -377,11 +374,11 @@ class TestMailbox(TestBase):
def test_lock_unlock(self):
# Lock and unlock the mailbox
- self.assertTrue(not os.path.exists(self._get_lock_path()))
+ self.assertFalse(os.path.exists(self._get_lock_path()))
self._box.lock()
self.assertTrue(os.path.exists(self._get_lock_path()))
self._box.unlock()
- self.assertTrue(not os.path.exists(self._get_lock_path()))
+ self.assertFalse(os.path.exists(self._get_lock_path()))
def test_close(self):
# Close mailbox and flush changes to disk
@@ -400,7 +397,7 @@ class TestMailbox(TestBase):
keys = self._box.keys()
self.assertEqual(len(keys), 3)
for key in keys:
- self.assertTrue(self._box.get_string(key) in contents)
+ self.assertIn(self._box.get_string(key), contents)
oldbox.close()
def test_dump_message(self):
@@ -571,7 +568,7 @@ class TestMaildir(TestMailbox):
self._box.add_folder('one')
self._box.add_folder('two')
self.assertEqual(len(self._box.list_folders()), 2)
- self.assertTrue(set(self._box.list_folders()) == set(('one', 'two')))
+ self.assertEqual(set(self._box.list_folders()), set(('one', 'two')))
self._box.remove_folder('one')
self.assertEqual(len(self._box.list_folders()), 1)
self.assertEqual(set(self._box.list_folders()), set(('two',)))
@@ -602,7 +599,7 @@ class TestMaildir(TestMailbox):
os.utime(foo_path, (time.time() - 129600 - 2,
foo_stat.st_mtime))
self._box.clean()
- self.assertTrue(not os.path.exists(foo_path))
+ self.assertFalse(os.path.exists(foo_path))
self.assertTrue(os.path.exists(bar_path))
def test_create_tmp(self, repetitions=10):
@@ -623,7 +620,7 @@ class TestMaildir(TestMailbox):
"tmp")),
"File in wrong location: '%s'" % head)
match = pattern.match(tail)
- self.assertTrue(match is not None, "Invalid file name: '%s'" % tail)
+ self.assertIsNot(match, None, "Invalid file name: '%s'" % tail)
groups = match.groups()
if previous_groups is not None:
self.assertTrue(int(groups[0] >= previous_groups[0]),
@@ -691,10 +688,10 @@ class TestMaildir(TestMailbox):
return None
box = self._factory(self._path, factory=dummy_factory)
folder = box.add_folder('folder1')
- self.assertTrue(folder._factory is dummy_factory)
+ self.assertIs(folder._factory, dummy_factory)
folder1_alias = box.get_folder('folder1')
- self.assertTrue(folder1_alias._factory is dummy_factory)
+ self.assertIs(folder1_alias._factory, dummy_factory)
def test_directory_in_folder (self):
# Test that mailboxes still work if there's a stray extra directory
@@ -721,7 +718,7 @@ class TestMaildir(TestMailbox):
os.umask(orig_umask)
path = os.path.join(self._path, self._box._lookup(key))
mode = os.stat(path).st_mode
- self.assertTrue(mode & 0o111 == 0)
+ self.assertFalse(mode & 0o111)
def test_folder_file_perms(self):
# From bug #3228, we want to verify that the file created inside a Maildir
@@ -802,7 +799,7 @@ class _TestMboxMMDF(TestMailbox):
self._box = self._factory(self._path)
self.assertEqual(len(self._box), 3)
for key in self._box.keys():
- self.assertTrue(self._box.get_string(key) in values)
+ self.assertIn(self._box.get_string(key), values)
self._box.close()
self.assertEqual(mtime, os.path.getmtime(self._path))
@@ -920,8 +917,8 @@ class TestMH(TestMailbox):
# Test for bug #1569790: verify that folders returned by .get_folder()
# use the same factory function.
- self.assertTrue(new_folder._factory is self._box._factory)
- self.assertTrue(folder0._factory is self._box._factory)
+ self.assertIs(new_folder._factory, self._box._factory)
+ self.assertIs(folder0._factory, self._box._factory)
def test_add_and_remove_folders(self):
# Delete folders
@@ -990,7 +987,7 @@ class TestMH(TestMailbox):
{'foo':[key0,key1,key3], 'unseen':[key0], 'bar':[key3],
'replied':[key3]})
self._box.pack()
- self.assertTrue(self._box.keys() == [1, 2, 3])
+ self.assertEqual(self._box.keys(), [1, 2, 3])
key0 = key0
key1 = key0 + 1
key2 = key1 + 1
@@ -1086,7 +1083,7 @@ class TestMessage(TestBase):
self.assertTrue(isinstance(msg, mailbox.Message))
self.assertTrue(isinstance(msg, self._factory))
self.assertEqual(msg.keys(), [])
- self.assertTrue(not msg.is_multipart())
+ self.assertFalse(msg.is_multipart())
self.assertEqual(msg.get_payload(), None)
def test_initialize_incorrectly(self):
@@ -1159,7 +1156,7 @@ class TestMaildirMessage(TestMessage):
def test_date(self):
# Use get_date() and set_date()
msg = mailbox.MaildirMessage(_sample_message)
- self.assertTrue(abs(msg.get_date() - time.time()) < 60)
+ self.assertLess(abs(msg.get_date() - time.time()), 60)
msg.set_date(0.0)
self.assertEqual(msg.get_date(), 0.0)
@@ -1309,7 +1306,7 @@ class TestBabylMessage(TestMessage):
msg = mailbox.BabylMessage(_sample_message)
visible = msg.get_visible()
self.assertEqual(visible.keys(), [])
- self.assertTrue(visible.get_payload() is None)
+ self.assertIs(visible.get_payload(), None)
visible['User-Agent'] = 'FooBar 1.0'
visible['X-Whatever'] = 'Blah'
self.assertEqual(msg.get_visible().keys(), [])
@@ -1318,10 +1315,10 @@ class TestBabylMessage(TestMessage):
self.assertTrue(visible.keys() == ['User-Agent', 'X-Whatever'])
self.assertTrue(visible['User-Agent'] == 'FooBar 1.0')
self.assertEqual(visible['X-Whatever'], 'Blah')
- self.assertTrue(visible.get_payload() is None)
+ self.assertIs(visible.get_payload(), None)
msg.update_visible()
self.assertEqual(visible.keys(), ['User-Agent', 'X-Whatever'])
- self.assertTrue(visible.get_payload() is None)
+ self.assertIs(visible.get_payload(), None)
visible = msg.get_visible()
self.assertEqual(visible.keys(), ['User-Agent', 'Date', 'From', 'To',
'Subject'])
@@ -1423,7 +1420,7 @@ class TestMessageConversion(TestBase):
msg_mboxMMDF.set_flags(setting)
msg = mailbox.MaildirMessage(msg_mboxMMDF)
self.assertEqual(msg.get_flags(), result)
- self.assertTrue(msg.get_date() == 0.0, msg.get_date())
+ self.assertEqual(msg.get_date(), 0.0)
msg_mboxMMDF.set_flags('O')
self.assertEqual(mailbox.MaildirMessage(msg_mboxMMDF).get_subdir(),
'cur')
@@ -1822,34 +1819,34 @@ class MaildirTestCase(unittest.TestCase):
self.mbox = mailbox.Maildir(support.TESTFN)
#self.assertTrue(hasattr(self.mbox, "boxes"))
#self.assertEqual(len(self.mbox.boxes), 0)
- self.assertTrue(self.mbox.next() is None)
- self.assertTrue(self.mbox.next() is None)
+ self.assertIs(self.mbox.next(), None)
+ self.assertIs(self.mbox.next(), None)
def test_nonempty_maildir_cur(self):
self.createMessage("cur")
self.mbox = mailbox.Maildir(support.TESTFN)
#self.assertEqual(len(self.mbox.boxes), 1)
- self.assertTrue(self.mbox.next() is not None)
- self.assertTrue(self.mbox.next() is None)
- self.assertTrue(self.mbox.next() is None)
+ self.assertIsNot(self.mbox.next(), None)
+ self.assertIs(self.mbox.next(), None)
+ self.assertIs(self.mbox.next(), None)
def test_nonempty_maildir_new(self):
self.createMessage("new")
self.mbox = mailbox.Maildir(support.TESTFN)
#self.assertEqual(len(self.mbox.boxes), 1)
- self.assertTrue(self.mbox.next() is not None)
- self.assertTrue(self.mbox.next() is None)
- self.assertTrue(self.mbox.next() is None)
+ self.assertIsNot(self.mbox.next(), None)
+ self.assertIs(self.mbox.next(), None)
+ self.assertIs(self.mbox.next(), None)
def test_nonempty_maildir_both(self):
self.createMessage("cur")
self.createMessage("new")
self.mbox = mailbox.Maildir(support.TESTFN)
#self.assertEqual(len(self.mbox.boxes), 2)
- self.assertTrue(self.mbox.next() is not None)
- self.assertTrue(self.mbox.next() is not None)
- self.assertTrue(self.mbox.next() is None)
- self.assertTrue(self.mbox.next() is None)
+ self.assertIsNot(self.mbox.next(), None)
+ self.assertIsNot(self.mbox.next(), None)
+ self.assertIs(self.mbox.next(), None)
+ self.assertIs(self.mbox.next(), None)
## End: tests from the original module (for backward compatibility).
diff --git a/Lib/test/test_memoryio.py b/Lib/test/test_memoryio.py
index 48d5354..07c80436 100644
--- a/Lib/test/test_memoryio.py
+++ b/Lib/test/test_memoryio.py
@@ -140,6 +140,7 @@ class MemoryTestMixin:
self.assertEqual(memio.getvalue(), buf * 2)
memio.__init__(buf)
self.assertEqual(memio.getvalue(), buf)
+ self.assertRaises(TypeError, memio.__init__, [])
def test_read(self):
buf = self.buftype("1234567890")
@@ -338,6 +339,13 @@ class MemoryTestMixin:
self.assertEqual(test1(), buf)
self.assertEqual(test2(), buf)
+ def test_instance_dict_leak(self):
+ # Test case for issue #6242.
+ # This will be caught by regrtest.py -R if this leak.
+ for _ in range(100):
+ memio = self.ioclass()
+ memio.foo = 1
+
class PyBytesIOTest(MemoryTestMixin, MemorySeekTestMixin, unittest.TestCase):
@@ -527,6 +535,13 @@ class PyStringIOTest(MemoryTestMixin, MemorySeekTestMixin, unittest.TestCase):
memio = self.ioclass("a\r\nb\r\n", newline=None)
self.assertEqual(memio.read(5), "a\nb\n")
+ def test_newline_argument(self):
+ self.assertRaises(TypeError, self.ioclass, newline=b"\n")
+ self.assertRaises(ValueError, self.ioclass, newline="error")
+ # These should not raise an error
+ for newline in (None, "", "\n", "\r", "\r\n"):
+ self.ioclass(newline=newline)
+
class CBytesIOTest(PyBytesIOTest):
ioclass = io.BytesIO
diff --git a/Lib/test/test_scope.py b/Lib/test/test_scope.py
index 84ceafa..ef56b88 100644
--- a/Lib/test/test_scope.py
+++ b/Lib/test/test_scope.py
@@ -272,19 +272,8 @@ def f():
inner()
y = 1
- try:
- errorInOuter()
- except UnboundLocalError:
- pass
- else:
- self.fail()
-
- try:
- errorInInner()
- except NameError:
- pass
- else:
- self.fail()
+ self.assertRaises(UnboundLocalError, errorInOuter)
+ self.assertRaises(NameError, errorInInner)
# test for bug #1501934: incorrect LOAD/STORE_GLOBAL generation
exec("""
diff --git a/Modules/_io/bytesio.c b/Modules/_io/bytesio.c
index cafe4a2..e3a7849 100644
--- a/Modules/_io/bytesio.c
+++ b/Modules/_io/bytesio.c
@@ -609,11 +609,14 @@ bytesio_close(bytesio *self)
static void
bytesio_dealloc(bytesio *self)
{
+ _PyObject_GC_UNTRACK(self);
if (self->buf != NULL) {
PyMem_Free(self->buf);
self->buf = NULL;
}
- Py_TYPE(self)->tp_clear((PyObject *)self);
+ Py_CLEAR(self->dict);
+ if (self->weakreflist != NULL)
+ PyObject_ClearWeakRefs((PyObject *) self);
Py_TYPE(self)->tp_free(self);
}
@@ -669,7 +672,6 @@ static int
bytesio_traverse(bytesio *self, visitproc visit, void *arg)
{
Py_VISIT(self->dict);
- Py_VISIT(self->weakreflist);
return 0;
}
@@ -677,8 +679,6 @@ static int
bytesio_clear(bytesio *self)
{
Py_CLEAR(self->dict);
- if (self->weakreflist != NULL)
- PyObject_ClearWeakRefs((PyObject *)self);
return 0;
}
diff --git a/Modules/_io/stringio.c b/Modules/_io/stringio.c
index 84a15be..bfb099c 100644
--- a/Modules/_io/stringio.c
+++ b/Modules/_io/stringio.c
@@ -509,11 +509,15 @@ static void
stringio_dealloc(stringio *self)
{
_PyObject_GC_UNTRACK(self);
+ self->ok = 0;
+ if (self->buf) {
+ PyMem_Free(self->buf);
+ self->buf = NULL;
+ }
Py_CLEAR(self->readnl);
Py_CLEAR(self->writenl);
Py_CLEAR(self->decoder);
- if (self->buf)
- PyMem_Free(self->buf);
+ Py_CLEAR(self->dict);
if (self->weakreflist != NULL)
PyObject_ClearWeakRefs((PyObject *) self);
Py_TYPE(self)->tp_free(self);
@@ -546,22 +550,42 @@ stringio_init(stringio *self, PyObject *args, PyObject *kwds)
{
char *kwlist[] = {"initial_value", "newline", NULL};
PyObject *value = NULL;
+ PyObject *newline_obj = NULL;
char *newline = "\n";
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oz:__init__", kwlist,
- &value, &newline))
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OO:__init__", kwlist,
+ &value, &newline_obj))
return -1;
+ /* Parse the newline argument. This used to be done with the 'z'
+ specifier, however this allowed any object with the buffer interface to
+ be converted. Thus we have to parse it manually since we only want to
+ allow unicode objects or None. */
+ if (newline_obj == Py_None) {
+ newline = NULL;
+ }
+ else if (newline_obj) {
+ if (!PyUnicode_Check(newline_obj)) {
+ PyErr_Format(PyExc_TypeError,
+ "newline must be str or None, not %.200s",
+ Py_TYPE(newline_obj)->tp_name);
+ return -1;
+ }
+ newline = _PyUnicode_AsString(newline_obj);
+ if (newline == NULL)
+ return -1;
+ }
+
if (newline && newline[0] != '\0'
&& !(newline[0] == '\n' && newline[1] == '\0')
&& !(newline[0] == '\r' && newline[1] == '\0')
&& !(newline[0] == '\r' && newline[1] == '\n' && newline[2] == '\0')) {
PyErr_Format(PyExc_ValueError,
- "illegal newline value: %s", newline);
+ "illegal newline value: %R", newline_obj);
return -1;
}
if (value && value != Py_None && !PyUnicode_Check(value)) {
- PyErr_Format(PyExc_ValueError,
+ PyErr_Format(PyExc_TypeError,
"initial_value must be str or None, not %.200s",
Py_TYPE(value)->tp_name);
return -1;
@@ -573,6 +597,9 @@ stringio_init(stringio *self, PyObject *args, PyObject *kwds)
Py_CLEAR(self->writenl);
Py_CLEAR(self->decoder);
+ assert((newline != NULL && newline_obj != Py_None) ||
+ (newline == NULL && newline_obj == Py_None));
+
if (newline) {
self->readnl = PyUnicode_FromString(newline);
if (self->readnl == NULL)
diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c
index 305289b..758d054 100644
--- a/Objects/unicodeobject.c
+++ b/Objects/unicodeobject.c
@@ -2044,7 +2044,7 @@ PyObject *PyUnicode_EncodeUTF7(const Py_UNICODE *s,
{
PyObject *v;
/* It might be possible to tighten this worst case */
- Py_ssize_t allocated = 5 * size;
+ Py_ssize_t allocated = 8 * size;
int inShift = 0;
Py_ssize_t i = 0;
unsigned int base64bits = 0;
@@ -2055,7 +2055,7 @@ PyObject *PyUnicode_EncodeUTF7(const Py_UNICODE *s,
if (size == 0)
return PyBytes_FromStringAndSize(NULL, 0);
- if (allocated / 5 != size)
+ if (allocated / 8 != size)
return PyErr_NoMemory();
v = PyBytes_FromStringAndSize(NULL, allocated);
diff --git a/Python/peephole.c b/Python/peephole.c
index de1b2ac..0e70183 100644
--- a/Python/peephole.c
+++ b/Python/peephole.c
@@ -329,7 +329,7 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names,
/* Bail out if an exception is set */
if (PyErr_Occurred())
- goto exitUnchanged;
+ goto exitError;
/* Bypass optimization when the lineno table is too complex */
assert(PyBytes_Check(lineno_obj));
@@ -347,7 +347,7 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names,
/* Make a modifiable copy of the code string */
codestr = (unsigned char *)PyMem_Malloc(codelen);
if (codestr == NULL)
- goto exitUnchanged;
+ goto exitError;
codestr = (unsigned char *)memcpy(codestr,
PyBytes_AS_STRING(code), codelen);
@@ -362,11 +362,11 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names,
/* Mapping to new jump targets after NOPs are removed */
addrmap = (int *)PyMem_Malloc(codelen * sizeof(int));
if (addrmap == NULL)
- goto exitUnchanged;
+ goto exitError;
blocks = markblocks(codestr, codelen);
if (blocks == NULL)
- goto exitUnchanged;
+ goto exitError;
assert(PyList_Check(consts));
for (i=0 ; i<codelen ; i += CODESIZE(codestr[i])) {
@@ -412,7 +412,7 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names,
name = _PyUnicode_AsString(PyTuple_GET_ITEM(names, j));
h = load_global(codestr, i, name, consts);
if (h < 0)
- goto exitUnchanged;
+ goto exitError;
else if (h == 0)
continue;
cumlc = lastlc + 1;
@@ -664,6 +664,9 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names,
PyMem_Free(blocks);
return code;
+ exitError:
+ code = NULL;
+
exitUnchanged:
if (blocks != NULL)
PyMem_Free(blocks);
@@ -671,6 +674,6 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names,
PyMem_Free(addrmap);
if (codestr != NULL)
PyMem_Free(codestr);
- Py_INCREF(code);
+ Py_XINCREF(code);
return code;
}