Skip to content

Commit c06b8ed

Browse files
authored
refactor!(mypy): additional type annotations and safety (#362)
See also: http://mypy-lang.org/
2 parents 0f89303 + 5fa1915 commit c06b8ed

File tree

15 files changed

+447
-76
lines changed

15 files changed

+447
-76
lines changed

.github/workflows/tests.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ jobs:
4141
- name: Lint with flake8
4242
run: poetry run flake8
4343

44+
- name: Lint with mypy
45+
run: poetry run mypy .
46+
4447
- name: Print python versions
4548
run: |
4649
python -V

CHANGES

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,19 @@ $ pip install --user --upgrade --pre libvcs
7070

7171
### Internals
7272

73+
- {issue}`362` [mypy] support added:
74+
75+
- Basic mypy tests now pass
76+
- Type annotations added, including improved typings for:
77+
78+
- {meth}`libvcs._internal.subprocess.SubprocessCommand.run`
79+
- {meth}`libvcs._internal.subprocess.SubprocessCommand.Popen`
80+
- {meth}`libvcs._internal.subprocess.SubprocessCommand.check_output`
81+
- {meth}`libvcs._internal.subprocess.run.run`
82+
83+
- `make mypy` and `make watch_mypy`
84+
- Automatic checking on CI
85+
7386
- {issue}`345` `libvcs.utils` -> `libvcs._internal` to make it more obvious the APIs are strictly
7487
closed.
7588
- `StrOrPath` -> `StrPath`
@@ -86,6 +99,9 @@ $ pip install --user --upgrade --pre libvcs
8699
### Documentation
87100

88101
- Document `libvcs.types`
102+
- {issue}`362`: Improve developer documentation to note [mypy] and have tabbed examples for flake8.
103+
104+
[mypy]: http://mypy-lang.org/
89105

90106
### Packaging
91107

docs/conf.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
sys.path.insert(0, str(doc_path / "_ext"))
1616

1717
# package data
18-
about = {}
18+
about: dict = {}
1919
with open(project_root / "libvcs" / "__about__.py") as fp:
2020
exec(fp.read(), about)
2121

@@ -58,8 +58,8 @@
5858
html_extra_path = ["manifest.json"]
5959
html_favicon = "_static/favicon.ico"
6060
html_theme = "furo"
61-
html_theme_path = []
62-
html_theme_options = {
61+
html_theme_path: list = []
62+
html_theme_options: dict = {
6363
"light_logo": "img/libvcs.svg",
6464
"dark_logo": "img/libvcs.svg",
6565
"footer_icons": [

docs/contributing/workflow.md

Lines changed: 110 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,24 @@
66

77
[poetry] is a required package to develop.
88

9+
```console
10+
$ git clone https://github.com/vcs-python/libvcs.git
911
```
10-
git clone https://github.com/vcs-python/libvcs.git
11-
cd libvcs
12-
poetry install -E "docs test coverage lint format"
12+
13+
```console
14+
$ cd libvcs
15+
```
16+
17+
```console
18+
$ poetry install -E "docs test coverage lint format"
1319
```
1420

1521
Makefile commands prefixed with `watch_` will watch files and rerun.
1622

1723
## Tests
1824

19-
```
20-
poetry run py.test
25+
```console
26+
$ poetry run py.test
2127
```
2228

2329
Helpers: `make test` Rerun tests on file change: `make watch_test` (requires [entr(1)])
@@ -43,13 +49,105 @@ Rebuild docs on file change: `make watch_docs` (requires [entr(1)])
4349
Rebuild docs and run server via one terminal: `make dev_docs` (requires above, and a `make(1)` with
4450
`-J` support, e.g. GNU Make)
4551

46-
## Formatting / Linting
52+
## Formatting
53+
54+
The project uses [black] and [isort] (one after the other). Configurations are in `pyproject.toml`
55+
and `setup.cfg`:
56+
57+
- `make black isort`: Run `black` first, then `isort` to handle import nuances
58+
59+
## Linting
60+
61+
[flake8] and [mypy] run via CI in our GitHub Actions. See the configuration in `pyproject.toml` and
62+
`setup.cfg`.
63+
64+
### flake8
65+
66+
[flake8] provides fast, reliable, barebones styling and linting.
67+
68+
````{tab} Command
69+
70+
poetry:
71+
72+
```console
73+
$ poetry run flake8
74+
```
75+
76+
If you setup manually:
77+
78+
```console
79+
$ flake8
80+
```
81+
82+
````
83+
84+
````{tab} make
85+
86+
```console
87+
$ make flake8
88+
```
89+
90+
````
91+
92+
````{tab} Watch
93+
94+
```console
95+
$ make watch_flake8
96+
```
4797
48-
The project uses [black] and [isort] (one after the other) and runs [flake8] via CI. See the
49-
configuration in `pyproject.toml` and `setup.cfg`:
98+
requires [`entr(1)`].
99+
100+
````
101+
102+
````{tab} Configuration
103+
104+
See `[flake8]` in setup.cfg.
105+
106+
```{literalinclude} ../../setup.cfg
107+
:language: ini
108+
:start-at: "[flake8]"
109+
:end-before: "[isort]"
110+
111+
```
112+
113+
````
114+
115+
### mypy
116+
117+
[mypy] is used for static type checking.
118+
119+
````{tab} Command
120+
121+
poetry:
122+
123+
```console
124+
$ poetry run mypy .
125+
```
126+
127+
If you setup manually:
128+
129+
```console
130+
$ mypy .
131+
```
132+
133+
````
134+
135+
````{tab} make
136+
137+
```console
138+
$ make mypy
139+
```
140+
141+
````
142+
143+
````{tab} Watch
144+
145+
```console
146+
$ make watch_mypy
147+
```
50148
51-
`make black isort`: Run `black` first, then `isort` to handle import nuances `make flake8`, to watch
52-
(requires `entr(1)`): `make watch_flake8`
149+
requires [`entr(1)`].
150+
````
53151

54152
## Releasing
55153

@@ -67,6 +165,8 @@ Update `__version__` in `__about__.py` and `pyproject.toml`::
67165

68166
[poetry]: https://python-poetry.org/
69167
[entr(1)]: http://eradman.com/entrproject/
168+
[`entr(1)`]: http://eradman.com/entrproject/
70169
[black]: https://github.com/psf/black
71170
[isort]: https://pypi.org/project/isort/
72171
[flake8]: https://flake8.pycqa.org/
172+
[mypy]: http://mypy-lang.org/

libvcs/_internal/run.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ def run(
178178
shell: bool = False,
179179
cwd: Optional[StrOrBytesPath] = None,
180180
env: Optional[_ENV] = None,
181-
universal_newlines: Optional[bool] = None,
181+
universal_newlines: bool = False,
182182
startupinfo: Optional[Any] = None,
183183
creationflags: int = 0,
184184
restore_signals: bool = True,
@@ -262,15 +262,15 @@ def progress_cb(output, timestamp):
262262
umask=umask,
263263
)
264264

265-
all_output = []
265+
all_output: list[str] = []
266266
code = None
267267
line = None
268268
while code is None:
269269
code = proc.poll()
270270

271271
# output = console_to_str(proc.stdout.readline())
272272
# all_output.append(output)
273-
if callback and callable(callback):
273+
if callback and callable(callback) and proc.stderr is not None:
274274
line = console_to_str(proc.stderr.read(128))
275275
if line:
276276
callback(output=line, timestamp=datetime.datetime.now())

0 commit comments

Comments
 (0)