Skip to content

Commit b17d689

Browse files
committed
typing: Make things stricter (3/4)
Check untyped functions. Signed-off-by: Stephen Finucane <stephen@that.guru>
1 parent 56f608e commit b17d689

7 files changed

Lines changed: 47 additions & 40 deletions

File tree

git_pw/api.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ def version() -> tuple[int, int]:
234234
return (1, 0)
235235

236236

237-
def get(url: str, params: Filters | None) -> dict[str, Any]:
237+
def get(url: str, params: Filters | None = None) -> dict[str, Any]:
238238
"""Get a JSON document from the API and return it as a dict."""
239239
return _get(url, params, stream=False).json()
240240

git_pw/bundle.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -172,13 +172,13 @@ def list_cmd(owners, limit, page, sort, fmt, headers, name):
172172

173173
# Format and print output
174174

175-
output = []
175+
output: list[Any] = []
176176

177177
for bundle in bundles:
178178
item = [
179179
bundle.get('id'),
180180
utils.trim(bundle.get('name') or ''),
181-
bundle.get('owner').get('username'),
181+
(bundle.get('owner') or {}).get('username'),
182182
'yes' if bundle.get('public') else 'no',
183183
]
184184

git_pw/config.py

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -25,20 +25,20 @@ def parse_boolean(value: str) -> bool:
2525

2626

2727
class Config:
28+
debug: bool
29+
token: str | None
30+
username: str | None
31+
password: str | None
32+
server: str | None
33+
project: str | None
34+
applyPatchDeps: str
35+
states: str
36+
2837
def __init__(self) -> None:
2938
self._git_config: dict[str, str] = {}
3039

31-
def __getattribute__(self, name: str) -> str:
32-
# attempt to use any attributes first
33-
try:
34-
value = super().__getattribute__(name)
35-
except AttributeError:
36-
value = None
37-
if value:
38-
LOG.debug(f"Retrieved '{name}' setting from cache")
39-
return value
40-
41-
# fallback to reading from git config otherwise
40+
def __getattr__(self, name: str) -> str:
41+
# fallback to reading from git config
4242
value = utils.git_config(f'pw.{name}')
4343
if value:
4444
LOG.debug(f"Retrieved '{name}' setting from git-config")

git_pw/patch.py

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import logging
66
import os
77
import sys
8+
from typing import Any
89

910
import arrow
1011
import click
@@ -90,9 +91,13 @@ def apply_cmd(patch_id, series, deps, args):
9091
elif not deps:
9192
series = None
9293

93-
mbox = api.download(patch['mbox'], {'series': series})
94+
mbox = api.download(
95+
patch['mbox'],
96+
[('series', str(series))] if series is not None else None,
97+
)
9498

95-
utils.git_am(mbox, args)
99+
if mbox:
100+
utils.git_am(mbox, args)
96101

97102

98103
@click.command(name='download')
@@ -415,16 +420,16 @@ def list_cmd(
415420

416421
# Format and print output
417422

418-
output = []
423+
output: list[Any] = []
419424

420425
for patch in patches:
421426
item = [
422427
patch.get('id'),
423-
arrow.get(patch.get('date')).humanize(),
424-
utils.trim(patch.get('name')),
428+
arrow.get(patch['date']).humanize(),
429+
utils.trim(patch.get('name') or ''),
425430
'{} ({})'.format(
426-
patch.get('submitter').get('name'),
427-
patch.get('submitter').get('email'),
431+
(patch.get('submitter') or {}).get('name'),
432+
(patch.get('submitter') or {}).get('email'),
428433
),
429434
patch.get('state'),
430435
'yes' if patch.get('archived') else 'no',

git_pw/series.py

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,15 @@
33
"""
44

55
import logging
6+
import os.path
7+
import sys
8+
from typing import Any
69

710
import arrow
811
import click
912

1013
from git_pw import api
1114
from git_pw import utils
12-
import os.path
13-
import sys
1415

1516
LOG = logging.getLogger(__name__)
1617

@@ -44,7 +45,7 @@ def apply_cmd(series_id, args, deps):
4445
series = api.detail('series', series_id)
4546

4647
# .mbox files are applied in the order they appear in this list.
47-
to_apply = []
48+
to_apply: list[Any] = []
4849

4950
if deps:
5051
if dependencies := series.get('dependencies'):
@@ -66,7 +67,8 @@ def apply_cmd(series_id, args, deps):
6667

6768
for mbox_url in to_apply:
6869
mbox = api.download(mbox_url)
69-
utils.git_am(mbox, args)
70+
if mbox:
71+
utils.git_am(mbox, args)
7072

7173

7274
@click.command(name='download')
@@ -109,7 +111,7 @@ def download_cmd(series_id, output, fmt):
109111
)
110112
sys.exit(1)
111113

112-
for patch in series.get('patches'):
114+
for patch in series.get('patches') or []:
113115
path = api.download(patch['mbox'], output=output)
114116
if path:
115117
LOG.info(
@@ -149,15 +151,15 @@ def _format_submission(submission):
149151
(
150152
'Submitter',
151153
'{} ({})'.format(
152-
series.get('submitter').get('name'),
153-
series.get('submitter').get('email'),
154+
(series.get('submitter') or {}).get('name'),
155+
(series.get('submitter') or {}).get('email'),
154156
),
155157
),
156-
('Project', series.get('project').get('name')),
158+
('Project', (series.get('project') or {}).get('name')),
157159
('Version', series.get('version')),
158160
(
159161
'Received',
160-
'%d of %d' % (series.get('received_total'), series.get('total')),
162+
'%d of %d' % (series['received_total'], series['total']),
161163
),
162164
('Complete', series.get('received_all')),
163165
(
@@ -171,7 +173,7 @@ def _format_submission(submission):
171173
]
172174

173175
prefix = 'Patches'
174-
for patch in series.get('patches'):
176+
for patch in series.get('patches') or []:
175177
output.append((prefix, _format_submission(patch)))
176178
prefix = ''
177179

@@ -239,17 +241,17 @@ def list_cmd(submitters, limit, page, sort, fmt, headers, name, since, before):
239241

240242
# Format and print output
241243

242-
output = []
244+
output: list[Any] = []
243245

244246
for series_ in series:
245247
item = [
246248
series_.get('id'),
247-
arrow.get(series_.get('date')).humanize(),
249+
arrow.get(series_['date']).humanize(),
248250
utils.trim(series_.get('name') or ''),
249251
series_.get('version'),
250252
'{} ({})'.format(
251-
series_.get('submitter').get('name'),
252-
series_.get('submitter').get('email'),
253+
(series_.get('submitter') or {}).get('name'),
254+
(series_.get('submitter') or {}).get('email'),
253255
),
254256
]
255257

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ show_column_numbers = true
6565
show_error_context = true
6666
ignore_missing_imports = false
6767
follow_imports = "normal"
68-
check_untyped_defs = false
68+
check_untyped_defs = true
6969
warn_unused_ignores = true
7070
# many of the following are false while we incrementally add typing
7171
warn_return_any = false

tests/test_patch.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ def test_apply(self, mock_git_am, mock_download, mock_detail):
2424

2525
assert result.exit_code == 0, result
2626
mock_detail.assert_called_once_with('patches', 123)
27-
mock_download.assert_called_once_with(rsp['mbox'], {'series': '*'})
27+
mock_download.assert_called_once_with(rsp['mbox'], [('series', '*')])
2828
mock_git_am.assert_called_once_with(mock_download.return_value, ())
2929

3030
def test_apply_with_series(self, mock_git_am, mock_download, mock_detail):
@@ -39,7 +39,7 @@ def test_apply_with_series(self, mock_git_am, mock_download, mock_detail):
3939

4040
assert result.exit_code == 0, result
4141
mock_detail.assert_called_once_with('patches', 123)
42-
mock_download.assert_called_once_with(rsp['mbox'], {'series': 3})
42+
mock_download.assert_called_once_with(rsp['mbox'], [('series', '3')])
4343
mock_git_am.assert_called_once_with(mock_download.return_value, ())
4444

4545
def test_apply_without_deps(self, mock_git_am, mock_download, mock_detail):
@@ -54,7 +54,7 @@ def test_apply_without_deps(self, mock_git_am, mock_download, mock_detail):
5454

5555
assert result.exit_code == 0, result
5656
mock_detail.assert_called_once_with('patches', 123)
57-
mock_download.assert_called_once_with(rsp['mbox'], {'series': None})
57+
mock_download.assert_called_once_with(rsp['mbox'], None)
5858
mock_git_am.assert_called_once_with(mock_download.return_value, ())
5959

6060
def test_apply_with_args(self, mock_git_am, mock_download, mock_detail):
@@ -69,7 +69,7 @@ def test_apply_with_args(self, mock_git_am, mock_download, mock_detail):
6969

7070
assert result.exit_code == 0, result
7171
mock_detail.assert_called_once_with('patches', 123)
72-
mock_download.assert_called_once_with(rsp['mbox'], {'series': '*'})
72+
mock_download.assert_called_once_with(rsp['mbox'], [('series', '*')])
7373
mock_git_am.assert_called_once_with(
7474
mock_download.return_value, ('-3',)
7575
)

0 commit comments

Comments
 (0)