Repository: pypa/setuptools

Issue:
Python 3.8 urllib.parse.splituser DeprecationWarning
Using setuptools on CPython master (Python 3.8) generates below warning. Just wanted to give a heads up on this.

Relevant commit : https://github.com/python/cpython/commit/0250de481

```
/home/karthi/requests-html-env/lib/python3.8/site-packages/setuptools/package_index.py:1049: DeprecationWarning: urllib.parse.splituser() is deprecated as of 3.8, use urllib.parse.urlparse() instead
  auth, host = urllib.parse.splituser(netloc)
```

Relevant code : 

https://github.com/pypa/setuptools/blob/e0433cf32dfdf39c0c14a3740c3920c496f09486/setuptools/package_index.py#L1057


Thanks


Discussion:

Resolving patch:
diff --git a/setuptools/package_index.py b/setuptools/package_index.py
--- a/setuptools/package_index.py
+++ b/setuptools/package_index.py
@@ -850,13 +850,16 @@ def _download_html(self, url, headers, filename):
 
     def _download_svn(self, url, filename):
         warnings.warn("SVN download support is deprecated", UserWarning)
+        def splituser(host):
+            user, delim, host = host.rpartition('@')
+            return user, host
         url = url.split('#', 1)[0]  # remove any fragment for svn's sake
         creds = ''
         if url.lower().startswith('svn:') and '@' in url:
             scheme, netloc, path, p, q, f = urllib.parse.urlparse(url)
             if not netloc and path.startswith('//') and '/' in path[2:]:
                 netloc, path = path[2:].split('/', 1)
-                auth, host = urllib.parse.splituser(netloc)
+                auth, host = splituser(netloc)
                 if auth:
                     if ':' in auth:
                         user, pw = auth.split(':', 1)
@@ -1047,15 +1050,16 @@ def find_credential(self, url):
 def open_with_auth(url, opener=urllib.request.urlopen):
     """Open a urllib2 request, handling HTTP authentication"""
 
-    scheme, netloc, path, params, query, frag = urllib.parse.urlparse(url)
+    parsed = urllib.parse.urlparse(url)
+    scheme, netloc, path, params, query, frag = parsed
 
     # Double scheme does not raise on Mac OS X as revealed by a
     # failing test. We would expect "nonnumeric port". Refs #20.
     if netloc.endswith(':'):
         raise http_client.InvalidURL("nonnumeric port: ''")
 
-    if scheme in ('http', 'https'):
-        auth, host = urllib.parse.splituser(netloc)
+    if scheme in ('http', 'https') and parsed.username:
+        auth = ':'.join((parsed.username, parsed.password))
     else:
         auth = None
 
@@ -1068,7 +1072,7 @@ def open_with_auth(url, opener=urllib.request.urlopen):
 
     if auth:
         auth = "Basic " + _encode_auth(auth)
-        parts = scheme, host, path, params, query, frag
+        parts = scheme, parsed.hostname, path, params, query, frag
         new_url = urllib.parse.urlunparse(parts)
         request = urllib.request.Request(new_url)
         request.add_header("Authorization", auth)
@@ -1082,7 +1086,7 @@ def open_with_auth(url, opener=urllib.request.urlopen):
         # Put authentication info back into request URL if same host,
         # so that links found on the page will work
         s2, h2, path2, param2, query2, frag2 = urllib.parse.urlparse(fp.url)
-        if s2 == scheme and h2 == host:
+        if s2 == scheme and h2 == parsed.hostname:
             parts = s2, netloc, path2, param2, query2, frag2
             fp.url = urllib.parse.urlunparse(parts)
 


Test patch:
diff --git a/setuptools/tests/test_packageindex.py b/setuptools/tests/test_packageindex.py
--- a/setuptools/tests/test_packageindex.py
+++ b/setuptools/tests/test_packageindex.py
@@ -262,6 +262,22 @@ def test_download_git_no_rev(self, tmpdir):
         ).format(**locals())
         os_system_mock.assert_called_once_with(expected)
 
+    def test_download_svn(self, tmpdir):
+        url = 'svn+https://svn.example/project#egg=foo'
+        index = setuptools.package_index.PackageIndex()
+
+        with mock.patch("os.system") as os_system_mock:
+            result = index.download(url, str(tmpdir))
+
+        os_system_mock.assert_called()
+
+        expected_dir = str(tmpdir / 'project')
+        expected = (
+            'svn checkout -q '
+            'svn+https://svn.example/project {expected_dir}'
+        ).format(**locals())
+        os_system_mock.assert_called_once_with(expected)
+
 
 class TestContentCheckers:
     def test_md5(self):