Skip to content

Commit 6cdfc72

Browse files
authored
refactor: Add mypy to CI, type corrections (#786)
2 parents 17caa0c + f130e9b commit 6cdfc72

17 files changed

+227
-56
lines changed

.github/workflows/tests.yml

+6-2
Original file line numberDiff line numberDiff line change
@@ -90,9 +90,13 @@ jobs:
9090
- name: Install python dependencies
9191
run: |
9292
poetry install -E "test coverage lint"
93+
9394
- name: Lint with flake8
94-
run: |
95-
poetry run flake8
95+
run: poetry run flake8
96+
97+
- name: Lint with mypy
98+
run: poetry run mypy .
99+
96100
- name: Test with pytest
97101
continue-on-error: ${{ matrix.tmux-version == 'master' }}
98102
run: |

CHANGES

+1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ $ pipx install --suffix=@next 'tmuxp' --pip-args '\--pre' --force
2424
- libtmux updated from v0.12 to v0.14 {issue}`790`
2525
- Add [doctest](https://docs.python.org/3/library/doctest.html) w/
2626
[pytest + doctest](https://docs.pytest.org/en/7.1.x/how-to/doctest.html), ({issue}`791`).
27+
- Added basic [mypy](http://mypy-lang.org/) type annotations via {issue}`786`
2728

2829
## tmuxp 1.12.1 (2022-08-04)
2930

docs/_ext/aafig.py

+3-7
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,15 @@
1010
:author: Leandro Lucarella <[email protected]>
1111
:license: BOLA, see LICENSE for details
1212
"""
13+
import logging
1314
import posixpath
15+
from hashlib import sha1 as sha
1416
from os import path
1517

1618
from docutils import nodes
1719
from docutils.parsers.rst.directives import flag, images, nonnegative_int
1820
from sphinx.errors import SphinxError
19-
from sphinx.util import ensuredir, logging, relative_uri
20-
21-
try:
22-
from hashlib import sha1 as sha
23-
except ImportError:
24-
from sha import sha
25-
21+
from sphinx.util.osutil import ensuredir, relative_uri
2622

2723
try:
2824
import aafigure

docs/conf.py

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# flake8: NOQA E5
22
import inspect
33
import sys
4+
import typing as t
45
from os.path import dirname, relpath
56
from pathlib import Path
67

@@ -14,7 +15,7 @@
1415
sys.path.insert(0, str(cwd / "_ext"))
1516

1617
# package data
17-
about = {}
18+
about: t.Dict[str, str] = {}
1819
with open(project_root / "tmuxp" / "__about__.py") as fp:
1920
exec(fp.read(), about)
2021

@@ -61,8 +62,8 @@
6162
html_static_path = ["_static"]
6263
html_favicon = "_static/favicon.ico"
6364
html_theme = "furo"
64-
html_theme_path = []
65-
html_theme_options = {
65+
html_theme_path: t.List[str] = []
66+
html_theme_options: t.Dict[str, t.Union[str, t.List[t.Dict[str, str]]]] = {
6667
"light_logo": "img/tmuxp.svg",
6768
"dark_logo": "img/tmuxp.svg",
6869
"footer_icons": [

docs/developing.md

+104
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,106 @@ this will load the `.tmuxp.yaml` in the root of the project.
334334

335335
```
336336

337+
## Formatting
338+
339+
The project uses [black] and [isort] (one after the other). Configurations are in `pyproject.toml`
340+
and `setup.cfg`:
341+
342+
- `make black isort`: Run `black` first, then `isort` to handle import nuances
343+
344+
## Linting
345+
346+
[flake8] and [mypy] run via CI in our GitHub Actions. See the configuration in `pyproject.toml` and
347+
`setup.cfg`.
348+
349+
### flake8
350+
351+
[flake8] provides fast, reliable, barebones styling and linting.
352+
353+
````{tab} Command
354+
355+
poetry:
356+
357+
```console
358+
$ poetry run flake8
359+
```
360+
361+
If you setup manually:
362+
363+
```console
364+
$ flake8
365+
```
366+
367+
````
368+
369+
````{tab} make
370+
371+
```console
372+
$ make flake8
373+
```
374+
375+
````
376+
377+
````{tab} Watch
378+
379+
```console
380+
$ make watch_flake8
381+
```
382+
383+
requires [`entr(1)`].
384+
385+
````
386+
387+
````{tab} Configuration
388+
389+
See `[flake8]` in setup.cfg.
390+
391+
```{literalinclude} ../setup.cfg
392+
:language: ini
393+
:start-at: "[flake8]"
394+
:end-before: "[isort]"
395+
396+
```
397+
398+
````
399+
400+
### mypy
401+
402+
[mypy] is used for static type checking.
403+
404+
````{tab} Command
405+
406+
poetry:
407+
408+
```console
409+
$ poetry run mypy .
410+
```
411+
412+
If you setup manually:
413+
414+
```console
415+
$ mypy .
416+
```
417+
418+
````
419+
420+
````{tab} make
421+
422+
```console
423+
$ make mypy
424+
```
425+
426+
````
427+
428+
````{tab} Watch
429+
430+
```console
431+
$ make watch_mypy
432+
```
433+
434+
requires [`entr(1)`].
435+
````
436+
337437
(gh-actions)=
338438

339439
## Continuous integration
@@ -350,6 +450,10 @@ the [gh build site].
350450
[py.test usage argument]: https://pytest.org/latest/usage.html
351451
[entr]: http://entrproject.org/
352452
[`entr(1)`]: http://entrproject.org/
453+
[black]: https://github.com/psf/black
454+
[isort]: https://pypi.org/project/isort/
455+
[flake8]: https://flake8.pycqa.org/
456+
[mypy]: http://mypy-lang.org/
353457
[github actions]: https://github.com/features/actions
354458
[gh build site]: https://github.com/tmux-python/tmuxp/actions?query=workflow%3Atests
355459
[.github/workflows/tests.yml]: https://github.com/tmux-python/tmuxp/blob/master/.github/workflows/tests.yml

poetry.lock

+25-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

+15-1
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,8 @@ isort = "*"
8686
### Lint ###
8787
flake8 = "*"
8888
mypy = "*"
89+
types-colorama = "^0.4.15"
90+
types-docutils = "^0.19.0"
8991

9092
[tool.poetry.extras]
9193
docs = [
@@ -107,8 +109,20 @@ docs = [
107109
test = ["pytest", "pytest-rerunfailures", "pytest-mock", "pytest-watcher"]
108110
coverage = ["codecov", "coverage", "pytest-cov"]
109111
format = ["black", "isort"]
110-
lint = ["flake8", "mypy"]
112+
lint = ["flake8", "mypy", "types-colorama", "types-docutils"]
111113

112114
[build-system]
113115
requires = ["poetry_core>=1.0.0"]
114116
build-backend = "poetry.core.masonry.api"
117+
118+
[[tool.mypy.overrides]]
119+
module = [
120+
"kaptan",
121+
"aafigure",
122+
"libtmux.*",
123+
"IPython.*",
124+
"ptpython.*",
125+
"prompt_toolkit.*",
126+
"bpython"
127+
]
128+
ignore_missing_imports = true

setup.cfg

+6-6
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,6 @@ max-line-length = 88
55
# Stuff we ignore thanks to black: https://github.com/ambv/black/issues/429
66
extend-ignore = E203,W503
77

8-
[tool:pytest]
9-
filterwarnings =
10-
ignore:distutils Version classes are deprecated. Use packaging.version instead.
11-
addopts = --reruns=0 --tb=short --no-header --showlocals --doctest-modules
12-
doctest_optionflags = ELLIPSIS NORMALIZE_WHITESPACE
13-
148
[isort]
159
profile = black
1610
combine_as_imports= true
@@ -21,3 +15,9 @@ known_pytest = pytest,py
2115
known_first_party = libtmux,tmuxp
2216
sections = FUTURE,STDLIB,PYTEST,THIRDPARTY,FIRSTPARTY,LOCALFOLDER
2317
line_length = 88
18+
19+
[tool:pytest]
20+
filterwarnings =
21+
ignore:distutils Version classes are deprecated. Use packaging.version instead.
22+
addopts = --reruns=0 --tb=short --no-header --showlocals --doctest-modules
23+
doctest_optionflags = ELLIPSIS NORMALIZE_WHITESPACE

tests/fixtures/structures.py

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import dataclasses
2+
import typing as t
3+
4+
5+
@dataclasses.dataclass
6+
class TestConfigData:
7+
expand1: t.Any
8+
expand2: t.Any
9+
expand_blank: t.Any
10+
sampleconfig: t.Any
11+
shell_command_before: t.Any
12+
shell_command_before_session: t.Any
13+
trickle: t.Any

tests/test_cli.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import json
33
import os
44
import pathlib
5+
import typing as t
56
from unittest.mock import MagicMock
67

78
import pytest
@@ -416,7 +417,7 @@ def test_regression_00132_session_name_with_dots(
416417
):
417418
yaml_config = FIXTURE_PATH / "workspacebuilder" / "regression_00132_dots.yaml"
418419
cli_args = [str(yaml_config)]
419-
inputs = []
420+
inputs: t.List[str] = []
420421
runner = CliRunner()
421422
result = runner.invoke(
422423
cli.command_load, cli_args, input="".join(inputs), standalone_mode=False

0 commit comments

Comments
 (0)