Skip to content

Commit e131398

Browse files
chore: add type-hints to imapclient/response_lexer.py
1 parent 0e315b9 commit e131398

File tree

2 files changed

+22
-16
lines changed

2 files changed

+22
-16
lines changed

imapclient/response_lexer.py

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
external callers.
1010
"""
1111

12+
from typing import Iterator, List, Optional, Tuple, TYPE_CHECKING, Union
13+
1214
from .util import assert_imap_protocol
1315

1416
__all__ = ["TokenSource"]
@@ -31,15 +33,17 @@ class TokenSource:
3133
the current IMAP literal.
3234
"""
3335

34-
def __init__(self, text):
36+
def __init__(self, text: List[bytes]):
3537
self.lex = Lexer(text)
3638
self.src = iter(self.lex)
3739

3840
@property
39-
def current_literal(self):
41+
def current_literal(self) -> Optional[bytes]:
42+
if TYPE_CHECKING:
43+
assert self.lex.current_source is not None
4044
return self.lex.current_source.literal
4145

42-
def __iter__(self):
46+
def __iter__(self) -> Iterator[bytes]:
4347
return self.src
4448

4549

@@ -48,11 +52,13 @@ class Lexer:
4852
A lexical analyzer class for IMAP
4953
"""
5054

51-
def __init__(self, text):
55+
def __init__(self, text: List[bytes]):
5256
self.sources = (LiteralHandlingIter(chunk) for chunk in text)
53-
self.current_source = None
57+
self.current_source: Optional[LiteralHandlingIter] = None
5458

55-
def read_until(self, stream_i, end_char, escape=True):
59+
def read_until(
60+
self, stream_i: "PushableIterator", end_char: int, escape: bool = True
61+
) -> bytearray:
5662
token = bytearray()
5763
try:
5864
for nextchar in stream_i:
@@ -71,7 +77,7 @@ def read_until(self, stream_i, end_char, escape=True):
7177
token.append(end_char)
7278
return token
7379

74-
def read_token_stream(self, stream_i):
80+
def read_token_stream(self, stream_i: "PushableIterator") -> Iterator[bytearray]:
7581
whitespace = WHITESPACE
7682
wordchars = NON_SPECIALS
7783
read_until = self.read_until
@@ -110,7 +116,7 @@ def read_token_stream(self, stream_i):
110116
yield token
111117
break
112118

113-
def __iter__(self):
119+
def __iter__(self) -> Iterator[bytes]:
114120
for source in self.sources:
115121
self.current_source = source
116122
for tok in self.read_token_stream(iter(source)):
@@ -129,7 +135,8 @@ def __iter__(self):
129135
# string literal is processed, we peek into this object to grab the
130136
# literal.
131137
class LiteralHandlingIter:
132-
def __init__(self, resp_record):
138+
def __init__(self, resp_record: Union[Tuple[bytes, bytes], bytes]):
139+
self.literal: Optional[bytes]
133140
if isinstance(resp_record, tuple):
134141
# A 'record' with a string which includes a literal marker, and
135142
# the literal itself.
@@ -141,27 +148,27 @@ def __init__(self, resp_record):
141148
self.src_text = resp_record
142149
self.literal = None
143150

144-
def __iter__(self):
151+
def __iter__(self) -> "PushableIterator":
145152
return PushableIterator(self.src_text)
146153

147154

148155
class PushableIterator:
149156
NO_MORE = object()
150157

151-
def __init__(self, it):
158+
def __init__(self, it: bytes):
152159
self.it = iter(it)
153-
self.pushed = []
160+
self.pushed: List[int] = []
154161

155-
def __iter__(self):
162+
def __iter__(self) -> "PushableIterator":
156163
return self
157164

158-
def __next__(self):
165+
def __next__(self) -> int:
159166
if self.pushed:
160167
return self.pushed.pop()
161168
return next(self.it)
162169

163170
# For Python 2 compatibility
164171
next = __next__
165172

166-
def push(self, item):
173+
def push(self, item: int) -> None:
167174
self.pushed.append(item)

pyproject.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@ module = [
5050
"imapclient.config",
5151
"imapclient.imapclient",
5252
"imapclient.interact",
53-
"imapclient.response_lexer",
5453
"imapclient.response_parser",
5554
"imapclient.response_types",
5655
"interact",

0 commit comments

Comments
 (0)