From f67449d555254b2d4d04377ff81296f974fc82f3 Mon Sep 17 00:00:00 2001 From: kishorhange111 Date: Sat, 25 Apr 2026 12:39:51 +0530 Subject: [PATCH 01/12] gh-148849: Deprecate http.cookies.BaseCookie.js_output() --- Doc/library/http.cookies.rst | 4 ++++ Doc/whatsnew/3.15.rst | 6 +++++ Lib/http/cookies.py | 5 +++++ Lib/test/test_http_cookies.py | 22 ++++++++++++------- ...-04-25-12-04-27.gh-issue-148849.Vk6yEW.rst | 2 ++ 5 files changed, 31 insertions(+), 8 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2026-04-25-12-04-27.gh-issue-148849.Vk6yEW.rst diff --git a/Doc/library/http.cookies.rst b/Doc/library/http.cookies.rst index b3fcd21c7e2244..5b5d0418f167ef 100644 --- a/Doc/library/http.cookies.rst +++ b/Doc/library/http.cookies.rst @@ -109,6 +109,10 @@ Cookie Objects The meaning for *attrs* is the same as in :meth:`output`. + .. deprecated:: 3.15 + :meth:`!js_output` is deprecated and will be removed in Python 3.17. + Use :meth:`output` instead. + .. method:: BaseCookie.load(rawdata) diff --git a/Doc/whatsnew/3.15.rst b/Doc/whatsnew/3.15.rst index dbdd5de01700a3..a51e38e36d5a8b 100644 --- a/Doc/whatsnew/3.15.rst +++ b/Doc/whatsnew/3.15.rst @@ -1741,6 +1741,12 @@ New deprecations (Contributed by Bénédikt Tran in :gh:`134978`.) +* :meth:`http.cookies.BaseCookie.js_output` is deprecated and will be + removed in Python 3.17. Use + :meth:`~http.cookies.BaseCookie.output` instead. + (Contributed by kishorhange111 in :gh:`148849`.) + + * :mod:`re`: * :func:`re.match` and :meth:`re.Pattern.match` are now diff --git a/Lib/http/cookies.py b/Lib/http/cookies.py index 660fec4f1be865..0bf2ebfce292a7 100644 --- a/Lib/http/cookies.py +++ b/Lib/http/cookies.py @@ -132,6 +132,7 @@ import re import string import types +import warnings __all__ = ["CookieError", "BaseCookie", "SimpleCookie"] @@ -539,6 +540,10 @@ def __repr__(self): l.append('%s=%s' % (key, repr(value.value))) return '<%s: %s>' % (self.__class__.__name__, _spacejoin(l)) + @warnings.deprecated( + "http.cookies.BaseCookie.js_output() is deprecated and will " + "be removed in Python 3.17; use output() instead" + ) def js_output(self, attrs=None): """Return a string suitable for JavaScript.""" result = [] diff --git a/Lib/test/test_http_cookies.py b/Lib/test/test_http_cookies.py index cfcbc17bd6df80..1533e4755dd827 100644 --- a/Lib/test/test_http_cookies.py +++ b/Lib/test/test_http_cookies.py @@ -176,7 +176,8 @@ def test_load(self): self.assertEqual(C.output(['path']), 'Set-Cookie: Customer="WILE_E_COYOTE"; Path=/acme') cookie_encoded = base64.b64encode(b'Customer="WILE_E_COYOTE"; Path=/acme; Version=1').decode('ascii') - self.assertEqual(C.js_output(), fr""" + with self.assertWarnsRegex(DeprecationWarning, "BaseCookie.js_output"): + self.assertEqual(C.js_output(), fr""" """) cookie_encoded = base64.b64encode(b'Customer="WILE_E_COYOTE"; Path=/acme').decode('ascii') - self.assertEqual(C.js_output(['path']), fr""" + with self.assertWarnsRegex(DeprecationWarning, "BaseCookie.js_output"): + self.assertEqual(C.js_output(['path']), fr""" """ % (expected_encoded_cookie,) - self.assertEqual(M.js_output(), expected_js_output) + with self.assertWarnsRegex(DeprecationWarning, r"Morsel\.js_output"): + self.assertEqual(M.js_output(), expected_js_output) for i in ["foo bar", "foo@bar"]: # Try some illegal characters self.assertRaises(cookies.CookieError, @@ -677,7 +678,7 @@ def test_control_characters_output(self): cookie = cookies.SimpleCookie() cookie["cookie"] = morsel with self.assertRaises(cookies.CookieError): - with self.assertWarnsRegex(DeprecationWarning, r"BaseCookie\.js_output"): + with self.assertWarnsRegex(DeprecationWarning, r"Morsel\.js_output"): cookie.js_output() morsel = cookies.Morsel() @@ -686,10 +687,27 @@ def test_control_characters_output(self): cookie = cookies.SimpleCookie() cookie["cookie"] = morsel with self.assertRaises(cookies.CookieError): - with self.assertWarnsRegex(DeprecationWarning, r"BaseCookie\.js_output"): + with self.assertWarnsRegex(DeprecationWarning, r"Morsel\.js_output"): cookie.js_output() + def test_morsel_js_output_deprecated(self): + morsel = cookies.Morsel() + morsel.set("key", "value", "value") + with self.assertWarnsRegex(DeprecationWarning, r"Morsel\.js_output"): + result = morsel.js_output() + self.assertIn("document.cookie", result) + def test_basecookie_js_output_warns_once(self): + C = cookies.SimpleCookie() + C["key"] = "value" + with self.assertWarns(DeprecationWarning) as cm: + C.js_output() + # Should only be one warning even though BaseCookie iterates Morsels + deprecation_warnings = [ + w for w in cm.warnings if issubclass(w.category, DeprecationWarning) + ] + self.assertEqual(len(deprecation_warnings), 1) + self.assertRegex(str(deprecation_warnings[0].message), r"Morsel\.js_output") def load_tests(loader, tests, pattern): tests.addTest(doctest.DocTestSuite(cookies)) diff --git a/Misc/NEWS.d/next/Library/2026-04-25-12-04-27.gh-issue-148849.Vk6yEW.rst b/Misc/NEWS.d/next/Library/2026-04-25-12-04-27.gh-issue-148849.Vk6yEW.rst index 7f1f708e36040b..9725d63747d451 100644 --- a/Misc/NEWS.d/next/Library/2026-04-25-12-04-27.gh-issue-148849.Vk6yEW.rst +++ b/Misc/NEWS.d/next/Library/2026-04-25-12-04-27.gh-issue-148849.Vk6yEW.rst @@ -1,2 +1,4 @@ -Deprecate :meth:`http.cookies.BaseCookie.js_output`, which will be -removed in Python 3.19. Use :meth:`http.cookies.BaseCookie.output` instead. +Deprecate :meth:`http.cookies.Morsel.js_output` and +:meth:`http.cookies.BaseCookie.js_output`, which will be removed in +Python 3.19. Use :meth:`http.cookies.Morsel.output` or +:meth:`http.cookies.BaseCookie.output` instead. From c957098a17aa28eb33932ef2c5e285a523443a79 Mon Sep 17 00:00:00 2001 From: kishorhange111 <101962449+kishorhange111@users.noreply.github.com> Date: Sat, 2 May 2026 07:57:46 +0000 Subject: [PATCH 12/12] gh-148849: Fix duplicate Morsel.js_output doc entry and indentation --- Doc/library/http.cookies.rst | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/Doc/library/http.cookies.rst b/Doc/library/http.cookies.rst index 4d5c2eb09b3b0f..4981f71ed7c306 100644 --- a/Doc/library/http.cookies.rst +++ b/Doc/library/http.cookies.rst @@ -102,20 +102,6 @@ Cookie Objects (CRLF). -.. method:: Morsel.js_output(attrs=None) - - Return an embeddable JavaScript snippet, which, if run on a browser which - supports JavaScript, will act the same as if the HTTP headers was sent. - - The meaning for *attrs* is the same as in :meth:`output`. - - .. deprecated-removed:: next 3.19 - This method generates a JavaScript snippet to set cookies in the browser, - which is no longer considered a standard or recommended approach. - Use :meth:`~http.cookies.Morsel.output` instead to generate HTTP - headers. - - .. method:: BaseCookie.js_output(attrs=None) Return an embeddable JavaScript snippet, which, if run on a browser which @@ -123,7 +109,7 @@ Cookie Objects The meaning for *attrs* is the same as in :meth:`output`. - .. deprecated-removed:: next 3.19 + .. deprecated-removed:: 3.15 3.19 This method generates a JavaScript snippet to set cookies in the browser, which is no longer considered a standard or recommended approach. Use :meth:`~http.cookies.BaseCookie.output` instead to generate HTTP @@ -245,6 +231,12 @@ Morsel Objects The meaning for *attrs* is the same as in :meth:`output`. + .. deprecated-removed:: 3.15 3.19 + This method generates a JavaScript snippet to set cookies in the browser, + which is no longer considered a standard or recommended approach. + Use :meth:`~http.cookies.Morsel.output` instead to generate HTTP + headers. + .. method:: Morsel.OutputString(attrs=None)