Skip to content

refactor: Move from type comments to inline type annotations. #910

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 7, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions tests/config/test_keys.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ def test_HELP_is_not_allowed_as_tip():


def test_commands_for_random_tips(mocker):
new_key_bindings = {
new_key_bindings: Dict[str, keys.KeyBinding] = {
'ALPHA': {
'keys': {'a'},
'help_text': 'alpha',
Expand All @@ -89,7 +89,7 @@ def test_commands_for_random_tips(mocker):
'help_text': 'delta',
'excluded_from_random_tips': True,
},
} # type: Dict[str, keys.KeyBinding]
}
mocker.patch.dict(keys.KEY_BINDINGS, new_key_bindings, clear=True)
result = keys.commands_for_random_tips()
assert len(result) == 2
Expand Down
8 changes: 4 additions & 4 deletions tests/ui_tools/test_buttons.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,11 +205,11 @@ class TestUserButton:
def test_text_content(self, mocker,
width, count, short_text, caption='caption'):
mocker.patch(STREAMBUTTON + ".mark_muted")
user = {
user: Dict[str, Any] = {
'email': 'some_email', # value unimportant
'user_id': 5, # value unimportant
'full_name': caption,
} # type: Dict[str, Any]
}
user_button = UserButton(user,
controller=mocker.Mock(),
view=mocker.Mock(),
Expand All @@ -234,11 +234,11 @@ def test_activate_called_once_on_keypress(
mocker, enter_key, widget_size,
caption="some user", width=30, email='some_email', user_id=5,
):
user = {
user: Dict[str, Any] = {
'email': email,
'user_id': user_id,
'full_name': caption,
} # type: Dict[str, Any]
}
activate = mocker.patch(BUTTONS + ".UserButton.activate")
user_button = UserButton(user,
controller=mocker.Mock(),
Expand Down
2 changes: 1 addition & 1 deletion zulipterminal/cli/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -411,7 +411,7 @@ def main(options: Optional[List[str]]=None) -> None:
'notify': ['enabled', 'disabled'],
'color-depth': ['1', '16', '256']
}
boolean_settings = dict() # type: Dict[str, bool]
boolean_settings: Dict[str, bool] = dict()
for setting, valid_values in valid_settings.items():
if zterm[setting][0] not in valid_values:
helper_text = ["Valid values are:"] + [
Expand Down
4 changes: 2 additions & 2 deletions zulipterminal/config/keys.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class KeyBinding(TypedDict, total=False):
key_category: str


KEY_BINDINGS = OrderedDict([
KEY_BINDINGS: 'OrderedDict[str, KeyBinding]' = OrderedDict([
# Key that is displayed in the UI is determined by the method
# primary_key_for_command. (Currently the first key in the list)

Expand Down Expand Up @@ -312,7 +312,7 @@ class KeyBinding(TypedDict, total=False):
'help_text': 'Clear compose screen',
'key_category': 'msg_compose',
}),
]) # type: OrderedDict[str, KeyBinding]
])

HELP_CATEGORIES = OrderedDict([
('general', 'General'),
Expand Down
4 changes: 2 additions & 2 deletions zulipterminal/config/themes.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@
'blue': 'zt_blue',
}

THEMES = {
THEMES: Dict[str, ThemeSpec] = {
'zt_dark': [
(None, 'white', 'black',
None, DEF['white'], DEF['black']),
Expand Down Expand Up @@ -367,7 +367,7 @@
('area:msg', 'white', 'brown'),
('area:error', 'white', 'dark red'),
]
} # type: Dict[str, ThemeSpec]
}


def all_themes() -> List[str]:
Expand Down
4 changes: 2 additions & 2 deletions zulipterminal/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ def __init__(self, config_file: str, maximum_footlinks: int,
self.notify_enabled = notify
self.maximum_footlinks = maximum_footlinks

self._editor = None # type: Optional[Any]
self._editor: Optional[Any] = None

self.show_loading()
client_identifier = f"ZulipTerminal/{ZT_VERSION} {platform()}"
Expand All @@ -72,7 +72,7 @@ def __init__(self, config_file: str, maximum_footlinks: int,
self._update_pipe = self.loop.watch_pipe(self._draw_screen)

# data and urwid pipe for inter-thread exception handling
self._exception_info = None # type: Optional[ExceptionInfo]
self._exception_info: Optional[ExceptionInfo] = None
self._critical_exception = False
self._exception_pipe = self.loop.watch_pipe(self._raise_exception)

Expand Down
12 changes: 7 additions & 5 deletions zulipterminal/helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ def set_count(id_list: List[int], controller: Any, new_count: int) -> None:
# (we could ensure this in a different way by a different type)
assert new_count == 1 or new_count == -1
messages = controller.model.index['messages']
unread_counts = controller.model.unread_counts # type: UnreadCounts
unread_counts: UnreadCounts = controller.model.unread_counts
changed_messages = [messages[id] for id in id_list]
_set_count_in_model(new_count, changed_messages, unread_counts)

Expand Down Expand Up @@ -572,10 +572,12 @@ def match_stream(data: List[Tuple[DataT, str]], search_text: str,
for datum, stream_name in data
]

matches = OrderedDict([
('pinned', defaultdict(list)),
('unpinned', defaultdict(list)),
]) # type: OrderedDict[str, DefaultDict[int, List[Tuple[DataT, str]]]]
matches: 'OrderedDict[str, DefaultDict[int, List[Tuple[DataT, str]]]]' = (
OrderedDict([
('pinned', defaultdict(list)),
('unpinned', defaultdict(list)),
])
)

for datum, splits in stream_splits:
stream_name = splits[0]
Expand Down
69 changes: 38 additions & 31 deletions zulipterminal/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,10 +99,10 @@ def __init__(self, controller: Any) -> None:
self.controller = controller
self.client = controller.client

self.narrow = [] # type: List[Any]
self._have_last_message = {} # type: Dict[str, bool]
self.narrow: List[Any] = []
self._have_last_message: Dict[str, bool] = {}
self.stream_id = -1
self.recipients = frozenset() # type: FrozenSet[Any]
self.recipients: FrozenSet[Any] = frozenset()
self.index = initial_index

self.user_id = -1
Expand All @@ -114,16 +114,19 @@ def __init__(self, controller: Any) -> None:

self._notified_user_of_notification_failure = False

self.event_actions = OrderedDict([
('message', self._handle_message_event),
('update_message', self._handle_update_message_event),
('reaction', self._handle_reaction_event),
('subscription', self._handle_subscription_event),
('typing', self._handle_typing_event),
('update_message_flags', self._handle_update_message_flags_event),
]) # type: OrderedDict[str, Callable[[Event], None]]
self.event_actions: 'OrderedDict[str, Callable[[Event], None]]' = (
OrderedDict([
('message', self._handle_message_event),
('update_message', self._handle_update_message_event),
('reaction', self._handle_reaction_event),
('subscription', self._handle_subscription_event),
('typing', self._handle_typing_event),
('update_message_flags',
self._handle_update_message_flags_event),
])
)

self.initial_data = {} # type: Dict[str, Any]
self.initial_data: Dict[str, Any] = {}

# Register to the queue before initializing further so that we don't
# lose any updates while messages are being fetched.
Expand All @@ -146,27 +149,27 @@ def __init__(self, controller: Any) -> None:
# feature level 1, server version 3.0.
muted_topics = self.initial_data['muted_topics']
assert set(map(len, muted_topics)) in (set(), {2}, {3})
self._muted_topics = {
self._muted_topics: Dict[Tuple[str, str], Optional[int]] = {
(stream_name, topic): (None if self.server_feature_level is None
else date_muted[0])
for stream_name, topic, *date_muted in muted_topics
} # type: Dict[Tuple[str, str], Optional[int]]
}

groups = self.initial_data['realm_user_groups']
self.user_group_by_id = {} # type: Dict[int, Dict[str, Any]]
self.user_group_by_id: Dict[int, Dict[str, Any]] = {}
self.user_group_names = self._group_info_from_realm_user_groups(groups)

self.unread_counts = classify_unread_counts(self)

self._draft = None # type: Optional[Message]
self._draft: Optional[Message] = None
unicode_emoji_data = unicode_emojis.EMOJI_DATA
for name, data in unicode_emoji_data.items():
data['type'] = 'unicode_emoji'
typed_unicode_emoji_data = cast(NamedEmojiData, unicode_emoji_data)
custom_emoji_data = self.fetch_custom_emojis()
zulip_extra_emoji = {
zulip_extra_emoji: NamedEmojiData = {
'zulip': {'code': 'zulip', 'type': 'zulip_extra_emoji'}
} # type: NamedEmojiData
}
all_emoji_data = {**typed_unicode_emoji_data,
**custom_emoji_data,
**zulip_extra_emoji}.items()
Expand Down Expand Up @@ -201,7 +204,7 @@ def set_narrow(self, *,
starred: bool=False,
mentioned: bool=False) -> bool:
selected_params = {k for k, v in locals().items() if k != 'self' and v}
valid_narrows = {
valid_narrows: Dict[FrozenSet[str], List[Any]] = {
frozenset(): [],
frozenset(['stream']): [['stream', stream]],
frozenset(['stream', 'topic']): [['stream', stream],
Expand All @@ -210,7 +213,7 @@ def set_narrow(self, *,
frozenset(['pm_with']): [['pm_with', pm_with]],
frozenset(['starred']): [['is', 'starred']],
frozenset(['mentioned']): [['is', 'mentioned']],
} # type: Dict[FrozenSet[str], List[Any]]
}
for narrow_param, narrow in valid_narrows.items():
if narrow_param == selected_params:
new_narrow = narrow
Expand Down Expand Up @@ -458,10 +461,14 @@ def update_stream_message(self, topic: str, message_id: int,

def fetch_custom_emojis(self) -> NamedEmojiData:
response = self.client.get_realm_emoji()
custom_emojis = {emoji['name']: {'code': emoji_code,
'type': 'realm_emoji'}
for emoji_code, emoji in response['emoji'].items()
if not emoji['deactivated']} # type: NamedEmojiData
custom_emojis: NamedEmojiData = {
emoji['name']: {
'code': emoji_code,
'type': 'realm_emoji',
}
for emoji_code, emoji in response['emoji'].items()
if not emoji['deactivated']
}
display_error_if_present(response, self.controller)
return custom_emojis

Expand Down Expand Up @@ -557,29 +564,29 @@ def _update_initial_data(self) -> None:
# Thread Processes to reduce start time.
# NOTE: Exceptions do not work well with threads
with ThreadPoolExecutor(max_workers=1) as executor:
futures = {
futures: Dict[str, Future[str]] = {
'get_messages': executor.submit(self.get_messages,
num_after=10,
num_before=30,
anchor=None),
'register': executor.submit(self._register_desired_events,
fetch_data=True),
} # type: Dict[str, Future[str]]
}

# Wait for threads to complete
wait(futures.values())

results = {
results: Dict[str, str] = {
name: self.exception_safe_result(future)
for name, future in futures.items()
} # type: Dict[str, str]
}
if not any(results.values()):
self.user_id = self.initial_data['user_id']
self.user_email = self.initial_data['email']
self.user_full_name = self.initial_data['full_name']
self.server_name = self.initial_data['realm_name']
else:
failures = defaultdict(list) # type: DefaultDict[str, List[str]]
failures: DefaultDict[str, List[str]] = defaultdict(list)
for name, result in results.items():
if result:
failures[result].append(name)
Expand Down Expand Up @@ -613,8 +620,8 @@ def get_all_users(self) -> List[Dict[str, Any]]:

# Construct a dict of each user in the realm to look up by email
# and a user-id to email mapping
self.user_dict = dict() # type: Dict[str, Dict[str, Any]]
self.user_id_email_dict = dict() # type: Dict[int, str]
self.user_dict: Dict[str, Dict[str, Any]] = dict()
self.user_id_email_dict: Dict[int, str] = dict()
for user in self.initial_data['realm_users']:
if self.user_id == user['user_id']:
current_user = {
Expand Down
5 changes: 2 additions & 3 deletions zulipterminal/ui.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ def __init__(self, controller: Any) -> None:
self.write_box = WriteBox(self)
self.search_box = SearchBox(self.controller)

self.message_view = None # type: Any
self.message_view: Any = None

super().__init__(self.main_window())

Expand Down Expand Up @@ -94,8 +94,7 @@ def set_typeahead_footer(self, suggestions: List[str],
is_truncated: bool) -> None:
if suggestions:
# Wrap by space.
footer_text = [' ' + s + ' '
for s in suggestions] # type: List[Any]
footer_text: List[Any] = [' ' + s + ' ' for s in suggestions]
if state is not None:
footer_text[state] = ('code', footer_text[state])
if is_truncated:
Expand Down
24 changes: 12 additions & 12 deletions zulipterminal/ui_tools/boxes.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,24 +59,24 @@ def __init__(self, view: Any) -> None:
self.view = view

# If editing a message, its id - otherwise None
self.msg_edit_id = None # type: Optional[int]
self.msg_edit_id: Optional[int] = None
# Determines if the message body (content) can be edited
self.msg_body_edit_enabled = True

self.is_in_typeahead_mode = False

# Set to int for stream box only
self.stream_id = None # type: Optional[int]
self.stream_id: Optional[int] = None

# Used in PM and stream boxes
# (empty list implies PM box empty, or not initialized)
# * prioritizes autocomplete in message body
# * updates server on PM typing events
self.recipient_user_ids = [] # type: List[int]
self.recipient_user_ids: List[int] = []

# Private message recipient text entry, None if stream-box
# or not initialized
self.to_write_box = None # type: Optional[ReadlineEdit]
self.to_write_box: Optional[ReadlineEdit] = None

# For tracking sending typing status updates
self.send_next_typing_update = datetime.now()
Expand Down Expand Up @@ -398,7 +398,7 @@ def _process_typeaheads(self, typeaheads: List[str], state: Optional[int],

if (state is not None and state < len(fewer_typeaheads)
and state >= -len(fewer_typeaheads)):
typeahead = fewer_typeaheads[state] # type: Optional[str]
typeahead: Optional[str] = fewer_typeaheads[state]
else:
typeahead = None
state = None
Expand Down Expand Up @@ -643,14 +643,14 @@ def __init__(self, message: Message, model: 'Model',
self.model = model
self.message = message
self.stream_name = ''
self.stream_id = None # type: Union[int, None]
self.stream_id: Union[int, None] = None
self.topic_name = ''
self.email = ''
self.user_id = None # type: Union[int, None]
self.message_links = (
self.user_id: Union[int, None] = None
self.message_links: 'OrderedDict[str, Tuple[str, int, bool]]' = (
OrderedDict()
) # type: OrderedDict[str, Tuple[str, int, bool]]
self.time_mentions = list() # type: List[Tuple[str, str]]
)
self.time_mentions: List[Tuple[str, str]] = list()
self.last_message = last_message
# if this is the first message
if self.last_message is None:
Expand Down Expand Up @@ -890,7 +890,7 @@ def footlinks_view(
def soup2markup(self, soup: Any, **state: Any) -> List[Any]:
# Ensure a string is provided, in case the soup finds none
# This could occur if eg. an image is removed or not shown
markup = [''] # type: List[Union[str, Tuple[Optional[str], Any]]]
markup: List[Union[str, Tuple[Optional[str], Any]]] = ['']
if soup is None: # This is not iterable, so return promptly
return markup
unrendered_tags = { # In pairs of 'tag_name': 'text'
Expand Down Expand Up @@ -1154,7 +1154,7 @@ def main_view(self) -> List[Any]:
if any_differences: # Construct content_header, if needed
TextType = Dict[str, Tuple[Optional[str], str]]
text_keys = ('author', 'star', 'time')
text = {key: (None, ' ') for key in text_keys} # type: TextType
text: TextType = {key: (None, ' ') for key in text_keys}

if any(different[key] for key in ('recipients', 'author', '24h')):
text['author'] = ('name', message['this']['author'])
Expand Down
Loading