Skip to content
This repository was archived by the owner on Jan 13, 2023. It is now read-only.

Commit 07f9a86

Browse files
authored
Merge pull request #321 from lzpap/type_annotations
Introduce Type Annotations
2 parents b1b068f + 0e609ad commit 07f9a86

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

70 files changed

+1369
-1370
lines changed

examples/send_transfer.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
Tag,
1313
TryteString,
1414
)
15-
from address_generator import get_seed, output_seed
15+
from .address_generator import get_seed, output_seed
1616

1717

1818
def main(address, depth, message, tag, uri, value):

iota/__init__.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,21 @@
1+
from typing import Dict
12

23
# Define a few magic constants.
3-
DEFAULT_PORT = 14265
4+
DEFAULT_PORT: int = 14265
45
"""
56
Default port to use when configuring an adapter, if the port is not
67
specified.
78
"""
89

9-
TRITS_PER_TRYTE = 3
10+
TRITS_PER_TRYTE: int = 3
1011
"""
1112
Number of trits in a tryte.
1213
Changing this will probably break everything, but there's a chance it
1314
could create a sexy new altcoin instead.
1415
In that way, it's kind of like toxic waste in a superhero story.
1516
"""
1617

17-
STANDARD_UNITS = {
18+
STANDARD_UNITS: Dict[str, int] = {
1819
# Valid IOTA unit suffixes. Example value '-273.15 Ki'
1920
'i': 1,
2021
'Ki': 1000,

iota/adapter/__init__.py

Lines changed: 60 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11

22
import json
33
from abc import ABCMeta, abstractmethod as abstract_method
4+
from asyncio import Future
45
from collections import deque
56
from inspect import isabstract as is_abstract
67
from logging import DEBUG, Logger
78
from socket import getdefaulttimeout as get_default_timeout
8-
from typing import Container, Dict, List, Optional, Text, Tuple, Union
9-
from httpx import AsyncClient, Response, codes, auth
9+
from typing import Container, List, Optional, Tuple, Union, Any, Dict
10+
from httpx import AsyncClient, Response, codes, BasicAuth
1011
import asyncio
1112

1213
from iota.exceptions import with_context
@@ -31,7 +32,7 @@
3132
"""
3233

3334
# Custom types for type hints and docstrings.
34-
AdapterSpec = Union[Text, 'BaseAdapter']
35+
AdapterSpec = Union[str, 'BaseAdapter']
3536
"""
3637
Placeholder that means “URI or adapter instance”.
3738
@@ -42,7 +43,8 @@
4243
# Load SplitResult for IDE type hinting and autocompletion.
4344
from urllib.parse import SplitResult, urlsplit
4445

45-
def async_return(result):
46+
47+
def async_return(result: Any) -> Future:
4648
"""
4749
Turns 'result' into a `Future` object with 'result' value.
4850
@@ -52,6 +54,7 @@ def async_return(result):
5254
f.set_result(result)
5355
return f
5456

57+
5558
class BadApiResponse(ValueError):
5659
"""
5760
Indicates that a non-success response was received from the node.
@@ -66,21 +69,20 @@ class InvalidUri(ValueError):
6669
pass
6770

6871

69-
adapter_registry = {} # type: Dict[Text, AdapterMeta]
72+
adapter_registry: Dict[str, 'AdapterMeta'] = {}
7073
"""
7174
Keeps track of available adapters and their supported protocols.
7275
"""
7376

7477

75-
def resolve_adapter(uri):
76-
# type: (AdapterSpec) -> BaseAdapter
78+
def resolve_adapter(uri: AdapterSpec) -> 'BaseAdapter':
7779
"""
7880
Given a URI, returns a properly-configured adapter instance.
7981
"""
8082
if isinstance(uri, BaseAdapter):
8183
return uri
8284

83-
parsed = urlsplit(uri) # type: SplitResult
85+
parsed: SplitResult = urlsplit(uri)
8486

8587
if not parsed.scheme:
8688
raise with_context(
@@ -116,7 +118,7 @@ class AdapterMeta(ABCMeta):
116118
Automatically registers new adapter classes in ``adapter_registry``.
117119
"""
118120

119-
def __init__(cls, what, bases=None, dict=None):
121+
def __init__(cls, what, bases=None, dict=None) -> None:
120122
super(AdapterMeta, cls).__init__(what, bases, dict)
121123

122124
if not is_abstract(cls):
@@ -125,8 +127,7 @@ def __init__(cls, what, bases=None, dict=None):
125127
# adapters.
126128
adapter_registry.setdefault(protocol, cls)
127129

128-
def configure(cls, parsed):
129-
# type: (Union[Text, SplitResult]) -> HttpAdapter
130+
def configure(cls, parsed: Union[str, SplitResult]) -> 'HttpAdapter':
130131
"""
131132
Creates a new instance using the specified URI.
132133
@@ -143,21 +144,20 @@ class BaseAdapter(object, metaclass=AdapterMeta):
143144
Adapters make it easy to customize the way an API instance
144145
communicates with a node.
145146
"""
146-
supported_protocols = () # type: Tuple[Text]
147+
supported_protocols: Tuple[str] = ()
147148
"""
148149
Protocols that ``resolve_adapter`` can use to identify this adapter
149150
type.
150151
"""
151152

152-
def __init__(self):
153+
def __init__(self) -> None:
153154
super(BaseAdapter, self).__init__()
154155

155-
self._logger = None # type: Logger
156-
self.local_pow = False # type: boolean
156+
self._logger: Optional[Logger] = None
157+
self.local_pow: bool = False
157158

158159
@abstract_method
159-
def get_uri(self):
160-
# type: () -> Text
160+
def get_uri(self) -> str:
161161
"""
162162
Returns the URI that this adapter will use.
163163
"""
@@ -166,8 +166,7 @@ def get_uri(self):
166166
)
167167

168168
@abstract_method
169-
def send_request(self, payload, **kwargs):
170-
# type: (dict, dict) -> dict
169+
def send_request(self, payload: dict, **kwargs: Any) -> dict:
171170
"""
172171
Sends an API request to the node.
173172
@@ -188,8 +187,7 @@ def send_request(self, payload, **kwargs):
188187
'Not implemented in {cls}.'.format(cls=type(self).__name__),
189188
)
190189

191-
def set_logger(self, logger):
192-
# type: (Logger) -> BaseAdapter
190+
def set_logger(self, logger: Logger) -> 'BaseAdapter':
193191
"""
194192
Attaches a logger instance to the adapter.
195193
The adapter will send information about API requests/responses
@@ -198,16 +196,19 @@ def set_logger(self, logger):
198196
self._logger = logger
199197
return self
200198

201-
def _log(self, level, message, context=None):
202-
# type: (int, Text, Optional[dict]) -> None
199+
def _log(
200+
self,
201+
level: int,
202+
message: str,
203+
context: Optional[dict] = None
204+
) -> None:
203205
"""
204206
Sends a message to the instance's logger, if configured.
205207
"""
206208
if self._logger:
207209
self._logger.log(level, message, extra={'context': context or {}})
208210

209-
def set_local_pow(self, local_pow):
210-
# type: (bool) -> None
211+
def set_local_pow(self, local_pow: bool) -> None:
211212
"""
212213
Sets the local_pow attribute of the adapter. If it is true,
213214
attach_to_tangle command calls external interface to perform
@@ -216,6 +217,7 @@ def set_local_pow(self, local_pow):
216217
"""
217218
self.local_pow = local_pow
218219

220+
219221
class HttpAdapter(BaseAdapter):
220222
"""
221223
Sends standard HTTP(S) requests to the node.
@@ -229,7 +231,7 @@ class HttpAdapter(BaseAdapter):
229231
:param Optional[int] timeout:
230232
Connection timeout in seconds.
231233
232-
:param Optional[Tuple(Text,Text)] authentication:
234+
:param Optional[Tuple(str,str)] authentication:
233235
Credetentials for basic authentication with the node.
234236
235237
:return:
@@ -257,16 +259,20 @@ class HttpAdapter(BaseAdapter):
257259
in the ``headers`` kwarg.
258260
"""
259261

260-
def __init__(self, uri, timeout=None, authentication=None):
261-
# type: (Union[Text, SplitResult], Optional[int]) -> None
262+
def __init__(
263+
self,
264+
uri: Union[str, SplitResult],
265+
timeout: Optional[int] = None,
266+
authentication: Optional[Tuple[str, str]] = None
267+
) -> None:
262268
super(HttpAdapter, self).__init__()
263269

264270
self.client = AsyncClient()
265271
self.timeout = timeout
266272
self.authentication = authentication
267273

268274
if isinstance(uri, str):
269-
uri = urlsplit(uri) # type: SplitResult
275+
uri: SplitResult = urlsplit(uri)
270276

271277
if uri.scheme not in self.supported_protocols:
272278
raise with_context(
@@ -310,19 +316,16 @@ def __init__(self, uri, timeout=None, authentication=None):
310316
self.uri = uri
311317

312318
@property
313-
def node_url(self):
314-
# type: () -> Text
319+
def node_url(self) -> str:
315320
"""
316321
Returns the node URL.
317322
"""
318323
return self.uri.geturl()
319324

320-
def get_uri(self):
321-
# type: () -> Text
325+
def get_uri(self) -> str:
322326
return self.uri.geturl()
323327

324-
async def send_request(self, payload, **kwargs):
325-
# type: (dict, dict) -> dict
328+
async def send_request(self, payload: dict, **kwargs: Any) -> dict:
326329
kwargs.setdefault('headers', {})
327330
for key, value in self.DEFAULT_HEADERS.items():
328331
kwargs['headers'].setdefault(key, value)
@@ -338,8 +341,13 @@ async def send_request(self, payload, **kwargs):
338341

339342
return self._interpret_response(response, payload, {codes['OK']})
340343

341-
async def _send_http_request(self, url, payload, method='post', **kwargs):
342-
# type: (Text, Optional[Text], Text, dict) -> Response
344+
async def _send_http_request(
345+
self,
346+
url: str,
347+
payload: Optional[str],
348+
method: str = 'post',
349+
**kwargs: Any
350+
) -> Response:
343351
"""
344352
Sends the actual HTTP request.
345353
@@ -352,7 +360,7 @@ async def _send_http_request(self, url, payload, method='post', **kwargs):
352360
)
353361

354362
if self.authentication:
355-
kwargs.setdefault('auth', auth.HTTPBasicAuth(*self.authentication))
363+
kwargs.setdefault('auth', BasicAuth(*self.authentication))
356364

357365
self._log(
358366
level=DEBUG,
@@ -394,8 +402,12 @@ async def _send_http_request(self, url, payload, method='post', **kwargs):
394402

395403
return response
396404

397-
def _interpret_response(self, response, payload, expected_status):
398-
# type: (Response, dict, Container[int]) -> dict
405+
def _interpret_response(
406+
self,
407+
response: Response,
408+
payload: dict,
409+
expected_status: Container[int]
410+
) -> dict:
399411
"""
400412
Interprets the HTTP response from the node.
401413
@@ -425,7 +437,7 @@ def _interpret_response(self, response, payload, expected_status):
425437
)
426438

427439
try:
428-
decoded = json.loads(raw_content) # type: dict
440+
decoded: dict = json.loads(raw_content)
429441
# :bc: py2k doesn't have JSONDecodeError
430442
except ValueError:
431443
raise with_context(
@@ -523,17 +535,16 @@ class MockAdapter(BaseAdapter):
523535
def configure(cls, uri):
524536
return cls()
525537

526-
def __init__(self):
538+
def __init__(self) -> None:
527539
super(MockAdapter, self).__init__()
528540

529-
self.responses = {} # type: Dict[Text, deque]
530-
self.requests = [] # type: List[dict]
541+
self.responses: Dict[str, deque] = {}
542+
self.requests: List[dict] = []
531543

532-
def get_uri(self):
544+
def get_uri(self) -> str:
533545
return 'mock://'
534546

535-
def seed_response(self, command, response):
536-
# type: (Text, dict) -> MockAdapter
547+
def seed_response(self, command: str, response: dict) -> 'MockAdapter':
537548
"""
538549
Sets the response that the adapter will return for the specified
539550
command.
@@ -547,7 +558,7 @@ def seed_response(self, command, response):
547558
have a seeded response for a particular command, it will raise a
548559
``BadApiResponse`` exception (simulates a 404 response).
549560
550-
:param Text command:
561+
:param str command:
551562
The name of the command. Note that this is the camelCase version
552563
of the command name (e.g., ``getNodeInfo``, not ``get_node_info``).
553564
@@ -573,11 +584,10 @@ def seed_response(self, command, response):
573584
self.responses[command].append(response)
574585
return self
575586

576-
async def send_request(self, payload, **kwargs):
587+
async def send_request(self, payload: Dict, **kwargs: Any) -> dict:
577588
"""
578589
Mimic asynchronous behavior of `HttpAdapter.send_request`.
579590
"""
580-
# type: (dict, dict) -> dict
581591
# Store a snapshot so that we can inspect the request later.
582592
self.requests.append(dict(payload))
583593

0 commit comments

Comments
 (0)