Skip to content
10 changes: 10 additions & 0 deletions Doc/deprecations/pending-removal-in-3.19.rst
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,13 @@ 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.BaseCookie.js_output` is deprecated and will be
removed in Python 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.
3 changes: 3 additions & 0 deletions Doc/library/http.cookies.rst
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,9 @@ Cookie Objects

The meaning for *attrs* is the same as in :meth:`output`.

.. deprecated-removed:: next 3.19
Use :meth:`output` instead.


.. method:: BaseCookie.load(rawdata)

Expand Down
8 changes: 8 additions & 0 deletions Doc/whatsnew/3.15.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1797,6 +1797,14 @@ New deprecations
(Contributed by Bénédikt Tran in :gh:`134978`.)


* :mod:`http.cookies`:

* :meth:`BaseCookie.js_output <http.cookies.BaseCookie.js_output>` is deprecated
and will be removed in Python 3.19. Use :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
Expand Down
6 changes: 6 additions & 0 deletions Lib/http/cookies.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@
import re
import string
import types
lazy import warnings

__all__ = ["CookieError", "BaseCookie", "SimpleCookie"]

Expand Down Expand Up @@ -540,6 +541,11 @@ def __repr__(self):
return '<%s: %s>' % (self.__class__.__name__, _spacejoin(l))

def js_output(self, attrs=None):
warnings._deprecated(
"http.cookies.BaseCookie.js_output",
warnings._DEPRECATED_MSG + "; use output() instead",
remove=(3, 19),
)
Comment thread
picnixz marked this conversation as resolved.
"""Return a string suitable for JavaScript."""
result = []
items = sorted(self.items())
Expand Down
19 changes: 13 additions & 6 deletions Lib/test/test_http_cookies.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,15 +176,17 @@ 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, r"BaseCookie\.js_output"):
self.assertEqual(C.js_output(), fr"""
<script type="text/javascript">
<!-- begin hiding
document.cookie = atob("{cookie_encoded}");
// end hiding -->
</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}");
Expand Down Expand Up @@ -293,15 +295,17 @@ def test_quoted_meta(self):
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}");
// end hiding -->
</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}");
Expand Down Expand Up @@ -673,15 +677,18 @@ def test_control_characters_output(self):
cookie = cookies.SimpleCookie()
cookie["cookie"] = morsel
with self.assertRaises(cookies.CookieError):
cookie.js_output()
with self.assertWarnsRegex(DeprecationWarning, r"BaseCookie\.js_output"):
cookie.js_output()

morsel = cookies.Morsel()
morsel.set("key", "value", "coded-value")
morsel._coded_value = c0 # Override private variable.
cookie = cookies.SimpleCookie()
cookie["cookie"] = morsel
with self.assertRaises(cookies.CookieError):
cookie.js_output()
with self.assertWarnsRegex(DeprecationWarning, r"BaseCookie\.js_output"):
cookie.js_output()



def load_tests(loader, tests, pattern):
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Deprecate :meth:`http.cookies.BaseCookie.js_output`, which will be
removed in Python 3.19. Use :meth:`http.cookies.BaseCookie.output` instead.
Loading