Search code examples
pythonmypy

mypy says request.json returns Optional[Any], how do I solve?


I am trying to understand mypy a little better. For the following line of code:

request_body: dict = {}
request_body = request.get_json()

mypy returns an error:

error: Incompatible types in assignment (expression has type "Optional[Any]", variable has type "Dict[Any, Any]")

What is the correct fix for this?


Solution

  • As you can see in the following code, taken from /wekzeug/wrappers/request.py, the function get_json doesn't always return a dictionary. I would suggest removing the type hinting from the variable, as it can be None or a dictionary.

    def get_json(
            self, force: bool = False, silent: bool = False, cache: bool = True
        ) -> t.Optional[t.Any]:
            """Parse :attr:`data` as JSON.
    
            If the mimetype does not indicate JSON
            (:mimetype:`application/json`, see :meth:`is_json`), this
            returns ``None``.
    
            If parsing fails, :meth:`on_json_loading_failed` is called and
            its return value is used as the return value.
    
            :param force: Ignore the mimetype and always try to parse JSON.
            :param silent: Silence parsing errors and return ``None``
                instead.
            :param cache: Store the parsed JSON to return for subsequent
                calls.
            """
            if cache and self._cached_json[silent] is not Ellipsis:
                return self._cached_json[silent]
    
            if not (force or self.is_json):
                return None
    
            data = self.get_data(cache=cache)
    
            try:
                rv = self.json_module.loads(data)
            except ValueError as e:
                if silent:
                    rv = None
    
                    if cache:
                        normal_rv, _ = self._cached_json
                        self._cached_json = (normal_rv, rv)
                else:
                    rv = self.on_json_loading_failed(e)
    
                    if cache:
                        _, silent_rv = self._cached_json
                        self._cached_json = (rv, silent_rv)
            else:
                if cache:
                    self._cached_json = (rv, rv)
    
            return rv
    

    This line specifically causes the method to return None:

    except ValueError as e:
                if silent:
                    rv = None```