mypy: Add annotations for github_detail.
MODIFY
tools/run-mypy
tools/run-mypy
@@ -40,6 +40,8 @@ force_include = [
"zulip_bots/zulip_bots/bots/followup/test_followup.py",
"zulip_bots/zulip_bots/bots/giphy/giphy.py",
"zulip_bots/zulip_bots/bots/giphy/test_giphy.py",
+ "zulip_bots/zulip_bots/bots/github_detail/github_detail.py",
+ "zulip_bots/zulip_bots/bots/github_detail/test_github_detail.py",
]
parser = argparse.ArgumentParser(description="Run mypy on files tracked by git.")

MODIFY
zulip_bots/zulip_bots/bots/github_detail/github_detail.py
zulip_bots/zulip_bots/bots/github_detail/github_detail.py
@@ -6,6 +6,8 @@ import six.moves.configparser
import requests
+from typing import Dict, Any, Tuple, Union
+
class GithubHandler(object):
'''
This bot provides details on github issues and pull requests when they're
@@ -15,21 +17,19 @@ class GithubHandler(object):
GITHUB_ISSUE_URL_TEMPLATE = 'https://api.github.com/repos/{owner}/{repo}/issues/{id}'
HANDLE_MESSAGE_REGEX = re.compile("(?:([\w-]+)\/)?([\w-]+)?#(\d+)")
- def initialize(self, bot_handler):
+ def initialize(self: Any, bot_handler: Any) -> None:
self.config_info = bot_handler.get_config_info('github_detail', optional=True)
self.owner = self.config_info.get("owner", False)
self.repo = self.config_info.get("repo", False)
- def usage(self):
- # type: () -> None
+ def usage(self: Any) -> str:
return ("This plugin displays details on github issues and pull requests. "
"To reference an issue or pull request usename mention the bot then "
"anytime in the message type its id, for example:\n"
"@**Github detail** #3212 zulip#3212 zulip/zulip#3212\n"
"The default owner is {} and the default repo is {}.".format(self.owner, self.repo))
- def format_message(self, details):
- # type: (Dict[Text, Union[Text, int, bool]]) -> Text
+ def format_message(self: Any, details: Dict[str, Any]) -> str:
number = details['number']
title = details['title']
link = details['html_url']
@@ -46,21 +46,19 @@ class GithubHandler(object):
'Status - **{status}**\n```quote\n{description}\n```'.format(status=status, description=description))
return ''.join(message_string)
- def get_details_from_github(self, owner, repo, number):
- # type: (Text, Text, Text) -> Dict[Text, Union[Text, Int, Bool]]
+ def get_details_from_github(self: Any, owner: str, repo: str, number: str) -> Union[None, Dict[str, Union[str, int, bool]]]:
# Gets the details of an issues or pull request
-
try:
r = requests.get(
self.GITHUB_ISSUE_URL_TEMPLATE.format(owner=owner, repo=repo, id=number))
except requests.exceptions.RequestException as e:
- logging.exception(e)
- return
+ logging.exception(str(e))
+ return None
if r.status_code != requests.codes.ok:
- return
+ return None
return r.json()
- def get_owner_and_repo(self, issue_pr):
+ def get_owner_and_repo(self: Any, issue_pr: Any) -> Tuple[str, str]:
owner = issue_pr.group(1)
repo = issue_pr.group(2)
if owner is None:
@@ -69,8 +67,7 @@ class GithubHandler(object):
repo = self.repo
return (owner, repo)
- def handle_message(self, message, bot_handler):
- # type: () -> None
+ def handle_message(self: Any, message: Dict[str, str], bot_handler: Any) -> None:
# Send help message
if message['content'] == 'help':
bot_handler.send_reply(message, self.usage())

MODIFY
zulip_bots/zulip_bots/bots/github_detail/test_github_detail.py
zulip_bots/zulip_bots/bots/github_detail/test_github_detail.py
@@ -7,18 +7,19 @@ import json
from zulip_bots.test_lib import BotTestCase
+from typing import Any
+
class TestGithubDetailBot(BotTestCase):
bot_name = "github_detail"
mock_config = {'owner': 'zulip', 'repo': 'zulip'}
# Overrides default test_bot_usage().
- def test_bot_usage(self):
- # type: () -> None
+ def test_bot_usage(self: Any) -> None:
with self.mock_config_info(self.mock_config):
self.initialize_bot()
self.assertNotEqual(self.message_handler.usage(), '')
- def test_issue(self):
+ def test_issue(self: Any) -> None:
bot_response = '**[zulip/zulip#5365](https://github.com/zulip/zulip/issues/5365)'\
' - frontend: Enable hot-reloading of CSS in development**\n'\
'Created by **[timabbott](https://github.com/timabbott)**\n'\
@@ -36,7 +37,7 @@ class TestGithubDetailBot(BotTestCase):
expected_method='send_reply'
)
- def test_pull_request(self):
+ def test_pull_request(self: Any) -> None:
bot_response = '**[zulip/zulip#5345](https://github.com/zulip/zulip/pull/5345)'\
' - [WIP] modal: Replace bootstrap modal with custom modal class**\n'\
'Created by **[jackrzhang](https://github.com/jackrzhang)**\n'\
@@ -56,7 +57,7 @@ class TestGithubDetailBot(BotTestCase):
expected_method='send_reply'
)
- def test_404(self):
+ def test_404(self: Any) -> None:
bot_response = 'Failed to find issue/pr: zulip/zulip#0'
# This message calls the `send_reply` function of BotHandlerApi
with self.mock_http_conversation('test_404'):
@@ -66,7 +67,7 @@ class TestGithubDetailBot(BotTestCase):
expected_method='send_reply'
)
- def test_random_text(self):
+ def test_random_text(self: Any) -> None:
bot_response = 'Failed to find any issue or PR.'
# This message calls the `send_reply` function of BotHandlerApi
self.assert_bot_response(
@@ -75,7 +76,7 @@ class TestGithubDetailBot(BotTestCase):
expected_method='send_reply'
)
- def test_help_text(self):
+ def test_help_text(self: Any) -> None:
bot_response = 'This plugin displays details on github issues and pull requests. '\
'To reference an issue or pull request usename mention the bot then '\
'anytime in the message type its id, for example:\n@**Github detail** '\

mypy: Add annotations for github_detail.