Skip to content

Commit 83fca5e

Browse files
authored
[Monitor][Query] Improve typing (Azure#28175)
[Monitor][Query] Improve typing This enables the mypy, pyright, verifytypes checks in the CI, and also adds some typing improvements in order to pass the checks.. * Use class attribute style typing * Class ordering in models file was changed a bit to allow for class attribute typing. Signed-off-by: Paul Van Eck <[email protected]>
1 parent c7ec3d1 commit 83fca5e

File tree

11 files changed

+446
-419
lines changed

11 files changed

+446
-419
lines changed
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__path__ = __import__('pkgutil').extend_path(__path__, __name__) # type: ignore
1+
__path__ = __import__('pkgutil').extend_path(__path__, __name__)
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__path__ = __import__('pkgutil').extend_path(__path__, __name__) # type: ignore
1+
__path__ = __import__('pkgutil').extend_path(__path__, __name__)

sdk/monitor/azure-monitor-query/azure/monitor/query/_exceptions.py

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,33 +4,40 @@
44
# Licensed under the MIT License. See License.txt in the project root for
55
# license information.
66
# --------------------------------------------------------------------------
7-
from typing import Any
7+
import sys
8+
from typing import Any, List, Optional
89

910
from ._models import LogsQueryStatus
1011

12+
if sys.version_info >= (3, 9):
13+
from collections.abc import MutableMapping
14+
else:
15+
from typing import MutableMapping # pylint: disable=ungrouped-imports
1116

1217

13-
class LogsQueryError(object):
14-
"""The code and message for an error.
18+
JSON = MutableMapping[str, Any] # pylint: disable=unsubscriptable-object
1519

16-
:ivar code: A machine readable error code.
17-
:vartype code: str
18-
:ivar message: A human readable error message.
19-
:vartype message: str
20-
:ivar details: A list of additional details about the error.
21-
:vartype details: list[JSON]
22-
:ivar status: status for error item when iterating over list of
23-
results. Always "Failure" for an instance of a LogsQueryError.
24-
:vartype status: ~azure.monitor.query.LogsQueryStatus
25-
"""
20+
21+
class LogsQueryError:
22+
"""The code and message for an error."""
23+
24+
code: str
25+
"""A machine readable error code."""
26+
message: str
27+
"""A human readable error message."""
28+
details: Optional[List[JSON]] = None
29+
"""A list of additional details about the error."""
30+
status: LogsQueryStatus
31+
"""Status for error item when iterating over list of results. Always "Failure" for an instance of a
32+
LogsQueryError."""
2633

2734
def __init__(self, **kwargs: Any) -> None:
28-
self.code = kwargs.get("code", None)
29-
self.message = kwargs.get("message", None)
35+
self.code = kwargs.get("code", "")
36+
self.message = kwargs.get("message", "")
3037
self.details = kwargs.get("details", None)
3138
self.status = LogsQueryStatus.FAILURE
3239

33-
def __str__(self):
40+
def __str__(self) -> str:
3441
return str(self.__dict__)
3542

3643
@classmethod

sdk/monitor/azure-monitor-query/azure/monitor/query/_helpers.py

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
# license information.
66
# --------------------------------------------------------------------------
77
from datetime import datetime, timedelta
8-
from typing import List, Dict, Any
8+
from typing import List, Dict, Any, Optional
99

1010
from azure.core.credentials import TokenCredential
1111
from azure.core.exceptions import HttpResponseError
@@ -16,7 +16,7 @@
1616

1717
def get_authentication_policy(
1818
credential: TokenCredential,
19-
audience: str = None
19+
audience: Optional[str] = None
2020
) -> BearerTokenCredentialPolicy:
2121
"""Returns the correct authentication policy"""
2222
if not audience:
@@ -34,7 +34,7 @@ def get_authentication_policy(
3434

3535
def get_metrics_authentication_policy(
3636
credential: TokenCredential,
37-
audience: str = None
37+
audience: Optional[str] = None
3838
) -> BearerTokenCredentialPolicy:
3939
"""Returns the correct authentication policy"""
4040
if not audience:
@@ -55,28 +55,34 @@ def order_results(request_order: List, mapping: Dict[str, Any], **kwargs: Any) -
5555
results = []
5656
for item in ordered:
5757
if not item["body"].get("error"):
58-
results.append(
59-
kwargs.get("obj")._from_generated(item["body"]) # pylint: disable=protected-access
60-
)
58+
result_obj = kwargs.get("obj")
59+
if result_obj:
60+
results.append(
61+
result_obj._from_generated(item["body"]) # pylint: disable=protected-access
62+
)
6163
else:
6264
error = item["body"]["error"]
6365
if error.get("code") == "PartialError":
64-
res = kwargs.get("partial_err")._from_generated( # pylint: disable=protected-access
65-
item["body"], kwargs.get("raise_with")
66-
)
67-
results.append(res)
66+
partial_err = kwargs.get("partial_err")
67+
if partial_err:
68+
res = partial_err._from_generated( # pylint: disable=protected-access
69+
item["body"], kwargs.get("raise_with")
70+
)
71+
results.append(res)
6872
else:
69-
results.append(
70-
kwargs.get("err")._from_generated(error) # pylint: disable=protected-access
71-
)
73+
err = kwargs.get("err")
74+
if err:
75+
results.append(
76+
err._from_generated(error) # pylint: disable=protected-access
77+
)
7278
return results
7379

7480

75-
def construct_iso8601(timespan=None):
81+
def construct_iso8601(timespan=None) -> Optional[str]:
7682
if not timespan:
7783
return None
84+
start, end, duration = None, None, None
7885
try:
79-
start, end, duration = None, None, None
8086
if isinstance(timespan[1], datetime): # we treat thi as start_time, end_time
8187
start, end = timespan[0], timespan[1]
8288
elif isinstance(
@@ -89,25 +95,26 @@ def construct_iso8601(timespan=None):
8995
)
9096
except TypeError:
9197
duration = timespan # it means only duration (timedelta) is provideds
98+
duration_str = ""
9299
if duration:
93100
try:
94-
duration = "PT{}S".format(duration.total_seconds())
101+
duration_str = "PT{}S".format(duration.total_seconds())
95102
except AttributeError:
96103
raise ValueError("timespan must be a timedelta or a tuple.")
97104
iso_str = None
98105
if start is not None:
99106
start = Serializer.serialize_iso(start)
100107
if end is not None:
101108
end = Serializer.serialize_iso(end)
102-
iso_str = start + "/" + end
103-
elif duration is not None:
104-
iso_str = start + "/" + duration
109+
iso_str = f"{start}/{end}"
110+
elif duration_str:
111+
iso_str = f"{start}/{duration_str}"
105112
else: # means that an invalid value None that is provided with start_time
106113
raise ValueError(
107114
"Duration or end_time cannot be None when provided with start_time."
108115
)
109116
else:
110-
iso_str = duration
117+
iso_str = duration_str
111118
return iso_str
112119

113120

@@ -124,7 +131,7 @@ def native_col_type(col_type, value):
124131
return value
125132

126133

127-
def process_row(col_types, row):
134+
def process_row(col_types, row) -> List[Any]:
128135
return [native_col_type(col_types[ind], val) for ind, val in enumerate(row)]
129136

130137

sdk/monitor/azure-monitor-query/azure/monitor/query/_logs_query_client.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ def query_workspace(
107107
:dedent: 0
108108
:caption: Get a response for a single Log Query
109109
"""
110-
timespan = construct_iso8601(timespan)
110+
timespan_iso = construct_iso8601(timespan)
111111
include_statistics = kwargs.pop("include_statistics", False)
112112
include_visualization = kwargs.pop("include_visualization", False)
113113
server_timeout = kwargs.pop("server_timeout", None)
@@ -119,7 +119,7 @@ def query_workspace(
119119

120120
body = {
121121
"query": query,
122-
"timespan": timespan,
122+
"timespan": timespan_iso,
123123
"workspaces": additional_workspaces
124124
}
125125

@@ -131,7 +131,8 @@ def query_workspace(
131131
)
132132
except HttpResponseError as err:
133133
process_error(err, LogsQueryError)
134-
response = None
134+
135+
response: Union[LogsQueryResult, LogsQueryPartialResult]
135136
if not generated_response.get("error"):
136137
response = LogsQueryResult._from_generated( # pylint: disable=protected-access
137138
generated_response
@@ -140,7 +141,7 @@ def query_workspace(
140141
response = LogsQueryPartialResult._from_generated( # pylint: disable=protected-access
141142
generated_response, LogsQueryError
142143
)
143-
return cast(Union[LogsQueryResult, LogsQueryPartialResult], response)
144+
return response
144145

145146
@distributed_trace
146147
def query_batch(
@@ -200,5 +201,5 @@ def __enter__(self) -> "LogsQueryClient":
200201
self._client.__enter__() # pylint:disable=no-member
201202
return self
202203

203-
def __exit__(self, *args) -> None:
204+
def __exit__(self, *args: Any) -> None:
204205
self._client.__exit__(*args) # pylint:disable=no-member

sdk/monitor/azure-monitor-query/azure/monitor/query/_metrics_query_client.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
# license information.
66
# --------------------------------------------------------------------------
77
# pylint: disable=anomalous-backslash-in-string
8-
from typing import Any, List
8+
from typing import Any, cast, List
99

1010
from azure.core.credentials import TokenCredential
1111
from azure.core.paging import ItemPaged
@@ -140,7 +140,7 @@ def list_metric_namespaces(self, resource_uri: str, **kwargs: Any) -> ItemPaged[
140140
start_time = kwargs.pop("start_time", None)
141141
if start_time:
142142
start_time = Serializer.serialize_iso(start_time)
143-
return self._namespace_op.list(
143+
res = self._namespace_op.list(
144144
resource_uri,
145145
start_time=start_time,
146146
cls=kwargs.pop(
@@ -152,6 +152,7 @@ def list_metric_namespaces(self, resource_uri: str, **kwargs: Any) -> ItemPaged[
152152
),
153153
**kwargs
154154
)
155+
return cast(ItemPaged[MetricNamespace], res)
155156

156157
@distributed_trace
157158
def list_metric_definitions(self, resource_uri: str, **kwargs: Any) -> ItemPaged[MetricDefinition]:
@@ -166,7 +167,7 @@ def list_metric_definitions(self, resource_uri: str, **kwargs: Any) -> ItemPaged
166167
:raises: ~azure.core.exceptions.HttpResponseError
167168
"""
168169
metric_namespace = kwargs.pop("namespace", None)
169-
return self._definitions_op.list(
170+
res = self._definitions_op.list(
170171
resource_uri,
171172
metricnamespace=metric_namespace,
172173
cls=kwargs.pop(
@@ -178,6 +179,7 @@ def list_metric_definitions(self, resource_uri: str, **kwargs: Any) -> ItemPaged
178179
),
179180
**kwargs
180181
)
182+
return cast(ItemPaged[MetricDefinition], res)
181183

182184
def close(self) -> None:
183185
"""Close the :class:`~azure.monitor.query.MetricsQueryClient` session."""

0 commit comments

Comments
 (0)