Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion Doc/library/http.cookies.rst
Original file line number Diff line number Diff line change
Expand Up @@ -109,14 +109,18 @@ Cookie Objects
The meaning for *attrs* is the same as in :meth:`output`.


.. method:: BaseCookie.load(rawdata)
.. method:: BaseCookie.load(rawdata, *, ignore_errors=False)

If *rawdata* is a string, parse it as an ``HTTP_COOKIE`` and add the values
found there as :class:`Morsel`\ s. If it is a dictionary, it is equivalent to::

for k, v in rawdata.items():
cookie[k] = v

if ignore_errors is True, skip Morsels that raise CookieError.

.. versionchanged:: 3.9
*ignore_errors* was added.

.. _morsel-objects:

Expand Down
14 changes: 9 additions & 5 deletions Lib/http/cookies.py
Original file line number Diff line number Diff line change
Expand Up @@ -519,21 +519,21 @@ def js_output(self, attrs=None):
result.append(value.js_output(attrs))
return _nulljoin(result)

def load(self, rawdata):
def load(self, rawdata, *, ignore_errors=False):
"""Load cookies from a string (presumably HTTP_COOKIE) or
from a dictionary. Loading cookies from a dictionary 'd'
is equivalent to calling:
map(Cookie.__setitem__, d.keys(), d.values())
"""
if isinstance(rawdata, str):
self.__parse_string(rawdata)
self.__parse_string(rawdata, ignore_errors)
else:
# self.update() wouldn't call our custom __setitem__
for key, value in rawdata.items():
self[key] = value
return

def __parse_string(self, str, patt=_CookiePattern):
def __parse_string(self, str, ignore_errors, patt=_CookiePattern):
i = 0 # Our starting point
n = len(str) # Length of string
parsed_items = [] # Parsed (type, key, value) triples
Expand Down Expand Up @@ -590,8 +590,12 @@ def __parse_string(self, str, patt=_CookiePattern):
else:
assert tp == TYPE_KEYVALUE
rval, cval = value
self.__set(key, rval, cval)
M = self[key]
try:
self.__set(key, rval, cval)
M = self[key]
except CookieError:
if not ignore_errors:
raise


class SimpleCookie(BaseCookie):
Expand Down
7 changes: 7 additions & 0 deletions Lib/test/test_http_cookies.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,13 @@ def test_load(self):
</script>
""")

C = cookies.SimpleCookie()
C.load('inv/alid=test; Customer="WILE_E_COYOTE"; Version=1; Path=/acme', ignore_errors=True)

self.assertEqual(C['Customer'].value, 'WILE_E_COYOTE')
self.assertEqual(C['Customer']['version'], '1')
self.assertEqual(C['Customer']['path'], '/acme')

def test_extended_encode(self):
# Issue 9824: some browsers don't follow the standard; we now
# encode , and ; to keep them from tripping up.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Added `ignore_errors` keyword argument to `BaseCookie` with default value False. When True, BaseCookie load skips invalid Morsels.