Skip to content

Commit a1fd3c5

Browse files
authored
Merge pull request #323 from xcp-ng/typing-fixes
Typing fixes
2 parents 762859d + 33bee12 commit a1fd3c5

File tree

6 files changed

+29
-20
lines changed

6 files changed

+29
-20
lines changed

.github/workflows/code-checkers.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ jobs:
1919
- name: Create a dummy data.py
2020
run: cp data.py-dist data.py
2121
- name: Install additional typing data and check with mypy
22-
run: mypy --install-types --non-interactive lib/ tests/
22+
run: mypy --install-types --non-interactive lib/ conftest.py pkgfixtures.py tests/
2323

2424
pyright:
2525
runs-on: ubuntu-latest
@@ -37,4 +37,4 @@ jobs:
3737
- name: Create a dummy data.py
3838
run: cp data.py-dist data.py
3939
- name: Check with pyright
40-
run: pyright lib/ # tests/
40+
run: pyright lib/ conftest.py pkgfixtures.py # tests/

conftest.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -544,10 +544,10 @@ def create_vms(request, host, tests_git_revision):
544544
# FIXME should check for extra args
545545
vm_defs.append(vm_def)
546546

547+
vms = []
548+
vdis = []
549+
vbds = []
547550
try:
548-
vms = []
549-
vdis = []
550-
vbds = []
551551
for vm_def in vm_defs:
552552
if "template" in vm_def:
553553
_create_vm(request, vm_def, host, vms, vdis, vbds)

lib/common.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
import time
88
import traceback
99
from enum import Enum
10-
from typing import Dict, Literal, Optional, overload, TYPE_CHECKING, Union
10+
from typing import Callable, cast, Dict, Literal, Optional, overload, TYPE_CHECKING, TypeVar, Union
1111
from uuid import UUID
1212

1313
import pytest
@@ -17,6 +17,8 @@
1717
if TYPE_CHECKING:
1818
import lib.host
1919

20+
T = TypeVar("T")
21+
2022
class PackageManagerEnum(Enum):
2123
UNKNOWN = 1
2224
RPM = 2
@@ -67,7 +69,7 @@ def expand_scope_relative_nodeid(scoped_nodeid, scope, ref_nodeid):
6769
logging.debug("scope: %r base: %r relative: %r", scope, base, scoped_nodeid)
6870
return "::".join(itertools.chain(base, (scoped_nodeid,)))
6971

70-
def callable_marker(value, request):
72+
def callable_marker(value: Union[T, Callable[..., T]], request: pytest.FixtureRequest) -> T:
7173
"""
7274
Process value optionally generated by fixture-dependent callable.
7375
@@ -83,8 +85,12 @@ def callable_marker(value, request):
8385
for arg_name in inspect.getfullargspec(value).args}
8486
except pytest.FixtureLookupError as e:
8587
raise RuntimeError("fixture in mapping not found on test") from e
86-
value = value(**params)
87-
return value
88+
# callable ensures the value is of type Callable[..., object], which is not enough in that case
89+
# we can trust the static checker though, and thus use cast
90+
fn = cast(Callable[..., T], value)
91+
return fn(**params)
92+
else:
93+
return value
8894

8995
def wait_for(fn, msg=None, timeout_secs=2 * 60, retry_delay_secs=2, invert=False):
9096
if msg is not None:

tests/install/conftest.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import logging
22
import os
3+
from typing import Generator, Sequence, Union
34
import pytest
45
import pytest_dependency # type: ignore
56
import tempfile
@@ -38,7 +39,7 @@ def skip_package_source(version, package_source):
3839
return True, "unknown source type {}".format(package_source)
3940

4041
@pytest.fixture(scope='function')
41-
def answerfile(request):
42+
def answerfile(request: pytest.FixtureRequest) -> Generator[Union[AnswerFile, None], None, None]:
4243
"""
4344
Makes an AnswerFile object available to test and other fixtures.
4445
@@ -65,7 +66,7 @@ def answerfile(request):
6566
return
6667

6768
# construct answerfile definition from option "base", and explicit bits
68-
answerfile_def = callable_marker(marker.args[0], request)
69+
answerfile_def: AnswerFile = callable_marker(marker.args[0], request)
6970
assert isinstance(answerfile_def, AnswerFile)
7071

7172
yield answerfile_def
@@ -322,6 +323,7 @@ def xcpng_chained(request):
322323
marker = request.node.get_closest_marker("continuation_of")
323324
assert marker is not None, "xcpng_chained fixture requires 'continuation_of' marker"
324325
continuation_of = callable_marker(marker.args[0], request)
326+
assert isinstance(continuation_of, Sequence)
325327

326328
vm_defs = [dict(name=vm_spec['vm'],
327329
image_test=vm_spec['image_test'],

tests/install/test.py

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ class TestNested:
7878
cd_vbd=dict(device="xvdd", userdevice="3"),
7979
vifs=[dict(index=0, network_name=NETWORKS["MGMT"])],
8080
))
81-
@pytest.mark.answerfile(
81+
@pytest.mark.answerfile.with_args(
8282
lambda system_disks_names, local_sr, package_source, iso_version: AnswerFile("INSTALL")
8383
.top_setattr({} if local_sr == "nosr" else {"sr-type": local_sr})
8484
.top_append(
@@ -111,7 +111,7 @@ def test_install(self, vm_booted_with_installer, system_disks_names,
111111
"xs70",
112112
))
113113
@pytest.mark.parametrize("firmware", ("uefi", "bios"))
114-
@pytest.mark.continuation_of(
114+
@pytest.mark.continuation_of.with_args(
115115
lambda version, firmware, local_sr, package_source: [dict(
116116
vm="vm1",
117117
image_test=f"TestNested::test_install[{firmware}-{version}-{package_source}-{local_sr}]")])
@@ -245,6 +245,7 @@ def _test_firstboot(self, create_vms, mode, *, machine='DEFAULT', is_restore=Fal
245245
raise AssertionError(f"Unhandled LSB release {lsb_rel!r}")
246246
# check for firstboot issues
247247
# FIXME: flaky, must check logs extraction on failure
248+
stamp = ''
248249
try:
249250
for stamp in sorted(STAMPS):
250251
wait_for(lambda: pool.master.ssh(["test", "-e", f"{STAMPS_DIR}/{stamp}"],
@@ -302,7 +303,7 @@ def _test_firstboot(self, create_vms, mode, *, machine='DEFAULT', is_restore=Fal
302303
"xs70",
303304
))
304305
@pytest.mark.parametrize("firmware", ("uefi", "bios"))
305-
@pytest.mark.continuation_of(
306+
@pytest.mark.continuation_of.with_args(
306307
lambda firmware, version, machine, local_sr, package_source: [
307308
dict(vm="vm1",
308309
image_test=("TestNested::test_tune_firstboot"
@@ -329,11 +330,11 @@ def test_boot_inst(self, create_vms,
329330
("821.1", "821.1"),
330331
])
331332
@pytest.mark.parametrize("firmware", ("uefi", "bios"))
332-
@pytest.mark.continuation_of(
333+
@pytest.mark.continuation_of.with_args(
333334
lambda firmware, orig_version, machine, package_source, local_sr: [dict(
334335
vm="vm1",
335336
image_test=f"TestNested::test_boot_inst[{firmware}-{orig_version}-{machine}-{package_source}-{local_sr}]")])
336-
@pytest.mark.answerfile(
337+
@pytest.mark.answerfile.with_args(
337338
lambda system_disks_names, package_source, iso_version: AnswerFile("UPGRADE").top_append(
338339
{"iso": {"TAG": "source", "type": "local"},
339340
"net": {"TAG": "source", "type": "url",
@@ -365,7 +366,7 @@ def test_upgrade(self, vm_booted_with_installer, system_disks_names,
365366
"821.1-821.1",
366367
))
367368
@pytest.mark.parametrize("firmware", ("uefi", "bios"))
368-
@pytest.mark.continuation_of(
369+
@pytest.mark.continuation_of.with_args(
369370
lambda firmware, mode, machine, package_source, local_sr: [dict(
370371
vm="vm1",
371372
image_test=(f"TestNested::test_upgrade[{firmware}-{mode}-{machine}-{package_source}-{local_sr}]"))])
@@ -390,7 +391,7 @@ def test_boot_upg(self, create_vms,
390391
("821.1-821.1", "821.1"),
391392
])
392393
@pytest.mark.parametrize("firmware", ("uefi", "bios"))
393-
@pytest.mark.continuation_of(
394+
@pytest.mark.continuation_of.with_args(
394395
lambda firmware, orig_version, local_sr, package_source: [dict(
395396
vm="vm1",
396397
image_test=f"TestNested::test_boot_upg[{firmware}-{orig_version}-host1-{package_source}-{local_sr}]")])
@@ -421,7 +422,7 @@ def test_restore(self, vm_booted_with_installer, system_disks_names,
421422
"821.1-821.1-821.1",
422423
))
423424
@pytest.mark.parametrize("firmware", ("uefi", "bios"))
424-
@pytest.mark.continuation_of(
425+
@pytest.mark.continuation_of.with_args(
425426
lambda firmware, mode, package_source, local_sr: [dict(
426427
vm="vm1",
427428
image_test=(f"TestNested::test_restore[{firmware}-{mode}-{package_source}-{local_sr}]"))])

tests/install/test_fixtures.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
# test the answerfile fixture can run on 2 parametrized instances
77
# of the test in one run
8-
@pytest.mark.answerfile(lambda: AnswerFile("INSTALL").top_append(
8+
@pytest.mark.answerfile.with_args(lambda: AnswerFile("INSTALL").top_append(
99
{"TAG": "source", "type": "local"},
1010
{"TAG": "primary-disk", "CONTENTS": "nvme0n1"},
1111
))

0 commit comments

Comments
 (0)