Repository: urllib3/urllib3

Issue:
DeprecationWarning regarding strict argument in connection.py
When using requests which includes urllib3 I get this deprecationwarning that traces back to connection.py.

It doesn't break code but just clutters logs.

'C:\Python33\lib\sitepackages\requests\packages\urllib3\connection.py:99: DeprecationWarning: the ´strict´ argument isn´t supported anymore; http.client now always assumes HTTP/1.x compliant servers.
 HTTPConnection.**init**(self, host, port, strict, timeout, source_address)'



Discussion:
Mmmm looks like a regression of #238/#239. :(

We need to add a test/configuration to break on DeprecationWarning which travisci would ideally catch under py3.


Resolving patch:
diff --git a/urllib3/connection.py b/urllib3/connection.py
--- a/urllib3/connection.py
+++ b/urllib3/connection.py
@@ -4,6 +4,7 @@
 # This module is part of urllib3 and is released under
 # the MIT License: http://www.opensource.org/licenses/mit-license.php
 
+import sys
 import socket
 from socket import timeout as SocketTimeout
 
@@ -38,6 +39,7 @@ class BaseSSLError(BaseException):
     ConnectTimeoutError,
 )
 from .packages.ssl_match_hostname import match_hostname
+from .packages import six
 from .util import (
     assert_fingerprint,
     resolve_cert_reqs,
@@ -53,27 +55,40 @@ class BaseSSLError(BaseException):
 
 
 class HTTPConnection(_HTTPConnection, object):
+    """
+    Based on httplib.HTTPConnection but provides an extra constructor
+    backwards-compatibility layer between older and newer Pythons.
+    """
+
     default_port = port_by_scheme['http']
 
     # By default, disable Nagle's Algorithm.
     tcp_nodelay = 1
 
+    def __init__(self, *args, **kw):
+        if six.PY3:  # Python 3
+            kw.pop('strict', None)
+
+        if sys.version_info < (2, 7):  # Python 2.6 and earlier
+            kw.pop('source_address', None)
+            self.source_address = None
+
+        _HTTPConnection.__init__(self, *args, **kw)
+
     def _new_conn(self):
         """ Establish a socket connection and set nodelay settings on it
 
         :return: a new socket connection
         """
-        try:
-            conn = socket.create_connection(
-                (self.host, self.port),
-                self.timeout,
-                self.source_address,
-            )
-        except AttributeError: # Python 2.6
-            conn = socket.create_connection(
-                (self.host, self.port),
-                self.timeout,
-            )
+        extra_args = []
+        if self.source_address:  # Python 2.7+
+            extra_args.append(self.source_address)
+
+        conn = socket.create_connection(
+            (self.host, self.port),
+            self.timeout,
+            *extra_args
+        )
         conn.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY,
                         self.tcp_nodelay)
         return conn
@@ -95,10 +110,12 @@ class HTTPSConnection(HTTPConnection):
     def __init__(self, host, port=None, key_file=None, cert_file=None,
                  strict=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT,
                  source_address=None):
-        try:
-            HTTPConnection.__init__(self, host, port, strict, timeout, source_address)
-        except TypeError: # Python 2.6
-            HTTPConnection.__init__(self, host, port, strict, timeout)
+
+        HTTPConnection.__init__(self, host, port,
+                                strict=strict,
+                                timeout=timeout,
+                                source_address=source_address)
+
         self.key_file = key_file
         self.cert_file = cert_file
 
diff --git a/urllib3/connectionpool.py b/urllib3/connectionpool.py
--- a/urllib3/connectionpool.py
+++ b/urllib3/connectionpool.py
@@ -170,13 +170,9 @@ def _new_conn(self):
         log.info("Starting new HTTP connection (%d): %s" %
                  (self.num_connections, self.host))
 
-        extra_params = {}
-        if not six.PY3:  # Python 2
-            extra_params['strict'] = self.strict
-
         conn = self.ConnectionCls(host=self.host, port=self.port,
                                   timeout=self.timeout.connect_timeout,
-                                  **extra_params)
+                                  strict=self.strict)
         if self.proxy is not None:
             # Enable Nagle's algorithm for proxies, to avoid packet
             # fragmentation.
@@ -238,8 +234,9 @@ def _put_conn(self, conn):
             pass
         except Full:
             # This should never happen if self.block == True
-            log.warning("HttpConnectionPool is full, discarding connection: %s"
-                        % self.host)
+            log.warning(
+                "Connection pool is full, discarding connection: %s" %
+                self.host)
 
         # Connection never got put back into the pool, close it.
         if conn:
@@ -538,8 +535,8 @@ def urlopen(self, method, url, body=None, headers=None, retries=3,
 
         if not conn:
             # Try again
-            log.warn("Retrying (%d attempts remain) after connection "
-                     "broken by '%r': %s" % (retries, err, url))
+            log.warning("Retrying (%d attempts remain) after connection "
+                        "broken by '%r': %s" % (retries, err, url))
             return self.urlopen(method, url, body, headers, retries - 1,
                                 redirect, assert_same_host,
                                 timeout=timeout, pool_timeout=pool_timeout,


Test patch:
diff --git a/test/__init__.py b/test/__init__.py
--- a/test/__init__.py
+++ b/test/__init__.py
@@ -7,6 +7,7 @@
 from urllib3.exceptions import MaxRetryError
 from urllib3.packages import six
 
+
 def onlyPY3(test):
     """Skips this test unless you are on Python3.x"""
 
diff --git a/test/test_compatibility.py b/test/test_compatibility.py
new file mode 100644
--- /dev/null
+++ b/test/test_compatibility.py
@@ -0,0 +1,23 @@
+import unittest
+import warnings
+
+from urllib3.connection import HTTPConnection
+
+
+class TestVersionCompatibility(unittest.TestCase):
+    def test_connection_strict(self):
+        with warnings.catch_warnings(record=True) as w:
+            warnings.simplefilter("always")
+
+            # strict=True is deprecated in Py33+
+            conn = HTTPConnection('localhost', 12345, strict=True)
+
+            if w:
+                self.fail('HTTPConnection raised warning on strict=True: %r' % w[0].message)
+
+    def test_connection_source_address(self):
+        try:
+            # source_address does not exist in Py26-
+            conn = HTTPConnection('localhost', 12345, source_address='127.0.0.1')
+        except TypeError as e:
+            self.fail('HTTPConnection raised TypeError on source_adddress: %r' % e)
diff --git a/test/test_filepost.py b/test/test_filepost.py
--- a/test/test_filepost.py
+++ b/test/test_filepost.py
@@ -124,7 +124,7 @@ def test_request_fields(self):
 
       encoded, content_type = encode_multipart_formdata(fields, boundary=BOUNDARY)
 
-      self.assertEquals(encoded,
+      self.assertEqual(encoded,
           b'--' + b(BOUNDARY) + b'\r\n'
           b'Content-Type: image/jpeg\r\n'
           b'\r\n'
diff --git a/test/test_util.py b/test/test_util.py
--- a/test/test_util.py
+++ b/test/test_util.py
@@ -64,7 +64,7 @@ def test_get_host(self):
         }
         for url, expected_host in url_host_map.items():
             returned_host = get_host(url)
-            self.assertEquals(returned_host, expected_host)
+            self.assertEqual(returned_host, expected_host)
 
     def test_invalid_host(self):
         # TODO: Add more tests
@@ -110,7 +110,7 @@ def test_parse_url(self):
         }
         for url, expected_url in url_host_map.items():
             returned_url = parse_url(url)
-            self.assertEquals(returned_url, expected_url)
+            self.assertEqual(returned_url, expected_url)
 
     def test_parse_url_invalid_IPv6(self):
         self.assertRaises(ValueError, parse_url, '[::1')
@@ -129,7 +129,7 @@ def test_request_uri(self):
         }
         for url, expected_request_uri in url_host_map.items():
             returned_url = parse_url(url)
-            self.assertEquals(returned_url.request_uri, expected_request_uri)
+            self.assertEqual(returned_url.request_uri, expected_request_uri)
 
     def test_netloc(self):
         url_netloc_map = {
@@ -140,7 +140,7 @@ def test_netloc(self):
         }
 
         for url, expected_netloc in url_netloc_map.items():
-            self.assertEquals(parse_url(url).netloc, expected_netloc)
+            self.assertEqual(parse_url(url).netloc, expected_netloc)
 
     def test_make_headers(self):
         self.assertEqual(
diff --git a/test/with_dummyserver/test_socketlevel.py b/test/with_dummyserver/test_socketlevel.py
--- a/test/with_dummyserver/test_socketlevel.py
+++ b/test/with_dummyserver/test_socketlevel.py
@@ -39,7 +39,7 @@ def multicookie_response_handler(listener):
         self._start_server(multicookie_response_handler)
         pool = HTTPConnectionPool(self.host, self.port)
         r = pool.request('GET', '/', retries=0)
-        self.assertEquals(r.headers, {'set-cookie': 'foo=1, bar=1'})
+        self.assertEqual(r.headers, {'set-cookie': 'foo=1, bar=1'})
 
 
 class TestSNI(SocketDummyServerTestCase):