[Python-checkins] cpython (3.4): in ftp cache pruning, avoid changing the size of a dict while iterating over it

benjamin.peterson python-checkins at python.org
Sun Jun 8 00:09:42 CEST 2014


http://hg.python.org/cpython/rev/b8f9ae84d211
changeset: 91070:b8f9ae84d211
branch: 3.4
parent: 91067:19172062e5c0
user: Benjamin Peterson <benjamin at python.org>
date: Sat Jun 07 15:08:04 2014 -0700
summary:
 in ftp cache pruning, avoid changing the size of a dict while iterating over it (closes #21463)
Patch by Skyler Leigh Amador.
files:
 Lib/test/test_urllib.py | 32 ++++++++++++++++++++++++++++-
 Lib/urllib/request.py | 2 +-
 Misc/ACKS | 1 +
 Misc/NEWS | 2 +
 4 files changed, 35 insertions(+), 2 deletions(-)
diff --git a/Lib/test/test_urllib.py b/Lib/test/test_urllib.py
--- a/Lib/test/test_urllib.py
+++ b/Lib/test/test_urllib.py
@@ -7,6 +7,7 @@
 import email.message
 import io
 import unittest
+from unittest.mock import patch
 from test import support
 import os
 import sys
@@ -89,6 +90,26 @@
 http.client.HTTPConnection = self._connection_class
 
 
+class FakeFTPMixin(object):
+ def fakeftp(self):
+ class FakeFtpWrapper(object):
+ def __init__(self, user, passwd, host, port, dirs, timeout=None,
+ persistent=True):
+ pass
+
+ def retrfile(self, file, type):
+ return io.BytesIO(), 0
+
+ def close(self):
+ pass
+
+ self._ftpwrapper_class = urllib.request.ftpwrapper
+ urllib.request.ftpwrapper = FakeFtpWrapper
+
+ def unfakeftp(self):
+ urllib.request.ftpwrapper = self._ftpwrapper_class
+
+
 class urlopen_FileTests(unittest.TestCase):
 """Test urlopen() opening a temporary file.
 
@@ -195,7 +216,7 @@
 self.env.set('NO_PROXY', 'localhost, anotherdomain.com, newdomain.com')
 self.assertTrue(urllib.request.proxy_bypass_environment('anotherdomain.com'))
 
-class urlopen_HttpTests(unittest.TestCase, FakeHTTPMixin):
+class urlopen_HttpTests(unittest.TestCase, FakeHTTPMixin, FakeFTPMixin):
 """Test urlopen() opening a fake http connection."""
 
 def check_read(self, ver):
@@ -309,6 +330,15 @@
 self.assertFalse(e.exception.filename)
 self.assertTrue(e.exception.reason)
 
+ @patch.object(urllib.request, 'MAXFTPCACHE', 0)
+ def test_ftp_cache_pruning(self):
+ self.fakeftp()
+ try:
+ urllib.request.ftpcache['test'] = urllib.request.ftpwrapper('user', 'pass', 'localhost', 21, [])
+ urlopen('ftp://localhost')
+ finally:
+ self.unfakeftp()
+
 
 def test_userpass_inurl(self):
 self.fakehttp(b"HTTP/1.0 200 OK\r\n\r\nHello!")
diff --git a/Lib/urllib/request.py b/Lib/urllib/request.py
--- a/Lib/urllib/request.py
+++ b/Lib/urllib/request.py
@@ -1911,7 +1911,7 @@
 # XXX thread unsafe!
 if len(self.ftpcache) > MAXFTPCACHE:
 # Prune the cache, rather arbitrarily
- for k in self.ftpcache.keys():
+ for k in list(self.ftpcache):
 if k != key:
 v = self.ftpcache[k]
 del self.ftpcache[k]
diff --git a/Misc/ACKS b/Misc/ACKS
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -32,6 +32,7 @@
 Ray Allen
 Billy G. Allie
 Kevin Altis
+Skyler Leigh Amador
 Joe Amenta
 A. Amoroso
 Mark Anacker
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -22,6 +22,8 @@
 Library
 -------
 
+- Issue #21463: In urllib.request, fix pruning of the FTP cache.
+
 - Issue #21618: The subprocess module could fail to close open fds that were
 inherited by the calling process and already higher than POSIX resource
 limits would otherwise allow. On systems with a functioning /proc/self/fd
-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list

AltStyle によって変換されたページ (->オリジナル) /