Skip to content

Mypy types for autocomplete.py, args.py, config.py and curtsies.py #929

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Oct 10, 2021
Merged
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
17 changes: 17 additions & 0 deletions .github/workflows/lint.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,20 @@ jobs:
with:
skip: '*.po'
ignore_words_list: ba,te,deltion

mypy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v2
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install mypy
pip install -r requirements.txt
pip install urwid twisted watchdog "jedi >=0.16" babel "sphinx >=1.5" numpy
pip install types-backports types-requests types-setuptools types-toml types-pygments
- name: Check with mypy
# for now only run on a few files to avoid slipping backward
run: mypy
2 changes: 1 addition & 1 deletion bpython/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
import os.path

try:
from ._version import __version__ as version
from ._version import __version__ as version # type: ignore
except ImportError:
version = "unknown"

Expand Down
31 changes: 23 additions & 8 deletions bpython/args.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,17 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.

# To gradually migrate to mypy we aren't setting these globally yet
# mypy: disallow_untyped_defs=True
# mypy: disallow_untyped_calls=True

"""
Module to handle command line argument parsing, for all front-ends.
"""

import argparse
from typing import Tuple
from typing import Tuple, List, Optional, NoReturn, Callable
import code
import curtsies
import cwcwidth
import greenlet
Expand All @@ -50,11 +55,11 @@ class ArgumentParserFailed(ValueError):


class RaisingArgumentParser(argparse.ArgumentParser):
def error(self, msg):
def error(self, msg: str) -> NoReturn:
raise ArgumentParserFailed()


def version_banner(base="bpython") -> str:
def version_banner(base: str = "bpython") -> str:
return _("{} version {} on top of Python {} {}").format(
base,
__version__,
Expand All @@ -67,7 +72,14 @@ def copyright_banner() -> str:
return _("{} See AUTHORS.rst for details.").format(__copyright__)


def parse(args, extras=None, ignore_stdin=False) -> Tuple:
Options = Tuple[str, str, Callable[[argparse._ArgumentGroup], None]]


def parse(
args: Optional[List[str]],
extras: Options = None,
ignore_stdin: bool = False,
) -> Tuple:
"""Receive an argument list - if None, use sys.argv - parse all args and
take appropriate action. Also receive optional extra argument: this should
be a tuple of (title, description, callback)
Expand Down Expand Up @@ -197,7 +209,7 @@ def callback(group):
logger.info(f"curtsies: {curtsies.__version__}")
logger.info(f"cwcwidth: {cwcwidth.__version__}")
logger.info(f"greenlet: {greenlet.__version__}")
logger.info(f"pygments: {pygments.__version__}")
logger.info(f"pygments: {pygments.__version__}") # type: ignore
logger.info(f"requests: {requests.__version__}")
logger.info(
"environment:\n{}".format(
Expand All @@ -214,7 +226,9 @@ def callback(group):
return Config(options.config), options, options.args


def exec_code(interpreter, args):
def exec_code(
interpreter: code.InteractiveInterpreter, args: List[str]
) -> None:
"""
Helper to execute code in a given interpreter, e.g. to implement the behavior of python3 [-i] file.py

Expand All @@ -230,9 +244,10 @@ def exec_code(interpreter, args):
old_argv, sys.argv = sys.argv, args
sys.path.insert(0, os.path.abspath(os.path.dirname(args[0])))
spec = importlib.util.spec_from_loader("__console__", loader=None)
assert spec
mod = importlib.util.module_from_spec(spec)
sys.modules["__console__"] = mod
interpreter.locals.update(mod.__dict__)
interpreter.locals["__file__"] = args[0]
interpreter.locals.update(mod.__dict__) # type: ignore # TODO use a more specific type that has a .locals attribute
interpreter.locals["__file__"] = args[0] # type: ignore # TODO use a more specific type that has a .locals attribute
interpreter.runsource(source, args[0], "exec")
sys.argv = old_argv
Loading