Skip to content

Commit 75650da

Browse files
committed
refactor: model: Use str for ThreadPool function return values.
This allows for more information to be returned beyond the success/fail from a bool, particularly useful in the case of failure. Return values are changed as follows: * True -> '' * False -> 'Some error response' Note that this flips the truthiness of the return type, leading to addition/removal of negation to retain previous behavior. Tests and typing amended, including addition of a missing 'type:' in a variable type hint.
1 parent d6d61ca commit 75650da

File tree

2 files changed

+32
-29
lines changed

2 files changed

+32
-29
lines changed

tests/model/test_model.py

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ def mock_external_classes(self, mocker: Any) -> None:
2222

2323
@pytest.fixture
2424
def model(self, mocker, initial_data, user_profile):
25-
mocker.patch('zulipterminal.model.Model.get_messages')
25+
mocker.patch('zulipterminal.model.Model.get_messages',
26+
return_value='')
2627
self.client.register.return_value = initial_data
2728
mocker.patch('zulipterminal.model.Model.get_all_users',
2829
return_value=[])
@@ -67,7 +68,8 @@ def test_init(self, model, initial_data, user_profile):
6768
assert model.unread_counts == []
6869

6970
def test_register_initial_desired_events(self, mocker, initial_data):
70-
mocker.patch('zulipterminal.model.Model.get_messages')
71+
mocker.patch('zulipterminal.model.Model.get_messages',
72+
return_value='')
7173
mocker.patch('zulipterminal.model.Model.get_all_users')
7274
mocker.patch('zulipterminal.model.Model.fetch_all_topics')
7375
self.client.register.return_value = initial_data
@@ -252,10 +254,11 @@ def test_get_message_ids_in_current_narrow(self, mocker, model,
252254

253255
@pytest.mark.parametrize("response, expected_index, return_value", [
254256
({'result': 'success', 'topics': [{'name': 'Foo'}, {'name': 'Boo'}]},
255-
{23: ['Foo', 'Boo']}, True),
257+
{23: ['Foo', 'Boo']}, ''),
256258
({'result': 'success', 'topics': []},
257-
{23: []}, True),
258-
({'result': 'failure', 'topics': []}, {23: []}, False)
259+
{23: []}, ''),
260+
({'result': 'failure', 'msg': 'Some Error', 'topics': []},
261+
{23: []}, 'Some Error')
259262
])
260263
def test_get_topics_in_streams(self, mocker, response, model, return_value,
261264
expected_index) -> None:
@@ -533,7 +536,7 @@ def test__update_initial_data(self, model, initial_data):
533536

534537
def test__update_initial_data_raises_exception(self, mocker, initial_data):
535538
# Initialize Model
536-
mocker.patch('zulipterminal.model.Model.get_messages')
539+
mocker.patch('zulipterminal.model.Model.get_messages', return_value='')
537540
mocker.patch('zulipterminal.model.Model.get_all_users',
538541
return_value=[])
539542
mocker.patch('zulipterminal.model.Model.'
@@ -568,7 +571,7 @@ def test__group_info_from_realm_user_groups(self, model,
568571

569572
def test_get_all_users(self, mocker, initial_data, user_list, user_dict,
570573
user_id):
571-
mocker.patch('zulipterminal.model.Model.get_messages')
574+
mocker.patch('zulipterminal.model.Model.get_messages', return_value='')
572575
self.client.register.return_value = initial_data
573576
mocker.patch('zulipterminal.model.Model.'
574577
'_stream_info_from_subscriptions',

zulipterminal/model.py

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,7 @@ def update_stream_message(self, topic: str, msg_id: int,
330330

331331
def get_messages(self, *,
332332
num_after: int, num_before: int,
333-
anchor: Optional[int]) -> bool:
333+
anchor: Optional[int]) -> str:
334334
# anchor value may be specific message (int) or next unread (None)
335335
first_anchor = anchor is None
336336
anchor_value = anchor if anchor is not None else 0
@@ -356,10 +356,10 @@ def get_messages(self, *,
356356
# 'found_newest' flag. Instead, we use this logic:
357357
query_range = num_after + num_before + 1
358358
self.found_newest = len(response['messages']) < query_range
359-
return True
360-
return False
359+
return ""
360+
return response['msg']
361361

362-
def get_topics_in_stream(self, stream_list: Iterable[int]) -> bool:
362+
def get_topics_in_stream(self, stream_list: Iterable[int]) -> str:
363363
"""
364364
Fetch all topics with specified stream_id's and
365365
index their names (Version 1)
@@ -371,15 +371,15 @@ def get_topics_in_stream(self, stream_list: Iterable[int]) -> bool:
371371
self.index['topics'][stream_id] = [topic['name'] for
372372
topic in response['topics']]
373373
else:
374-
return False
375-
return True
374+
return response['msg']
375+
return ""
376376

377377
@staticmethod
378-
def exception_safe_result(future: 'Future[bool]') -> bool:
378+
def exception_safe_result(future: 'Future[str]') -> str:
379379
try:
380380
return future.result()
381-
except zulip.ZulipError:
382-
return False
381+
except zulip.ZulipError as e:
382+
return str(e)
383383

384384
def fetch_all_topics(self, workers: int) -> None:
385385
"""
@@ -392,17 +392,17 @@ def fetch_all_topics(self, workers: int) -> None:
392392
i: executor.submit(self.get_topics_in_stream,
393393
list_of_streams[i::workers])
394394
for i in range(workers)
395-
} # type: Dict[int, Future[bool]]
395+
} # type: Dict[int, Future[str]]
396396
wait(thread_objects.values())
397397

398398
results = {
399399
str(name): self.exception_safe_result(thread_object)
400400
for name, thread_object in thread_objects.items()
401-
} # type: Dict[str, bool]
402-
if not all(results.values()):
401+
} # type: Dict[str, str]
402+
if any(results.values()):
403403
failures = ['fetch_topics[{}]'.format(name)
404404
for name, result in results.items()
405-
if not result]
405+
if result]
406406
raise ServerConnectionFailure(", ".join(failures))
407407

408408
def is_muted_stream(self, stream_id: int) -> bool:
@@ -426,22 +426,22 @@ def _update_initial_data(self) -> None:
426426
anchor=None),
427427
'register': executor.submit(self._register_desired_events,
428428
fetch_data=True),
429-
} # Dict[str, Future[bool]]
429+
} # type: Dict[str, Future[str]]
430430

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

434434
results = {
435435
name: self.exception_safe_result(future)
436436
for name, future in futures.items()
437-
} # type: Dict[str, bool]
438-
if all(results.values()):
437+
} # type: Dict[str, str]
438+
if not any(results.values()):
439439
self.user_id = self.initial_data['user_id']
440440
self.user_email = self.initial_data['email']
441441
self.user_full_name = self.initial_data['full_name']
442442
self.server_name = self.initial_data['realm_name']
443443
else:
444-
failures = [name for name, result in results.items() if not result]
444+
failures = [name for name, result in results.items() if result]
445445
raise ServerConnectionFailure(", ".join(failures))
446446

447447
def get_all_users(self) -> List[Dict[str, Any]]:
@@ -869,7 +869,7 @@ def update_rendered_view(self, msg_id: int) -> None:
869869
self.controller.update_screen()
870870
return
871871

872-
def _register_desired_events(self, *, fetch_data: bool=False) -> bool:
872+
def _register_desired_events(self, *, fetch_data: bool=False) -> str:
873873
fetch_types = None if not fetch_data else [
874874
'realm',
875875
'presence',
@@ -886,17 +886,17 @@ def _register_desired_events(self, *, fetch_data: bool=False) -> bool:
886886
fetch_event_types=fetch_types,
887887
client_gravatar=True,
888888
apply_markdown=True)
889-
except zulip.ZulipError:
890-
return False
889+
except zulip.ZulipError as e:
890+
return str(e)
891891

892892
if response['result'] == 'success':
893893
if fetch_data:
894894
self.initial_data.update(response)
895895
self.max_message_id = response['max_message_id']
896896
self.queue_id = response['queue_id']
897897
self.last_event_id = response['last_event_id']
898-
return True
899-
return False
898+
return ""
899+
return response['msg']
900900

901901
@asynch
902902
def poll_for_events(self) -> None:

0 commit comments

Comments
 (0)