From e30b3b094bab9aaf1887760eaf64e0ccdc35baf9 Mon Sep 17 00:00:00 2001 From: Anders Kaseorg Date: Thu, 9 Apr 2020 17:14:01 -0700 Subject: [PATCH] Modernize legacy Python 2 syntax with pyupgrade. Generated by `pyupgrade --py3-plus --keep-percent-format` followed by manual indentation fixes. Signed-off-by: Anders Kaseorg --- tools/custom_check.py | 38 +++++++++---------- tools/deploy | 2 +- .../run-interrealm-bridge | 3 +- .../bridge_with_irc/irc_mirror_backend.py | 2 +- .../codebase/zulip_codebase_config.py | 2 - .../codebase/zulip_codebase_mirror | 7 ++-- zulip/integrations/git/post-receive | 1 - zulip/integrations/git/zulip_git_config.py | 3 +- zulip/integrations/google/google-calendar | 2 +- zulip/integrations/hg/zulip_changegroup.py | 3 +- .../jabber/jabber_mirror_backend.py | 14 +++---- zulip/integrations/log2zulip/log2zulip | 4 +- zulip/integrations/openshift/post_deploy | 1 - .../openshift/zulip_openshift_config.py | 4 +- zulip/integrations/perforce/git_p4.py | 26 ++++++------- .../perforce/zulip_change-commit.py | 1 - .../perforce/zulip_perforce_config.py | 2 - zulip/integrations/rss/rss-bot | 11 +++--- zulip/integrations/svn/post-commit | 3 +- zulip/integrations/svn/zulip_svn_config.py | 4 +- zulip/integrations/trac/zulip_trac.py | 2 - zulip/integrations/trac/zulip_trac_config.py | 2 - zulip/integrations/trello/zulip_trello.py | 5 +-- zulip/integrations/twitter/twitter-bot | 1 - zulip/integrations/zephyr/check-mirroring | 6 +-- zulip/integrations/zephyr/process_ccache | 2 +- .../zephyr/zephyr_mirror_backend.py | 30 +++++++-------- zulip/setup.py | 3 +- zulip/zulip/__init__.py | 14 +++---- zulip/zulip/examples/alert-words | 1 - zulip/zulip/examples/create-user | 1 - zulip/zulip/examples/delete-message | 1 - zulip/zulip/examples/delete-stream | 1 - zulip/zulip/examples/edit-message | 1 - zulip/zulip/examples/edit-stream | 1 - zulip/zulip/examples/get-messages | 1 - zulip/zulip/examples/get-public-streams | 1 - zulip/zulip/examples/get-raw-message | 1 - zulip/zulip/examples/get-stream-topics | 1 - zulip/zulip/examples/get-user-presence | 1 - zulip/zulip/examples/list-members | 1 - zulip/zulip/examples/list-subscriptions | 1 - zulip/zulip/examples/message-history | 1 - zulip/zulip/examples/mute-topic | 1 - zulip/zulip/examples/print-events | 1 - zulip/zulip/examples/print-messages | 1 - zulip/zulip/examples/realm-emoji | 1 - zulip/zulip/examples/send-message | 1 - zulip/zulip/examples/subscribe | 1 - zulip/zulip/examples/unsubscribe | 1 - zulip/zulip/examples/update-message-flags | 1 - zulip/zulip/examples/upload-file | 1 - zulip/zulip/send.py | 1 - zulip_bots/setup.py | 3 +- .../bots/baremetrics/baremetrics.py | 2 +- .../zulip_bots/bots/beeminder/beeminder.py | 2 +- .../zulip_bots/bots/chessbot/chessbot.py | 4 +- .../bots/connect_four/connect_four.py | 4 +- .../bots/connect_four/controller.py | 2 +- .../zulip_bots/bots/converter/converter.py | 2 +- zulip_bots/zulip_bots/bots/define/define.py | 2 +- .../zulip_bots/bots/dialogflow/dialogflow.py | 2 +- .../bots/dropbox_share/dropbox_share.py | 12 +++--- zulip_bots/zulip_bots/bots/encrypt/encrypt.py | 2 +- .../bots/file_uploader/file_uploader.py | 2 +- zulip_bots/zulip_bots/bots/flock/flock.py | 2 +- .../zulip_bots/bots/followup/followup.py | 2 +- zulip_bots/zulip_bots/bots/front/front.py | 2 +- .../bots/game_handler_bot/game_handler_bot.py | 8 ++-- .../bots/game_of_fifteen/game_of_fifteen.py | 8 ++-- zulip_bots/zulip_bots/bots/giphy/giphy.py | 2 +- .../bots/github_detail/github_detail.py | 4 +- .../bots/google_search/google_search.py | 2 +- .../bots/google_translate/google_translate.py | 2 +- .../zulip_bots/bots/helloworld/helloworld.py | 2 +- zulip_bots/zulip_bots/bots/help/help.py | 2 +- .../zulip_bots/bots/idonethis/idonethis.py | 2 +- .../zulip_bots/bots/incident/incident.py | 2 +- .../bots/incrementor/incrementor.py | 2 +- zulip_bots/zulip_bots/bots/jira/jira.py | 16 ++++---- .../bots/link_shortener/link_shortener.py | 10 ++--- zulip_bots/zulip_bots/bots/mention/mention.py | 2 +- .../zulip_bots/bots/merels/libraries/game.py | 2 +- .../bots/merels/libraries/mechanics.py | 8 ++-- zulip_bots/zulip_bots/bots/merels/merels.py | 8 ++-- .../bots/monkeytestit/monkeytestit.py | 2 +- .../zulip_bots/bots/salesforce/salesforce.py | 6 +-- .../bots/stack_overflow/stack_overflow.py | 2 +- zulip_bots/zulip_bots/bots/susi/susi.py | 2 +- .../zulip_bots/bots/tictactoe/tictactoe.py | 8 ++-- zulip_bots/zulip_bots/bots/trello/trello.py | 2 +- .../bots/trivia_quiz/trivia_quiz.py | 2 +- .../zulip_bots/bots/twitpost/twitpost.py | 2 +- .../zulip_bots/bots/virtual_fs/virtual_fs.py | 6 +-- zulip_bots/zulip_bots/bots/weather/weather.py | 2 +- .../zulip_bots/bots/wikipedia/wikipedia.py | 2 +- zulip_bots/zulip_bots/bots/witai/witai.py | 2 +- zulip_bots/zulip_bots/bots/xkcd/xkcd.py | 4 +- zulip_bots/zulip_bots/bots/yoda/yoda.py | 2 +- zulip_bots/zulip_bots/bots/youtube/youtube.py | 2 +- zulip_bots/zulip_bots/game_handler.py | 18 ++++----- zulip_bots/zulip_bots/lib.py | 8 ++-- zulip_bots/zulip_bots/terminal.py | 4 +- zulip_bots/zulip_bots/tests/test_run.py | 2 +- zulip_botserver/setup.py | 3 +- zulip_botserver/tests/test_server.py | 4 +- zulip_botserver/zulip_botserver/server.py | 2 +- 107 files changed, 192 insertions(+), 244 deletions(-) diff --git a/tools/custom_check.py b/tools/custom_check.py index 809ee02..0b36693 100644 --- a/tools/custom_check.py +++ b/tools/custom_check.py @@ -7,7 +7,7 @@ if MYPY: whitespace_rules = [ # This linter should be first since bash_rules depends on it. - {'pattern': '\s+$', + {'pattern': r'\s+$', 'strip': '\n', 'description': 'Fix trailing whitespace'}, {'pattern': '\t', @@ -15,11 +15,11 @@ whitespace_rules = [ 'description': 'Fix tab-based whitespace'}, ] # type: Rule -markdown_whitespace_rules = list([rule for rule in whitespace_rules if rule['pattern'] != '\s+$']) + [ +markdown_whitespace_rules = list([rule for rule in whitespace_rules if rule['pattern'] != r'\s+$']) + [ # Two spaces trailing a line with other content is okay--it's a markdown line break. # This rule finds one space trailing a non-space, three or more trailing spaces, and # spaces on an empty line. - {'pattern': '((?~"]', 'description': 'Missing whitespace after "="'}, - {'pattern': '":\w[^"]*$', + {'pattern': r'":\w[^"]*$', 'description': 'Missing whitespace after ":"'}, - {'pattern': "':\w[^']*$", + {'pattern': r"':\w[^']*$", 'description': 'Missing whitespace after ":"'}, - {'pattern': "^\s+[#]\w", + {'pattern': r"^\s+[#]\w", 'strip': '\n', 'description': 'Missing whitespace after "#"'}, {'pattern': "assertEquals[(]", @@ -67,26 +67,26 @@ python_rules = RuleList( # This next check could have false positives, but it seems pretty # rare; if we find any, they can be added to the exclude list for # this rule. - {'pattern': ' % [a-zA-Z0-9_.]*\)?$', + {'pattern': r' % [a-zA-Z0-9_.]*\)?$', 'description': 'Used % comprehension without a tuple'}, - {'pattern': '.*%s.* % \([a-zA-Z0-9_.]*\)$', + {'pattern': r'.*%s.* % \([a-zA-Z0-9_.]*\)$', 'description': 'Used % comprehension without a tuple'}, {'pattern': '__future__', - 'include_only': set(['zulip_bots/zulip_bots/bots/']), + 'include_only': {'zulip_bots/zulip_bots/bots/'}, 'description': 'Bots no longer need __future__ imports.'}, {'pattern': '#!/usr/bin/env python$', - 'include_only': set(['zulip_bots/']), + 'include_only': {'zulip_bots/'}, 'description': 'Python shebangs must be python3'}, - {'pattern': '(^|\s)open\s*\(', + {'pattern': r'(^|\s)open\s*\(', 'description': 'open() should not be used in Zulip\'s bots. Use functions' ' provided by the bots framework to access the filesystem.', - 'include_only': set(['zulip_bots/zulip_bots/bots/'])}, + 'include_only': {'zulip_bots/zulip_bots/bots/'}}, {'pattern': 'pprint', 'description': 'Used pprint, which is most likely a debugging leftover. For user output, use print().'}, - {'pattern': '\(BotTestCase\)', + {'pattern': r'\(BotTestCase\)', 'bad_lines': ['class TestSomeBot(BotTestCase):'], 'description': 'Bot test cases should directly inherit from BotTestCase *and* DefaultTests.'}, - {'pattern': '\(DefaultTests, BotTestCase\)', + {'pattern': r'\(DefaultTests, BotTestCase\)', 'bad_lines': ['class TestSomeBot(DefaultTests, BotTestCase):'], 'good_lines': ['class TestSomeBot(BotTestCase, DefaultTests):'], 'description': 'Bot test cases should inherit from BotTestCase before DefaultTests.'}, @@ -117,9 +117,9 @@ json_rules = RuleList( ) prose_style_rules = [ - {'pattern': '[^\/\#\-\"]([jJ]avascript)', # exclude usage in hrefs/divs + {'pattern': '[^\\/\\#\\-\"]([jJ]avascript)', # exclude usage in hrefs/divs 'description': "javascript should be spelled JavaScript"}, - {'pattern': '[^\/\-\.\"\'\_\=\>]([gG]ithub)[^\.\-\_\"\<]', # exclude usage in hrefs/divs + {'pattern': '[^\\/\\-\\.\"\'\\_\\=\\>]([gG]ithub)[^\\.\\-\\_\"\\<]', # exclude usage in hrefs/divs 'description': "github should be spelled GitHub"}, {'pattern': '[oO]rganisation', # exclude usage in hrefs/divs 'description': "Organization is spelled with a z"}, @@ -136,7 +136,7 @@ markdown_docs_length_exclude = { markdown_rules = RuleList( langs=['md'], rules=markdown_whitespace_rules + prose_style_rules + [ - {'pattern': '\[(?P[^\]]+)\]\((?P=url)\)', + {'pattern': r'\[(?P[^\]]+)\]\((?P=url)\)', 'description': 'Linkified markdown URLs should use cleaner syntax.'} ], max_length=120, diff --git a/tools/deploy b/tools/deploy index 36625fc..1379b26 100755 --- a/tools/deploy +++ b/tools/deploy @@ -201,7 +201,7 @@ def print_bots(bots: List[Any], pretty_print: bool) -> None: print_bots_pretty(bots) else: for bot in bots: - print('{0}\t{1}\t{2}\t{3}'.format(bot['name'], bot['status'], bot['email'], bot['site'])) + print('{}\t{}\t{}\t{}'.format(bot['name'], bot['status'], bot['email'], bot['site'])) def print_bots_pretty(bots: List[Any]) -> None: if len(bots) == 0: diff --git a/zulip/integrations/bridge_between_zulips/run-interrealm-bridge b/zulip/integrations/bridge_between_zulips/run-interrealm-bridge index f876507..97434bf 100755 --- a/zulip/integrations/bridge_between_zulips/run-interrealm-bridge +++ b/zulip/integrations/bridge_between_zulips/run-interrealm-bridge @@ -1,5 +1,4 @@ #!/usr/bin/env python3 -# -*- coding: utf-8 -*- import sys import os @@ -42,7 +41,7 @@ def create_pipe_event(to_client: zulip.Client, from_bot: Dict[str, Any], "type": "stream", "to": to_bot["stream"], "subject": subject, - "content": "**{0}**: {1}".format(msg["sender_full_name"], msg["content"]), + "content": "**{}**: {}".format(msg["sender_full_name"], msg["content"]), "has_attachment": msg.get("has_attachment", False), "has_image": msg.get("has_image", False), "has_link": msg.get("has_link", False) diff --git a/zulip/integrations/bridge_with_irc/irc_mirror_backend.py b/zulip/integrations/bridge_with_irc/irc_mirror_backend.py index 888f500..f87274c 100644 --- a/zulip/integrations/bridge_with_irc/irc_mirror_backend.py +++ b/zulip/integrations/bridge_with_irc/irc_mirror_backend.py @@ -116,7 +116,7 @@ class IRCBot(irc.bot.SingleServerIRCBot): "to": self.stream, "subject": self.topic, "content": content, - "content": "**{0}**: {1}".format(sender, content), + "content": "**{}**: {}".format(sender, content), })) def on_dccmsg(self, c, e): diff --git a/zulip/integrations/codebase/zulip_codebase_config.py b/zulip/integrations/codebase/zulip_codebase_config.py index 254545c..51d5de5 100644 --- a/zulip/integrations/codebase/zulip_codebase_config.py +++ b/zulip/integrations/codebase/zulip_codebase_config.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - # Change these values to configure authentication for your codebase account # Note that this is the Codebase API Username, found in the Settings page # for your account diff --git a/zulip/integrations/codebase/zulip_codebase_mirror b/zulip/integrations/codebase/zulip_codebase_mirror index 1ae17b1..7aadbd8 100755 --- a/zulip/integrations/codebase/zulip_codebase_mirror +++ b/zulip/integrations/codebase/zulip_codebase_mirror @@ -1,5 +1,4 @@ #!/usr/bin/env python3 -# -*- coding: utf-8 -*- # Zulip mirror of Codebase HQ activity # The "zulip_codebase_mirror" script is run continuously, possibly on a work @@ -256,7 +255,7 @@ def run_mirror(): since = default_since() else: since = datetime.fromtimestamp(float(timestamp), tz=pytz.utc) - except (ValueError, IOError) as e: + except (ValueError, OSError) as e: logging.warn("Could not open resume file: %s" % (str(e))) since = default_since() @@ -289,13 +288,13 @@ def check_permissions(): if config.LOG_FILE: try: open(config.LOG_FILE, "w") - except IOError as e: + except OSError as e: sys.stderr.write("Could not open up log for writing:") sys.stderr.write(str(e)) # check that the resume file can be written (this creates if it doesn't exist) try: open(config.RESUME_FILE, "a+") - except IOError as e: + except OSError as e: sys.stderr.write("Could not open up the file %s for reading and writing" % (config.RESUME_FILE,)) sys.stderr.write(str(e)) diff --git a/zulip/integrations/git/post-receive b/zulip/integrations/git/post-receive index d45a10f..c26d365 100755 --- a/zulip/integrations/git/post-receive +++ b/zulip/integrations/git/post-receive @@ -1,5 +1,4 @@ #!/usr/bin/env python3 -# -*- coding: utf-8 -*- # Zulip notification post-receive hook. # diff --git a/zulip/integrations/git/zulip_git_config.py b/zulip/integrations/git/zulip_git_config.py index 58502a9..2d31266 100644 --- a/zulip/integrations/git/zulip_git_config.py +++ b/zulip/integrations/git/zulip_git_config.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # from typing import Dict, Text, Optional @@ -28,7 +27,7 @@ def commit_notice_destination(repo, branch, commit): # type: (Text, Text, Text) -> Optional[Dict[Text, Text]] if branch in ["master", "test-post-receive"]: return dict(stream = STREAM_NAME, - subject = u"%s" % (branch,)) + subject = "%s" % (branch,)) # Return None for cases where you don't want a notice sent return None diff --git a/zulip/integrations/google/google-calendar b/zulip/integrations/google/google-calendar index 4675ef8..cf6ec3c 100755 --- a/zulip/integrations/google/google-calendar +++ b/zulip/integrations/google/google-calendar @@ -100,7 +100,7 @@ def get_credentials(): return credentials except client.Error: logging.exception('Error while trying to open the `google-credentials.json` file.') - except IOError: + except OSError: logging.error("Run the get-google-credentials script from this directory first.") diff --git a/zulip/integrations/hg/zulip_changegroup.py b/zulip/integrations/hg/zulip_changegroup.py index d671aeb..91845e6 100755 --- a/zulip/integrations/hg/zulip_changegroup.py +++ b/zulip/integrations/hg/zulip_changegroup.py @@ -1,5 +1,4 @@ #!/usr/bin/env python3 -# -*- coding: utf-8 -*- # Zulip hook for Mercurial changeset pushes. # @@ -35,7 +34,7 @@ def format_summary_line(web_url, user, base, tip, branch, node): formatted_commit_count = "{revcount} commit{s}".format( revcount=revcount, s=plural) - return u"**{user}** pushed {commits} to **{branch}** (`{tip}:{node}`):\n\n".format( + return "**{user}** pushed {commits} to **{branch}** (`{tip}:{node}`):\n\n".format( user=user, commits=formatted_commit_count, branch=branch, tip=tip, node=node[:12]) diff --git a/zulip/integrations/jabber/jabber_mirror_backend.py b/zulip/integrations/jabber/jabber_mirror_backend.py index 37df59b..f5d5d50 100755 --- a/zulip/integrations/jabber/jabber_mirror_backend.py +++ b/zulip/integrations/jabber/jabber_mirror_backend.py @@ -161,7 +161,7 @@ class JabberToZulipBot(ClientXMPP): def private(self, msg): # type: (JabberMessage) -> None - if options.mode == 'public' or msg['thread'] == u'\u1FFFE': + if options.mode == 'public' or msg['thread'] == '\u1FFFE': return sender = jid_to_zulip(msg["from"]) recipient = jid_to_zulip(msg["to"]) @@ -178,7 +178,7 @@ class JabberToZulipBot(ClientXMPP): def group(self, msg): # type: (JabberMessage) -> None - if options.mode == 'personal' or msg["thread"] == u'\u1FFFE': + if options.mode == 'personal' or msg["thread"] == '\u1FFFE': return subject = msg["subject"] @@ -212,7 +212,7 @@ class JabberToZulipBot(ClientXMPP): else: return jid -class ZulipToJabberBot(object): +class ZulipToJabberBot: def __init__(self, zulip_client): # type: (Client) -> None self.client = zulip_client @@ -254,7 +254,7 @@ class ZulipToJabberBot(object): mto = jabber_recipient, mbody = msg['content'], mtype = 'groupchat') - outgoing['thread'] = u'\u1FFFE' + outgoing['thread'] = '\u1FFFE' outgoing.send() def private_message(self, msg): @@ -271,7 +271,7 @@ class ZulipToJabberBot(object): mto = jabber_recipient, mbody = msg['content'], mtype = 'chat') - outgoing['thread'] = u'\u1FFFE' + outgoing['thread'] = '\u1FFFE' outgoing.send() def process_subscription(self, event): @@ -415,9 +415,9 @@ option does not affect login credentials.'''.replace("\n", " ")) config = SafeConfigParser() try: - with open(config_file, 'r') as f: + with open(config_file) as f: config.readfp(f, config_file) - except IOError: + except OSError: pass for option in ("jid", "jabber_password", "conference_domain", "mode", "zulip_email_suffix", "jabber_server_address", "jabber_server_port"): diff --git a/zulip/integrations/log2zulip/log2zulip b/zulip/integrations/log2zulip/log2zulip index bd1ca26..e36e740 100755 --- a/zulip/integrations/log2zulip/log2zulip +++ b/zulip/integrations/log2zulip/log2zulip @@ -112,8 +112,8 @@ if __name__ == "__main__": open(lock_path, "w").write("1") zulip_client = zulip.init_from_options(args) try: - log_files = json.loads(open(args.control_path, "r").read()) - except (json.JSONDecodeError, IOError): # type: ignore # error: Cannot determine type of 'IOError' + log_files = json.loads(open(args.control_path).read()) + except (json.JSONDecodeError, OSError): # type: ignore # error: Cannot determine type of 'IOError' print("Could not load control data from %s" % (args.control_path,)) traceback.print_exc() sys.exit(1) diff --git a/zulip/integrations/openshift/post_deploy b/zulip/integrations/openshift/post_deploy index be2f6bd..cbeea7a 100755 --- a/zulip/integrations/openshift/post_deploy +++ b/zulip/integrations/openshift/post_deploy @@ -1,5 +1,4 @@ #!/usr/bin/env python3 -# -*- coding: utf-8 -*- # # Zulip notification post-receive hook. diff --git a/zulip/integrations/openshift/zulip_openshift_config.py b/zulip/integrations/openshift/zulip_openshift_config.py index ec6dae0..0b86321 100755 --- a/zulip/integrations/openshift/zulip_openshift_config.py +++ b/zulip/integrations/openshift/zulip_openshift_config.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - # https://github.com/python/mypy/issues/1141 from typing import Dict, Text, Optional @@ -25,7 +23,7 @@ def deployment_notice_destination(branch): # type: (str) -> Optional[Dict[str, Text]] if branch in ['master', 'test-post-receive']: return dict(stream = 'deployments', - subject = u'%s' % (branch,)) + subject = '%s' % (branch,)) # Return None for cases where you don't want a notice sent return None diff --git a/zulip/integrations/perforce/git_p4.py b/zulip/integrations/perforce/git_p4.py index 7b86cd0..670af2a 100755 --- a/zulip/integrations/perforce/git_p4.py +++ b/zulip/integrations/perforce/git_p4.py @@ -339,7 +339,7 @@ def setP4ExecBit(file, mode): if not isModeExec(mode): p4Type = getP4OpenedType(file) p4Type = re.sub('^([cku]?)x(.*)', '\\1\\2', p4Type) - p4Type = re.sub('(.*?\+.*?)x(.*?)', '\\1\\2', p4Type) + p4Type = re.sub(r'(.*?\+.*?)x(.*?)', '\\1\\2', p4Type) if p4Type[-1] == "+": p4Type = p4Type[0:-1] @@ -349,7 +349,7 @@ def getP4OpenedType(file): # Returns the perforce file type for the given file. result = p4_read_pipe(["opened", wildcard_encode(file)]) - match = re.match(".*\((.+)\)\r?$", result) + match = re.match(".*\\((.+)\\)\r?$", result) if match: return match.group(1) else: @@ -378,7 +378,7 @@ def getGitTags(): def diffTreePattern(): # This is a simple generator for the diff tree regex pattern. This could be # a class variable if this and parseDiffTreeEntry were a part of a class. - pattern = re.compile(':(\d+) (\d+) (\w+) (\w+) ([A-Z])(\d+)?\t(.*?)((\t(.*))|$)') + pattern = re.compile(':(\\d+) (\\d+) (\\w+) (\\w+) ([A-Z])(\\d+)?\t(.*?)((\t(.*))|$)') while True: yield pattern @@ -820,13 +820,13 @@ def wildcard_present(path): m = re.search("[*#@%]", path) return m is not None -class Command(object): +class Command: def __init__(self): self.usage = "usage: %prog [options]" self.needsGit = True self.verbose = False -class P4UserMap(object): +class P4UserMap: def __init__(self): self.userMapFromPerforceServer = False self.myP4UserId = None @@ -883,7 +883,7 @@ class P4UserMap(object): for line in lines: entry = line.strip().split("\t") self.users[entry[0]] = entry[1] - except IOError: + except OSError: self.getUserMapFromPerforceServer() class P4Debug(Command): @@ -1056,7 +1056,7 @@ class P4Submit(Command, P4UserMap): (handle, outFileName) = tempfile.mkstemp(dir='.') try: outFile = os.fdopen(handle, "w+") - inFile = open(file, "r") + inFile = open(file) regexp = re.compile(pattern, re.VERBOSE) for line in inFile.readlines(): line = regexp.sub(r'$\1$', line) @@ -1391,7 +1391,7 @@ class P4Submit(Command, P4UserMap): newdiff += "==== new file ====\n" newdiff += "--- /dev/null\n" newdiff += "+++ %s\n" % newFile - f = open(newFile, "r") + f = open(newFile) for line in f.readlines(): newdiff += "+" + line f.close() @@ -1773,7 +1773,7 @@ class P4Submit(Command, P4UserMap): return True -class View(object): +class View: """Represent a p4 view ("p4 help views"), and map files in a repo according to the view.""" @@ -2377,7 +2377,7 @@ class P4Sync(Command, P4UserMap): # find the corresponding git commit; take the oldest commit changelist = int(change['change']) gitCommit = read_pipe(["git", "rev-list", "--max-count=1", - "--reverse", ":/\[git-p4:.*change = %d\]" % changelist]) + "--reverse", r":/\[git-p4:.*change = %d\]" % changelist]) if len(gitCommit) == 0: print("could not find git commit for changelist %d" % changelist) else: @@ -2657,7 +2657,7 @@ class P4Sync(Command, P4UserMap): self.initialParent) # only needed once, to connect to the previous commit self.initialParent = "" - except IOError: + except OSError: print(self.gitError.read()) sys.exit(1) @@ -2712,7 +2712,7 @@ class P4Sync(Command, P4UserMap): self.updateOptionDict(details) try: self.commit(details, self.extractFilesFromCommit(details), self.branch) - except IOError: + except OSError: print("IO error with git fast-import. Is your git version recent enough?") print(self.gitError.read()) @@ -2878,7 +2878,7 @@ class P4Sync(Command, P4UserMap): if len(self.changesFile) == 0: revision = "#head" - p = re.sub ("\.\.\.$", "", p) + p = re.sub (r"\.\.\.$", "", p) if not p.endswith("/"): p += "/" diff --git a/zulip/integrations/perforce/zulip_change-commit.py b/zulip/integrations/perforce/zulip_change-commit.py index b4f2eb9..eecafc5 100755 --- a/zulip/integrations/perforce/zulip_change-commit.py +++ b/zulip/integrations/perforce/zulip_change-commit.py @@ -1,5 +1,4 @@ #!/usr/bin/env python3 -# -*- coding: utf-8 -*- '''Zulip notification change-commit hook. diff --git a/zulip/integrations/perforce/zulip_perforce_config.py b/zulip/integrations/perforce/zulip_perforce_config.py index ec03774..22884d8 100644 --- a/zulip/integrations/perforce/zulip_perforce_config.py +++ b/zulip/integrations/perforce/zulip_perforce_config.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - from typing import Dict, Optional, Text # Change these values to configure authentication for the plugin diff --git a/zulip/integrations/rss/rss-bot b/zulip/integrations/rss/rss-bot index 69f38c6..3dc1128 100755 --- a/zulip/integrations/rss/rss-bot +++ b/zulip/integrations/rss/rss-bot @@ -1,5 +1,4 @@ #!/usr/bin/env python3 -# -*- coding: utf-8 -*- # # RSS integration for Zulip # @@ -174,9 +173,9 @@ def send_zulip(entry, feed_name): return client.send_message(message) try: - with open(opts.feed_file, "r") as f: + with open(opts.feed_file) as f: feed_urls = [feed.strip() for feed in f.readlines()] # type: List[str] -except IOError: +except OSError: log_error_and_exit("Unable to read feed file at %s." % (opts.feed_file,)) client = zulip.Client(email=opts.zulip_email, api_key=opts.zulip_api_key, @@ -189,9 +188,9 @@ for feed_url in feed_urls: feed_file = os.path.join(opts.data_dir, urllib.parse.urlparse(feed_url).netloc) # Type: str try: - with open(feed_file, "r") as f: - old_feed_hashes = dict((line.strip(), True) for line in f.readlines()) # type: Dict[str, bool] - except IOError: + with open(feed_file) as f: + old_feed_hashes = {line.strip(): True for line in f.readlines()} # type: Dict[str, bool] + except OSError: old_feed_hashes = {} new_hashes = [] # type: List[str] diff --git a/zulip/integrations/svn/post-commit b/zulip/integrations/svn/post-commit index 250a178..23cebe0 100755 --- a/zulip/integrations/svn/post-commit +++ b/zulip/integrations/svn/post-commit @@ -1,5 +1,4 @@ #!/usr/bin/env python3 -# -*- coding: utf-8 -*- # # Zulip notification post-commit hook. # @@ -39,7 +38,7 @@ path, rev = sys.argv[1:] # type: Tuple[Text, Text] path = "file://" + path entry = svn.log(path, revision_end=pysvn.Revision(pysvn.opt_revision_kind.number, rev))[0] # type: Dict[Text, Any] -message = "**{0}** committed revision r{1} to `{2}`.\n\n> {3}".format( +message = "**{}** committed revision r{} to `{}`.\n\n> {}".format( entry['author'], rev, path.split('/')[-1], diff --git a/zulip/integrations/svn/zulip_svn_config.py b/zulip/integrations/svn/zulip_svn_config.py index 658250d..ffd88cf 100644 --- a/zulip/integrations/svn/zulip_svn_config.py +++ b/zulip/integrations/svn/zulip_svn_config.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - from typing import Dict, Optional, Text # Change these values to configure authentication for the plugin @@ -25,7 +23,7 @@ def commit_notice_destination(path, commit): repo = path.split('/')[-1] if repo not in ["evil-master-plan", "my-super-secret-repository"]: return dict(stream = "commits", - subject = u"%s" % (repo,)) + subject = "%s" % (repo,)) # Return None for cases where you don't want a notice sent return None diff --git a/zulip/integrations/trac/zulip_trac.py b/zulip/integrations/trac/zulip_trac.py index 5896d3e..0e2a9cd 100644 --- a/zulip/integrations/trac/zulip_trac.py +++ b/zulip/integrations/trac/zulip_trac.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - # Zulip trac plugin -- sends zulips when tickets change. # # Install by copying this file and zulip_trac_config.py to the trac diff --git a/zulip/integrations/trac/zulip_trac_config.py b/zulip/integrations/trac/zulip_trac_config.py index ce0fcdb..e4ddfda 100644 --- a/zulip/integrations/trac/zulip_trac_config.py +++ b/zulip/integrations/trac/zulip_trac_config.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - # See zulip_trac.py for installation and configuration instructions # Change these constants to configure the plugin: diff --git a/zulip/integrations/trello/zulip_trello.py b/zulip/integrations/trello/zulip_trello.py index 7a04c1b..eb13565 100755 --- a/zulip/integrations/trello/zulip_trello.py +++ b/zulip/integrations/trello/zulip_trello.py @@ -1,5 +1,4 @@ #!/usr/bin/env python3 -# -*- coding: utf-8 -*- # # An easy Trello integration for Zulip. @@ -39,7 +38,7 @@ def get_model_id(options): params=params ) - if trello_response.status_code is not 200: + if trello_response.status_code != 200: print('Error: Can\'t get the idModel. Please check the configuration') sys.exit(1) @@ -77,7 +76,7 @@ def get_webhook_id(options, id_model): data=data ) - if trello_response.status_code is not 200: + if trello_response.status_code != 200: print('Error: Can\'t create the Webhook:', trello_response.text) sys.exit(1) diff --git a/zulip/integrations/twitter/twitter-bot b/zulip/integrations/twitter/twitter-bot index db34a67..eb04ec5 100755 --- a/zulip/integrations/twitter/twitter-bot +++ b/zulip/integrations/twitter/twitter-bot @@ -1,5 +1,4 @@ #!/usr/bin/env python3 -# -*- coding: utf-8 -*- # Twitter integration for Zulip diff --git a/zulip/integrations/zephyr/check-mirroring b/zulip/integrations/zephyr/check-mirroring index 615cba9..ced6720 100755 --- a/zulip/integrations/zephyr/check-mirroring +++ b/zulip/integrations/zephyr/check-mirroring @@ -155,7 +155,7 @@ for tries in range(10): if missing == 0: actually_subscribed = True break - except IOError as e: + except OSError as e: if "SERVNAK received" in e: # type: ignore # https://github.com/python/mypy/issues/2118 logger.error("SERVNAK repeatedly received, punting rest of test") else: @@ -283,8 +283,8 @@ def process_keys(content_list): key_counts[key] = 0 for key in content_keys: key_counts[key] += 1 - z_missing = set(key for key in zhkeys.keys() if key_counts[key] == 0) - h_missing = set(key for key in hzkeys.keys() if key_counts[key] == 0) + z_missing = {key for key in zhkeys.keys() if key_counts[key] == 0} + h_missing = {key for key in hzkeys.keys() if key_counts[key] == 0} duplicates = any(val > 1 for val in key_counts.values()) success = all(val == 1 for val in key_counts.values()) return key_counts, z_missing, h_missing, duplicates, success diff --git a/zulip/integrations/zephyr/process_ccache b/zulip/integrations/zephyr/process_ccache index 3983f02..260df19 100755 --- a/zulip/integrations/zephyr/process_ccache +++ b/zulip/integrations/zephyr/process_ccache @@ -26,7 +26,7 @@ session_path = "/home/zulip/zephyr_sessions/%s" % (program_name,) # Preserve mail zephyrs forwarding setting across rewriting the config file try: - if "--forward-mail-zephyrs" in open(supervisor_path, "r").read(): + if "--forward-mail-zephyrs" in open(supervisor_path).read(): template_data = template_data.replace("--use-sessions", "--use-sessions --forward-mail-zephyrs") except Exception: pass diff --git a/zulip/integrations/zephyr/zephyr_mirror_backend.py b/zulip/integrations/zephyr/zephyr_mirror_backend.py index 2b2cac2..b25598e 100755 --- a/zulip/integrations/zephyr/zephyr_mirror_backend.py +++ b/zulip/integrations/zephyr/zephyr_mirror_backend.py @@ -20,7 +20,7 @@ import select DEFAULT_SITE = "https://api.zulip.com" -class States(object): +class States: Startup, ZulipToZephyr, ZephyrToZulip, ChildSending = list(range(4)) CURRENT_STATE = States.Startup @@ -142,7 +142,7 @@ def zephyr_bulk_subscribe(subs): # type: (List[Tuple[str, str, str]]) -> None try: zephyr._z.subAll(subs) - except IOError: + except OSError: # Since we haven't added the subscription to # current_zephyr_subs yet, we can just return (so that we'll # continue processing normal messages) and we'll end up @@ -153,7 +153,7 @@ def zephyr_bulk_subscribe(subs): return try: actual_zephyr_subs = [cls for (cls, _, _) in zephyr._z.getSubscriptions()] - except IOError: + except OSError: logger.exception("Error getting current Zephyr subscriptions") # Don't add anything to current_zephyr_subs so that we'll # retry the next time we check for streams to subscribe to @@ -169,7 +169,7 @@ def zephyr_bulk_subscribe(subs): # missing 15 seconds of messages on the affected # classes zephyr._z.sub(cls, instance, recipient) - except IOError: + except OSError: pass else: current_zephyr_subs.add(cls) @@ -177,7 +177,7 @@ def zephyr_bulk_subscribe(subs): def update_subscriptions(): # type: () -> None try: - f = open(options.stream_file_path, "r") + f = open(options.stream_file_path) public_streams = json.loads(f.read()) f.close() except Exception: @@ -217,7 +217,7 @@ def maybe_restart_mirroring_script(): maybe_kill_child() try: zephyr._z.cancelSubs() - except IOError: + except OSError: # We don't care whether we failed to cancel subs properly, but we should log it logger.exception("") while True: @@ -288,14 +288,14 @@ def parse_crypt_table(zephyr_class, instance): # type: (Text, str) -> Optional[str] try: crypt_table = open(os.path.join(os.environ["HOME"], ".crypt-table")) - except IOError: + except OSError: return None for line in crypt_table.readlines(): if line.strip() == "": # Ignore blank lines continue - match = re.match("^crypt-(?P\S+):\s+((?P(AES|DES)):\s+)?(?P\S+)$", line) + match = re.match(r"^crypt-(?P\S+):\s+((?P(AES|DES)):\s+)?(?P\S+)$", line) if match is None: # Malformed crypt_table line logger.debug("Invalid crypt_table line!") @@ -464,7 +464,7 @@ def zephyr_init_autoretry(): zephyr.init() backoff.succeed() return - except IOError: + except OSError: logger.exception("Error initializing Zephyr library (retrying). Traceback:") backoff.fail() @@ -475,12 +475,12 @@ def zephyr_load_session_autoretry(session_path): backoff = zulip.RandomExponentialBackoff() while backoff.keep_going(): try: - session = open(session_path, "r").read() + session = open(session_path).read() zephyr._z.initialize() zephyr._z.load_session(session) zephyr.__inited = True return - except IOError: + except OSError: logger.exception("Error loading saved Zephyr session (retrying). Traceback:") backoff.fail() @@ -494,7 +494,7 @@ def zephyr_subscribe_autoretry(sub): zephyr.Subscriptions().add(sub) backoff.succeed() return - except IOError: + except OSError: # Probably a SERVNAK from the zephyr server, but log the # traceback just in case it's something else logger.exception("Error subscribing to personals (retrying). Traceback:") @@ -522,7 +522,7 @@ def zephyr_to_zulip(options): open(options.session_path, "w").write(zephyr._z.dump_session()) if options.logs_to_resend is not None: - with open(options.logs_to_resend, 'r') as log: + with open(options.logs_to_resend) as log: for ln in log: try: zeph = json.loads(ln) @@ -884,7 +884,7 @@ def parse_zephyr_subs(verbose=False): logger.error("Couldn't find ~/.zephyr.subs!") return zephyr_subscriptions - for line in open(subs_file, "r").readlines(): + for line in open(subs_file).readlines(): line = line.strip() if len(line) == 0: continue @@ -1039,7 +1039,7 @@ def die_gracefully(signal, frame): try: # zephyr=>zulip processes may have added subs, so run cancelSubs zephyr._z.cancelSubs() - except IOError: + except OSError: # We don't care whether we failed to cancel subs properly, but we should log it logger.exception("") diff --git a/zulip/setup.py b/zulip/setup.py index d97e7f8..7d7e2e6 100755 --- a/zulip/setup.py +++ b/zulip/setup.py @@ -1,5 +1,4 @@ #!/usr/bin/env python3 -# -*- coding: utf-8 -*- if False: from typing import Any, Dict, Generator, List, Tuple @@ -9,7 +8,7 @@ import sys import itertools -with open("README.md", "r") as fh: +with open("README.md") as fh: long_description = fh.read() def version(): diff --git a/zulip/zulip/__init__.py b/zulip/zulip/__init__.py index 551f3b5..c646104 100644 --- a/zulip/zulip/__init__.py +++ b/zulip/zulip/__init__.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - import json import requests import time @@ -34,7 +32,7 @@ requests_json_is_function = callable(requests.Response.json) API_VERSTRING = "v1/" -class CountingBackoff(object): +class CountingBackoff: def __init__(self, maximum_retries=10, timeout_success_equivalent=None, delay_cap=90.0): # type: (int, Optional[float], float) -> None self.number_of_retries = 0 @@ -70,7 +68,7 @@ class CountingBackoff(object): class RandomExponentialBackoff(CountingBackoff): def fail(self): # type: () -> None - super(RandomExponentialBackoff, self).fail() + super().fail() # Exponential growth with ratio sqrt(2); compute random delay # between x and 2x where x is growing exponentially delay_scale = int(2 ** (self.number_of_retries / 2.0 - 1)) + 1 @@ -278,7 +276,7 @@ class MissingURLError(ZulipError): class UnrecoverableNetworkError(ZulipError): pass -class Client(object): +class Client: def __init__(self, email=None, api_key=None, config_file=None, verbose=False, retry_on_errors=True, site=None, client=None, @@ -324,7 +322,7 @@ class Client(object): if config_file is not None and os.path.exists(config_file): config = SafeConfigParser() - with open(config_file, 'r') as f: + with open(config_file) as f: config.readfp(f, config_file) if api_key is None: api_key = config.get("api", "key") @@ -438,7 +436,7 @@ class Client(object): try: vendor = platform.system() vendor_version = platform.release() - except IOError: + except OSError: # If the calling process is handling SIGCHLD, platform.system() can # fail with an IOError. See http://bugs.python.org/issue9127 pass @@ -1475,7 +1473,7 @@ class Client(object): request=request ) -class ZulipStream(object): +class ZulipStream: """ A Zulip stream-like object """ diff --git a/zulip/zulip/examples/alert-words b/zulip/zulip/examples/alert-words index ee09c50..03278e8 100755 --- a/zulip/zulip/examples/alert-words +++ b/zulip/zulip/examples/alert-words @@ -1,5 +1,4 @@ #!/usr/bin/env python3 -# -*- coding: utf-8 -*- import argparse diff --git a/zulip/zulip/examples/create-user b/zulip/zulip/examples/create-user index 1f2dc55..1ac6b9c 100755 --- a/zulip/zulip/examples/create-user +++ b/zulip/zulip/examples/create-user @@ -1,5 +1,4 @@ #!/usr/bin/env python3 -# -*- coding: utf-8 -*- import argparse diff --git a/zulip/zulip/examples/delete-message b/zulip/zulip/examples/delete-message index 6dc1146..b657f06 100755 --- a/zulip/zulip/examples/delete-message +++ b/zulip/zulip/examples/delete-message @@ -1,5 +1,4 @@ #!/usr/bin/env python3 -# -*- coding: utf-8 -*- import argparse diff --git a/zulip/zulip/examples/delete-stream b/zulip/zulip/examples/delete-stream index b5ed99b..ca0eb7d 100755 --- a/zulip/zulip/examples/delete-stream +++ b/zulip/zulip/examples/delete-stream @@ -1,5 +1,4 @@ #!/usr/bin/env python3 -# -*- coding: utf-8 -*- import argparse diff --git a/zulip/zulip/examples/edit-message b/zulip/zulip/examples/edit-message index 2b63c4b..b1a8c53 100755 --- a/zulip/zulip/examples/edit-message +++ b/zulip/zulip/examples/edit-message @@ -1,5 +1,4 @@ #!/usr/bin/env python3 -# -*- coding: utf-8 -*- import argparse diff --git a/zulip/zulip/examples/edit-stream b/zulip/zulip/examples/edit-stream index 7baff49..06a7be7 100755 --- a/zulip/zulip/examples/edit-stream +++ b/zulip/zulip/examples/edit-stream @@ -1,5 +1,4 @@ #!/usr/bin/env python3 -# -*- coding: utf-8 -*- import argparse diff --git a/zulip/zulip/examples/get-messages b/zulip/zulip/examples/get-messages index cc55c6a..0bd944e 100755 --- a/zulip/zulip/examples/get-messages +++ b/zulip/zulip/examples/get-messages @@ -1,5 +1,4 @@ #!/usr/bin/env python3 -# -*- coding: utf-8 -*- import argparse diff --git a/zulip/zulip/examples/get-public-streams b/zulip/zulip/examples/get-public-streams index 5968981..4da2d9d 100755 --- a/zulip/zulip/examples/get-public-streams +++ b/zulip/zulip/examples/get-public-streams @@ -1,5 +1,4 @@ #!/usr/bin/env python3 -# -*- coding: utf-8 -*- import argparse diff --git a/zulip/zulip/examples/get-raw-message b/zulip/zulip/examples/get-raw-message index b2c89f0..7302679 100755 --- a/zulip/zulip/examples/get-raw-message +++ b/zulip/zulip/examples/get-raw-message @@ -1,5 +1,4 @@ #!/usr/bin/env python3 -# -*- coding: utf-8 -*- import argparse diff --git a/zulip/zulip/examples/get-stream-topics b/zulip/zulip/examples/get-stream-topics index a80d187..2d29b5d 100755 --- a/zulip/zulip/examples/get-stream-topics +++ b/zulip/zulip/examples/get-stream-topics @@ -1,5 +1,4 @@ #!/usr/bin/env python3 -# -*- coding: utf-8 -*- import argparse diff --git a/zulip/zulip/examples/get-user-presence b/zulip/zulip/examples/get-user-presence index 5e7c940..4e70350 100755 --- a/zulip/zulip/examples/get-user-presence +++ b/zulip/zulip/examples/get-user-presence @@ -1,5 +1,4 @@ #!/usr/bin/env python3 -# -*- coding: utf-8 -*- import argparse diff --git a/zulip/zulip/examples/list-members b/zulip/zulip/examples/list-members index 2c682ff..934b59a 100755 --- a/zulip/zulip/examples/list-members +++ b/zulip/zulip/examples/list-members @@ -1,5 +1,4 @@ #!/usr/bin/env python3 -# -*- coding: utf-8 -*- import argparse diff --git a/zulip/zulip/examples/list-subscriptions b/zulip/zulip/examples/list-subscriptions index cf00432..a32d2b8 100755 --- a/zulip/zulip/examples/list-subscriptions +++ b/zulip/zulip/examples/list-subscriptions @@ -1,5 +1,4 @@ #!/usr/bin/env python3 -# -*- coding: utf-8 -*- import argparse diff --git a/zulip/zulip/examples/message-history b/zulip/zulip/examples/message-history index d8a72f8..ba2aea7 100755 --- a/zulip/zulip/examples/message-history +++ b/zulip/zulip/examples/message-history @@ -1,5 +1,4 @@ #!/usr/bin/env python3 -# -*- coding: utf-8 -*- import argparse diff --git a/zulip/zulip/examples/mute-topic b/zulip/zulip/examples/mute-topic index 74be46d..a105147 100755 --- a/zulip/zulip/examples/mute-topic +++ b/zulip/zulip/examples/mute-topic @@ -1,5 +1,4 @@ #!/usr/bin/env python3 -# -*- coding: utf-8 -*- import argparse diff --git a/zulip/zulip/examples/print-events b/zulip/zulip/examples/print-events index 5f698ed..70c80c4 100755 --- a/zulip/zulip/examples/print-events +++ b/zulip/zulip/examples/print-events @@ -1,5 +1,4 @@ #!/usr/bin/env python3 -# -*- coding: utf-8 -*- import argparse diff --git a/zulip/zulip/examples/print-messages b/zulip/zulip/examples/print-messages index 21adb28..e17891b 100755 --- a/zulip/zulip/examples/print-messages +++ b/zulip/zulip/examples/print-messages @@ -1,5 +1,4 @@ #!/usr/bin/env python3 -# -*- coding: utf-8 -*- import argparse diff --git a/zulip/zulip/examples/realm-emoji b/zulip/zulip/examples/realm-emoji index 787920b..fa139e9 100755 --- a/zulip/zulip/examples/realm-emoji +++ b/zulip/zulip/examples/realm-emoji @@ -1,5 +1,4 @@ #!/usr/bin/env python3 -# -*- coding: utf-8 -*- import argparse diff --git a/zulip/zulip/examples/send-message b/zulip/zulip/examples/send-message index 2cfb592..4a29830 100755 --- a/zulip/zulip/examples/send-message +++ b/zulip/zulip/examples/send-message @@ -1,5 +1,4 @@ #!/usr/bin/env python3 -# -*- coding: utf-8 -*- import argparse diff --git a/zulip/zulip/examples/subscribe b/zulip/zulip/examples/subscribe index 503b88b..5ba956c 100755 --- a/zulip/zulip/examples/subscribe +++ b/zulip/zulip/examples/subscribe @@ -1,5 +1,4 @@ #!/usr/bin/env python3 -# -*- coding: utf-8 -*- import sys import argparse diff --git a/zulip/zulip/examples/unsubscribe b/zulip/zulip/examples/unsubscribe index f728c99..976dc5a 100755 --- a/zulip/zulip/examples/unsubscribe +++ b/zulip/zulip/examples/unsubscribe @@ -1,5 +1,4 @@ #!/usr/bin/env python3 -# -*- coding: utf-8 -*- import sys import argparse diff --git a/zulip/zulip/examples/update-message-flags b/zulip/zulip/examples/update-message-flags index 7d962e6..d134f62 100755 --- a/zulip/zulip/examples/update-message-flags +++ b/zulip/zulip/examples/update-message-flags @@ -1,5 +1,4 @@ #!/usr/bin/env python3 -# -*- coding: utf-8 -*- import argparse diff --git a/zulip/zulip/examples/upload-file b/zulip/zulip/examples/upload-file index 26dc9d8..f432a75 100755 --- a/zulip/zulip/examples/upload-file +++ b/zulip/zulip/examples/upload-file @@ -1,5 +1,4 @@ #!/usr/bin/env python3 -# -*- coding: utf-8 -*- import argparse diff --git a/zulip/zulip/send.py b/zulip/zulip/send.py index 5e9262c..c8562d4 100755 --- a/zulip/zulip/send.py +++ b/zulip/zulip/send.py @@ -1,5 +1,4 @@ #!/usr/bin/env python3 -# -*- coding: utf-8 -*- # zulip-send -- Sends a message to the specified recipients. import sys diff --git a/zulip_bots/setup.py b/zulip_bots/setup.py index 7dc2ffc..a5e0742 100755 --- a/zulip_bots/setup.py +++ b/zulip_bots/setup.py @@ -1,5 +1,4 @@ #!/usr/bin/env python3 -# -*- coding: utf-8 -*- import os import sys @@ -23,7 +22,7 @@ if not IS_PYPA_PACKAGE: package_data[''].append('fixtures/*.json') package_data[''].append('logo.*') -with open("README.md", "r") as fh: +with open("README.md") as fh: long_description = fh.read() # We should be installable with either setuptools or distutils. diff --git a/zulip_bots/zulip_bots/bots/baremetrics/baremetrics.py b/zulip_bots/zulip_bots/bots/baremetrics/baremetrics.py index 780471d..45bef60 100644 --- a/zulip_bots/zulip_bots/bots/baremetrics/baremetrics.py +++ b/zulip_bots/zulip_bots/bots/baremetrics/baremetrics.py @@ -3,7 +3,7 @@ from typing import Any, List, Dict import requests -class BaremetricsHandler(object): +class BaremetricsHandler: def initialize(self, bot_handler: Any) -> None: self.config_info = bot_handler.get_config_info('baremetrics') self.api_key = self.config_info['api_key'] diff --git a/zulip_bots/zulip_bots/bots/beeminder/beeminder.py b/zulip_bots/zulip_bots/bots/beeminder/beeminder.py index 9268e6c..98948c5 100644 --- a/zulip_bots/zulip_bots/bots/beeminder/beeminder.py +++ b/zulip_bots/zulip_bots/bots/beeminder/beeminder.py @@ -74,7 +74,7 @@ at syntax by: @mention-botname help" right now.\nPlease try again later" -class BeeminderHandler(object): +class BeeminderHandler: ''' This plugin allows users to easily add datapoints towards their beeminder goals via zulip diff --git a/zulip_bots/zulip_bots/bots/chessbot/chessbot.py b/zulip_bots/zulip_bots/bots/chessbot/chessbot.py index 2e651d8..f3e3376 100644 --- a/zulip_bots/zulip_bots/bots/chessbot/chessbot.py +++ b/zulip_bots/zulip_bots/bots/chessbot/chessbot.py @@ -11,7 +11,7 @@ START_COMPUTER_REGEX = re.compile( MOVE_REGEX = re.compile('do (?P.+)$') RESIGN_REGEX = re.compile('resign$') -class ChessHandler(object): +class ChessHandler: def usage(self) -> str: return ( 'Chess Bot is a bot that allows you to play chess against either ' @@ -742,4 +742,4 @@ def trim_whitespace_before_newline(str_to_trim: str) -> str: Returns: The trimmed string. """ - return re.sub('\s+$', '', str_to_trim, flags=re.M) + return re.sub(r'\s+$', '', str_to_trim, flags=re.M) diff --git a/zulip_bots/zulip_bots/bots/connect_four/connect_four.py b/zulip_bots/zulip_bots/bots/connect_four/connect_four.py index 350b8ea..8bd983f 100644 --- a/zulip_bots/zulip_bots/bots/connect_four/connect_four.py +++ b/zulip_bots/zulip_bots/bots/connect_four/connect_four.py @@ -3,7 +3,7 @@ from zulip_bots.bots.connect_four.controller import ConnectFourModel from typing import Any -class ConnectFourMessageHandler(object): +class ConnectFourMessageHandler: tokens = [':blue_circle:', ':red_circle:'] def parse_board(self, board: Any) -> str: @@ -52,7 +52,7 @@ class ConnectFourBotHandler(GameAdapter): gameMessageHandler = ConnectFourMessageHandler rules = '''Try to get four pieces in row, Diagonals count too!''' - super(ConnectFourBotHandler, self).__init__( + super().__init__( game_name, bot_name, move_help_message, diff --git a/zulip_bots/zulip_bots/bots/connect_four/controller.py b/zulip_bots/zulip_bots/bots/connect_four/controller.py index a6f371c..0c4ef98 100644 --- a/zulip_bots/zulip_bots/bots/connect_four/controller.py +++ b/zulip_bots/zulip_bots/bots/connect_four/controller.py @@ -4,7 +4,7 @@ from functools import reduce from zulip_bots.game_handler import BadMoveException -class ConnectFourModel(object): +class ConnectFourModel: ''' Object that manages running the Connect Four logic for the Connect Four Bot diff --git a/zulip_bots/zulip_bots/bots/converter/converter.py b/zulip_bots/zulip_bots/bots/converter/converter.py index 68be264..88a05b7 100644 --- a/zulip_bots/zulip_bots/bots/converter/converter.py +++ b/zulip_bots/zulip_bots/bots/converter/converter.py @@ -25,7 +25,7 @@ def is_float(value: Any) -> bool: def round_to(x: float, digits: int) -> float: return round(x, digits-int(floor(log10(abs(x))))) -class ConverterHandler(object): +class ConverterHandler: ''' This plugin allows users to make conversions between various units, e.g. Celsius to Fahrenheit, or kilobytes to gigabytes. diff --git a/zulip_bots/zulip_bots/bots/define/define.py b/zulip_bots/zulip_bots/bots/define/define.py index aa171c7..aa2314c 100644 --- a/zulip_bots/zulip_bots/bots/define/define.py +++ b/zulip_bots/zulip_bots/bots/define/define.py @@ -7,7 +7,7 @@ import string from typing import Any, Dict -class DefineHandler(object): +class DefineHandler: ''' This plugin define a word that the user inputs. It looks for messages starting with '@mention-bot'. diff --git a/zulip_bots/zulip_bots/bots/dialogflow/dialogflow.py b/zulip_bots/zulip_bots/bots/dialogflow/dialogflow.py index b9acaf2..6c3144a 100644 --- a/zulip_bots/zulip_bots/bots/dialogflow/dialogflow.py +++ b/zulip_bots/zulip_bots/bots/dialogflow/dialogflow.py @@ -35,7 +35,7 @@ def get_bot_result(message_content: str, config: Dict[str, str], sender_id: str) logging.exception(str(e)) return 'Error. {}.'.format(str(e)) -class DialogFlowHandler(object): +class DialogFlowHandler: ''' This plugin allows users to easily add their own DialogFlow bots to zulip diff --git a/zulip_bots/zulip_bots/bots/dropbox_share/dropbox_share.py b/zulip_bots/zulip_bots/bots/dropbox_share/dropbox_share.py index 214481a..f80bf9f 100644 --- a/zulip_bots/zulip_bots/bots/dropbox_share/dropbox_share.py +++ b/zulip_bots/zulip_bots/bots/dropbox_share/dropbox_share.py @@ -4,7 +4,7 @@ import re URL = "[{name}](https://www.dropbox.com/home{path})" -class DropboxHandler(object): +class DropboxHandler: ''' This bot allows you to easily share, search and upload files between zulip and your dropbox account. @@ -60,11 +60,11 @@ def get_usage_examples() -> str: REGEXES = dict( command='(ls|mkdir|read|rm|write|search|usage|help)', - path='(\S+)', - optional_path='(\S*)', + path=r'(\S+)', + optional_path=r'(\S*)', some_text='(.+?)', - folder='?(?:--fd (\S+))?', - max_results='?(?:--mr (\d+))?' + folder=r'?(?:--fd (\S+))?', + max_results=r'?(?:--mr (\d+))?' ) def get_commands() -> Dict[str, Tuple[Any, List[str]]]: @@ -137,7 +137,7 @@ def dbx_ls(client: Any, fn: str) -> str: files_list += [" - " + URL.format(name=meta.name, path=meta.path_lower)] msg = '\n'.join(files_list) - if msg is '': + if msg == '': msg = '`No files available`' except Exception: diff --git a/zulip_bots/zulip_bots/bots/encrypt/encrypt.py b/zulip_bots/zulip_bots/bots/encrypt/encrypt.py index 7a5c1d2..ac9e200 100755 --- a/zulip_bots/zulip_bots/bots/encrypt/encrypt.py +++ b/zulip_bots/zulip_bots/bots/encrypt/encrypt.py @@ -17,7 +17,7 @@ def encrypt(text: str) -> str: return newtext -class EncryptHandler(object): +class EncryptHandler: ''' This bot allows users to quickly encrypt messages using ROT13 encryption. It encrypts/decrypts messages starting with @mention-bot. diff --git a/zulip_bots/zulip_bots/bots/file_uploader/file_uploader.py b/zulip_bots/zulip_bots/bots/file_uploader/file_uploader.py index febfcfc..1efadff 100644 --- a/zulip_bots/zulip_bots/bots/file_uploader/file_uploader.py +++ b/zulip_bots/zulip_bots/bots/file_uploader/file_uploader.py @@ -3,7 +3,7 @@ from typing import Any, Dict import os from pathlib import Path -class FileUploaderHandler(object): +class FileUploaderHandler: def usage(self) -> str: return ( 'This interactive bot is used to upload files (such as images) to the Zulip server:' diff --git a/zulip_bots/zulip_bots/bots/flock/flock.py b/zulip_bots/zulip_bots/bots/flock/flock.py index d6eb660..c8f8f2b 100644 --- a/zulip_bots/zulip_bots/bots/flock/flock.py +++ b/zulip_bots/zulip_bots/bots/flock/flock.py @@ -86,7 +86,7 @@ def get_flock_bot_response(content: str, config: Dict[str, str]) -> None: result = get_flock_response(content, config) return result -class FlockHandler(object): +class FlockHandler: ''' This is flock bot. Now you can send messages to any of your flock user without having to leave Zulip. diff --git a/zulip_bots/zulip_bots/bots/followup/followup.py b/zulip_bots/zulip_bots/bots/followup/followup.py index 453059e..8d2e7ed 100644 --- a/zulip_bots/zulip_bots/bots/followup/followup.py +++ b/zulip_bots/zulip_bots/bots/followup/followup.py @@ -1,7 +1,7 @@ # See readme.md for instructions on running this code. from typing import Dict, Any -class FollowupHandler(object): +class FollowupHandler: ''' This plugin facilitates creating follow-up tasks when you are using Zulip to conduct a virtual meeting. It diff --git a/zulip_bots/zulip_bots/bots/front/front.py b/zulip_bots/zulip_bots/bots/front/front.py index 51e5214..03a1c95 100644 --- a/zulip_bots/zulip_bots/bots/front/front.py +++ b/zulip_bots/zulip_bots/bots/front/front.py @@ -2,7 +2,7 @@ import requests import re from typing import Any, Dict, Optional -class FrontHandler(object): +class FrontHandler: FRONT_API = "https://api2.frontapp.com/conversations/{}" COMMANDS = [ ('archive', "Archive a conversation."), diff --git a/zulip_bots/zulip_bots/bots/game_handler_bot/game_handler_bot.py b/zulip_bots/zulip_bots/bots/game_handler_bot/game_handler_bot.py index 1d47f67..3c52218 100644 --- a/zulip_bots/zulip_bots/bots/game_handler_bot/game_handler_bot.py +++ b/zulip_bots/zulip_bots/bots/game_handler_bot/game_handler_bot.py @@ -2,7 +2,7 @@ from zulip_bots.game_handler import GameAdapter, BadMoveException from typing import List, Any -class GameHandlerBotMessageHandler(object): +class GameHandlerBotMessageHandler: tokens = [':blue_circle:', ':red_circle:'] def parse_board(self, board: Any) -> str: @@ -21,7 +21,7 @@ The first player to get 4 in a row wins!\n \ Good Luck!' -class MockModel(object): +class MockModel: def __init__(self) -> None: self.current_board = 'mock board' @@ -53,12 +53,12 @@ class GameHandlerBotHandler(GameAdapter): bot_name = 'game_handler_bot' move_help_message = '* To make your move during a game, type\n' \ '```move ```' - move_regex = 'move (\d)$' + move_regex = r'move (\d)$' model = MockModel gameMessageHandler = GameHandlerBotMessageHandler rules = '' - super(GameHandlerBotHandler, self).__init__( + super().__init__( game_name, bot_name, move_help_message, diff --git a/zulip_bots/zulip_bots/bots/game_of_fifteen/game_of_fifteen.py b/zulip_bots/zulip_bots/bots/game_of_fifteen/game_of_fifteen.py index 73019b8..0e1a263 100644 --- a/zulip_bots/zulip_bots/bots/game_of_fifteen/game_of_fifteen.py +++ b/zulip_bots/zulip_bots/bots/game_of_fifteen/game_of_fifteen.py @@ -4,7 +4,7 @@ import random from typing import List, Any, Tuple, Dict from zulip_bots.game_handler import GameAdapter, BadMoveException -class GameOfFifteenModel(object): +class GameOfFifteenModel: final_board = [[0, 1, 2], [3, 4, 5], @@ -84,7 +84,7 @@ class GameOfFifteenModel(object): if m == moves - 1: return board -class GameOfFifteenMessageHandler(object): +class GameOfFifteenMessageHandler: tiles = { '0': ':grey_question:', @@ -127,14 +127,14 @@ class GameOfFifteenBotHandler(GameAdapter): bot_name = 'Game of Fifteen' move_help_message = '* To make your move during a game, type\n' \ '```move ...```' - move_regex = 'move [\d{1}\s]+$' + move_regex = r'move [\d{1}\s]+$' model = GameOfFifteenModel gameMessageHandler = GameOfFifteenMessageHandler rules = '''Arrange the board’s tiles from smallest to largest, left to right, top to bottom, and tiles adjacent to :grey_question: can only be moved. Final configuration will have :grey_question: in top left.''' - super(GameOfFifteenBotHandler, self).__init__( + super().__init__( game_name, bot_name, move_help_message, diff --git a/zulip_bots/zulip_bots/bots/giphy/giphy.py b/zulip_bots/zulip_bots/bots/giphy/giphy.py index d64ed6c..eb7dc29 100644 --- a/zulip_bots/zulip_bots/bots/giphy/giphy.py +++ b/zulip_bots/zulip_bots/bots/giphy/giphy.py @@ -9,7 +9,7 @@ GIPHY_TRANSLATE_API = 'http://api.giphy.com/v1/gifs/translate' GIPHY_RANDOM_API = 'http://api.giphy.com/v1/gifs/random' -class GiphyHandler(object): +class GiphyHandler: """ This plugin posts a GIF in response to the keywords provided by the user. Images are provided by Giphy, through the public API. diff --git a/zulip_bots/zulip_bots/bots/github_detail/github_detail.py b/zulip_bots/zulip_bots/bots/github_detail/github_detail.py index 45f1bd3..83bc290 100644 --- a/zulip_bots/zulip_bots/bots/github_detail/github_detail.py +++ b/zulip_bots/zulip_bots/bots/github_detail/github_detail.py @@ -8,14 +8,14 @@ import requests from typing import Dict, Any, Tuple, Union -class GithubHandler(object): +class GithubHandler: ''' This bot provides details on github issues and pull requests when they're referenced in the chat. ''' GITHUB_ISSUE_URL_TEMPLATE = 'https://api.github.com/repos/{owner}/{repo}/issues/{id}' - HANDLE_MESSAGE_REGEX = re.compile("(?:([\w-]+)\/)?([\w-]+)?#(\d+)") + HANDLE_MESSAGE_REGEX = re.compile(r"(?:([\w-]+)\/)?([\w-]+)?#(\d+)") def initialize(self, bot_handler: Any) -> None: self.config_info = bot_handler.get_config_info('github_detail', optional=True) diff --git a/zulip_bots/zulip_bots/bots/google_search/google_search.py b/zulip_bots/zulip_bots/bots/google_search/google_search.py index 00ef3da..a47769b 100644 --- a/zulip_bots/zulip_bots/bots/google_search/google_search.py +++ b/zulip_bots/zulip_bots/bots/google_search/google_search.py @@ -63,7 +63,7 @@ def get_google_result(search_keywords: str) -> str: logging.exception(str(e)) return 'Error: Search failed. {}.'.format(e) -class GoogleSearchHandler(object): +class GoogleSearchHandler: ''' This plugin allows users to enter a search term in Zulip and get the top URL sent back diff --git a/zulip_bots/zulip_bots/bots/google_translate/google_translate.py b/zulip_bots/zulip_bots/bots/google_translate/google_translate.py index 2d494ee..6614568 100644 --- a/zulip_bots/zulip_bots/bots/google_translate/google_translate.py +++ b/zulip_bots/zulip_bots/bots/google_translate/google_translate.py @@ -4,7 +4,7 @@ import requests from requests.exceptions import HTTPError, ConnectionError -class GoogleTranslateHandler(object): +class GoogleTranslateHandler: ''' This bot will translate any messages sent to it using google translate. Before using it, make sure you set up google api keys, and enable google diff --git a/zulip_bots/zulip_bots/bots/helloworld/helloworld.py b/zulip_bots/zulip_bots/bots/helloworld/helloworld.py index f9d9450..24b520a 100644 --- a/zulip_bots/zulip_bots/bots/helloworld/helloworld.py +++ b/zulip_bots/zulip_bots/bots/helloworld/helloworld.py @@ -2,7 +2,7 @@ from typing import Any, Dict -class HelloWorldHandler(object): +class HelloWorldHandler: def usage(self) -> str: return ''' This is a boilerplate bot that responds to a user query with diff --git a/zulip_bots/zulip_bots/bots/help/help.py b/zulip_bots/zulip_bots/bots/help/help.py index 5b878a1..10eb135 100644 --- a/zulip_bots/zulip_bots/bots/help/help.py +++ b/zulip_bots/zulip_bots/bots/help/help.py @@ -1,7 +1,7 @@ # See readme.md for instructions on running this code. from typing import Any, Dict -class HelpHandler(object): +class HelpHandler: def usage(self) -> str: return ''' This plugin will give info about Zulip to diff --git a/zulip_bots/zulip_bots/bots/idonethis/idonethis.py b/zulip_bots/zulip_bots/bots/idonethis/idonethis.py index 1c232c1..7bff9a5 100644 --- a/zulip_bots/zulip_bots/bots/idonethis/idonethis.py +++ b/zulip_bots/zulip_bots/bots/idonethis/idonethis.py @@ -128,7 +128,7 @@ More information in my help""") data = api_create_entry(new_message, team_id) return "Great work :thumbs_up:. New entry `{}` created!".format(data['body_formatted']) -class IDoneThisHandler(object): +class IDoneThisHandler: def initialize(self, bot_handler: Any) -> None: global api_key, default_team self.config_info = bot_handler.get_config_info('idonethis') diff --git a/zulip_bots/zulip_bots/bots/incident/incident.py b/zulip_bots/zulip_bots/bots/incident/incident.py index fde3b6f..a0b7aef 100644 --- a/zulip_bots/zulip_bots/bots/incident/incident.py +++ b/zulip_bots/zulip_bots/bots/incident/incident.py @@ -59,7 +59,7 @@ def start_new_incident(query: str, message: Dict[str, Any], bot_handler: Any) -> bot_handler.send_reply(message, bot_response, widget_content) def parse_answer(query: str) -> Tuple[str, str]: - m = re.match('answer\s+(TICKET....)\s+(.)', query) + m = re.match(r'answer\s+(TICKET....)\s+(.)', query) if not m: raise InvalidAnswerException() diff --git a/zulip_bots/zulip_bots/bots/incrementor/incrementor.py b/zulip_bots/zulip_bots/bots/incrementor/incrementor.py index d4bb50b..bb94ff5 100644 --- a/zulip_bots/zulip_bots/bots/incrementor/incrementor.py +++ b/zulip_bots/zulip_bots/bots/incrementor/incrementor.py @@ -2,7 +2,7 @@ from typing import Dict, Any -class IncrementorHandler(object): +class IncrementorHandler: META = { 'name': 'Incrementor', 'description': 'Example bot to test the update_message() function.', diff --git a/zulip_bots/zulip_bots/bots/jira/jira.py b/zulip_bots/zulip_bots/bots/jira/jira.py index d877522..10ea287 100644 --- a/zulip_bots/zulip_bots/bots/jira/jira.py +++ b/zulip_bots/zulip_bots/bots/jira/jira.py @@ -106,7 +106,7 @@ Jira Bot: > Issue *BOTS-16* was edited! https://example.atlassian.net/browse/BOTS-16 ''' -class JiraHandler(object): +class JiraHandler: def usage(self) -> str: return ''' Jira Bot uses the Jira REST API to interact with Jira. In order to use @@ -164,14 +164,14 @@ class JiraHandler(object): response = 'Oh no! Jira raised an error:\n > ' + ', '.join(errors) else: response = ( - '**Issue *[{0}]({1})*: {2}**\n\n' - ' - Type: *{3}*\n' + '**Issue *[{}]({})*: {}**\n\n' + ' - Type: *{}*\n' ' - Description:\n' - ' > {4}\n' - ' - Creator: *{5}*\n' - ' - Project: *{6}*\n' - ' - Priority: *{7}*\n' - ' - Status: *{8}*\n' + ' > {}\n' + ' - Creator: *{}*\n' + ' - Project: *{}*\n' + ' - Priority: *{}*\n' + ' - Status: *{}*\n' ).format(key, url, summary, type_name, description, creator_name, project_name, priority_name, status_name) elif create_match: diff --git a/zulip_bots/zulip_bots/bots/link_shortener/link_shortener.py b/zulip_bots/zulip_bots/bots/link_shortener/link_shortener.py index 9d5e983..0ef0675 100644 --- a/zulip_bots/zulip_bots/bots/link_shortener/link_shortener.py +++ b/zulip_bots/zulip_bots/bots/link_shortener/link_shortener.py @@ -4,7 +4,7 @@ import logging from typing import Any, Dict -class LinkShortenerHandler(object): +class LinkShortenerHandler: '''A Zulip bot that will shorten URLs ("links") in a conversation using the goo.gl URL shortener. ''' @@ -33,10 +33,10 @@ class LinkShortenerHandler(object): def handle_message(self, message: Dict[str, str], bot_handler: Any) -> None: REGEX_STR = ( '(' - '(?:http|https):\/\/' # This allows for the HTTP or HTTPS - # protocol. - '[^"<>\{\}|\\^~[\]` ]+' # This allows for any character except - # for certain non-URL-safe ones. + r'(?:http|https):\/\/' # This allows for the HTTP or HTTPS + # protocol. + '[^"<>\\{\\}|\\^~[\\]` ]+' # This allows for any character except + # for certain non-URL-safe ones. ')' ) diff --git a/zulip_bots/zulip_bots/bots/mention/mention.py b/zulip_bots/zulip_bots/bots/mention/mention.py index 12bfa98..b078b41 100644 --- a/zulip_bots/zulip_bots/bots/mention/mention.py +++ b/zulip_bots/zulip_bots/bots/mention/mention.py @@ -4,7 +4,7 @@ import requests from typing import Any, List, Dict import logging -class MentionHandler(object): +class MentionHandler: def initialize(self, bot_handler: Any) -> None: self.config_info = bot_handler.get_config_info('mention') self.access_token = self.config_info['access_token'] diff --git a/zulip_bots/zulip_bots/bots/merels/libraries/game.py b/zulip_bots/zulip_bots/bots/merels/libraries/game.py index 3e7d43d..3190f91 100644 --- a/zulip_bots/zulip_bots/bots/merels/libraries/game.py +++ b/zulip_bots/zulip_bots/bots/merels/libraries/game.py @@ -199,5 +199,5 @@ def check_win(topic_name, merels_storage): win = mechanics.who_won(topic_name, merels_storage) if win != "None": merels.remove_game(topic_name) - return "{0} wins the game!".format(win) + return "{} wins the game!".format(win) return "" diff --git a/zulip_bots/zulip_bots/bots/merels/libraries/mechanics.py b/zulip_bots/zulip_bots/bots/merels/libraries/mechanics.py index 48b152d..1018d71 100644 --- a/zulip_bots/zulip_bots/bots/merels/libraries/mechanics.py +++ b/zulip_bots/zulip_bots/bots/merels/libraries/mechanics.py @@ -285,7 +285,7 @@ def create_room(topic_name, merels_storage): return response else: - return "Failed: Cannot create an already existing game in {0}. " \ + return "Failed: Cannot create an already existing game in {}. " \ "Please finish the game first.".format(topic_name) @@ -358,7 +358,7 @@ def move_man(topic_name, p1, p2, merels_storage): merels.update_game(data.topic_name, data.turn, data.x_taken, data.o_taken, data.board, data.hill_uid, data.take_mode) - return "Moved a man from ({0}, {1}) -> ({2}, {3}) for {4}.".format( + return "Moved a man from ({}, {}) -> ({}, {}) for {}.".format( p1[0], p1[1], p2[0], p2[1], data.turn) else: raise BadMoveException("Failed: That's not a legal move. Please try again.") @@ -390,7 +390,7 @@ def put_man(topic_name, v, h, merels_storage): merels.update_game(data.topic_name, data.turn, data.x_taken, data.o_taken, data.board, data.hill_uid, data.take_mode) - return "Put a man to ({0}, {1}) for {2}.".format(v, h, data.turn) + return "Put a man to ({}, {}) for {}.".format(v, h, data.turn) else: raise BadMoveException("Failed: That's not a legal put. Please try again.") @@ -428,7 +428,7 @@ def take_man(topic_name, v, h, merels_storage): merels.update_game(data.topic_name, data.turn, data.x_taken, data.o_taken, data.board, data.hill_uid, data.take_mode) - return "Taken a man from ({0}, {1}) for {2}.".format(v, h, data.turn) + return "Taken a man from ({}, {}) for {}.".format(v, h, data.turn) else: raise BadMoveException("Failed: That's not a legal take. Please try again.") diff --git a/zulip_bots/zulip_bots/bots/merels/merels.py b/zulip_bots/zulip_bots/bots/merels/merels.py index 6bea75e..430e38f 100644 --- a/zulip_bots/zulip_bots/bots/merels/merels.py +++ b/zulip_bots/zulip_bots/bots/merels/merels.py @@ -7,7 +7,7 @@ from zulip_bots.bots.merels.libraries import ( ) from zulip_bots.game_handler import GameAdapter, SamePlayerMove, GameInstance -class Storage(object): +class Storage: data = {} def __init__(self, topic_name): @@ -19,7 +19,7 @@ class Storage(object): def get(self, topic_name): return self.data[topic_name] -class MerelsModel(object): +class MerelsModel: def __init__(self, board: Any=None) -> None: self.topic = "merels" @@ -54,7 +54,7 @@ class MerelsModel(object): raise SamePlayerMove(same_player_move) return self.current_board -class MerelsMessageHandler(object): +class MerelsMessageHandler: tokens = [':o_button:', ':cross_mark_button:'] def parse_board(self, board: Any) -> str: @@ -90,7 +90,7 @@ class MerelsHandler(GameAdapter): model = MerelsModel rules = game.getInfo() gameMessageHandler = MerelsMessageHandler - super(MerelsHandler, self).__init__( + super().__init__( game_name, bot_name, move_help_message, diff --git a/zulip_bots/zulip_bots/bots/monkeytestit/monkeytestit.py b/zulip_bots/zulip_bots/bots/monkeytestit/monkeytestit.py index 9cc14c2..a731246 100644 --- a/zulip_bots/zulip_bots/bots/monkeytestit/monkeytestit.py +++ b/zulip_bots/zulip_bots/bots/monkeytestit/monkeytestit.py @@ -5,7 +5,7 @@ from zulip_bots.bots.monkeytestit.lib import parse from zulip_bots.lib import NoBotConfigException -class MonkeyTestitBot(object): +class MonkeyTestitBot: def __init__(self): self.api_key = "None" self.config = None diff --git a/zulip_bots/zulip_bots/bots/salesforce/salesforce.py b/zulip_bots/zulip_bots/bots/salesforce/salesforce.py index 071f0e3..c4c9e02 100644 --- a/zulip_bots/zulip_bots/bots/salesforce/salesforce.py +++ b/zulip_bots/zulip_bots/bots/salesforce/salesforce.py @@ -82,7 +82,7 @@ def query_salesforce(arg: str, salesforce: simple_salesforce.Salesforce, command raw_arg = ' -' + arg.split(' -', 1)[1] split_args = raw_arg.split(' -') limit_num = 5 - re_limit = re.compile('-limit \d+') + re_limit = re.compile(r'-limit \d+') limit = re_limit.search(raw_arg) if limit: limit_num = int(limit.group().rsplit(' ', 1)[1]) @@ -122,7 +122,7 @@ def get_salesforce_link_details(link: str, sf: Any) -> str: return 'No object found. Make sure it is of the supported types. Type `help` for more info.' -class SalesforceHandler(object): +class SalesforceHandler: def usage(self) -> str: return ''' This is a Salesforce bot, which can search for Contacts, @@ -136,7 +136,7 @@ class SalesforceHandler(object): def get_salesforce_response(self, content: str) -> str: content = content.strip() - if content is '' or content == 'help': + if content == '' or content == 'help': return get_help_text() if content.startswith('http') and 'force' in content: return get_salesforce_link_details(content, self.sf) diff --git a/zulip_bots/zulip_bots/bots/stack_overflow/stack_overflow.py b/zulip_bots/zulip_bots/bots/stack_overflow/stack_overflow.py index b287e4b..edfe19d 100644 --- a/zulip_bots/zulip_bots/bots/stack_overflow/stack_overflow.py +++ b/zulip_bots/zulip_bots/bots/stack_overflow/stack_overflow.py @@ -7,7 +7,7 @@ from typing import Optional, Any, Dict # See readme.md for instructions on running this code. -class StackOverflowHandler(object): +class StackOverflowHandler: ''' This plugin facilitates searching Stack Overflow for a specific query and returns the top 3 questions from the diff --git a/zulip_bots/zulip_bots/bots/susi/susi.py b/zulip_bots/zulip_bots/bots/susi/susi.py index 63c54a8..66514e4 100644 --- a/zulip_bots/zulip_bots/bots/susi/susi.py +++ b/zulip_bots/zulip_bots/bots/susi/susi.py @@ -1,7 +1,7 @@ import requests from typing import Dict, Any, Tuple, Union -class SusiHandler(object): +class SusiHandler: ''' Susi AI Bot To create and know more of SUSI skills go to `https://skills.susi.ai/` diff --git a/zulip_bots/zulip_bots/bots/tictactoe/tictactoe.py b/zulip_bots/zulip_bots/bots/tictactoe/tictactoe.py index b25c38e..99924d5 100644 --- a/zulip_bots/zulip_bots/bots/tictactoe/tictactoe.py +++ b/zulip_bots/zulip_bots/bots/tictactoe/tictactoe.py @@ -9,7 +9,7 @@ from zulip_bots.game_handler import GameAdapter, BadMoveException State = List[List[str]] -class TicTacToeModel(object): +class TicTacToeModel: smarter = True # If smarter is True, the computer will do some extra thinking - it'll be harder for the user. @@ -208,7 +208,7 @@ class TicTacToeModel(object): return board -class TicTacToeMessageHandler(object): +class TicTacToeMessageHandler: tokens = [':x:', ':o:'] def parse_row(self, row: Tuple[int, int], row_num: int) -> str: @@ -259,11 +259,11 @@ class ticTacToeHandler(GameAdapter): game_name = 'Tic Tac Toe' bot_name = 'tictactoe' move_help_message = '* To move during a game, type\n`move ` or ``' - move_regex = '(move (\d)$)|((\d)$)' + move_regex = r'(move (\d)$)|((\d)$)' model = TicTacToeModel gameMessageHandler = TicTacToeMessageHandler rules = '''Try to get three in horizontal or vertical or diagonal row to win the game.''' - super(ticTacToeHandler, self).__init__( + super().__init__( game_name, bot_name, move_help_message, diff --git a/zulip_bots/zulip_bots/bots/trello/trello.py b/zulip_bots/zulip_bots/bots/trello/trello.py index fd0198a..d153d18 100644 --- a/zulip_bots/zulip_bots/bots/trello/trello.py +++ b/zulip_bots/zulip_bots/bots/trello/trello.py @@ -14,7 +14,7 @@ supported_commands = [ INVALID_ARGUMENTS_ERROR_MESSAGE = 'Invalid Arguments.' RESPONSE_ERROR_MESSAGE = 'Invalid Response. Please check configuration and parameters.' -class TrelloHandler(object): +class TrelloHandler: def initialize(self, bot_handler: Any) -> None: self.config_info = bot_handler.get_config_info('trello') self.api_key = self.config_info['api_key'] diff --git a/zulip_bots/zulip_bots/bots/trivia_quiz/trivia_quiz.py b/zulip_bots/zulip_bots/bots/trivia_quiz/trivia_quiz.py index d79a1cc..99e34b6 100644 --- a/zulip_bots/zulip_bots/bots/trivia_quiz/trivia_quiz.py +++ b/zulip_bots/zulip_bots/bots/trivia_quiz/trivia_quiz.py @@ -65,7 +65,7 @@ def start_new_quiz(message: Dict[str, Any], bot_handler: Any) -> None: bot_handler.send_reply(message, bot_response, widget_content) def parse_answer(query: str) -> Tuple[str, str]: - m = re.match('answer\s+(Q...)\s+(.)', query) + m = re.match(r'answer\s+(Q...)\s+(.)', query) if not m: raise InvalidAnswerException() diff --git a/zulip_bots/zulip_bots/bots/twitpost/twitpost.py b/zulip_bots/zulip_bots/bots/twitpost/twitpost.py index 18b0e75..23f3e07 100644 --- a/zulip_bots/zulip_bots/bots/twitpost/twitpost.py +++ b/zulip_bots/zulip_bots/bots/twitpost/twitpost.py @@ -3,7 +3,7 @@ import tweepy from typing import Dict, Any, Union, List, Tuple, Optional -class TwitpostBot(object): +class TwitpostBot: def usage(self) -> str: return ''' This bot posts on twitter from zulip chat itself. diff --git a/zulip_bots/zulip_bots/bots/virtual_fs/virtual_fs.py b/zulip_bots/zulip_bots/bots/virtual_fs/virtual_fs.py index dd05b6e..a99c45e 100644 --- a/zulip_bots/zulip_bots/bots/virtual_fs/virtual_fs.py +++ b/zulip_bots/zulip_bots/bots/virtual_fs/virtual_fs.py @@ -5,7 +5,7 @@ import os from typing import Any, Dict, List, Tuple, Callable, Set, Union -class VirtualFsHandler(object): +class VirtualFsHandler: META = { 'name': 'VirtualFs', 'description': 'Provides a simple, permanent file system to store and retrieve strings.', @@ -112,8 +112,8 @@ def sample_conversation() -> List[Tuple[str, str]]: REGEXES = dict( command='(cd|ls|mkdir|read|rmdir|rm|write|pwd)', - path='(\S+)', - optional_path='(\S*)', + path=r'(\S+)', + optional_path=r'(\S*)', some_text='(.+)', ) diff --git a/zulip_bots/zulip_bots/bots/weather/weather.py b/zulip_bots/zulip_bots/bots/weather/weather.py index 8ad12c9..c19c093 100644 --- a/zulip_bots/zulip_bots/bots/weather/weather.py +++ b/zulip_bots/zulip_bots/bots/weather/weather.py @@ -7,7 +7,7 @@ from typing import Any, Dict api_url = 'http://api.openweathermap.org/data/2.5/weather' -class WeatherHandler(object): +class WeatherHandler: def initialize(self, bot_handler: Any) -> None: self.api_key = bot_handler.get_config_info('weather')['key'] self.response_pattern = 'Weather in {}, {}:\n{:.2f} F / {:.2f} C\n{}' diff --git a/zulip_bots/zulip_bots/bots/wikipedia/wikipedia.py b/zulip_bots/zulip_bots/bots/wikipedia/wikipedia.py index a7f7105..3e6f757 100644 --- a/zulip_bots/zulip_bots/bots/wikipedia/wikipedia.py +++ b/zulip_bots/zulip_bots/bots/wikipedia/wikipedia.py @@ -8,7 +8,7 @@ from typing import Optional, Any, Dict # See readme.md for instructions on running this code. -class WikipediaHandler(object): +class WikipediaHandler: ''' This plugin facilitates searching Wikipedia for a specific key term and returns the top 3 articles from the diff --git a/zulip_bots/zulip_bots/bots/witai/witai.py b/zulip_bots/zulip_bots/bots/witai/witai.py index dd9cb2d..0a63fa5 100644 --- a/zulip_bots/zulip_bots/bots/witai/witai.py +++ b/zulip_bots/zulip_bots/bots/witai/witai.py @@ -5,7 +5,7 @@ import wit import sys import importlib.util -class WitaiHandler(object): +class WitaiHandler: def usage(self) -> str: return ''' Wit.ai bot uses pywit API to interact with Wit.ai. In order to use diff --git a/zulip_bots/zulip_bots/bots/xkcd/xkcd.py b/zulip_bots/zulip_bots/bots/xkcd/xkcd.py index d473922..39be875 100644 --- a/zulip_bots/zulip_bots/bots/xkcd/xkcd.py +++ b/zulip_bots/zulip_bots/bots/xkcd/xkcd.py @@ -8,7 +8,7 @@ from typing import Any, Dict, Optional XKCD_TEMPLATE_URL = 'https://xkcd.com/%s/info.0.json' LATEST_XKCD_URL = 'https://xkcd.com/info.0.json' -class XkcdHandler(object): +class XkcdHandler: ''' This plugin provides several commands that can be used for fetch a comic strip from https://xkcd.com. The bot looks for messages starting with @@ -39,7 +39,7 @@ class XkcdHandler(object): xkcd_bot_response = get_xkcd_bot_response(message, quoted_name) bot_handler.send_reply(message, xkcd_bot_response) -class XkcdBotCommand(object): +class XkcdBotCommand: LATEST = 0 RANDOM = 1 COMIC_ID = 2 diff --git a/zulip_bots/zulip_bots/bots/yoda/yoda.py b/zulip_bots/zulip_bots/bots/yoda/yoda.py index 4f535a9..e940310 100644 --- a/zulip_bots/zulip_bots/bots/yoda/yoda.py +++ b/zulip_bots/zulip_bots/bots/yoda/yoda.py @@ -28,7 +28,7 @@ class ServiceUnavailableError(Exception): '''raise this when the service is unavailable.''' -class YodaSpeakHandler(object): +class YodaSpeakHandler: ''' This bot will allow users to translate a sentence into 'Yoda speak'. It looks for messages starting with '@mention-bot'. diff --git a/zulip_bots/zulip_bots/bots/youtube/youtube.py b/zulip_bots/zulip_bots/bots/youtube/youtube.py index 2aa9aef..f74fa4f 100644 --- a/zulip_bots/zulip_bots/bots/youtube/youtube.py +++ b/zulip_bots/zulip_bots/bots/youtube/youtube.py @@ -7,7 +7,7 @@ from typing import Dict, Any, Union, List, Tuple, Optional commands_list = ('list', 'top', 'help') -class YoutubeHandler(object): +class YoutubeHandler: def usage(self) -> str: return ''' diff --git a/zulip_bots/zulip_bots/game_handler.py b/zulip_bots/zulip_bots/game_handler.py index 2c9b9de..29dc02d 100644 --- a/zulip_bots/zulip_bots/game_handler.py +++ b/zulip_bots/zulip_bots/game_handler.py @@ -23,7 +23,7 @@ class SamePlayerMove(Exception): def __str__(self) -> str: return self.message -class GameAdapter(object): +class GameAdapter: ''' Class that serves as a template to easily create multiplayer games. @@ -248,7 +248,7 @@ class GameAdapter(object): elif content.lower() == 'join': self.command_join(message, sender, content) - elif self.is_user_in_game(sender) is not '': + elif self.is_user_in_game(sender) != '': self.parse_message(message) elif self.move_regex.match(content) is not None or content.lower() == 'draw' or content.lower() == 'forfeit': @@ -299,7 +299,7 @@ class GameAdapter(object): message, self.already_in_game_message()) return game_id = self.set_invite_by_user(sender, True, message) - if game_id is '': + if game_id == '': self.send_reply( message, 'No active invites. Type `help` for commands.') return @@ -366,7 +366,7 @@ class GameAdapter(object): message, self.already_in_game_message()) return game_id = self.set_invite_by_user(sender, False, message) - if game_id is '': + if game_id == '': self.send_reply( message, 'No active invites. Type `help` for commands.') return @@ -381,7 +381,7 @@ class GameAdapter(object): if message['type'] == 'private' and self.is_single_player: self.send_reply(message, 'You are not allowed to play games in private messages.') return - if game_id is '': + if game_id == '': self.send_reply( message, 'You are not in a game. Type `help` for all commands.') sender_avatar = "!avatar({})".format(sender) @@ -399,7 +399,7 @@ class GameAdapter(object): return game_id = self.get_invite_in_subject( message['subject'], message['display_recipient']) - if game_id is '': + if game_id == '': self.send_reply( message, 'There is not a game in this subject. Type `help` for all commands.') return @@ -408,7 +408,7 @@ class GameAdapter(object): def command_play(self, message: Dict[str, Any], sender: str, content: str) -> None: game_id = self.get_invite_in_subject( message['subject'], message['display_recipient']) - if game_id is '': + if game_id == '': self.send_reply( message, 'There is not a game in this subject. Type `help` for all commands.') return @@ -683,7 +683,7 @@ To move subjects, send your message again, otherwise join the game using the lin return '' def is_game_in_subject(self, subject_name: str, stream_name: str) -> bool: - return self.get_invite_in_subject(subject_name, stream_name) is not '' or \ + return self.get_invite_in_subject(subject_name, stream_name) != '' or \ self.get_game_instance_by_subject( subject_name, stream_name) is not None @@ -752,7 +752,7 @@ To move subjects, send your message again, otherwise join the game using the lin return self.bot_handler.full_name -class GameInstance(object): +class GameInstance: ''' The GameInstance class handles the game logic for a certain game, and is associated with a certain stream. diff --git a/zulip_bots/zulip_bots/lib.py b/zulip_bots/zulip_bots/lib.py index 2541b81..ca0f21a 100644 --- a/zulip_bots/zulip_bots/lib.py +++ b/zulip_bots/zulip_bots/lib.py @@ -47,7 +47,7 @@ def zulip_env_vars_are_present() -> bool: # missing, we can proceed without a config file. return True -class RateLimit(object): +class RateLimit: def __init__(self, message_limit: int, interval_limit: int) -> None: self.message_limit = message_limit self.interval_limit = interval_limit @@ -69,7 +69,7 @@ class RateLimit(object): sys.exit(1) -class StateHandler(object): +class StateHandler: def __init__(self, client: Client) -> None: self._client = client self.marshal = lambda obj: json.dumps(obj) @@ -97,13 +97,13 @@ class StateHandler(object): def contains(self, key: Text) -> bool: return key in self.state_ -class BotIdentity(object): +class BotIdentity: def __init__(self, name: str, email: str) -> None: self.name = name self.email = email self.mention = '@**' + name + '**' -class ExternalBotHandler(object): +class ExternalBotHandler: def __init__( self, client: Client, diff --git a/zulip_bots/zulip_bots/terminal.py b/zulip_bots/zulip_bots/terminal.py index 26c2b86..b278da7 100644 --- a/zulip_bots/zulip_bots/terminal.py +++ b/zulip_bots/zulip_bots/terminal.py @@ -38,8 +38,8 @@ def main(): try: lib_module = import_module_from_source(bot_path, bot_name) if lib_module is None: - raise IOError - except IOError: + raise OSError + except OSError: print("Could not find and import bot '{}'".format(bot_name)) sys.exit(1) diff --git a/zulip_bots/zulip_bots/tests/test_run.py b/zulip_bots/zulip_bots/tests/test_run.py index d4096a1..7dd59bd 100644 --- a/zulip_bots/zulip_bots/tests/test_run.py +++ b/zulip_bots/zulip_bots/tests/test_run.py @@ -95,7 +95,7 @@ class TestBotLib(TestCase): test_message("brokenmention", "@**brokenmention* foo", None) test_message("nomention", "foo", None) test_message("Max Mustermann", "@**Max Mustermann** foo", "foo") - test_message("Max (Mustermann)#(*$&12]\]", "@**Max (Mustermann)#(*$&12]\]** foo", "foo") + test_message(r"Max (Mustermann)#(*$&12]\]", r"@**Max (Mustermann)#(*$&12]\]** foo", "foo") if __name__ == '__main__': unittest.main() diff --git a/zulip_botserver/setup.py b/zulip_botserver/setup.py index 89d13a1..3f13587 100755 --- a/zulip_botserver/setup.py +++ b/zulip_botserver/setup.py @@ -1,5 +1,4 @@ #!/usr/bin/env python3 -# -*- coding: utf-8 -*- import sys if False: @@ -7,7 +6,7 @@ if False: ZULIP_BOTSERVER_VERSION = "0.6.4" -with open("README.md", "r") as fh: +with open("README.md") as fh: long_description = fh.read() # We should be installable with either setuptools or distutils. diff --git a/zulip_botserver/tests/test_server.py b/zulip_botserver/tests/test_server.py index eb1601c..d38cd93 100644 --- a/zulip_botserver/tests/test_server.py +++ b/zulip_botserver/tests/test_server.py @@ -12,11 +12,11 @@ from zulip_botserver.input_parameters import parse_args class BotServerTests(BotServerTestCase): - class MockMessageHandler(object): + class MockMessageHandler: def handle_message(self, message: Dict[str, str], bot_handler: Any) -> None: assert message == {'key': "test message"} - class MockLibModule(object): + class MockLibModule: def handler_class(self) -> Any: return BotServerTests.MockMessageHandler() diff --git a/zulip_botserver/zulip_botserver/server.py b/zulip_botserver/zulip_botserver/server.py index 04b423c..fe204c4 100644 --- a/zulip_botserver/zulip_botserver/server.py +++ b/zulip_botserver/zulip_botserver/server.py @@ -65,7 +65,7 @@ def read_config_file(config_file_path: str, bot_name: Optional[str]=None) -> Dic def parse_config_file(config_file_path: str) -> configparser.ConfigParser: config_file_path = os.path.abspath(os.path.expanduser(config_file_path)) if not os.path.isfile(config_file_path): - raise IOError("Could not read config file {}: File not found.".format(config_file_path)) + raise OSError("Could not read config file {}: File not found.".format(config_file_path)) parser = configparser.ConfigParser() parser.read(config_file_path) return parser