Skip to content

Commit 5b80df3

Browse files
committed
gh-105382: Remove urllib.request cafile parameter
Remove cafile, capath and cadefault parameters of the urllib.request.urlopen() function, deprecated in Python 3.6.
1 parent 0cb6b9b commit 5b80df3

File tree

6 files changed

+17
-77
lines changed

6 files changed

+17
-77
lines changed

Doc/library/urllib.request.rst

+4-15
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ authentication, redirections, cookies and more.
2626
The :mod:`urllib.request` module defines the following functions:
2727

2828

29-
.. function:: urlopen(url, data=None[, timeout], *, cafile=None, capath=None, cadefault=False, context=None)
29+
.. function:: urlopen(url, data=None[, timeout], *, context=None)
3030

3131
Open *url*, which can be either a string containing a valid, properly
3232
encoded URL, or a :class:`Request` object.
@@ -47,14 +47,6 @@ The :mod:`urllib.request` module defines the following functions:
4747
describing the various SSL options. See :class:`~http.client.HTTPSConnection`
4848
for more details.
4949

50-
The optional *cafile* and *capath* parameters specify a set of trusted
51-
CA certificates for HTTPS requests. *cafile* should point to a single
52-
file containing a bundle of CA certificates, whereas *capath* should
53-
point to a directory of hashed certificate files. More information can
54-
be found in :meth:`ssl.SSLContext.load_verify_locations`.
55-
56-
The *cadefault* parameter is ignored.
57-
5850
This function always returns an object which can work as a
5951
:term:`context manager` and has the properties *url*, *headers*, and *status*.
6052
See :class:`urllib.response.addinfourl` for more detail on these properties.
@@ -115,12 +107,9 @@ The :mod:`urllib.request` module defines the following functions:
115107
``http/1.1`` when no *context* is given. Custom *context* should set
116108
ALPN protocols with :meth:`~ssl.SSLContext.set_alpn_protocol`.
117109

118-
.. deprecated:: 3.6
119-
120-
*cafile*, *capath* and *cadefault* are deprecated in favor of *context*.
121-
Please use :meth:`ssl.SSLContext.load_cert_chain` instead, or let
122-
:func:`ssl.create_default_context` select the system's trusted CA
123-
certificates for you.
110+
.. versionchanged:: 3.13
111+
Remove *cafile*, *capath* and *cadefault* parameters: use the *context*
112+
parameter instead.
124113

125114

126115
.. function:: install_opener(opener)

Doc/whatsnew/3.13.rst

+8
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,14 @@ Removed
310310
use ``locale.setlocale(locale.LC_ALL, "")`` instead.
311311
(Contributed by Victor Stinner in :gh:`104783`.)
312312

313+
* Remove *cafile*, *capath* and *cadefault* parameters of the
314+
:func:`urllib.request.urlopen` function, deprecated in Python 3.6: use the
315+
*context* parameter instead. Please use
316+
:meth:`ssl.SSLContext.load_cert_chain` instead, or let
317+
:func:`ssl.create_default_context` select the system's trusted CA
318+
certificates for you.
319+
(Contributed by Victor Stinner in :gh:`105382`.)
320+
313321

314322
Porting to Python 3.13
315323
======================

Lib/test/test_urllib.py

-9
Original file line numberDiff line numberDiff line change
@@ -597,15 +597,6 @@ def test_URLopener_deprecation(self):
597597
with warnings_helper.check_warnings(('',DeprecationWarning)):
598598
urllib.request.URLopener()
599599

600-
@unittest.skipUnless(ssl, "ssl module required")
601-
def test_cafile_and_context(self):
602-
context = ssl.create_default_context()
603-
with warnings_helper.check_warnings(('', DeprecationWarning)):
604-
with self.assertRaises(ValueError):
605-
urllib.request.urlopen(
606-
"https://localhost", cafile="/nonexistent/path", context=context
607-
)
608-
609600

610601
class urlopen_DataTests(unittest.TestCase):
611602
"""Test urlopen() opening a data URL."""

Lib/test/test_urllib2_localnet.py

-25
Original file line numberDiff line numberDiff line change
@@ -568,31 +568,6 @@ def test_https(self):
568568
data = self.urlopen("https://localhost:%s/bizarre" % handler.port, context=context)
569569
self.assertEqual(data, b"we care a bit")
570570

571-
def test_https_with_cafile(self):
572-
handler = self.start_https_server(certfile=CERT_localhost)
573-
with warnings_helper.check_warnings(('', DeprecationWarning)):
574-
# Good cert
575-
data = self.urlopen("https://localhost:%s/bizarre" % handler.port,
576-
cafile=CERT_localhost)
577-
self.assertEqual(data, b"we care a bit")
578-
# Bad cert
579-
with self.assertRaises(urllib.error.URLError) as cm:
580-
self.urlopen("https://localhost:%s/bizarre" % handler.port,
581-
cafile=CERT_fakehostname)
582-
# Good cert, but mismatching hostname
583-
handler = self.start_https_server(certfile=CERT_fakehostname)
584-
with self.assertRaises(urllib.error.URLError) as cm:
585-
self.urlopen("https://localhost:%s/bizarre" % handler.port,
586-
cafile=CERT_fakehostname)
587-
588-
def test_https_with_cadefault(self):
589-
handler = self.start_https_server(certfile=CERT_localhost)
590-
# Self-signed cert should fail verification with system certificate store
591-
with warnings_helper.check_warnings(('', DeprecationWarning)):
592-
with self.assertRaises(urllib.error.URLError) as cm:
593-
self.urlopen("https://localhost:%s/bizarre" % handler.port,
594-
cadefault=True)
595-
596571
def test_https_sni(self):
597572
if ssl is None:
598573
self.skipTest("ssl module required")

Lib/urllib/request.py

+2-28
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@
136136

137137
_opener = None
138138
def urlopen(url, data=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT,
139-
*, cafile=None, capath=None, cadefault=False, context=None):
139+
*, context=None):
140140
'''Open the URL url, which can be either a string or a Request object.
141141
142142
*data* must be an object specifying additional data to be sent to
@@ -154,14 +154,6 @@ def urlopen(url, data=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT,
154154
If *context* is specified, it must be a ssl.SSLContext instance describing
155155
the various SSL options. See HTTPSConnection for more details.
156156
157-
The optional *cafile* and *capath* parameters specify a set of trusted CA
158-
certificates for HTTPS requests. cafile should point to a single file
159-
containing a bundle of CA certificates, whereas capath should point to a
160-
directory of hashed certificate files. More information can be found in
161-
ssl.SSLContext.load_verify_locations().
162-
163-
The *cadefault* parameter is ignored.
164-
165157
166158
This function always returns an object which can work as a
167159
context manager and has the properties url, headers, and status.
@@ -187,25 +179,7 @@ def urlopen(url, data=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT,
187179
188180
'''
189181
global _opener
190-
if cafile or capath or cadefault:
191-
import warnings
192-
warnings.warn("cafile, capath and cadefault are deprecated, use a "
193-
"custom context instead.", DeprecationWarning, 2)
194-
if context is not None:
195-
raise ValueError(
196-
"You can't pass both context and any of cafile, capath, and "
197-
"cadefault"
198-
)
199-
if not _have_ssl:
200-
raise ValueError('SSL support not available')
201-
context = ssl.create_default_context(ssl.Purpose.SERVER_AUTH,
202-
cafile=cafile,
203-
capath=capath)
204-
# send ALPN extension to indicate HTTP/1.1 protocol
205-
context.set_alpn_protocols(['http/1.1'])
206-
https_handler = HTTPSHandler(context=context)
207-
opener = build_opener(https_handler)
208-
elif context:
182+
if context:
209183
https_handler = HTTPSHandler(context=context)
210184
opener = build_opener(https_handler)
211185
elif _opener is None:
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Remove *cafile*, *capath* and *cadefault* parameters of the
2+
:func:`urllib.request.urlopen` function, deprecated in Python 3.6. Patch by
3+
Victor Stinner.

0 commit comments

Comments
 (0)