Skip to content

Commit de8c44f

Browse files
committed
Typing fixes for new version of mypy
1 parent 8b18ce1 commit de8c44f

File tree

6 files changed

+107
-148
lines changed

6 files changed

+107
-148
lines changed

lisa/environment.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -486,15 +486,13 @@ def load_environments(
486486
class EnvironmentHookSpec:
487487
@hookspec
488488
def get_environment_information(self, environment: Environment) -> Dict[str, str]:
489-
...
489+
raise NotImplementedError
490490

491491

492492
class EnvironmentHookImpl:
493493
@hookimpl
494494
def get_environment_information(self, environment: Environment) -> Dict[str, str]:
495-
information: Dict[str, str] = {}
496-
information["name"] = environment.name
497-
495+
information: Dict[str, str] = {"name": environment.name}
498496
if environment.nodes:
499497
node = environment.default_node
500498
try:

lisa/node.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -733,7 +733,7 @@ def quick_connect(
733733
class NodeHookSpec:
734734
@hookspec
735735
def get_node_information(self, node: Node) -> Dict[str, str]:
736-
...
736+
raise NotImplementedError
737737

738738

739739
class NodeHookImpl:

lisa/sut_orchestrator/aws/common.py

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Copyright (c) Microsoft Corporation.
22
# Licensed under the MIT license.
33

4-
from dataclasses import InitVar, dataclass, field
4+
from dataclasses import dataclass, field
55
from typing import Dict, List, Optional
66

77
from dataclasses_json import dataclass_json
@@ -67,16 +67,13 @@ class AwsNodeSchema:
6767
data_disk_size: int = 32
6868
disk_type: str = ""
6969

70-
# for marketplace image, which need to accept terms
71-
_marketplace: InitVar[Optional[AwsVmMarketplaceSchema]] = None
70+
def __post_init__(self) -> None:
71+
# Caching for marketplace image
72+
self._marketplace: Optional[AwsVmMarketplaceSchema] = None
7273

7374
@property
7475
def marketplace(self) -> AwsVmMarketplaceSchema:
75-
# this is a safe guard and prevent mypy error on typing
76-
if not hasattr(self, "_marketplace"):
77-
self._marketplace: Optional[AwsVmMarketplaceSchema] = None
78-
79-
if not self._marketplace:
76+
if self._marketplace is None:
8077
assert isinstance(
8178
self.marketplace_raw, str
8279
), f"actual: {type(self.marketplace_raw)}"

lisa/sut_orchestrator/azure/common.py

Lines changed: 96 additions & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
import re
55
import sys
6-
from dataclasses import InitVar, dataclass, field
6+
from dataclasses import dataclass, field
77
from datetime import datetime, timedelta
88
from pathlib import Path
99
from threading import Lock
@@ -189,13 +189,12 @@ class AzureNodeSchema:
189189
# image.
190190
is_linux: Optional[bool] = None
191191

192-
_marketplace: InitVar[Optional[AzureVmMarketplaceSchema]] = None
192+
def __post_init__(self) -> None:
193+
# Caching
194+
self._marketplace: Optional[AzureVmMarketplaceSchema] = None
195+
self._shared_gallery: Optional[SharedImageGallerySchema] = None
196+
self._vhd: Optional[VhdSchema] = None
193197

194-
_shared_gallery: InitVar[Optional[SharedImageGallerySchema]] = None
195-
196-
_vhd: InitVar[Optional[VhdSchema]] = None
197-
198-
def __post_init__(self, *args: Any, **kwargs: Any) -> None:
199198
# trim whitespace of values.
200199
strip_strs(
201200
self,
@@ -218,109 +217,96 @@ def __post_init__(self, *args: Any, **kwargs: Any) -> None:
218217

219218
@property
220219
def marketplace(self) -> Optional[AzureVmMarketplaceSchema]:
221-
# this is a safe guard and prevent mypy error on typing
222-
if not hasattr(self, "_marketplace"):
223-
self._marketplace: Optional[AzureVmMarketplaceSchema] = None
224-
marketplace: Optional[AzureVmMarketplaceSchema] = self._marketplace
225-
if not marketplace:
226-
if isinstance(self.marketplace_raw, dict):
220+
if self._marketplace is not None:
221+
return self._marketplace
222+
223+
if isinstance(self.marketplace_raw, dict):
224+
# Users decide the cases of image names,
225+
# inconsistent cases cause a mismatch error in notifiers.
226+
# lower() normalizes the image names, it has no impact on deployment
227+
self.marketplace_raw = {
228+
k: v.lower() for k, v in self.marketplace_raw.items()
229+
}
230+
self._marketplace = schema.load_by_type(
231+
AzureVmMarketplaceSchema, self.marketplace_raw
232+
)
233+
# Validated marketplace_raw and filter out any unwanted content
234+
self.marketplace_raw = self._marketplace.to_dict() # type: ignore
235+
236+
elif self.marketplace_raw:
237+
assert isinstance(
238+
self.marketplace_raw, str
239+
), f"actual: {type(self.marketplace_raw)}"
240+
241+
self.marketplace_raw = self.marketplace_raw.strip()
242+
243+
if self.marketplace_raw:
227244
# Users decide the cases of image names,
228-
# the inconsistent cases cause the mismatched error in notifiers.
229-
# The lower() normalizes the image names,
230-
# it has no impact on deployment.
231-
self.marketplace_raw = dict(
232-
(k, v.lower()) for k, v in self.marketplace_raw.items()
233-
)
234-
marketplace = schema.load_by_type(
235-
AzureVmMarketplaceSchema, self.marketplace_raw
236-
)
237-
# this step makes marketplace_raw is validated, and
238-
# filter out any unwanted content.
239-
self.marketplace_raw = marketplace.to_dict() # type: ignore
240-
elif self.marketplace_raw:
241-
assert isinstance(
242-
self.marketplace_raw, str
243-
), f"actual: {type(self.marketplace_raw)}"
244-
245-
self.marketplace_raw = self.marketplace_raw.strip()
246-
247-
if self.marketplace_raw:
248-
# Users decide the cases of image names,
249-
# the inconsistent cases cause the mismatched error in notifiers.
250-
# The lower() normalizes the image names,
251-
# it has no impact on deployment.
252-
marketplace_strings = re.split(
253-
r"[:\s]+", self.marketplace_raw.lower()
245+
# inconsistent cases cause a mismatch error in notifiers.
246+
# lower() normalizes the image names, it has no impact on deployment
247+
marketplace_strings = re.split(r"[:\s]+", self.marketplace_raw.lower())
248+
249+
if len(marketplace_strings) != 4:
250+
raise LisaException(
251+
"Invalid value for the provided marketplace "
252+
f"parameter: '{self.marketplace_raw}'."
253+
"The marketplace parameter should be in the format: "
254+
"'<Publisher> <Offer> <Sku> <Version>' "
255+
"or '<Publisher>:<Offer>:<Sku>:<Version>'"
254256
)
257+
self._marketplace = AzureVmMarketplaceSchema(*marketplace_strings)
258+
# marketplace_raw is used
259+
self.marketplace_raw = (
260+
self._marketplace.to_dict() # type: ignore [attr-defined]
261+
)
255262

256-
if len(marketplace_strings) == 4:
257-
marketplace = AzureVmMarketplaceSchema(*marketplace_strings)
258-
# marketplace_raw is used
259-
self.marketplace_raw = marketplace.to_dict() # type: ignore
260-
else:
261-
raise LisaException(
262-
f"Invalid value for the provided marketplace "
263-
f"parameter: '{self.marketplace_raw}'."
264-
f"The marketplace parameter should be in the format: "
265-
f"'<Publisher> <Offer> <Sku> <Version>' "
266-
f"or '<Publisher>:<Offer>:<Sku>:<Version>'"
267-
)
268-
self._marketplace = marketplace
269-
return marketplace
263+
return self._marketplace
270264

271265
@marketplace.setter
272266
def marketplace(self, value: Optional[AzureVmMarketplaceSchema]) -> None:
273267
self._marketplace = value
274-
if value is None:
275-
self.marketplace_raw = None
276-
else:
277-
self.marketplace_raw = value.to_dict() # type: ignore
268+
# dataclass_json doesn't use a protocol return type, so to_dict() is unknown
269+
self.marketplace_raw = (
270+
None if value is None else value.to_dict() # type: ignore [attr-defined]
271+
)
278272

279273
@property
280274
def shared_gallery(self) -> Optional[SharedImageGallerySchema]:
281-
# this is a safe guard and prevent mypy error on typing
282-
if not hasattr(self, "_shared_gallery"):
283-
self._shared_gallery: Optional[SharedImageGallerySchema] = None
284-
shared_gallery: Optional[SharedImageGallerySchema] = self._shared_gallery
285-
if shared_gallery:
286-
return shared_gallery
275+
if self._shared_gallery is not None:
276+
return self._shared_gallery
277+
287278
if isinstance(self.shared_gallery_raw, dict):
288279
# Users decide the cases of image names,
289-
# the inconsistent cases cause the mismatched error in notifiers.
290-
# The lower() normalizes the image names,
291-
# it has no impact on deployment.
292-
self.shared_gallery_raw = dict(
293-
(k, v.lower()) for k, v in self.shared_gallery_raw.items()
294-
)
295-
shared_gallery = schema.load_by_type(
280+
# inconsistent cases cause a mismatch error in notifiers.
281+
# lower() normalizes the image names, it has no impact on deployment
282+
self.shared_gallery_raw = {
283+
k: v.lower() for k, v in self.shared_gallery_raw.items()
284+
}
285+
286+
self._shared_gallery = schema.load_by_type(
296287
SharedImageGallerySchema, self.shared_gallery_raw
297288
)
298-
if not shared_gallery.subscription_id:
299-
shared_gallery.subscription_id = self.subscription_id
300-
# this step makes shared_gallery_raw is validated, and
301-
# filter out any unwanted content.
302-
self.shared_gallery_raw = shared_gallery.to_dict() # type: ignore
289+
if not self._shared_gallery.subscription_id:
290+
self._shared_gallery.subscription_id = self.subscription_id
291+
# Validated shared_gallery_raw and filter out any unwanted content
292+
self.shared_gallery_raw = self._shared_gallery.to_dict() # type: ignore
293+
303294
elif self.shared_gallery_raw:
304295
assert isinstance(
305296
self.shared_gallery_raw, str
306297
), f"actual: {type(self.shared_gallery_raw)}"
307298
# Users decide the cases of image names,
308-
# the inconsistent cases cause the mismatched error in notifiers.
309-
# The lower() normalizes the image names,
310-
# it has no impact on deployment.
299+
# inconsistent cases cause a mismatch error in notifiers.
300+
# lower() normalizes the image names, it has no impact on deployment
311301
shared_gallery_strings = re.split(
312302
r"[/]+", self.shared_gallery_raw.strip().lower()
313303
)
314304
if len(shared_gallery_strings) == 5:
315-
shared_gallery = SharedImageGallerySchema(*shared_gallery_strings)
316-
# shared_gallery_raw is used
317-
self.shared_gallery_raw = shared_gallery.to_dict() # type: ignore
305+
self._shared_gallery = SharedImageGallerySchema(*shared_gallery_strings)
318306
elif len(shared_gallery_strings) == 3:
319-
shared_gallery = SharedImageGallerySchema(
307+
self._shared_gallery = SharedImageGallerySchema(
320308
self.subscription_id, None, *shared_gallery_strings
321309
)
322-
# shared_gallery_raw is used
323-
self.shared_gallery_raw = shared_gallery.to_dict() # type: ignore
324310
else:
325311
raise LisaException(
326312
f"Invalid value for the provided shared gallery "
@@ -330,51 +316,43 @@ def shared_gallery(self) -> Optional[SharedImageGallerySchema]:
330316
f"<image_definition>/<image_version>' or '<image_gallery>/"
331317
f"<image_definition>/<image_version>'"
332318
)
333-
self._shared_gallery = shared_gallery
334-
return shared_gallery
319+
self.shared_gallery_raw = self._shared_gallery.to_dict() # type: ignore
320+
321+
return self._shared_gallery
335322

336323
@shared_gallery.setter
337324
def shared_gallery(self, value: Optional[SharedImageGallerySchema]) -> None:
338325
self._shared_gallery = value
339-
if value is None:
340-
self.shared_gallery_raw = None
341-
else:
342-
self.shared_gallery_raw = value.to_dict() # type: ignore
326+
# dataclass_json doesn't use a protocol return type, so to_dict() is unknown
327+
self.shared_gallery_raw = (
328+
None if value is None else value.to_dict() # type: ignore [attr-defined]
329+
)
343330

344331
@property
345332
def vhd(self) -> Optional[VhdSchema]:
346-
# this is a safe guard and prevent mypy error on typing
347-
if not hasattr(self, "_vhd"):
348-
self._vhd: Optional[VhdSchema] = None
349-
vhd: Optional[VhdSchema] = self._vhd
350-
if vhd:
351-
return vhd
333+
if self._vhd is not None:
334+
return self._vhd
335+
352336
if isinstance(self.vhd_raw, dict):
353-
vhd = schema.load_by_type(VhdSchema, self.vhd_raw)
354-
add_secret(vhd.vhd_path, PATTERN_URL)
355-
if vhd.vmgs_path:
356-
add_secret(vhd.vmgs_path, PATTERN_URL)
357-
# this step makes vhd_raw is validated, and
358-
# filter out any unwanted content.
359-
self.vhd_raw = vhd.to_dict() # type: ignore
337+
self._vhd = schema.load_by_type(VhdSchema, self.vhd_raw)
338+
add_secret(self._vhd.vhd_path, PATTERN_URL)
339+
if self._vhd.vmgs_path:
340+
add_secret(self._vhd.vmgs_path, PATTERN_URL)
341+
# Validated vhd_raw and filter out any unwanted content
342+
self.vhd_raw = self._vhd.to_dict() # type: ignore
343+
360344
elif self.vhd_raw is not None:
361345
assert isinstance(self.vhd_raw, str), f"actual: {type(self.vhd_raw)}"
362-
vhd = VhdSchema(self.vhd_raw)
363-
add_secret(vhd.vhd_path, PATTERN_URL)
364-
self.vhd_raw = vhd.to_dict() # type: ignore
365-
self._vhd = vhd
366-
if vhd:
367-
return vhd
368-
else:
369-
return None
346+
self._vhd = VhdSchema(self.vhd_raw)
347+
add_secret(self._vhd.vhd_path, PATTERN_URL)
348+
self.vhd_raw = self._vhd.to_dict() # type: ignore
349+
350+
return self._vhd
370351

371352
@vhd.setter
372353
def vhd(self, value: Optional[VhdSchema]) -> None:
373354
self._vhd = value
374-
if value is None:
375-
self.vhd_raw = None
376-
else:
377-
self.vhd_raw = self._vhd.to_dict() # type: ignore
355+
self.vhd_raw = None if value is None else self._vhd.to_dict() # type: ignore
378356

379357
def get_image_name(self) -> str:
380358
result = ""
@@ -385,7 +363,7 @@ def get_image_name(self) -> str:
385363
self.shared_gallery_raw, dict
386364
), f"actual type: {type(self.shared_gallery_raw)}"
387365
if self.shared_gallery.resource_group_name:
388-
result = "/".join([x for x in self.shared_gallery_raw.values()])
366+
result = "/".join(self.shared_gallery_raw.values())
389367
else:
390368
result = (
391369
f"{self.shared_gallery.image_gallery}/"
@@ -396,7 +374,7 @@ def get_image_name(self) -> str:
396374
assert isinstance(
397375
self.marketplace_raw, dict
398376
), f"actual type: {type(self.marketplace_raw)}"
399-
result = " ".join([x for x in self.marketplace_raw.values()])
377+
result = " ".join(self.marketplace_raw.values())
400378
return result
401379

402380

@@ -420,9 +398,7 @@ def from_node_runbook(cls, runbook: AzureNodeSchema) -> "AzureNodeArmParameter":
420398
parameters["vhd_raw"] = parameters["vhd"]
421399
del parameters["vhd"]
422400

423-
arm_parameters = AzureNodeArmParameter(**parameters)
424-
425-
return arm_parameters
401+
return AzureNodeArmParameter(**parameters)
426402

427403

428404
class DataDiskCreateOption:

lisa/sut_orchestrator/azure/platform_.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2162,7 +2162,7 @@ def _get_vhd_os_disk_size(self, blob_url: str) -> int:
21622162
assert properties.size, f"fail to get blob size of {blob_url}"
21632163
# Azure requires only megabyte alignment of vhds, round size up
21642164
# for cases where the size is megabyte aligned
2165-
return math.ceil(properties.size / 1024 / 1024 / 1024)
2165+
return int(math.ceil(properties.size / 1024 / 1024 / 1024))
21662166

21672167
def _get_sig_info(
21682168
self, shared_image: SharedImageGallerySchema

0 commit comments

Comments
 (0)