Brange merge
diff --git a/Doc/library/crypto.rst b/Doc/library/crypto.rst
index 8650094..a233561 100644
--- a/Doc/library/crypto.rst
+++ b/Doc/library/crypto.rst
@@ -25,5 +25,5 @@
A.M. Kuchling of further interest; the package contains modules for various
encryption algorithms, most notably AES. These modules are not distributed with
Python but available separately. See the URL
-http://www.amk.ca/python/code/crypto.html for more information.
+http://www.pycrypto.org for more information.
diff --git a/Doc/whatsnew/3.2.rst b/Doc/whatsnew/3.2.rst
index 358e5be..a20bda6 100644
--- a/Doc/whatsnew/3.2.rst
+++ b/Doc/whatsnew/3.2.rst
@@ -385,7 +385,7 @@
=====================================================
This informational PEP clarifies how bytes/text issues are to be handled by the
-WGSI protocol. The challenge is that string handling in Python 3 is most
+WSGI protocol. The challenge is that string handling in Python 3 is most
conveniently handled with the :class:`str` type even though the HTTP protocol
is itself bytes oriented.
diff --git a/Lib/multiprocessing/process.py b/Lib/multiprocessing/process.py
index 99ee532..86c291e 100644
--- a/Lib/multiprocessing/process.py
+++ b/Lib/multiprocessing/process.py
@@ -267,9 +267,15 @@
sys.stdin = open(os.devnull)
except (OSError, ValueError):
pass
+ old_process = _current_process
_current_process = self
- util._finalizer_registry.clear()
- util._run_after_forkers()
+ try:
+ util._finalizer_registry.clear()
+ util._run_after_forkers()
+ finally:
+ # delay finalization of the old process object until after
+ # _run_after_forkers() is executed
+ del old_process
util.info('child process calling self.run()')
try:
self.run()
diff --git a/Lib/packaging/tests/support.py b/Lib/packaging/tests/support.py
index 501f126..8394f54 100644
--- a/Lib/packaging/tests/support.py
+++ b/Lib/packaging/tests/support.py
@@ -37,7 +37,7 @@
from packaging import logger
from packaging.dist import Distribution
from packaging.tests import unittest
-from test.support import requires_zlib
+from test.support import requires_zlib, unlink
__all__ = ['LoggingCatcher', 'TempdirManager', 'EnvironRestorer',
'DummyCommand', 'unittest', 'create_distribution',
@@ -121,21 +121,17 @@
def setUp(self):
super(TempdirManager, self).setUp()
+ self._olddir = os.getcwd()
self._basetempdir = tempfile.mkdtemp()
self._files = []
def tearDown(self):
- shutil.rmtree(self._basetempdir, os.name in ('nt', 'cygwin'))
-
for handle, name in self._files:
handle.close()
- if os.path.exists(name):
- try:
- os.remove(name)
- except OSError as exc:
- if exc.errno != errno.ENOENT:
- raise
+ unlink(name)
+ os.chdir(self._olddir)
+ shutil.rmtree(self._basetempdir)
super(TempdirManager, self).tearDown()
def mktempfile(self):
diff --git a/Lib/packaging/tests/test_command_build_ext.py b/Lib/packaging/tests/test_command_build_ext.py
index 930a38f..8f61ce4 100644
--- a/Lib/packaging/tests/test_command_build_ext.py
+++ b/Lib/packaging/tests/test_command_build_ext.py
@@ -8,13 +8,10 @@
from packaging.errors import UnknownFileError, CompileError
from packaging.command.build_ext import build_ext
from packaging.compiler.extension import Extension
+from test.script_helper import assert_python_ok
from packaging.tests import support, unittest, verbose, unload
-# http://bugs.python.org/issue4373
-# Don't load the xx module more than once.
-ALREADY_TESTED = False
-
def _get_source_filename():
srcdir = sysconfig.get_config_var('srcdir')
@@ -29,7 +26,6 @@
# Note that we're making changes to sys.path
super(BuildExtTestCase, self).setUp()
self.tmp_dir = self.mkdtemp()
- sys.path.append(self.tmp_dir)
filename = _get_source_filename()
if os.path.exists(filename):
shutil.copy(filename, self.tmp_dir)
@@ -39,8 +35,6 @@
def tearDown(self):
# Get everything back to normal
- unload('xx')
- sys.path.remove(self.tmp_dir)
if sys.version > "2.6":
site.USER_BASE = self.old_user_base
build_ext.USER_BASE = self.old_user_base
@@ -67,7 +61,6 @@
cmd.library_dirs = value.split(os.pathsep)
def test_build_ext(self):
- global ALREADY_TESTED
xx_c = os.path.join(self.tmp_dir, 'xxmodule.c')
if not os.path.exists(xx_c):
# skipping if we cannot find it
@@ -95,23 +88,24 @@
finally:
sys.stdout = old_stdout
- if ALREADY_TESTED:
- return
- else:
- ALREADY_TESTED = True
+ code = """if 1:
+ import sys
+ sys.path.insert(0, %r)
- import xx
+ import xx
- for attr in ('error', 'foo', 'new', 'roj'):
- self.assertTrue(hasattr(xx, attr))
+ for attr in ('error', 'foo', 'new', 'roj'):
+ assert hasattr(xx, attr)
- self.assertEqual(xx.foo(2, 5), 7)
- self.assertEqual(xx.foo(13, 15), 28)
- self.assertEqual(xx.new().demo(), None)
- doc = 'This is a template module just for instruction.'
- self.assertEqual(xx.__doc__, doc)
- self.assertTrue(isinstance(xx.Null(), xx.Null))
- self.assertTrue(isinstance(xx.Str(), xx.Str))
+ assert xx.foo(2, 5) == 7
+ assert xx.foo(13, 15) == 28
+ assert xx.new().demo() is None
+ doc = 'This is a template module just for instruction.'
+ assert xx.__doc__ == doc
+ assert isinstance(xx.Null(), xx.Null)
+ assert isinstance(xx.Str(), xx.Str)"""
+ code = code % self.tmp_dir
+ assert_python_ok('-c', code)
def test_solaris_enable_shared(self):
dist = Distribution({'name': 'xx'})
diff --git a/Lib/test/test_urllib2.py b/Lib/test/test_urllib2.py
index 8cd5ca0..d19e116 100644
--- a/Lib/test/test_urllib2.py
+++ b/Lib/test/test_urllib2.py
@@ -318,6 +318,9 @@
def getresponse(self):
return MockHTTPResponse(MockFile(), {}, 200, "OK")
+ def close(self):
+ pass
+
class MockHandler:
# useful for testing handler machinery
# see add_ordered_mock_handlers() docstring
diff --git a/Lib/test/test_urllib2net.py b/Lib/test/test_urllib2net.py
index 7ca6119..eaad325 100644
--- a/Lib/test/test_urllib2net.py
+++ b/Lib/test/test_urllib2net.py
@@ -234,6 +234,7 @@
url = "http://www.python.org"
with support.transient_internet(url, timeout=None):
u = _urlopen_with_retry(url)
+ self.addCleanup(u.close)
self.assertTrue(u.fp.raw._sock.gettimeout() is None)
def test_http_default_timeout(self):
@@ -243,6 +244,7 @@
socket.setdefaulttimeout(60)
try:
u = _urlopen_with_retry(url)
+ self.addCleanup(u.close)
finally:
socket.setdefaulttimeout(None)
self.assertEqual(u.fp.raw._sock.gettimeout(), 60)
@@ -254,6 +256,7 @@
socket.setdefaulttimeout(60)
try:
u = _urlopen_with_retry(url, timeout=None)
+ self.addCleanup(u.close)
finally:
socket.setdefaulttimeout(None)
self.assertTrue(u.fp.raw._sock.gettimeout() is None)
@@ -262,6 +265,7 @@
url = "http://www.python.org"
with support.transient_internet(url):
u = _urlopen_with_retry(url, timeout=120)
+ self.addCleanup(u.close)
self.assertEqual(u.fp.raw._sock.gettimeout(), 120)
FTP_HOST = "ftp://ftp.mirror.nl/pub/gnu/"
@@ -270,6 +274,7 @@
self.assertTrue(socket.getdefaulttimeout() is None)
with support.transient_internet(self.FTP_HOST, timeout=None):
u = _urlopen_with_retry(self.FTP_HOST)
+ self.addCleanup(u.close)
self.assertTrue(u.fp.fp.raw._sock.gettimeout() is None)
def test_ftp_default_timeout(self):
@@ -278,6 +283,7 @@
socket.setdefaulttimeout(60)
try:
u = _urlopen_with_retry(self.FTP_HOST)
+ self.addCleanup(u.close)
finally:
socket.setdefaulttimeout(None)
self.assertEqual(u.fp.fp.raw._sock.gettimeout(), 60)
@@ -288,6 +294,7 @@
socket.setdefaulttimeout(60)
try:
u = _urlopen_with_retry(self.FTP_HOST, timeout=None)
+ self.addCleanup(u.close)
finally:
socket.setdefaulttimeout(None)
self.assertTrue(u.fp.fp.raw._sock.gettimeout() is None)
@@ -295,6 +302,7 @@
def test_ftp_timeout(self):
with support.transient_internet(self.FTP_HOST):
u = _urlopen_with_retry(self.FTP_HOST, timeout=60)
+ self.addCleanup(u.close)
self.assertEqual(u.fp.fp.raw._sock.gettimeout(), 60)
diff --git a/Lib/urllib/request.py b/Lib/urllib/request.py
index e98a976..316e0f9 100644
--- a/Lib/urllib/request.py
+++ b/Lib/urllib/request.py
@@ -1146,6 +1146,8 @@
r = h.getresponse() # an HTTPResponse instance
except socket.error as err:
raise URLError(err)
+ finally:
+ h.close()
r.url = req.get_full_url()
# This line replaces the .msg attribute of the HTTPResponse
diff --git a/Makefile.pre.in b/Makefile.pre.in
index ff20360..1a06d3e 100644
--- a/Makefile.pre.in
+++ b/Makefile.pre.in
@@ -916,7 +916,7 @@
test/subprocessdata \
test/tracedmodules test/encoded_modules \
collections concurrent concurrent/futures encodings \
- email email/mime email/test email/test/data \
+ email email/mime test/test_email test/test_email/data \
html json test/json_tests http dbm xmlrpc \
sqlite3 sqlite3/test \
logging csv wsgiref urllib \
diff --git a/Misc/NEWS b/Misc/NEWS
index 38850c7..630b890 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -193,6 +193,10 @@
Library
-------
+- Issue #12133: AbstractHTTPHandler.do_open() of urllib.request closes the HTTP
+ connection if its getresponse() method fails with a socket error. Patch
+ written by Ezio Melotti.
+
- Issue #12240: Allow multiple setup hooks in packaging's setup.cfg files.
Original patch by Erik Bray.
diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c
index d93d358..60c374d 100644
--- a/Modules/posixmodule.c
+++ b/Modules/posixmodule.c
@@ -1162,11 +1162,11 @@
win32_xstat_impl(const char *path, struct win32_stat *result,
BOOL traverse)
{
- int code;
+ int code;
HANDLE hFile, hFile2;
BY_HANDLE_FILE_INFORMATION info;
ULONG reparse_tag = 0;
- wchar_t *target_path;
+ wchar_t *target_path;
const char *dot;
if(!check_GetFinalPathNameByHandle()) {
@@ -1262,7 +1262,7 @@
HANDLE hFile, hFile2;
BY_HANDLE_FILE_INFORMATION info;
ULONG reparse_tag = 0;
- wchar_t *target_path;
+ wchar_t *target_path;
const wchar_t *dot;
if(!check_GetFinalPathNameByHandle()) {
@@ -1281,7 +1281,7 @@
/* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
Because of this, calls like GetFinalPathNameByHandle will return
the symlink path agin and not the actual final path. */
- FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
+ FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
FILE_FLAG_OPEN_REPARSE_POINT,
NULL);
@@ -2275,7 +2275,7 @@
int fd;
long uid, gid;
int res;
- if (!PyArg_ParseTuple(args, "ill:chown", &fd, &uid, &gid))
+ if (!PyArg_ParseTuple(args, "ill:fchown", &fd, &uid, &gid))
return NULL;
Py_BEGIN_ALLOW_THREADS
res = fchown(fd, (uid_t) uid, (gid_t) gid);
@@ -6076,7 +6076,7 @@
#ifdef MS_WINDOWS
PyUnicodeObject *po;
- if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
+ if (PyArg_ParseTuple(args, "Ui|i:open", &po, &flag, &mode)) {
Py_BEGIN_ALLOW_THREADS
/* PyUnicode_AS_UNICODE OK without thread
lock as it is a simple dereference. */
@@ -6091,7 +6091,7 @@
PyErr_Clear();
#endif
- if (!PyArg_ParseTuple(args, "O&i|i",
+ if (!PyArg_ParseTuple(args, "O&i|i:open",
PyUnicode_FSConverter, &ofile,
&flag, &mode))
return NULL;
@@ -8982,12 +8982,12 @@
}
else {
if (extract_time(PyTuple_GET_ITEM(arg, 0),
- &(buf[0].tv_sec), &(buf[0].tv_usec)) == -1) {
+ &(buf[0].tv_sec), &(buf[0].tv_usec)) == -1) {
Py_DECREF(opath);
return NULL;
}
if (extract_time(PyTuple_GET_ITEM(arg, 1),
- &(buf[1].tv_sec), &(buf[1].tv_usec)) == -1) {
+ &(buf[1].tv_sec), &(buf[1].tv_usec)) == -1) {
Py_DECREF(opath);
return NULL;
}