Repository: pallets/werkzeug (python)

Issue:
MultiDict does not handle None values
The following code will result in a `TypeError`:
```python
invalid_values = MultiDict([('a', 'x'), ('b', ''), ('d', None)])
print(invalid_values.get('a', type=int))  # None
print(invalid_values.get('b', type=int))  # None
print(invalid_values.get('c', type=int))  # None
print(invalid_values.get('d', type=int))  # TypeError
```
I think the expected behavior would be to return `None` as all other error cases do.

This happens because the following code only checks for `ValueError` and not other errors like `TypeError`:
https://github.com/pallets/werkzeug/blob/d3dd65a27388fbd39d146caacf2563639ba622f0/src/werkzeug/datastructures/structures.py#L81-L84

Pull request:
Handle TypeError in TypeConversionDict.get()
`TypeConversionDict.get()` did not handle `TypeError`. Since this is probably unexpected by the user this PR changes this to return the default value on `TypeError` instead.

- fixes #2842

Checklist:

- [x] Add tests that demonstrate the correct behavior of the change. Tests should fail without the change.
- [x] Add or update relevant docs, in the docs folder and in code.
- [x] Add an entry in `CHANGES.rst` summarizing the change and linking to the issue.
- [x] Add `.. versionchanged::` entries in any relevant code docs.
- [x] Run `pre-commit` hooks and fix any issues.
- [x] Run `pytest` and `tox`, no tests failed.


Patch:
diff --git a/CHANGES.rst b/CHANGES.rst
index 1dd64041..3e999348 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -5,6 +5,8 @@ Version 3.0.2
 
 Unreleased
 
+-   Fix handling of TypeError in TypeConversionDict.get() to match
+    ValueErrors. :issue:`2843`
 -   Fix response_wrapper type check in test client. :issue:`2831`
 -   Make the return type of ``MultiPartParser.parse`` more
     precise. :issue:`2840`
diff --git a/src/werkzeug/datastructures/structures.py b/src/werkzeug/datastructures/structures.py
index e863cd8a..4279ceb9 100644
--- a/src/werkzeug/datastructures/structures.py
+++ b/src/werkzeug/datastructures/structures.py
@@ -70,8 +70,12 @@ class TypeConversionDict(dict):
                         be looked up.  If not further specified `None` is
                         returned.
         :param type: A callable that is used to cast the value in the
-                     :class:`MultiDict`.  If a :exc:`ValueError` is raised
-                     by this callable the default value is returned.
+                     :class:`MultiDict`.  If a :exc:`ValueError` or a
+                     :exc:`TypeError` is raised by this callable the default
+                     value is returned.
+
+        .. versionchanged:: 3.0.2
+           Returns the default value on :exc:`TypeError`, too.
         """
         try:
             rv = self[key]
@@ -80,7 +84,7 @@ class TypeConversionDict(dict):
         if type is not None:
             try:
                 rv = type(rv)
-            except ValueError:
+            except (ValueError, TypeError):
                 rv = default
         return rv
 


Test patch:
diff --git a/tests/test_datastructures.py b/tests/test_datastructures.py
index 5206aa6a..64330e1e 100644
--- a/tests/test_datastructures.py
+++ b/tests/test_datastructures.py
@@ -550,8 +550,9 @@ class TestTypeConversionDict:
         assert d.get("foo", type=int) == 1
 
     def test_return_default_when_conversion_is_not_possible(self):
-        d = self.storage_class(foo="bar")
+        d = self.storage_class(foo="bar", baz=None)
         assert d.get("foo", default=-1, type=int) == -1
+        assert d.get("baz", default=-1, type=int) == -1
 
     def test_propagate_exceptions_in_conversion(self):
         d = self.storage_class(foo="bar")