While writing code for my Weave project, I encountered a type error when adding a command line interface to my Flask application:
$ mypy --ignore-missing-imports --follow-imports=silent server/cli.py server/cli.py:11: error: Unexpected keyword argument "cli_group" for "Blueprint"
The offending code:
from flask import Blueprint blueprint = Blueprint("cli", __name__, cli_group=None)
cli_group argument had not been added to the stub library, typeshed.
The function declaration source code is:
# a singleton sentinel value for parameter defaults _sentinel = object() class Blueprint(_PackageBoundObject): def __init__( self, <arguments>, cli_group=_sentinel, ):
Blueprint uses a sentinel as a default argument to know when the user explicitly passes
None, as I did.
Users will never pass the sentinel explicitly, but we still need to include that type. Sentinel is an
object instance, but so is everything else, so typing it as
Union[Optional[str], object] is no different than just typing it as
object. The solution:
class _Sentinel(object): ... def __init__(self, <arguments>, cli_group: Union[Optional[str], _Sentinel] = ...) -> None: ...
Note that the ellipsis are actually in the stub code as a literal, so I used
<arguments>as a placeholder.
The pull request made it in to typeshed relatively quickly, but even when I installed the master branch of mypy, the error still persisted in my code. This is because mypy uses a submodule of typeshed. The solution is to fork mypy and update typeshed there. If my changes hadn’t been merged into typeshed yet, I could fork that as well.
# Using clone-cd from my fish functions to cd automatically # (https://github.com/razzius/fish-functions#clone-cd-url-destination-source) clone-cd https://github.com/python/mypy # Go into typeshed submodule cd mypy/typeshed git pull # Back out to mypy cd .. git commit -am 'Update mypy/typeshed' # Create a fork hub fork git push razzius
Now to incorporate my fork into my project using Pipenv:
pipenv install --dev -e git+https://github.com/razzius/mypy.git#egg=mypy
At some point, typeshed will be updated in mypy and mypy will release a new edition, and I can go back to the mainline then.
$ mypy --ignore-missing-imports --follow-imports=silent server/cli.py
Success: no issues found in 1 source file