[Python-checkins] bpo-27485: Rename and deprecate undocumented functions in urllib.parse (GH-2205)

Łukasz Langa webhook-mailer at python.org
Wed Apr 25 19:51:59 EDT 2018


https://github.com/python/cpython/commit/0250de48199552cdaed5a4fe44b3f9cdb5325363
commit: 0250de48199552cdaed5a4fe44b3f9cdb5325363
branch: master
author: Cheryl Sabella <cheryl.sabella at gmail.com>
committer: Łukasz Langa <lukasz at langa.pl>
date: 2018-04-25T16:51:54-07:00
summary:

bpo-27485: Rename and deprecate undocumented functions in urllib.parse (GH-2205)

files:
A Misc/NEWS.d/next/Library/2018-04-25-14-05-21.bpo-27485.nclVSU.rst
M Lib/mimetypes.py
M Lib/test/test_urlparse.py
M Lib/urllib/parse.py
M Lib/urllib/request.py
M Lib/xmlrpc/client.py

diff --git a/Lib/mimetypes.py b/Lib/mimetypes.py
index c86dd6d13457..f25872102b8c 100644
--- a/Lib/mimetypes.py
+++ b/Lib/mimetypes.py
@@ -113,7 +113,7 @@ def guess_type(self, url, strict=True):
         Optional `strict' argument when False adds a bunch of commonly found,
         but non-standard types.
         """
-        scheme, url = urllib.parse.splittype(url)
+        scheme, url = urllib.parse._splittype(url)
         if scheme == 'data':
             # syntax of data URLs:
             # dataurl   := "data:" [ mediatype ] [ ";base64" ] "," data
diff --git a/Lib/test/test_urlparse.py b/Lib/test/test_urlparse.py
index 9d5121792833..25c3762d8130 100644
--- a/Lib/test/test_urlparse.py
+++ b/Lib/test/test_urlparse.py
@@ -1,5 +1,6 @@
 import unittest
 import urllib.parse
+import warnings
 
 RFC1808_BASE = "http://a/b/c/d;p?q#f"
 RFC2396_BASE = "http://a/b/c/d;p?q"
@@ -1129,7 +1130,7 @@ def test_splitvalue(self):
     def test_to_bytes(self):
         result = urllib.parse.to_bytes('http://www.python.org')
         self.assertEqual(result, 'http://www.python.org')
-        self.assertRaises(UnicodeError, urllib.parse.to_bytes,
+        self.assertRaises(UnicodeError, urllib.parse._to_bytes,
                           'http://www.python.org/medi\u00e6val')
 
     def test_unwrap(self):
@@ -1137,5 +1138,90 @@ def test_unwrap(self):
         self.assertEqual(url, 'type://host/path')
 
 
+class DeprecationTest(unittest.TestCase):
+
+    def test_splittype_deprecation(self):
+        with self.assertWarns(DeprecationWarning) as cm:
+            urllib.parse.splittype('')
+        self.assertEqual(str(cm.warning),
+                         'urllib.parse.splittype() is deprecated as of 3.8, '
+                         'use urllib.parse.urlparse() instead')
+
+    def test_splithost_deprecation(self):
+        with self.assertWarns(DeprecationWarning) as cm:
+            urllib.parse.splithost('')
+        self.assertEqual(str(cm.warning),
+                         'urllib.parse.splithost() is deprecated as of 3.8, '
+                         'use urllib.parse.urlparse() instead')
+
+    def test_splituser_deprecation(self):
+        with self.assertWarns(DeprecationWarning) as cm:
+            urllib.parse.splituser('')
+        self.assertEqual(str(cm.warning),
+                         'urllib.parse.splituser() is deprecated as of 3.8, '
+                         'use urllib.parse.urlparse() instead')
+
+    def test_splitpasswd_deprecation(self):
+        with self.assertWarns(DeprecationWarning) as cm:
+            urllib.parse.splitpasswd('')
+        self.assertEqual(str(cm.warning),
+                         'urllib.parse.splitpasswd() is deprecated as of 3.8, '
+                         'use urllib.parse.urlparse() instead')
+
+    def test_splitport_deprecation(self):
+        with self.assertWarns(DeprecationWarning) as cm:
+            urllib.parse.splitport('')
+        self.assertEqual(str(cm.warning),
+                         'urllib.parse.splitport() is deprecated as of 3.8, '
+                         'use urllib.parse.urlparse() instead')
+
+    def test_splitnport_deprecation(self):
+        with self.assertWarns(DeprecationWarning) as cm:
+            urllib.parse.splitnport('')
+        self.assertEqual(str(cm.warning),
+                         'urllib.parse.splitnport() is deprecated as of 3.8, '
+                         'use urllib.parse.urlparse() instead')
+
+    def test_splitquery_deprecation(self):
+        with self.assertWarns(DeprecationWarning) as cm:
+            urllib.parse.splitquery('')
+        self.assertEqual(str(cm.warning),
+                         'urllib.parse.splitquery() is deprecated as of 3.8, '
+                         'use urllib.parse.urlparse() instead')
+
+    def test_splittag_deprecation(self):
+        with self.assertWarns(DeprecationWarning) as cm:
+            urllib.parse.splittag('')
+        self.assertEqual(str(cm.warning),
+                         'urllib.parse.splittag() is deprecated as of 3.8, '
+                         'use urllib.parse.urlparse() instead')
+
+    def test_splitattr_deprecation(self):
+        with self.assertWarns(DeprecationWarning) as cm:
+            urllib.parse.splitattr('')
+        self.assertEqual(str(cm.warning),
+                         'urllib.parse.splitattr() is deprecated as of 3.8, '
+                         'use urllib.parse.urlparse() instead')
+
+    def test_splitvalue_deprecation(self):
+        with self.assertWarns(DeprecationWarning) as cm:
+            urllib.parse.splitvalue('')
+        self.assertEqual(str(cm.warning),
+                         'urllib.parse.splitvalue() is deprecated as of 3.8, '
+                         'use urllib.parse.parse_qsl() instead')
+
+    def test_to_bytes_deprecation(self):
+        with self.assertWarns(DeprecationWarning) as cm:
+            urllib.parse.to_bytes('')
+        self.assertEqual(str(cm.warning),
+                         'urllib.parse.to_bytes() is deprecated as of 3.8')
+
+    def test_unwrap(self):
+        with self.assertWarns(DeprecationWarning) as cm:
+            urllib.parse.unwrap('')
+        self.assertEqual(str(cm.warning),
+                         'urllib.parse.unwrap() is deprecated as of 3.8')
+
+
 if __name__ == "__main__":
     unittest.main()
diff --git a/Lib/urllib/parse.py b/Lib/urllib/parse.py
index 3f8cfe5300c0..f21b8eb49cca 100644
--- a/Lib/urllib/parse.py
+++ b/Lib/urllib/parse.py
@@ -30,6 +30,7 @@
 import re
 import sys
 import collections
+import warnings
 
 __all__ = ["urlparse", "urlunparse", "urljoin", "urldefrag",
            "urlsplit", "urlunsplit", "urlencode", "parse_qs",
@@ -288,7 +289,7 @@ def _hostinfo(self):
 """
 
 _ParseResultBase.__doc__ = """
-ParseResult(scheme, netloc, path, params,  query, fragment)
+ParseResult(scheme, netloc, path, params, query, fragment)
 
 A 6-tuple that contains components of a parsed URL.
 """
@@ -913,7 +914,14 @@ def urlencode(query, doseq=False, safe='', encoding=None, errors=None,
                         l.append(k + '=' + elt)
     return '&'.join(l)
 
+
 def to_bytes(url):
+    warnings.warn("urllib.parse.to_bytes() is deprecated as of 3.8",
+                  DeprecationWarning, stacklevel=2)
+    return _to_bytes(url)
+
+
+def _to_bytes(url):
     """to_bytes(u"URL") --> 'URL'."""
     # Most URL schemes require ASCII. If that changes, the conversion
     # can be relaxed.
@@ -926,7 +934,14 @@ def to_bytes(url):
                                " contains non-ASCII characters")
     return url
 
+
 def unwrap(url):
+    warnings.warn("urllib.parse.unwrap() is deprecated as of 3.8",
+                  DeprecationWarning, stacklevel=2)
+    return _unwrap(url)
+
+
+def _unwrap(url):
     """unwrap('<URL:type://host/path>') --> 'type://host/path'."""
     url = str(url).strip()
     if url[:1] == '<' and url[-1:] == '>':
@@ -934,8 +949,16 @@ def unwrap(url):
     if url[:4] == 'URL:': url = url[4:].strip()
     return url
 
-_typeprog = None
+
 def splittype(url):
+    warnings.warn("urllib.parse.splittype() is deprecated as of 3.8, "
+                  "use urllib.parse.urlparse() instead",
+                  DeprecationWarning, stacklevel=2)
+    return _splittype(url)
+
+
+_typeprog = None
+def _splittype(url):
     """splittype('type:opaquestring') --> 'type', 'opaquestring'."""
     global _typeprog
     if _typeprog is None:
@@ -947,8 +970,16 @@ def splittype(url):
         return scheme.lower(), data
     return None, url
 
-_hostprog = None
+
 def splithost(url):
+    warnings.warn("urllib.parse.splithost() is deprecated as of 3.8, "
+                  "use urllib.parse.urlparse() instead",
+                  DeprecationWarning, stacklevel=2)
+    return _splithost(url)
+
+
+_hostprog = None
+def _splithost(url):
     """splithost('//host[:port]/path') --> 'host[:port]', '/path'."""
     global _hostprog
     if _hostprog is None:
@@ -962,19 +993,43 @@ def splithost(url):
         return host_port, path
     return None, url
 
+
 def splituser(host):
+    warnings.warn("urllib.parse.splituser() is deprecated as of 3.8, "
+                  "use urllib.parse.urlparse() instead",
+                  DeprecationWarning, stacklevel=2)
+    return _splituser(host)
+
+
+def _splituser(host):
     """splituser('user[:passwd]@host[:port]') --> 'user[:passwd]', 'host[:port]'."""
     user, delim, host = host.rpartition('@')
     return (user if delim else None), host
 
+
 def splitpasswd(user):
+    warnings.warn("urllib.parse.splitpasswd() is deprecated as of 3.8, "
+                  "use urllib.parse.urlparse() instead",
+                  DeprecationWarning, stacklevel=2)
+    return _splitpasswd(user)
+
+
+def _splitpasswd(user):
     """splitpasswd('user:passwd') -> 'user', 'passwd'."""
     user, delim, passwd = user.partition(':')
     return user, (passwd if delim else None)
 
+
+def splitport(host):
+    warnings.warn("urllib.parse.splitport() is deprecated as of 3.8, "
+                  "use urllib.parse.urlparse() instead",
+                  DeprecationWarning, stacklevel=2)
+    return _splitport(host)
+
+
 # splittag('/path#tag') --> '/path', 'tag'
 _portprog = None
-def splitport(host):
+def _splitport(host):
     """splitport('host:port') --> 'host', 'port'."""
     global _portprog
     if _portprog is None:
@@ -987,7 +1042,15 @@ def splitport(host):
             return host, port
     return host, None
 
+
 def splitnport(host, defport=-1):
+    warnings.warn("urllib.parse.splitnport() is deprecated as of 3.8, "
+                  "use urllib.parse.urlparse() instead",
+                  DeprecationWarning, stacklevel=2)
+    return _splitnport(host, defport)
+
+
+def _splitnport(host, defport=-1):
     """Split host and port, returning numeric port.
     Return given default port if no ':' found; defaults to -1.
     Return numerical port if a valid number are found after ':'.
@@ -1003,27 +1066,59 @@ def splitnport(host, defport=-1):
         return host, nport
     return host, defport
 
+
 def splitquery(url):
+    warnings.warn("urllib.parse.splitquery() is deprecated as of 3.8, "
+                  "use urllib.parse.urlparse() instead",
+                  DeprecationWarning, stacklevel=2)
+    return _splitquery(url)
+
+
+def _splitquery(url):
     """splitquery('/path?query') --> '/path', 'query'."""
     path, delim, query = url.rpartition('?')
     if delim:
         return path, query
     return url, None
 
+
 def splittag(url):
+    warnings.warn("urllib.parse.splittag() is deprecated as of 3.8, "
+                  "use urllib.parse.urlparse() instead",
+                  DeprecationWarning, stacklevel=2)
+    return _splittag(url)
+
+
+def _splittag(url):
     """splittag('/path#tag') --> '/path', 'tag'."""
     path, delim, tag = url.rpartition('#')
     if delim:
         return path, tag
     return url, None
 
+
 def splitattr(url):
+    warnings.warn("urllib.parse.splitattr() is deprecated as of 3.8, "
+                  "use urllib.parse.urlparse() instead",
+                  DeprecationWarning, stacklevel=2)
+    return _splitattr(url)
+
+
+def _splitattr(url):
     """splitattr('/path;attr1=value1;attr2=value2;...') ->
         '/path', ['attr1=value1', 'attr2=value2', ...]."""
     words = url.split(';')
     return words[0], words[1:]
 
+
 def splitvalue(attr):
+    warnings.warn("urllib.parse.splitvalue() is deprecated as of 3.8, "
+                  "use urllib.parse.parse_qsl() instead",
+                  DeprecationWarning, stacklevel=2)
+    return _splitvalue(attr)
+
+
+def _splitvalue(attr):
     """splitvalue('attr=value') --> 'attr', 'value'."""
     attr, delim, value = attr.partition('=')
     return attr, (value if delim else None)
diff --git a/Lib/urllib/request.py b/Lib/urllib/request.py
index 5b962f7dc20b..9d50b688a3a5 100644
--- a/Lib/urllib/request.py
+++ b/Lib/urllib/request.py
@@ -101,9 +101,9 @@
 
 from urllib.error import URLError, HTTPError, ContentTooShortError
 from urllib.parse import (
-    urlparse, urlsplit, urljoin, unwrap, quote, unquote,
-    splittype, splithost, splitport, splituser, splitpasswd,
-    splitattr, splitquery, splitvalue, splittag, to_bytes,
+    urlparse, urlsplit, urljoin, _unwrap, quote, unquote,
+    _splittype, _splithost, _splitport, _splituser, _splitpasswd,
+    _splitattr, _splitquery, _splitvalue, _splittag, _to_bytes,
     unquote_to_bytes, urlunparse)
 from urllib.response import addinfourl, addclosehook
 
@@ -242,7 +242,7 @@ def urlretrieve(url, filename=None, reporthook=None, data=None):
     Returns a tuple containing the path to the newly created
     data file as well as the resulting HTTPMessage object.
     """
-    url_type, path = splittype(url)
+    url_type, path = _splittype(url)
 
     with contextlib.closing(urlopen(url, data)) as fp:
         headers = fp.info()
@@ -349,8 +349,8 @@ def full_url(self):
     @full_url.setter
     def full_url(self, url):
         # unwrap('<URL:type://host/path>') --> 'type://host/path'
-        self._full_url = unwrap(url)
-        self._full_url, self.fragment = splittag(self._full_url)
+        self._full_url = _unwrap(url)
+        self._full_url, self.fragment = _splittag(self._full_url)
         self._parse()
 
     @full_url.deleter
@@ -378,10 +378,10 @@ def data(self):
         self.data = None
 
     def _parse(self):
-        self.type, rest = splittype(self._full_url)
+        self.type, rest = _splittype(self._full_url)
         if self.type is None:
             raise ValueError("unknown url type: %r" % self.full_url)
-        self.host, self.selector = splithost(rest)
+        self.host, self.selector = _splithost(rest)
         if self.host:
             self.host = unquote(self.host)
 
@@ -768,7 +768,7 @@ def _parse_proxy(proxy):
     According to RFC 3986, having an authority component means the URL must
     have two slashes after the scheme.
     """
-    scheme, r_scheme = splittype(proxy)
+    scheme, r_scheme = _splittype(proxy)
     if not r_scheme.startswith("/"):
         # authority
         scheme = None
@@ -783,9 +783,9 @@ def _parse_proxy(proxy):
         if end == -1:
             end = None
         authority = r_scheme[2:end]
-    userinfo, hostport = splituser(authority)
+    userinfo, hostport = _splituser(authority)
     if userinfo is not None:
-        user, password = splitpasswd(userinfo)
+        user, password = _splitpasswd(userinfo)
     else:
         user = password = None
     return scheme, user, password, hostport
@@ -872,7 +872,7 @@ def reduce_uri(self, uri, default_port=True):
             scheme = None
             authority = uri
             path = '/'
-        host, port = splitport(authority)
+        host, port = _splitport(authority)
         if default_port and port is None and scheme is not None:
             dport = {"http": 80,
                      "https": 443,
@@ -1261,8 +1261,8 @@ def do_request_(self, request):
 
         sel_host = host
         if request.has_proxy():
-            scheme, sel = splittype(request.selector)
-            sel_host, sel_path = splithost(sel)
+            scheme, sel = _splittype(request.selector)
+            sel_host, sel_path = _splithost(sel)
         if not request.has_header('Host'):
             request.add_unredirected_header('Host', sel_host)
         for name, value in self.parent.addheaders:
@@ -1478,7 +1478,7 @@ def open_local_file(self, req):
                 'Content-type: %s\nContent-length: %d\nLast-modified: %s\n' %
                 (mtype or 'text/plain', size, modified))
             if host:
-                host, port = splitport(host)
+                host, port = _splitport(host)
             if not host or \
                 (not port and _safe_gethostbyname(host) in self.get_names()):
                 if host:
@@ -1503,16 +1503,16 @@ def ftp_open(self, req):
         host = req.host
         if not host:
             raise URLError('ftp error: no host given')
-        host, port = splitport(host)
+        host, port = _splitport(host)
         if port is None:
             port = ftplib.FTP_PORT
         else:
             port = int(port)
 
         # username/password handling
-        user, host = splituser(host)
+        user, host = _splituser(host)
         if user:
-            user, passwd = splitpasswd(user)
+            user, passwd = _splitpasswd(user)
         else:
             passwd = None
         host = unquote(host)
@@ -1523,7 +1523,7 @@ def ftp_open(self, req):
             host = socket.gethostbyname(host)
         except OSError as msg:
             raise URLError(msg)
-        path, attrs = splitattr(req.selector)
+        path, attrs = _splitattr(req.selector)
         dirs = path.split('/')
         dirs = list(map(unquote, dirs))
         dirs, file = dirs[:-1], dirs[-1]
@@ -1533,7 +1533,7 @@ def ftp_open(self, req):
             fw = self.connect_ftp(user, passwd, host, port, dirs, req.timeout)
             type = file and 'I' or 'D'
             for attr in attrs:
-                attr, value = splitvalue(attr)
+                attr, value = _splitvalue(attr)
                 if attr.lower() == 'type' and \
                    value in ('a', 'A', 'i', 'I', 'd', 'D'):
                     type = value.upper()
@@ -1727,19 +1727,19 @@ def addheader(self, *args):
     # External interface
     def open(self, fullurl, data=None):
         """Use URLopener().open(file) instead of open(file, 'r')."""
-        fullurl = unwrap(to_bytes(fullurl))
+        fullurl = _unwrap(_to_bytes(fullurl))
         fullurl = quote(fullurl, safe="%/:=&?~#+!$,;'@()*[]|")
         if self.tempcache and fullurl in self.tempcache:
             filename, headers = self.tempcache[fullurl]
             fp = open(filename, 'rb')
             return addinfourl(fp, headers, fullurl)
-        urltype, url = splittype(fullurl)
+        urltype, url = _splittype(fullurl)
         if not urltype:
             urltype = 'file'
         if urltype in self.proxies:
             proxy = self.proxies[urltype]
-            urltype, proxyhost = splittype(proxy)
-            host, selector = splithost(proxyhost)
+            urltype, proxyhost = _splittype(proxy)
+            host, selector = _splithost(proxyhost)
             url = (host, fullurl) # Signal special case to open_*()
         else:
             proxy = None
@@ -1763,22 +1763,22 @@ def open(self, fullurl, data=None):
 
     def open_unknown(self, fullurl, data=None):
         """Overridable interface to open unknown URL type."""
-        type, url = splittype(fullurl)
+        type, url = _splittype(fullurl)
         raise OSError('url error', 'unknown url type', type)
 
     def open_unknown_proxy(self, proxy, fullurl, data=None):
         """Overridable interface to open unknown URL type."""
-        type, url = splittype(fullurl)
+        type, url = _splittype(fullurl)
         raise OSError('url error', 'invalid proxy for %s' % type, proxy)
 
     # External interface
     def retrieve(self, url, filename=None, reporthook=None, data=None):
         """retrieve(url) returns (filename, headers) for a local object
         or (tempfilename, headers) for a remote object."""
-        url = unwrap(to_bytes(url))
+        url = _unwrap(_to_bytes(url))
         if self.tempcache and url in self.tempcache:
             return self.tempcache[url]
-        type, url1 = splittype(url)
+        type, url1 = _splittype(url)
         if filename is None and (not type or type == 'file'):
             try:
                 fp = self.open_local_file(url1)
@@ -1853,25 +1853,25 @@ def _open_generic_http(self, connection_factory, url, data):
         user_passwd = None
         proxy_passwd= None
         if isinstance(url, str):
-            host, selector = splithost(url)
+            host, selector = _splithost(url)
             if host:
-                user_passwd, host = splituser(host)
+                user_passwd, host = _splituser(host)
                 host = unquote(host)
             realhost = host
         else:
             host, selector = url
             # check whether the proxy contains authorization information
-            proxy_passwd, host = splituser(host)
+            proxy_passwd, host = _splituser(host)
             # now we proceed with the url we want to obtain
-            urltype, rest = splittype(selector)
+            urltype, rest = _splittype(selector)
             url = rest
             user_passwd = None
             if urltype.lower() != 'http':
                 realhost = None
             else:
-                realhost, rest = splithost(rest)
+                realhost, rest = _splithost(rest)
                 if realhost:
-                    user_passwd, realhost = splituser(realhost)
+                    user_passwd, realhost = _splituser(realhost)
                 if user_passwd:
                     selector = "%s://%s%s" % (urltype, realhost, rest)
                 if proxy_bypass(realhost):
@@ -1977,7 +1977,7 @@ def open_local_file(self, url):
         """Use local file."""
         import email.utils
         import mimetypes
-        host, file = splithost(url)
+        host, file = _splithost(url)
         localname = url2pathname(file)
         try:
             stats = os.stat(localname)
@@ -1994,7 +1994,7 @@ def open_local_file(self, url):
             if file[:1] == '/':
                 urlfile = 'file://' + file
             return addinfourl(open(localname, 'rb'), headers, urlfile)
-        host, port = splitport(host)
+        host, port = _splitport(host)
         if (not port
            and socket.gethostbyname(host) in ((localhost(),) + thishost())):
             urlfile = file
@@ -2010,11 +2010,11 @@ def open_ftp(self, url):
         if not isinstance(url, str):
             raise URLError('ftp error: proxy support for ftp protocol currently not implemented')
         import mimetypes
-        host, path = splithost(url)
+        host, path = _splithost(url)
         if not host: raise URLError('ftp error: no host given')
-        host, port = splitport(host)
-        user, host = splituser(host)
-        if user: user, passwd = splitpasswd(user)
+        host, port = _splitport(host)
+        user, host = _splituser(host)
+        if user: user, passwd = _splitpasswd(user)
         else: passwd = None
         host = unquote(host)
         user = unquote(user or '')
@@ -2025,7 +2025,7 @@ def open_ftp(self, url):
             port = ftplib.FTP_PORT
         else:
             port = int(port)
-        path, attrs = splitattr(path)
+        path, attrs = _splitattr(path)
         path = unquote(path)
         dirs = path.split('/')
         dirs, file = dirs[:-1], dirs[-1]
@@ -2047,7 +2047,7 @@ def open_ftp(self, url):
             if not file: type = 'D'
             else: type = 'I'
             for attr in attrs:
-                attr, value = splitvalue(attr)
+                attr, value = _splitvalue(attr)
                 if attr.lower() == 'type' and \
                    value in ('a', 'A', 'i', 'I', 'd', 'D'):
                     type = value.upper()
@@ -2230,11 +2230,11 @@ def http_error_407(self, url, fp, errcode, errmsg, headers, data=None,
             return getattr(self,name)(url, realm, data)
 
     def retry_proxy_http_basic_auth(self, url, realm, data=None):
-        host, selector = splithost(url)
+        host, selector = _splithost(url)
         newurl = 'http://' + host + selector
         proxy = self.proxies['http']
-        urltype, proxyhost = splittype(proxy)
-        proxyhost, proxyselector = splithost(proxyhost)
+        urltype, proxyhost = _splittype(proxy)
+        proxyhost, proxyselector = _splithost(proxyhost)
         i = proxyhost.find('@') + 1
         proxyhost = proxyhost[i:]
         user, passwd = self.get_user_passwd(proxyhost, realm, i)
@@ -2248,11 +2248,11 @@ def retry_proxy_http_basic_auth(self, url, realm, data=None):
             return self.open(newurl, data)
 
     def retry_proxy_https_basic_auth(self, url, realm, data=None):
-        host, selector = splithost(url)
+        host, selector = _splithost(url)
         newurl = 'https://' + host + selector
         proxy = self.proxies['https']
-        urltype, proxyhost = splittype(proxy)
-        proxyhost, proxyselector = splithost(proxyhost)
+        urltype, proxyhost = _splittype(proxy)
+        proxyhost, proxyselector = _splithost(proxyhost)
         i = proxyhost.find('@') + 1
         proxyhost = proxyhost[i:]
         user, passwd = self.get_user_passwd(proxyhost, realm, i)
@@ -2266,7 +2266,7 @@ def retry_proxy_https_basic_auth(self, url, realm, data=None):
             return self.open(newurl, data)
 
     def retry_http_basic_auth(self, url, realm, data=None):
-        host, selector = splithost(url)
+        host, selector = _splithost(url)
         i = host.find('@') + 1
         host = host[i:]
         user, passwd = self.get_user_passwd(host, realm, i)
@@ -2280,7 +2280,7 @@ def retry_http_basic_auth(self, url, realm, data=None):
             return self.open(newurl, data)
 
     def retry_https_basic_auth(self, url, realm, data=None):
-        host, selector = splithost(url)
+        host, selector = _splithost(url)
         i = host.find('@') + 1
         host = host[i:]
         user, passwd = self.get_user_passwd(host, realm, i)
@@ -2502,7 +2502,7 @@ def proxy_bypass_environment(host, proxies=None):
     if no_proxy == '*':
         return 1
     # strip port off host
-    hostonly, port = splitport(host)
+    hostonly, port = _splitport(host)
     # check if the host ends with any of the DNS suffixes
     no_proxy_list = [proxy.strip() for proxy in no_proxy.split(',')]
     for name in no_proxy_list:
@@ -2533,7 +2533,7 @@ def _proxy_bypass_macosx_sysconf(host, proxy_settings):
     """
     from fnmatch import fnmatch
 
-    hostonly, port = splitport(host)
+    hostonly, port = _splitport(host)
 
     def ip2num(ipAddr):
         parts = ipAddr.split('.')
@@ -2687,7 +2687,7 @@ def proxy_bypass_registry(host):
         if not proxyEnable or not proxyOverride:
             return 0
         # try to make a host list from name and IP address.
-        rawHost, port = splitport(host)
+        rawHost, port = _splitport(host)
         host = [rawHost]
         try:
             addr = socket.gethostbyname(rawHost)
diff --git a/Lib/xmlrpc/client.py b/Lib/xmlrpc/client.py
index 1e8bb5f1bb96..ddab76ffbe83 100644
--- a/Lib/xmlrpc/client.py
+++ b/Lib/xmlrpc/client.py
@@ -1214,7 +1214,7 @@ def get_host_info(self, host):
         if isinstance(host, tuple):
             host, x509 = host
 
-        auth, host = urllib.parse.splituser(host)
+        auth, host = urllib.parse._splituser(host)
 
         if auth:
             auth = urllib.parse.unquote_to_bytes(auth)
@@ -1413,10 +1413,10 @@ def __init__(self, uri, transport=None, encoding=None, verbose=False,
         # establish a "logical" server connection
 
         # get the url
-        type, uri = urllib.parse.splittype(uri)
+        type, uri = urllib.parse._splittype(uri)
         if type not in ("http", "https"):
             raise OSError("unsupported XML-RPC protocol")
-        self.__host, self.__handler = urllib.parse.splithost(uri)
+        self.__host, self.__handler = urllib.parse._splithost(uri)
         if not self.__handler:
             self.__handler = "/RPC2"
 
diff --git a/Misc/NEWS.d/next/Library/2018-04-25-14-05-21.bpo-27485.nclVSU.rst b/Misc/NEWS.d/next/Library/2018-04-25-14-05-21.bpo-27485.nclVSU.rst
new file mode 100644
index 000000000000..8962d8229264
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2018-04-25-14-05-21.bpo-27485.nclVSU.rst
@@ -0,0 +1 @@
+Rename and deprecate undocumented functions in :func:`urllib.parse`.



More information about the Python-checkins mailing list