Skip to content

Commit 811069f

Browse files
authored
[ml] Fix azure/ai/ml/_internal mypy errors (#33643)
* Add mypy.ini file * Fix bug 2810296, replace ResourceConfiguration with CodeConfiguration * Turn on mypy gate * Update pyproject.toml * Remove mypy.ini file * Update exclude section of pyproject.toml * Exclude _schema folder from mypy check * Fix _internal errors * Fix remaining _internal errors * Fix remaining _internal errors * Revert _schema fixes, _schema excluded from checks * Address comment * Update pyproject.toml to exclude everything but _internal * Update pyproject.toml to exclude everything but _internal * Exclude remaining files * Ignore overload error in inputs_outputs * Fix typo * Revert is_deterministic changes * Fix formatting * Revert last is_deterministic change * Fix line too long pylint error
1 parent d871011 commit 811069f

File tree

14 files changed

+95
-59
lines changed

14 files changed

+95
-59
lines changed

sdk/ml/azure-ai-ml/azure/ai/ml/_internal/entities/_additional_includes.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
# Copyright (c) Microsoft Corporation. All rights reserved.
33
# ---------------------------------------------------------
44
from pathlib import Path
5+
from typing import Optional
56

67
from ...constants._common import AzureDevopsArtifactsType
78
from ...entities._component._additional_includes import AdditionalIncludes
@@ -17,7 +18,7 @@ def includes(self):
1718
return self.origin_configs
1819

1920
@property
20-
def code_path(self) -> Path:
21+
def code_path(self) -> Optional[Path]:
2122
return self.resolved_code_path
2223

2324
@property

sdk/ml/azure-ai-ml/azure/ai/ml/_internal/entities/_input_outputs.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -91,12 +91,13 @@ def _get_python_builtin_type_str(self) -> str:
9191
if self._lower_type in [_INPUT_TYPE_ENUM, _INPUT_TYPE_FLOAT]:
9292
return self._lower_type
9393
if self._is_primitive_type:
94-
return IOConstants.PRIMITIVE_STR_2_TYPE[self._lower_type].__name__
94+
return IOConstants.PRIMITIVE_STR_2_TYPE[self._lower_type].__name__ # type: ignore[index]
95+
# TODO: Bug 2881900
9596
return super()._get_python_builtin_type_str()
9697

9798
@overload
9899
@classmethod
99-
def _from_base(cls, _input: None) -> None:
100+
def _from_base(cls, _input: None) -> None: # type: ignore[misc]
100101
...
101102

102103
@overload
@@ -125,7 +126,7 @@ def _from_base(cls, _input: Optional[Union[Input, Dict]]) -> Optional["InternalI
125126
# do force cast directly as there is no new field added in InternalInput
126127
# need to change the logic if new field is added
127128
_input.__class__ = InternalInput
128-
return _input
129+
return _input # type: ignore[return-value]
129130
return InternalInput(**_input)
130131

131132

@@ -180,7 +181,7 @@ def _from_base(cls, _output: Union[Output, Dict]) -> Optional["InternalOutput"]:
180181
# do force cast directly as there is no new field added in InternalInput
181182
# need to change the logic if new field is added
182183
_output.__class__ = InternalOutput
183-
return _output
184+
return _output # type: ignore[return-value]
184185
return InternalOutput(**_output)
185186

186187
def map_pipeline_output_type(self) -> str:

sdk/ml/azure-ai-ml/azure/ai/ml/_internal/entities/command.py

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22
# Copyright (c) Microsoft Corporation. All rights reserved.
33
# ---------------------------------------------------------
44
# pylint: disable=protected-access
5-
from typing import Dict, List, Union
5+
from typing import Dict, List, Optional, Union
66

77
from marshmallow import INCLUDE, Schema
88

9-
from ... import MpiDistribution, PyTorchDistribution, TensorFlowDistribution, RayDistribution
9+
from ... import MpiDistribution, PyTorchDistribution, RayDistribution, TensorFlowDistribution
1010
from ..._schema import PathAwareSchema
1111
from ..._schema.core.fields import DistributionField
1212
from ...entities import CommandJobLimits, JobResourceConfiguration
@@ -34,16 +34,16 @@ def __init__(self, **kwargs):
3434
self._init = False
3535

3636
@property
37-
def compute(self) -> str:
37+
def compute(self) -> Optional[str]:
3838
"""Get the compute definition for the command.
3939
4040
:return: The compute definition
41-
:rtype: str
41+
:rtype: Optional[str]
4242
"""
4343
return self._compute
4444

4545
@compute.setter
46-
def compute(self, value: str):
46+
def compute(self, value: str) -> None:
4747
"""Set the compute definition for the command.
4848
4949
:param value: The new compute definition
@@ -52,16 +52,16 @@ def compute(self, value: str):
5252
self._compute = value
5353

5454
@property
55-
def environment(self) -> str:
55+
def environment(self) -> Optional[str]:
5656
"""Get the environment definition for the command.
5757
5858
:return: The environment definition
59-
:rtype: str
59+
:rtype: Optional[str]
6060
"""
6161
return self._environment
6262

6363
@environment.setter
64-
def environment(self, value: str):
64+
def environment(self, value: str) -> None:
6565
"""Set the environment definition for the command.
6666
6767
:param value: The new environment definition
@@ -70,16 +70,16 @@ def environment(self, value: str):
7070
self._environment = value
7171

7272
@property
73-
def environment_variables(self) -> Dict[str, str]:
73+
def environment_variables(self) -> Optional[Dict[str, str]]:
7474
"""Get the environment variables for the command.
7575
7676
:return: The environment variables
77-
:rtype: Dict[str, str]
77+
:rtype: Optional[Dict[str, str]]
7878
"""
7979
return self._environment_variables
8080

8181
@environment_variables.setter
82-
def environment_variables(self, value: Dict[str, str]):
82+
def environment_variables(self, value: Dict[str, str]) -> None:
8383
"""Set the environment variables for the command.
8484
8585
:param value: The new environment variables

sdk/ml/azure-ai-ml/azure/ai/ml/_internal/entities/component.py

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,14 @@
33
# ---------------------------------------------------------
44
# pylint: disable=protected-access, redefined-builtin
55
# disable redefined-builtin to use id/type as argument name
6+
import os
67
from contextlib import contextmanager
78
from os import PathLike
89
from pathlib import Path
9-
from typing import Dict, Iterable, List, Optional, Union
10+
from typing import Any, Dict, Iterable, List, Optional, Union
1011
from uuid import UUID
1112

12-
import yaml
13+
import yaml # type: ignore[import]
1314
from marshmallow import Schema
1415

1516
from ... import Input, Output
@@ -20,7 +21,7 @@
2021
from ...constants._common import DefaultOpenEncoding
2122
from ...entities import Component
2223
from ...entities._assets import Code
23-
from ...entities._component._additional_includes import AdditionalIncludesMixin, AdditionalIncludes
24+
from ...entities._component._additional_includes import AdditionalIncludes, AdditionalIncludesMixin
2425
from ...entities._component.code import ComponentIgnoreFile
2526
from ...entities._job.distribution import DistributionConfiguration
2627
from ...entities._system_data import SystemData
@@ -86,7 +87,7 @@ def __init__(
8687
successful_return_code: Optional[str] = None,
8788
inputs: Optional[Dict] = None,
8889
outputs: Optional[Dict] = None,
89-
code: Optional[str] = None,
90+
code: Optional[Union[str, os.PathLike]] = None,
9091
environment: Optional[Dict] = None,
9192
environment_variables: Optional[Dict] = None,
9293
command: Optional[str] = None,
@@ -200,11 +201,13 @@ def _get_additional_includes_field_name(cls) -> str:
200201

201202
def _get_all_additional_includes_configs(self) -> List:
202203
# internal components must have a source path
203-
return self._read_additional_include_configs(Path(self._source_path))
204+
return self._read_additional_include_configs(Path(self._source_path)) # type: ignore[arg-type]
205+
# TODO: Bug 2881943
204206

205207
def _get_base_path_for_code(self) -> Path:
206208
# internal components must have a source path
207-
return Path(self._source_path).parent
209+
return Path(self._source_path).parent # type: ignore[arg-type]
210+
# TODO: Bug 2881943
208211

209212
def _get_origin_code_value(self) -> Union[str, PathLike, None]:
210213
return super()._get_origin_code_value() or "."
@@ -276,8 +279,9 @@ def _from_rest_object_to_init_params(cls, obj: ComponentVersion) -> Dict:
276279
return init_kwargs
277280

278281
def _to_rest_object(self) -> ComponentVersion:
279-
component = convert_ordered_dict_to_dict(self._to_dict())
280-
component["_source"] = self._source
282+
component: Union[Dict[Any, Any], List[Any]] = convert_ordered_dict_to_dict(self._to_dict())
283+
component["_source"] = self._source # type: ignore[call-overload]
284+
# TODO: 2883063
281285

282286
properties = ComponentVersionProperties(
283287
component_spec=component,
@@ -310,7 +314,7 @@ def _get_snapshot_id(
310314
snapshot_id = str(UUID(curr_root.hexdigest_hash[::4]))
311315
return snapshot_id
312316

313-
@contextmanager
317+
@contextmanager # type: ignore[arg-type]
314318
def _try_build_local_code(self) -> Iterable[Code]:
315319
"""Build final code when origin code is a local code.
316320
Will merge code path with additional includes into a temp folder if additional includes is specified.
@@ -319,6 +323,8 @@ def _try_build_local_code(self) -> Iterable[Code]:
319323
:return: The code instance
320324
:rtype: Iterable[Code]
321325
"""
326+
327+
tmp_code_dir: Path
322328
# origin code value of internal component will never be None. check _get_origin_code_value for details
323329
with self._generate_additional_includes_obj().merge_local_code_and_additional_includes() as tmp_code_dir:
324330
# use absolute path in case temp folder & work dir are in different drive
@@ -334,8 +340,12 @@ def _try_build_local_code(self) -> Iterable[Code]:
334340
# additional includes config file itself should be ignored
335341
rebased_ignore_file = ComponentIgnoreFile(
336342
tmp_code_dir,
337-
additional_includes_file_name=Path(self._source_path).with_suffix(_ADDITIONAL_INCLUDES_SUFFIX).name,
343+
additional_includes_file_name=Path(self._source_path)
344+
.with_suffix(_ADDITIONAL_INCLUDES_SUFFIX)
345+
.name # type: ignore[arg-type]
346+
# TODO: Bug 2881943
338347
)
348+
339349
# Use the snapshot id in ml-components as code name to enable anonymous
340350
# component reuse from ml-component runs.
341351
# calculate snapshot id here instead of inside InternalCode to ensure that

sdk/ml/azure-ai-ml/azure/ai/ml/_internal/entities/node.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,8 @@ def __init__(
6565
BaseNode.__init__(
6666
self,
6767
type=type,
68-
component=component,
68+
component=component, # type: ignore[arg-type]
69+
# TODO: Bug 2881892
6970
inputs=inputs,
7071
outputs=outputs,
7172
compute=compute,

sdk/ml/azure-ai-ml/azure/ai/ml/_internal/entities/runsettings/ai_super_computer_configuration.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@
22
# Copyright (c) Microsoft Corporation. All rights reserved.
33
# ---------------------------------------------------------
44

5-
from typing import Dict, List, Optional
5+
from typing import Any, Dict, List, Optional
66

77
from ....entities._job.job_resource_configuration import BaseProperty
88

99

1010
class PascalCaseProperty(BaseProperty):
11-
_KEY_MAPPING = {}
11+
_KEY_MAPPING: Dict[str, Any] = {}
1212

1313
def items(self):
1414
result = []

sdk/ml/azure-ai-ml/azure/ai/ml/_internal/entities/spark.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ def __init__(
4040
dynamic_allocation_min_executors: Optional[int] = None,
4141
dynamic_allocation_max_executors: Optional[int] = None,
4242
conf: Optional[Dict[str, str]] = None,
43-
args: Optional[Dict] = None,
43+
args: Optional[str] = None,
4444
**kwargs,
4545
):
4646
SparkJobEntryMixin.__init__(self, entry=entry, **kwargs)
@@ -90,12 +90,12 @@ def __init__(
9090
def _create_schema_for_validation(cls, context) -> Union[PathAwareSchema, Schema]:
9191
return InternalSparkComponentSchema(context=context)
9292

93-
@property
94-
def environment(self) -> Union[str, Environment, dict]:
93+
@property # type: ignore[override]
94+
def environment(self) -> Optional[Union[Environment, str]]:
9595
"""Get the environment of the component.
9696
9797
:return: The environment of the component.
98-
:rtype: Union[str, Environment, dict]
98+
:rtype: Optional[Union[Environment, str]]]
9999
"""
100100
if isinstance(self._environment, Environment) and self._environment.image is None:
101101
return Environment(conda_file=self._environment.conda_file, image=DUMMY_IMAGE)
@@ -131,11 +131,11 @@ def environment(self, value):
131131
raise ValueError(f"Unsupported environment type: {type(value)}")
132132

133133
@property
134-
def jars(self) -> List[str]:
134+
def jars(self) -> Optional[List[str]]:
135135
"""Get the jars of the component.
136136
137137
:return: The jars of the component.
138-
:rtype: List[str]
138+
:rtype: Optional[List[str]]
139139
"""
140140
return self._jars
141141

@@ -153,11 +153,11 @@ def jars(self, value: Union[str, List[str]]):
153153
self._jars = value
154154

155155
@property
156-
def py_files(self) -> List[str]:
156+
def py_files(self) -> Optional[List[str]]:
157157
"""Get the py_files of the component.
158158
159159
:return: The py_files of the component.
160-
:rtype: List[str]
160+
:rtype: Optional[List[str]]
161161
"""
162162
return self._py_files
163163

sdk/ml/azure-ai-ml/azure/ai/ml/_schema/_datastore/azure_storage.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ class AzureFileSchema(AzureStorageSchema):
4747
)
4848

4949
@post_load
50-
def make(self, data: Dict[str, Any], **kwargs) -> "AzureFileDatastore":
50+
def make(self, data: Dict[str, Any], **kwargs) -> "AzureFileDatastore": # type: ignore[name-defined]
5151
from azure.ai.ml.entities import AzureFileDatastore
5252

5353
return AzureFileDatastore(**data)
@@ -69,7 +69,7 @@ class AzureBlobSchema(AzureStorageSchema):
6969
)
7070

7171
@post_load
72-
def make(self, data: Dict[str, Any], **kwargs) -> "AzureBlobDatastore":
72+
def make(self, data: Dict[str, Any], **kwargs) -> "AzureBlobDatastore": # type: ignore[name-defined]
7373
from azure.ai.ml.entities import AzureBlobDatastore
7474

7575
return AzureBlobDatastore(**data)

sdk/ml/azure-ai-ml/azure/ai/ml/_schema/_datastore/one_lake.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,9 @@
66

77
from typing import Any, Dict
88

9-
from marshmallow import fields, post_load, Schema
9+
from marshmallow import Schema, fields, post_load
1010

1111
from azure.ai.ml._restclient.v2023_04_01_preview.models import DatastoreType, OneLakeArtifactType
12-
1312
from azure.ai.ml._schema.core.fields import NestedField, PathAwareSchema, StringTransformedEnum, UnionField
1413
from azure.ai.ml._utils.utils import camel_to_snake
1514

sdk/ml/azure-ai-ml/azure/ai/ml/_utils/_arm_id_utils.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -330,8 +330,8 @@ def parse_name_version(name: str) -> Tuple[str, Optional[str]]:
330330
return name, ":".join(version)
331331

332332

333-
def parse_name_label(name: str) -> Tuple[str, Optional[str]]:
334-
if name.find("/") != -1 and name[0] != "/":
333+
def parse_name_label(name: Optional[str]) -> Tuple[str, Optional[str]]:
334+
if not name or (name.find("/") != -1 and name[0] != "/"):
335335
raise ValidationException(
336336
f"Could not parse {name}. If providing an ARM id, it should start with a '/'.",
337337
no_personal_data_message=f"Could not parse {name}.",

0 commit comments

Comments
 (0)