gh-148849: Deprecate http.cookies.BaseCookie.js_output() (GH-148978)

This commit is contained in:
kishorhange111
2026-05-04 15:21:17 +05:30
committed by GitHub
parent 0c6d2f64c0
commit 246fe14e7c
6 changed files with 87 additions and 9 deletions
@@ -22,3 +22,12 @@ Pending removal in Python 3.19
supported depending on the backend implementation of hash functions.
Prefer passing the initial data as a positional argument for maximum
backwards compatibility.
* :mod:`http.cookies`:
* :meth:`http.cookies.Morsel.js_output` is deprecated and will be
removed in Python 3.19.
* :meth:`http.cookies.BaseCookie.js_output` is deprecated and will be
removed in Python 3.19.
+12
View File
@@ -107,6 +107,12 @@ Cookie 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.BaseCookie.output` instead to generate HTTP
headers.
.. method:: BaseCookie.load(rawdata)
@@ -223,6 +229,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)
+10
View File
@@ -1921,6 +1921,16 @@ New deprecations
(Contributed by Bénédikt Tran in :gh:`134978`.)
* :mod:`http.cookies`:
* :meth:`Morsel.js_output <http.cookies.Morsel.js_output>` and
:meth:`BaseCookie.js_output <http.cookies.BaseCookie.js_output>` are
deprecated and will be removed in Python 3.19. Use
:meth:`Morsel.output <http.cookies.Morsel.output>` or
:meth:`BaseCookie.output <http.cookies.BaseCookie.output>` instead.
(Contributed by kishorhange111 in :gh:`148849`.)
* :mod:`re`:
* :func:`re.match` and :meth:`re.Pattern.match` are now
+18 -2
View File
@@ -132,6 +132,7 @@ Finis.
import re
import string
import types
lazy import warnings
__all__ = ["CookieError", "BaseCookie", "SimpleCookie"]
@@ -390,7 +391,9 @@ class Morsel(dict):
def __repr__(self):
return '<%s: %s>' % (self.__class__.__name__, self.OutputString())
def js_output(self, attrs=None):
def _js_output(self, attrs=None):
"""Internal implementation without deprecation warning."""
import base64
# Print javascript
output_string = self.OutputString(attrs)
@@ -407,6 +410,14 @@ class Morsel(dict):
</script>
""" % (output_encoded,)
def js_output(self, attrs=None):
warnings._deprecated(
"http.cookies.Morsel.js_output",
message=warnings._DEPRECATED_MSG + "; use output() instead",
remove=(3, 19),
)
return self._js_output(attrs)
def OutputString(self, attrs=None):
# Build up our result
#
@@ -541,10 +552,15 @@ class BaseCookie(dict):
def js_output(self, attrs=None):
"""Return a string suitable for JavaScript."""
warnings._deprecated(
"http.cookies.BaseCookie.js_output",
message=warnings._DEPRECATED_MSG + "; use output() instead",
remove=(3, 19),
)
result = []
items = sorted(self.items())
for key, value in items:
result.append(value.js_output(attrs))
result.append(value._js_output(attrs))
return _nulljoin(result)
def load(self, rawdata):
+34 -7
View File
@@ -153,7 +153,8 @@ class CookieTests(unittest.TestCase):
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, r"BaseCookie\.js_output"):
self.assertEqual(C.js_output(), fr"""
<script type="text/javascript">
<!-- begin hiding
document.cookie = atob("{cookie_encoded}");
@@ -161,7 +162,8 @@ class CookieTests(unittest.TestCase):
</script>
""")
cookie_encoded = base64.b64encode(b'Customer="WILE_E_COYOTE"; Path=/acme').decode('ascii')
self.assertEqual(C.js_output(['path']), fr"""
with self.assertWarnsRegex(DeprecationWarning, r"BaseCookie\.js_output"):
self.assertEqual(C.js_output(['path']), fr"""
<script type="text/javascript">
<!-- begin hiding
document.cookie = atob("{cookie_encoded}");
@@ -270,7 +272,8 @@ class CookieTests(unittest.TestCase):
self.assertEqual(C.output(['path']),
'Set-Cookie: Customer="WILE_E_COYOTE"; Path=/acme')
expected_encoded_cookie = base64.b64encode(b'Customer=\"WILE_E_COYOTE\"; Path=/acme; Version=1').decode('ascii')
self.assertEqual(C.js_output(), fr"""
with self.assertWarnsRegex(DeprecationWarning, r"BaseCookie\.js_output"):
self.assertEqual(C.js_output(), fr"""
<script type="text/javascript">
<!-- begin hiding
document.cookie = atob("{expected_encoded_cookie}");
@@ -278,7 +281,8 @@ class CookieTests(unittest.TestCase):
</script>
""")
expected_encoded_cookie = base64.b64encode(b'Customer=\"WILE_E_COYOTE\"; Path=/acme').decode('ascii')
self.assertEqual(C.js_output(['path']), fr"""
with self.assertWarnsRegex(DeprecationWarning, r"BaseCookie\.js_output"):
self.assertEqual(C.js_output(['path']), fr"""
<script type="text/javascript">
<!-- begin hiding
document.cookie = atob("{expected_encoded_cookie}");
@@ -382,7 +386,8 @@ class MorselTests(unittest.TestCase):
// end hiding -->
</script>
""" % (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,
@@ -650,7 +655,8 @@ class MorselTests(unittest.TestCase):
cookie = cookies.SimpleCookie()
cookie["cookie"] = morsel
with self.assertRaises(cookies.CookieError):
cookie.js_output()
with self.assertWarnsRegex(DeprecationWarning, r"Morsel\.js_output"):
cookie.js_output()
morsel = cookies.Morsel()
morsel.set("key", "value", "coded-value")
@@ -658,8 +664,29 @@ class MorselTests(unittest.TestCase):
cookie = cookies.SimpleCookie()
cookie["cookie"] = morsel
with self.assertRaises(cookies.CookieError):
cookie.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") as cm:
result = morsel.js_output()
self.assertEqual(cm.filename, __file__)
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()
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"BaseCookie\.js_output")
self.assertEqual(cm.filename, __file__)
def load_tests(loader, tests, pattern):
tests.addTest(doctest.DocTestSuite(cookies))
@@ -0,0 +1,4 @@
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.