Skip to content

Commit b5ba69f

Browse files
authored
Merge pull request #350 from RaileyHartheim/main add type hints for issues.py and types.py
2 parents 8aad508 + 86db765 commit b5ba69f

File tree

2 files changed

+69
-25
lines changed

2 files changed

+69
-25
lines changed

ydb/issues.py

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,19 @@
11
# -*- coding: utf-8 -*-
2+
from __future__ import annotations
3+
24
from google.protobuf import text_format
35
import enum
46
import queue
7+
import typing
58

69
from . import _apis
710

11+
# Workaround for good IDE and universal for runtime
12+
if typing.TYPE_CHECKING:
13+
from _grpc.v4.protos import ydb_issue_message_pb2, ydb_operation_pb2
14+
else:
15+
from ._grpc.common.protos import ydb_issue_message_pb2, ydb_operation_pb2
16+
817

918
_TRANSPORT_STATUSES_FIRST = 401000
1019
_CLIENT_STATUSES_FIRST = 402000
@@ -43,10 +52,19 @@ class StatusCode(enum.IntEnum):
4352
SESSION_POOL_EMPTY = _CLIENT_STATUSES_FIRST + 40
4453

4554

55+
# TODO: convert from proto IssueMessage
56+
class _IssueMessage:
57+
def __init__(self, message: str, issue_code: int, severity: int, issues) -> None:
58+
self.message = message
59+
self.issue_code = issue_code
60+
self.severity = severity
61+
self.issues = issues
62+
63+
4664
class Error(Exception):
4765
status = None
4866

49-
def __init__(self, message, issues=None):
67+
def __init__(self, message: str, issues: typing.Optional[typing.Iterable[_IssueMessage]] = None):
5068
super(Error, self).__init__(message)
5169
self.issues = issues
5270
self.message = message
@@ -161,14 +179,14 @@ def __init__(self, message: str):
161179
super().__init__(message)
162180

163181

164-
def _format_issues(issues):
182+
def _format_issues(issues: typing.Iterable[ydb_issue_message_pb2.IssueMessage]) -> str:
165183
if not issues:
166184
return ""
167185

168186
return " ,".join(text_format.MessageToString(issue, as_utf8=False, as_one_line=True) for issue in issues)
169187

170188

171-
def _format_response(response):
189+
def _format_response(response: ydb_operation_pb2.Operation) -> str:
172190
fmt_issues = _format_issues(response.issues)
173191
return f"{fmt_issues} (server_code: {response.status})"
174192

@@ -196,7 +214,7 @@ def _format_response(response):
196214
}
197215

198216

199-
def _process_response(response_proto):
217+
def _process_response(response_proto: ydb_operation_pb2.Operation) -> None:
200218
if response_proto.status not in _success_status_codes:
201219
exc_obj = _server_side_error_map.get(response_proto.status)
202220
raise exc_obj(_format_response(response_proto), response_proto.issues)

ydb/types.py

Lines changed: 47 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,76 +1,94 @@
11
# -*- coding: utf-8 -*-
2+
from __future__ import annotations
3+
24
import abc
35
import enum
46
import json
57
from . import _utilities, _apis
68
from datetime import date, datetime, timedelta
9+
import typing
710
import uuid
811
import struct
912
from google.protobuf import struct_pb2
1013

14+
from . import table
15+
16+
17+
# Workaround for good IDE and universal for runtime
18+
if typing.TYPE_CHECKING:
19+
from ._grpc.v4.protos import ydb_value_pb2
20+
else:
21+
from ._grpc.common.protos import ydb_value_pb2
22+
1123

1224
_SECONDS_IN_DAY = 60 * 60 * 24
1325
_EPOCH = datetime(1970, 1, 1)
1426

1527

16-
def _from_date(x, table_client_settings):
28+
def _from_date(x: ydb_value_pb2.Value, table_client_settings: table.TableClientSettings) -> typing.Union[date, int]:
1729
if table_client_settings is not None and table_client_settings._native_date_in_result_sets:
1830
return _EPOCH.date() + timedelta(days=x.uint32_value)
1931
return x.uint32_value
2032

2133

22-
def _to_date(pb, value):
34+
def _to_date(pb: ydb_value_pb2.Value, value: typing.Union[date, int]) -> None:
2335
if isinstance(value, date):
2436
pb.uint32_value = (value - _EPOCH.date()).days
2537
else:
2638
pb.uint32_value = value
2739

2840

29-
def _from_datetime_number(x, table_client_settings):
41+
def _from_datetime_number(
42+
x: typing.Union[float, datetime], table_client_settings: table.TableClientSettings
43+
) -> datetime:
3044
if table_client_settings is not None and table_client_settings._native_datetime_in_result_sets:
3145
return datetime.utcfromtimestamp(x)
3246
return x
3347

3448

35-
def _from_json(x, table_client_settings):
49+
def _from_json(x: typing.Union[str, bytearray, bytes], table_client_settings: table.TableClientSettings):
3650
if table_client_settings is not None and table_client_settings._native_json_in_result_sets:
3751
return json.loads(x)
3852
return x
3953

4054

41-
def _to_uuid(value_pb, table_client_settings):
55+
def _to_uuid(value_pb: ydb_value_pb2.Value, table_client_settings: table.TableClientSettings) -> uuid.UUID:
4256
return uuid.UUID(bytes_le=struct.pack("QQ", value_pb.low_128, value_pb.high_128))
4357

4458

45-
def _from_uuid(pb, value):
59+
def _from_uuid(pb: ydb_value_pb2.Value, value: uuid.UUID):
4660
pb.low_128 = struct.unpack("Q", value.bytes_le[0:8])[0]
4761
pb.high_128 = struct.unpack("Q", value.bytes_le[8:16])[0]
4862

4963

50-
def _from_interval(value_pb, table_client_settings):
64+
def _from_interval(
65+
value_pb: ydb_value_pb2.Value, table_client_settings: table.TableClientSettings
66+
) -> typing.Union[timedelta, int]:
5167
if table_client_settings is not None and table_client_settings._native_interval_in_result_sets:
5268
return timedelta(microseconds=value_pb.int64_value)
5369
return value_pb.int64_value
5470

5571

56-
def _timedelta_to_microseconds(value):
72+
def _timedelta_to_microseconds(value: timedelta) -> int:
5773
return (value.days * _SECONDS_IN_DAY + value.seconds) * 1000000 + value.microseconds
5874

5975

60-
def _to_interval(pb, value):
76+
def _to_interval(pb: ydb_value_pb2.Value, value: typing.Union[timedelta, int]):
6177
if isinstance(value, timedelta):
6278
pb.int64_value = _timedelta_to_microseconds(value)
6379
else:
6480
pb.int64_value = value
6581

6682

67-
def _from_timestamp(value_pb, table_client_settings):
83+
def _from_timestamp(
84+
value_pb: ydb_value_pb2.Value, table_client_settings: table.TableClientSettings
85+
) -> typing.Union[datetime, int]:
6886
if table_client_settings is not None and table_client_settings._native_timestamp_in_result_sets:
6987
return _EPOCH + timedelta(microseconds=value_pb.uint64_value)
7088
return value_pb.uint64_value
7189

7290

73-
def _to_timestamp(pb, value):
91+
def _to_timestamp(pb: ydb_value_pb2.Value, value: typing.Union[datetime, int]):
7492
if isinstance(value, datetime):
7593
pb.uint64_value = _timedelta_to_microseconds(value - _EPOCH)
7694
else:
@@ -129,13 +147,15 @@ class PrimitiveType(enum.Enum):
129147

130148
DyNumber = _apis.primitive_types.DYNUMBER, "text_value"
131149

132-
def __init__(self, idn, proto_field, to_obj=None, from_obj=None):
150+
def __init__(
151+
self, idn: ydb_value_pb2.Type.PrimitiveTypeId, proto_field: typing.Optional[str], to_obj=None, from_obj=None
152+
):
133153
self._idn_ = idn
134154
self._to_obj = to_obj
135155
self._from_obj = from_obj
136156
self._proto_field = proto_field
137157

138-
def get_value(self, value_pb, table_client_settings):
158+
def get_value(self, value_pb: ydb_value_pb2.Value, table_client_settings: table.TableClientSettings):
139159
"""
140160
Extracts value from protocol buffer
141161
:param value_pb: A protocol buffer
@@ -149,7 +169,7 @@ def get_value(self, value_pb, table_client_settings):
149169

150170
return getattr(value_pb, self._proto_field)
151171

152-
def set_value(self, pb, value):
172+
def set_value(self, pb: ydb_value_pb2.Value, value):
153173
"""
154174
Sets value in a protocol buffer
155175
:param pb: A protocol buffer
@@ -176,7 +196,9 @@ def proto(self):
176196
class DataQuery(object):
177197
__slots__ = ("yql_text", "parameters_types", "name")
178198

179-
def __init__(self, query_id, parameters_types, name=None):
199+
def __init__(
200+
self, query_id: str, parameters_types: "dict[str, ydb_value_pb2.Type]", name: typing.Optional[str] = None
201+
):
180202
self.yql_text = query_id
181203
self.parameters_types = parameters_types
182204
self.name = _utilities.get_query_hash(self.yql_text) if name is None else name
@@ -259,7 +281,7 @@ def __str__(self):
259281
class OptionalType(AbstractTypeBuilder):
260282
__slots__ = ("_repr", "_proto", "_item")
261283

262-
def __init__(self, optional_type):
284+
def __init__(self, optional_type: typing.Union[AbstractTypeBuilder, PrimitiveType]):
263285
"""
264286
Represents optional type that wraps inner type
265287
:param optional_type: An instance of an inner type
@@ -291,7 +313,7 @@ def __str__(self):
291313
class ListType(AbstractTypeBuilder):
292314
__slots__ = ("_repr", "_proto")
293315

294-
def __init__(self, list_type):
316+
def __init__(self, list_type: typing.Union[AbstractTypeBuilder, PrimitiveType]):
295317
"""
296318
:param list_type: List item type builder
297319
"""
@@ -313,7 +335,11 @@ def __str__(self):
313335
class DictType(AbstractTypeBuilder):
314336
__slots__ = ("__repr", "__proto")
315337

316-
def __init__(self, key_type, payload_type):
338+
def __init__(
339+
self,
340+
key_type: typing.Union[AbstractTypeBuilder, PrimitiveType],
341+
payload_type: typing.Union[AbstractTypeBuilder, PrimitiveType],
342+
):
317343
"""
318344
:param key_type: Key type builder
319345
:param payload_type: Payload type builder
@@ -341,7 +367,7 @@ def __init__(self):
341367
self.__elements_repr = []
342368
self.__proto = _apis.ydb_value.Type(tuple_type=_apis.ydb_value.TupleType())
343369

344-
def add_element(self, element_type):
370+
def add_element(self, element_type: typing.Union[AbstractTypeBuilder, PrimitiveType]):
345371
"""
346372
:param element_type: Adds additional element of tuple
347373
:return: self
@@ -366,7 +392,7 @@ def __init__(self):
366392
self.__members_repr = []
367393
self.__proto = _apis.ydb_value.Type(struct_type=_apis.ydb_value.StructType())
368394

369-
def add_member(self, name, member_type):
395+
def add_member(self, name: str, member_type: typing.Union[AbstractTypeBuilder, PrimitiveType]):
370396
"""
371397
:param name:
372398
:param member_type:
@@ -393,7 +419,7 @@ def __init__(self):
393419
self.__columns_repr = []
394420
self.__proto = _apis.ydb_value.Type(struct_type=_apis.ydb_value.StructType())
395421

396-
def add_column(self, name, column_type):
422+
def add_column(self, name: str, column_type: typing.Union[AbstractTypeBuilder, PrimitiveType]):
397423
"""
398424
:param name: A column name
399425
:param column_type: A column type

0 commit comments

Comments
 (0)