mirror of
https://github.com/python/cpython.git
synced 2025-09-26 18:29:57 +00:00
issue13287 - Define __all__ for urllib.request and urllib.error and expose only
the relevant module. Other cleanup improvements. Patch by flox.
This commit is contained in:
parent
712b14fc2a
commit
6c5bd40a3e
4 changed files with 40 additions and 18 deletions
|
@ -19,6 +19,18 @@ import urllib.error
|
||||||
# parse_keqv_list, parse_http_list, HTTPDigestAuthHandler
|
# parse_keqv_list, parse_http_list, HTTPDigestAuthHandler
|
||||||
|
|
||||||
class TrivialTests(unittest.TestCase):
|
class TrivialTests(unittest.TestCase):
|
||||||
|
|
||||||
|
def test___all__(self):
|
||||||
|
# Verify which names are exposed
|
||||||
|
for module in 'request', 'response', 'parse', 'error', 'robotparser':
|
||||||
|
context = {}
|
||||||
|
exec('from urllib.%s import *' % module, context)
|
||||||
|
del context['__builtins__']
|
||||||
|
for k, v in context.items():
|
||||||
|
self.assertEqual(v.__module__, 'urllib.%s' % module,
|
||||||
|
"%r is exposed in 'urllib.%s' but defined in %r" %
|
||||||
|
(k, module, v.__module__))
|
||||||
|
|
||||||
def test_trivial(self):
|
def test_trivial(self):
|
||||||
# A couple trivial tests
|
# A couple trivial tests
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,9 @@ response.
|
||||||
|
|
||||||
import urllib.response
|
import urllib.response
|
||||||
|
|
||||||
|
__all__ = ['URLError', 'HTTPError', 'ContentTooShortError']
|
||||||
|
|
||||||
|
|
||||||
# do these error classes make sense?
|
# do these error classes make sense?
|
||||||
# make sure all of the IOError stuff is overridden. we just want to be
|
# make sure all of the IOError stuff is overridden. we just want to be
|
||||||
# subtypes.
|
# subtypes.
|
||||||
|
|
|
@ -89,7 +89,6 @@ import http.client
|
||||||
import io
|
import io
|
||||||
import os
|
import os
|
||||||
import posixpath
|
import posixpath
|
||||||
import random
|
|
||||||
import re
|
import re
|
||||||
import socket
|
import socket
|
||||||
import sys
|
import sys
|
||||||
|
@ -111,6 +110,22 @@ except ImportError:
|
||||||
else:
|
else:
|
||||||
_have_ssl = True
|
_have_ssl = True
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
# Classes
|
||||||
|
'Request', 'OpenerDirector', 'BaseHandler', 'HTTPDefaultErrorHandler',
|
||||||
|
'HTTPRedirectHandler', 'HTTPCookieProcessor', 'ProxyHandler',
|
||||||
|
'HTTPPasswordMgr', 'HTTPPasswordMgrWithDefaultRealm',
|
||||||
|
'AbstractBasicAuthHandler', 'HTTPBasicAuthHandler', 'ProxyBasicAuthHandler',
|
||||||
|
'AbstractDigestAuthHandler', 'HTTPDigestAuthHandler', 'ProxyDigestAuthHandler',
|
||||||
|
'HTTPHandler', 'FileHandler', 'FTPHandler', 'CacheFTPHandler',
|
||||||
|
'UnknownHandler', 'HTTPErrorProcessor',
|
||||||
|
# Functions
|
||||||
|
'urlopen', 'install_opener', 'build_opener',
|
||||||
|
'pathname2url', 'url2pathname', 'getproxies',
|
||||||
|
# Legacy interface
|
||||||
|
'urlretrieve', 'urlcleanup', 'URLopener', 'FancyURLopener',
|
||||||
|
]
|
||||||
|
|
||||||
# used in User-Agent header sent
|
# used in User-Agent header sent
|
||||||
__version__ = sys.version[:3]
|
__version__ = sys.version[:3]
|
||||||
|
|
||||||
|
@ -885,9 +900,9 @@ class ProxyBasicAuthHandler(AbstractBasicAuthHandler, BaseHandler):
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
|
||||||
def randombytes(n):
|
# Return n random bytes.
|
||||||
"""Return n random bytes."""
|
_randombytes = os.urandom
|
||||||
return os.urandom(n)
|
|
||||||
|
|
||||||
class AbstractDigestAuthHandler:
|
class AbstractDigestAuthHandler:
|
||||||
# Digest authentication is specified in RFC 2617.
|
# Digest authentication is specified in RFC 2617.
|
||||||
|
@ -951,7 +966,7 @@ class AbstractDigestAuthHandler:
|
||||||
# authentication, and to provide some message integrity protection.
|
# authentication, and to provide some message integrity protection.
|
||||||
# This isn't a fabulous effort, but it's probably Good Enough.
|
# This isn't a fabulous effort, but it's probably Good Enough.
|
||||||
s = "%s:%s:%s:" % (self.nonce_count, nonce, time.ctime())
|
s = "%s:%s:%s:" % (self.nonce_count, nonce, time.ctime())
|
||||||
b = s.encode("ascii") + randombytes(8)
|
b = s.encode("ascii") + _randombytes(8)
|
||||||
dig = hashlib.sha1(b).hexdigest()
|
dig = hashlib.sha1(b).hexdigest()
|
||||||
return dig[:16]
|
return dig[:16]
|
||||||
|
|
||||||
|
@ -1171,7 +1186,6 @@ class HTTPHandler(AbstractHTTPHandler):
|
||||||
http_request = AbstractHTTPHandler.do_request_
|
http_request = AbstractHTTPHandler.do_request_
|
||||||
|
|
||||||
if hasattr(http.client, 'HTTPSConnection'):
|
if hasattr(http.client, 'HTTPSConnection'):
|
||||||
import ssl
|
|
||||||
|
|
||||||
class HTTPSHandler(AbstractHTTPHandler):
|
class HTTPSHandler(AbstractHTTPHandler):
|
||||||
|
|
||||||
|
@ -1677,13 +1691,11 @@ class URLopener:
|
||||||
if not host: raise IOError('http error', 'no host given')
|
if not host: raise IOError('http error', 'no host given')
|
||||||
|
|
||||||
if proxy_passwd:
|
if proxy_passwd:
|
||||||
import base64
|
|
||||||
proxy_auth = base64.b64encode(proxy_passwd.encode()).decode('ascii')
|
proxy_auth = base64.b64encode(proxy_passwd.encode()).decode('ascii')
|
||||||
else:
|
else:
|
||||||
proxy_auth = None
|
proxy_auth = None
|
||||||
|
|
||||||
if user_passwd:
|
if user_passwd:
|
||||||
import base64
|
|
||||||
auth = base64.b64encode(user_passwd.encode()).decode('ascii')
|
auth = base64.b64encode(user_passwd.encode()).decode('ascii')
|
||||||
else:
|
else:
|
||||||
auth = None
|
auth = None
|
||||||
|
@ -1773,8 +1785,8 @@ class URLopener:
|
||||||
|
|
||||||
def open_local_file(self, url):
|
def open_local_file(self, url):
|
||||||
"""Use local file."""
|
"""Use local file."""
|
||||||
import mimetypes, email.utils
|
import email.utils
|
||||||
from io import StringIO
|
import mimetypes
|
||||||
host, file = splithost(url)
|
host, file = splithost(url)
|
||||||
localname = url2pathname(file)
|
localname = url2pathname(file)
|
||||||
try:
|
try:
|
||||||
|
@ -1806,7 +1818,6 @@ class URLopener:
|
||||||
if not isinstance(url, str):
|
if not isinstance(url, str):
|
||||||
raise URLError('ftp error', 'proxy support for ftp protocol currently not implemented')
|
raise URLError('ftp error', 'proxy support for ftp protocol currently not implemented')
|
||||||
import mimetypes
|
import mimetypes
|
||||||
from io import StringIO
|
|
||||||
host, path = splithost(url)
|
host, path = splithost(url)
|
||||||
if not host: raise URLError('ftp error', 'no host given')
|
if not host: raise URLError('ftp error', 'no host given')
|
||||||
host, port = splitport(host)
|
host, port = splitport(host)
|
||||||
|
@ -1888,7 +1899,6 @@ class URLopener:
|
||||||
time.gmtime(time.time())))
|
time.gmtime(time.time())))
|
||||||
msg.append('Content-type: %s' % type)
|
msg.append('Content-type: %s' % type)
|
||||||
if encoding == 'base64':
|
if encoding == 'base64':
|
||||||
import base64
|
|
||||||
# XXX is this encoding/decoding ok?
|
# XXX is this encoding/decoding ok?
|
||||||
data = base64.decodebytes(data.encode('ascii')).decode('latin-1')
|
data = base64.decodebytes(data.encode('ascii')).decode('latin-1')
|
||||||
else:
|
else:
|
||||||
|
@ -1984,7 +1994,6 @@ class FancyURLopener(URLopener):
|
||||||
URLopener.http_error_default(self, url, fp,
|
URLopener.http_error_default(self, url, fp,
|
||||||
errcode, errmsg, headers)
|
errcode, errmsg, headers)
|
||||||
stuff = headers['www-authenticate']
|
stuff = headers['www-authenticate']
|
||||||
import re
|
|
||||||
match = re.match('[ \t]*([^ \t]+)[ \t]+realm="([^"]*)"', stuff)
|
match = re.match('[ \t]*([^ \t]+)[ \t]+realm="([^"]*)"', stuff)
|
||||||
if not match:
|
if not match:
|
||||||
URLopener.http_error_default(self, url, fp,
|
URLopener.http_error_default(self, url, fp,
|
||||||
|
@ -2010,7 +2019,6 @@ class FancyURLopener(URLopener):
|
||||||
URLopener.http_error_default(self, url, fp,
|
URLopener.http_error_default(self, url, fp,
|
||||||
errcode, errmsg, headers)
|
errcode, errmsg, headers)
|
||||||
stuff = headers['proxy-authenticate']
|
stuff = headers['proxy-authenticate']
|
||||||
import re
|
|
||||||
match = re.match('[ \t]*([^ \t]+)[ \t]+realm="([^"]*)"', stuff)
|
match = re.match('[ \t]*([^ \t]+)[ \t]+realm="([^"]*)"', stuff)
|
||||||
if not match:
|
if not match:
|
||||||
URLopener.http_error_default(self, url, fp,
|
URLopener.http_error_default(self, url, fp,
|
||||||
|
@ -2302,8 +2310,6 @@ def _proxy_bypass_macosx_sysconf(host, proxy_settings):
|
||||||
'exceptions': ['foo.bar', '*.bar.com', '127.0.0.1', '10.1', '10.0/16']
|
'exceptions': ['foo.bar', '*.bar.com', '127.0.0.1', '10.1', '10.0/16']
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
import re
|
|
||||||
import socket
|
|
||||||
from fnmatch import fnmatch
|
from fnmatch import fnmatch
|
||||||
|
|
||||||
hostonly, port = splitport(host)
|
hostonly, port = splitport(host)
|
||||||
|
@ -2406,7 +2412,6 @@ elif os.name == 'nt':
|
||||||
for p in proxyServer.split(';'):
|
for p in proxyServer.split(';'):
|
||||||
protocol, address = p.split('=', 1)
|
protocol, address = p.split('=', 1)
|
||||||
# See if address has a type:// prefix
|
# See if address has a type:// prefix
|
||||||
import re
|
|
||||||
if not re.match('^([^/:]+)://', address):
|
if not re.match('^([^/:]+)://', address):
|
||||||
address = '%s://%s' % (protocol, address)
|
address = '%s://%s' % (protocol, address)
|
||||||
proxies[protocol] = address
|
proxies[protocol] = address
|
||||||
|
@ -2438,7 +2443,6 @@ elif os.name == 'nt':
|
||||||
def proxy_bypass_registry(host):
|
def proxy_bypass_registry(host):
|
||||||
try:
|
try:
|
||||||
import winreg
|
import winreg
|
||||||
import re
|
|
||||||
except ImportError:
|
except ImportError:
|
||||||
# Std modules, so should be around - but you never know!
|
# Std modules, so should be around - but you never know!
|
||||||
return 0
|
return 0
|
||||||
|
|
|
@ -350,6 +350,9 @@ Core and Builtins
|
||||||
Library
|
Library
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
- Issue #13287: urllib.request and urllib.error now contains a __all__ and
|
||||||
|
exposes only relevant Classes, Functions. Patch by Florent Xicluna.
|
||||||
|
|
||||||
- Issue #670664: Fix HTMLParser to correctly handle the content of
|
- Issue #670664: Fix HTMLParser to correctly handle the content of
|
||||||
``<script>...</script>`` and ``<style>...</style>``.
|
``<script>...</script>`` and ``<style>...</style>``.
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue