Skip to content

Commit

Permalink
pop raises type conversion failure
Browse files Browse the repository at this point in the history
  • Loading branch information
davidism committed Oct 25, 2024
1 parent 3c13402 commit 2433bc5
Showing 1 changed file with 29 additions and 28 deletions.
57 changes: 29 additions & 28 deletions src/werkzeug/datastructures/structures.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ def __repr__(self):


class TypeConversionDict(dict):
"""Works like a regular dict but the :meth:`get` method can perform
type conversions. :class:`MultiDict` and :class:`CombinedMultiDict`
"""Works like a regular dict but the :meth:`get` and :meth:`pop` methods can
perform type conversions. :class:`MultiDict` and :class:`CombinedMultiDict`
are subclasses of this class and provide the same feature.
.. versionadded:: 0.5
Expand Down Expand Up @@ -89,51 +89,52 @@ def get(self, key, default=None, type=None):
return rv

def pop(self, key, default=_missing, type=None):
"""Like :meth:`get` but removes the key/value pair.
"""Similar to :meth:`get` but removes the item, and does not default to
``None`` if the key doesn't exist. If type conversion fails and no
default is given, the item is not removed and the error is re-raised.
>>> d = TypeConversionDict(foo='42', bar='blub')
>>> d.pop('foo', type=int)
>>> d = TypeConversionDict(a="42", b="abc", c="def")
>>> d.pop("a", type=int)
42
>>> 'foo' in d
>>> "a" in d
False
>>> d.pop('bar', -1, type=int)
>>> d.pop("b", -1, type=int)
-1
>>> 'bar' in d
>>> "b" in d
False
>>> d.pop("c", type=int)
ValueError: ...
>>> "c" in d
True
:param key: The key to be looked up.
:param default: The default value to be returned if the key is not
in the dictionary. If not further specified it's
an :exc:`KeyError`.
:param type: A callable that is used to cast the value in the dict.
If a :exc:`ValueError` or a :exc:`TypeError` is raised
by this callable the default value is returned.
.. admonition:: note
If the type conversion fails, the key is **not** removed from the
dictionary.
:param default: The value to be returned if the key doesn't exist. If
not given, a ``KeyError`` is raised.
:param type: A callable that is used to convert the value.
If a ``ValueError`` or ``TypeError`` is raised, the default value is
returned if given, otherwise the error is raised.
"""

try:
# Don't remove the item yet, type conversion might fail.
rv = self[key]
except KeyError:
if default is _missing:
raise

return default

if type is not None:
try:
rv = type(rv)
except (ValueError, TypeError):
if default is _missing:
return None
return default
try:
# This method is not meant to be thread-safe, but at least lets not
# fall over if the dict was mutated between the get and the delete. -MK
del self[key]
except KeyError:
pass
raise

rv = default

# Remove the item after type conversion succeeds.
del self[key]
return rv


Expand Down

0 comments on commit 2433bc5

Please sign in to comment.