diff --git a/confirmation/models.py b/confirmation/models.py index 2e5385c30c..072c60932b 100644 --- a/confirmation/models.py +++ b/confirmation/models.py @@ -124,8 +124,10 @@ _properties = { Confirmation.INVITATION: ConfirmationType('check_prereg_key_and_redirect', validity_in_days=settings.INVITATION_LINK_VALIDITY_DAYS), Confirmation.EMAIL_CHANGE: ConfirmationType('zerver.views.user_settings.confirm_email_change'), - Confirmation.UNSUBSCRIBE: ConfirmationType('zerver.views.unsubscribe.email_unsubscribe', - validity_in_days=1000000), # should never expire + Confirmation.UNSUBSCRIBE: ConfirmationType( + 'zerver.views.unsubscribe.email_unsubscribe', + validity_in_days=1000000, # should never expire + ), Confirmation.MULTIUSE_INVITE: ConfirmationType( 'zerver.views.registration.accounts_home_from_multiuse_invite', validity_in_days=settings.INVITATION_LINK_VALIDITY_DAYS), diff --git a/scripts/nagios/check-rabbitmq-consumers b/scripts/nagios/check-rabbitmq-consumers index e8f1ca6431..1fd697ba5f 100755 --- a/scripts/nagios/check-rabbitmq-consumers +++ b/scripts/nagios/check-rabbitmq-consumers @@ -47,10 +47,11 @@ output = subprocess.check_output(['/usr/sbin/rabbitmqctl', 'list_consumers'], consumers: Dict[str, int] = defaultdict(int) sys.path.append(os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))))) -queues = set(normal_queues).union({ +queues = { + *normal_queues, # These queues may not be present if settings.TORNADO_PROCESSES > 1 'notify_tornado', -}) +} for queue_name in queues: queue_name = queue_name.strip() diff --git a/scripts/setup/restore-backup b/scripts/setup/restore-backup index bb6900204b..10a076f573 100755 --- a/scripts/setup/restore-backup +++ b/scripts/setup/restore-backup @@ -97,9 +97,9 @@ def restore_backup(tarball_file: IO[bytes]) -> None: run( [ os.path.join( - settings.DEPLOY_ROOT, "scripts", "setup", "terminate-psql-sessions", + settings.DEPLOY_ROOT, "scripts", "setup", "terminate-psql-sessions" ), - db["NAME"], + db["NAME"] ], env=postgres_env, ) @@ -136,8 +136,8 @@ def restore_backup(tarball_file: IO[bytes]) -> None: run( [ os.path.join(settings.DEPLOY_ROOT, "scripts", "zulip-puppet-apply"), - "-f", - ], + "-f" + ] ) # Now, restore the the database backup using pg_restore. This diff --git a/tools/documentation_crawler/documentation_crawler/spiders/common/spiders.py b/tools/documentation_crawler/documentation_crawler/spiders/common/spiders.py index 430ca55e0f..89c1c259d4 100644 --- a/tools/documentation_crawler/documentation_crawler/spiders/common/spiders.py +++ b/tools/documentation_crawler/documentation_crawler/spiders/common/spiders.py @@ -28,7 +28,7 @@ EXCLUDED_URLS = [ 'https://www.udemy.com/course/the-complete-react-native-and-redux-course/', ] -VNU_IGNORE = re.compile(r'|'.join([ +VNU_IGNORE = [ # Real errors that should be fixed. r'Duplicate ID “[^”]*”\.', r'The first occurrence of ID “[^”]*” was here\.', @@ -39,7 +39,8 @@ VNU_IGNORE = re.compile(r'|'.join([ # Warnings that are probably less important. r'The “type” attribute is unnecessary for JavaScript resources\.', -])) +] +VNU_IGNORE_REGEX = re.compile(r'|'.join(VNU_IGNORE)) class BaseDocumentationSpider(scrapy.Spider): @@ -91,7 +92,7 @@ class BaseDocumentationSpider(scrapy.Spider): def callback(response: Response) -> None: vnu_out = json.loads(response.text) for message in vnu_out['messages']: - if not VNU_IGNORE.fullmatch(message['message']): + if not VNU_IGNORE_REGEX.fullmatch(message['message']): self.logger.error( '"%s":%d.%d-%d.%d: %s: %s', url, diff --git a/tools/lib/capitalization.py b/tools/lib/capitalization.py index 625778e54d..5609710ef4 100644 --- a/tools/lib/capitalization.py +++ b/tools/lib/capitalization.py @@ -174,15 +174,15 @@ SPLIT_BOUNDARY = '?.!' # Used to split string into sentences. SPLIT_BOUNDARY_REGEX = re.compile(fr'[{SPLIT_BOUNDARY}]') # Regexes which check capitalization in sentences. -DISALLOWED_REGEXES = [re.compile(regex) for regex in [ +DISALLOWED = [ r'^[a-z](?!\})', # Checks if the sentence starts with a lower case character. r'^[A-Z][a-z]+[\sa-z0-9]+[A-Z]', # Checks if an upper case character exists # after a lower case character when the first character is in upper case. -]] +] +DISALLOWED_REGEX = re.compile(r"|".join(DISALLOWED)) BANNED_WORDS = { - 'realm': ('The term realm should not appear in user-facing strings. ' - 'Use organization instead.'), + 'realm': 'The term realm should not appear in user-facing strings. Use organization instead.', } def get_safe_phrase(phrase: str) -> str: @@ -232,18 +232,7 @@ def get_safe_text(text: str) -> str: def is_capitalized(safe_text: str) -> bool: sentences = SPLIT_BOUNDARY_REGEX.split(safe_text) - sentences = [sentence.strip() - for sentence in sentences if sentence.strip()] - - if not sentences: - return False - - for sentence in sentences: - for regex in DISALLOWED_REGEXES: - if regex.search(sentence): - return False - - return True + return not any(DISALLOWED_REGEX.search(sentence.strip()) for sentence in sentences) def check_banned_words(text: str) -> List[str]: lower_cased_text = text.lower() diff --git a/tools/lib/gitlint-rules.py b/tools/lib/gitlint-rules.py index de77c52cc5..9149ddca59 100644 --- a/tools/lib/gitlint-rules.py +++ b/tools/lib/gitlint-rules.py @@ -72,7 +72,7 @@ WORD_SET = { 'uses', 'using', 'used', } -imperative_forms = sorted([ +imperative_forms = [ 'add', 'allow', 'amend', 'bump', 'calculate', 'change', 'clean', 'commit', 'correct', 'create', 'darken', 'disable', 'display', 'document', 'dry', 'end', 'enforce', 'enqueue', 'extract', 'finish', 'fix', 'format', 'guard', @@ -81,7 +81,8 @@ imperative_forms = sorted([ 'refactor', 'remove', 'rename', 'reorder', 'replace', 'require', 'restore', 'send', 'separate', 'set', 'show', 'simplify', 'skip', 'sort', 'speed', 'start', 'support', 'take', 'test', 'truncate', 'update', 'use', -]) +] +imperative_forms.sort() def head_binary_search(key: Text, words: List[str]) -> str: diff --git a/tools/test-backend b/tools/test-backend index 50f414ab80..d9a44a6f6c 100755 --- a/tools/test-backend +++ b/tools/test-backend @@ -22,7 +22,7 @@ import responses from django.conf import settings from django.test.utils import get_runner -target_fully_covered = {path for target in [ +target_fully_covered = [ 'analytics/lib/*.py', 'analytics/models.py', 'analytics/tests/*.py', @@ -51,9 +51,9 @@ target_fully_covered = {path for target in [ # 'zerver/webhooks/*/*.py', # 'zerver/webhooks/*/*/*.py', 'zerver/worker/*.py', -] for path in glob.glob(target)} +] -not_yet_fully_covered = {path for target in [ +not_yet_fully_covered = [ # Analytics fixtures library is used to generate test fixtures; # isn't properly accounted for in test coverage analysis since it # runs before tests. @@ -136,9 +136,12 @@ not_yet_fully_covered = {path for target in [ 'zerver/webhooks/teamcity/view.py', 'zerver/webhooks/travis/view.py', 'zerver/webhooks/zapier/view.py', -] for path in glob.glob(target)} +] -enforce_fully_covered = sorted(target_fully_covered - not_yet_fully_covered) +enforce_fully_covered = sorted( + {path for target in target_fully_covered for path in glob.glob(target)} + - {path for target in not_yet_fully_covered for path in glob.glob(target)} +) FAILED_TEST_PATH = 'var/last_test_failure.json' diff --git a/tools/tests/test_capitalization_checker.py b/tools/tests/test_capitalization_checker.py index 2789f653c7..a03118132c 100644 --- a/tools/tests/test_capitalization_checker.py +++ b/tools/tests/test_capitalization_checker.py @@ -102,10 +102,9 @@ class IsCapitalizedTestCase(TestCase): string = "" capitalized = is_capitalized(string) - self.assertFalse(capitalized) + self.assertTrue(capitalized) - string = ("Please re-enter your password to confirm your identity." - " (Forgotten it?)") + string = "Please re-enter your password to confirm your identity. (Forgotten it?)" capitalized = is_capitalized(string) self.assertTrue(capitalized) diff --git a/zerver/data_import/import_util.py b/zerver/data_import/import_util.py index 5281416ca9..f8d2dbd53c 100644 --- a/zerver/data_import/import_util.py +++ b/zerver/data_import/import_util.py @@ -300,7 +300,8 @@ def build_recipient(type_id: int, recipient_id: int, type: int) -> ZerverFieldsT recipient = Recipient( type_id=type_id, # stream id id=recipient_id, - type=type) + type=type, + ) recipient_dict = model_to_dict(recipient) return recipient_dict diff --git a/zerver/lib/actions.py b/zerver/lib/actions.py index 58e976041f..c8c2a1695c 100644 --- a/zerver/lib/actions.py +++ b/zerver/lib/actions.py @@ -1534,7 +1534,8 @@ def do_send_messages(messages_maybe_none: Sequence[Optional[MutableMapping[str, if message['stream'] is None: stream_id = message['message'].recipient.type_id message['stream'] = Stream.objects.select_related().get(id=stream_id) - assert message['stream'] is not None # assert needed because stubs for django are missing + # assert needed because stubs for django are missing + assert message['stream'] is not None realm_id = message['stream'].realm_id # Deliver events to the real-time push system, as well as @@ -1592,7 +1593,9 @@ def do_send_messages(messages_maybe_none: Sequence[Optional[MutableMapping[str, # notify new_message request if it's a public stream, # ensuring that in the tornado server, non-public stream # messages are only associated to their subscribed users. - assert message['stream'] is not None # assert needed because stubs for django are missing + + # assert needed because stubs for django are missing + assert message['stream'] is not None if message['stream'].is_public(): event['realm_id'] = message['stream'].realm_id event['stream_name'] = message['stream'].name diff --git a/zerver/lib/hotspots.py b/zerver/lib/hotspots.py index 35b27d6dea..a0dfde4438 100644 --- a/zerver/lib/hotspots.py +++ b/zerver/lib/hotspots.py @@ -25,8 +25,7 @@ ALL_HOTSPOTS: Dict[str, Dict[str, str]] = { }, 'intro_gear': { 'title': _('Settings'), - 'description': _('Go to Settings to configure your ' - 'notifications and display settings.'), + 'description': _('Go to Settings to configure your notifications and display settings.'), }, 'intro_compose': { 'title': _('Compose'), diff --git a/zerver/lib/markdown/fenced_code.py b/zerver/lib/markdown/fenced_code.py index 21826a6073..79edb00917 100644 --- a/zerver/lib/markdown/fenced_code.py +++ b/zerver/lib/markdown/fenced_code.py @@ -405,8 +405,7 @@ class FencedBlockPreprocessor(markdown.preprocessors.Preprocessor): def format_spoiler(self, header: str, text: str) -> str: output = [] header_div_open_html = '
' - end_header_start_content_html = '
' output.append(self.placeholder(header_div_open_html)) diff --git a/zerver/lib/name_restrictions.py b/zerver/lib/name_restrictions.py index 02f3f9f401..151cfb44f1 100644 --- a/zerver/lib/name_restrictions.py +++ b/zerver/lib/name_restrictions.py @@ -17,7 +17,7 @@ def is_disposable_domain(domain: str) -> bool: return False return domain.lower() in DISPOSABLE_DOMAINS -ZULIP_RESERVED_SUBDOMAINS = frozenset([ +ZULIP_RESERVED_SUBDOMAINS = { # zulip terms 'stream', 'channel', 'topic', 'thread', 'installation', 'organization', 'realm', 'team', 'subdomain', 'activity', 'octopus', 'acme', 'push', @@ -40,12 +40,12 @@ ZULIP_RESERVED_SUBDOMAINS = frozenset([ # Things that sound like security 'auth', 'authentication', 'security', # tech blogs - 'engineering', 'infrastructure', 'tooling', 'tools', 'javascript', 'python']) + 'engineering', 'infrastructure', 'tooling', 'tools', 'javascript', 'python'} # Most of this list was curated from the following sources: # http://wiki.dwscoalition.org/notes/List_of_reserved_subdomains (license: CC-BY-SA 3.0) # https://stackoverflow.com/questions/11868191/which-saas-subdomains-to-block (license: CC-BY-SA 2.5) -GENERIC_RESERVED_SUBDOMAINS = frozenset([ +GENERIC_RESERVED_SUBDOMAINS = { 'about', 'abuse', 'account', 'ad', 'admanager', 'admin', 'admindashboard', 'administrator', 'adsense', 'adword', 'affiliate', 'alpha', 'anonymous', 'api', 'assets', 'audio', 'badges', 'beta', 'billing', 'biz', 'blog', @@ -77,12 +77,12 @@ GENERIC_RESERVED_SUBDOMAINS = frozenset([ 'testers', 'ticket', 'tool', 'tos', 'trac', 'translate', 'update', 'upgrade', 'uploads', 'use', 'user', 'username', 'validation', 'videos', 'volunteer', 'web', 'webdisk', 'webmail', 'webmaster', 'whm', 'whois', - 'wiki', 'www', 'www0', 'www8', 'www9', 'xml', 'xmpp', 'xoxo']) + 'wiki', 'www', 'www0', 'www8', 'www9', 'xml', 'xmpp', 'xoxo'} -DISPOSABLE_DOMAINS = frozenset(blacklist) +DISPOSABLE_DOMAINS = set(blacklist) -WHITELISTED_EMAIL_DOMAINS = frozenset([ +WHITELISTED_EMAIL_DOMAINS = { # Controlled by https://www.abine.com; more legitimate than most # disposable domains 'opayq.com', 'abinemail.com', 'blurmail.net', 'maskmemail.com', -]) +} diff --git a/zerver/lib/test_fixtures.py b/zerver/lib/test_fixtures.py index e92d78f52a..88291106b6 100644 --- a/zerver/lib/test_fixtures.py +++ b/zerver/lib/test_fixtures.py @@ -94,18 +94,19 @@ class Database: # what the database is as runtime. # Also we export ZULIP_DB_NAME which is ignored by dev platform but # recognised by test platform and used to migrate correct db. - env_prelude = [ + manage_py = [ 'env', 'DJANGO_SETTINGS_MODULE=' + self.settings, 'ZULIP_DB_NAME=' + self.database_name, + './manage.py', ] run([ - *env_prelude, './manage.py', 'migrate', '--no-input', + *manage_py, 'migrate', '--no-input' ]) run([ - *env_prelude, './manage.py', 'get_migration_status', '--output='+self.migration_status_file, + *manage_py, 'get_migration_status', '--output='+self.migration_status_file ]) def what_to_do_with_migrations(self) -> str: diff --git a/zerver/lib/test_runner.py b/zerver/lib/test_runner.py index f3473eea56..cb621f884f 100644 --- a/zerver/lib/test_runner.py +++ b/zerver/lib/test_runner.py @@ -79,9 +79,9 @@ class TextTestResult(runner.TextTestResult): def addSkip(self, test: TestCase, reason: str) -> None: TestResult.addSkip(self, test, reason) - self.stream.writeln("** Skipping {}: {}".format( # type: ignore[attr-defined] # https://github.com/python/typeshed/issues/3139 - test.id(), - reason)) + self.stream.writeln( # type: ignore[attr-defined] # https://github.com/python/typeshed/issues/3139 + "** Skipping {}: {}".format(test.id(), reason) + ) self.stream.flush() class RemoteTestResult(django_runner.RemoteTestResult): diff --git a/zerver/lib/upload.py b/zerver/lib/upload.py index 18346830f9..9a1eee1cae 100644 --- a/zerver/lib/upload.py +++ b/zerver/lib/upload.py @@ -182,11 +182,11 @@ def resize_emoji(image_data: bytes, size: int=DEFAULT_EMOJI_SIZE) -> bytes: # results in resized gifs being broken. To work around this we # only resize under certain conditions to minimize the chance of # creating ugly gifs. - should_resize = any(( - im.size[0] != im.size[1], # not square - im.size[0] > MAX_EMOJI_GIF_SIZE, # dimensions too large - len(image_data) > MAX_EMOJI_GIF_FILE_SIZE_BYTES, # filesize too large - )) + should_resize = ( + im.size[0] != im.size[1] # not square + or im.size[0] > MAX_EMOJI_GIF_SIZE # dimensions too large + or len(image_data) > MAX_EMOJI_GIF_FILE_SIZE_BYTES # filesize too large + ) return resize_gif(im, size) if should_resize else image_data else: im = exif_rotate(im) diff --git a/zerver/lib/utils.py b/zerver/lib/utils.py index e33478cb2e..e1fcacf98d 100644 --- a/zerver/lib/utils.py +++ b/zerver/lib/utils.py @@ -153,7 +153,6 @@ def query_chunker(queries: List[Any], q = q.order_by('id') min_id = -1 while True: - assert db_chunk_size is not None # Hint for mypy, but also workaround for mypy bug #3442. rows = list(q.filter(id__gt=min_id)[0:db_chunk_size]) if len(rows) == 0: break diff --git a/zerver/management/commands/email_mirror.py b/zerver/management/commands/email_mirror.py index eba015c8ee..2d3b904b03 100644 --- a/zerver/management/commands/email_mirror.py +++ b/zerver/management/commands/email_mirror.py @@ -53,7 +53,8 @@ def get_imap_messages() -> Generator[EmailMessage, None, None]: assert isinstance(msg_data[0], tuple) msg_as_bytes = msg_data[0][1] message = email.message_from_bytes(msg_as_bytes, policy=email.policy.default) - assert isinstance(message, EmailMessage) # https://github.com/python/typeshed/issues/2417 + # https://github.com/python/typeshed/issues/2417 + assert isinstance(message, EmailMessage) yield message mbox.store(message_id, '+FLAGS', '\\Deleted') mbox.expunge() diff --git a/zerver/management/commands/send_to_email_mirror.py b/zerver/management/commands/send_to_email_mirror.py index 70f030b275..0c0e962566 100644 --- a/zerver/management/commands/send_to_email_mirror.py +++ b/zerver/management/commands/send_to_email_mirror.py @@ -94,7 +94,8 @@ Example: else: with open(fixture_path, "rb") as fp: message = email.message_from_binary_file(fp, policy=email.policy.default) - assert isinstance(message, EmailMessage) # https://github.com/python/typeshed/issues/2417 + # https://github.com/python/typeshed/issues/2417 + assert isinstance(message, EmailMessage) return message def _prepare_message(self, message: EmailMessage, realm: Realm, stream_name: str) -> None: diff --git a/zerver/middleware.py b/zerver/middleware.py index 1c360089d6..f23f8c7038 100644 --- a/zerver/middleware.py +++ b/zerver/middleware.py @@ -383,7 +383,8 @@ class RateLimitMiddleware(MiddlewareMixin): def process_exception(self, request: HttpRequest, exception: Exception) -> Optional[HttpResponse]: if isinstance(exception, RateLimited): - secs_to_freedom = float(str(exception)) # secs_to_freedom is passed to RateLimited when raising + # secs_to_freedom is passed to RateLimited when raising + secs_to_freedom = float(str(exception)) resp = json_error( _("API usage exceeded rate limit"), data={'retry-after': secs_to_freedom}, diff --git a/zerver/models.py b/zerver/models.py index 9d4beaaae8..dda87c3d27 100644 --- a/zerver/models.py +++ b/zerver/models.py @@ -1409,7 +1409,7 @@ def filter_to_valid_prereg_users(query: QuerySet) -> QuerySet: class MultiuseInvite(models.Model): id: int = models.AutoField(auto_created=True, primary_key=True, verbose_name='ID') - referred_by: UserProfile = models.ForeignKey(UserProfile, on_delete=CASCADE) # Optional[UserProfile] + referred_by: UserProfile = models.ForeignKey(UserProfile, on_delete=CASCADE) streams: Manager = models.ManyToManyField('Stream') realm: Realm = models.ForeignKey(Realm, on_delete=CASCADE) invited_as: int = models.PositiveSmallIntegerField(default=PreregistrationUser.INVITE_AS['MEMBER']) @@ -2599,7 +2599,8 @@ class UserPresence(models.Model): @staticmethod def status_from_string(status: str) -> Optional[int]: if status == 'active': - status_val: Optional[int] = UserPresence.ACTIVE # See https://github.com/python/mypy/issues/2611 + # See https://github.com/python/mypy/issues/2611 + status_val: Optional[int] = UserPresence.ACTIVE elif status == 'idle': status_val = UserPresence.IDLE else: diff --git a/zerver/tests/test_auth_backends.py b/zerver/tests/test_auth_backends.py index 509dfc04db..58474d4895 100644 --- a/zerver/tests/test_auth_backends.py +++ b/zerver/tests/test_auth_backends.py @@ -576,7 +576,8 @@ class RateLimitAuthenticationTests(ZulipTestCase): with mock.patch('time.time', return_value=start_time + 11.0): self.assertIsNone(attempt_authentication(username, wrong_password)) - self.assertEqual(attempt_authentication(username, correct_password), expected_user_profile) # Correct password + # Correct password + self.assertEqual(attempt_authentication(username, correct_password), expected_user_profile) # A correct login attempt should reset the rate limits for this user profile, # so the next two attempts shouldn't get limited: self.assertIsNone(attempt_authentication(username, wrong_password)) @@ -1704,7 +1705,7 @@ class SAMLAuthBackendTest(SocialAuthBase): relay_state = orjson.dumps(dict( state_token=SAMLAuthBackend.put_data_in_redis({"subdomain": "zulip"}), )).decode() - post_params = {"RelayState": relay_state, 'SAMLResponse': 'dGVzdA=='} # base64 encoded 'test' + post_params = {"RelayState": relay_state, 'SAMLResponse': base64.b64encode(b"test").decode()} result = self.client_post('/complete/saml/', post_params) self.assertEqual(result.status_code, 302) self.assertIn('login', result.url) @@ -1756,7 +1757,7 @@ class SAMLAuthBackendTest(SocialAuthBase): relay_state = orjson.dumps(dict( state_token=SAMLAuthBackend.put_data_in_redis({"subdomain": "zulip"}), )).decode() - post_params = {"RelayState": relay_state, 'SAMLResponse': 'dGVzdA=='} + post_params = {"RelayState": relay_state, 'SAMLResponse': base64.b64encode(b"test").decode()} result = self.client_post('/complete/saml/', post_params) self.assertEqual(result.status_code, 302) self.assertIn('login', result.url) @@ -4626,7 +4627,8 @@ class TestZulipLDAPUserPopulator(ZulipLDAPTestCase): do_deactivate_user(othello) mock_logger = mock.MagicMock() result = sync_user_from_ldap(othello, mock_logger) - self.assertEqual(mock_logger.method_calls, []) # In this case the logger shouldn't be used. + # In this case the logger shouldn't be used. + self.assertEqual(mock_logger.method_calls, []) self.assertFalse(result) def test_update_user_avatar(self) -> None: diff --git a/zerver/tests/test_email_mirror.py b/zerver/tests/test_email_mirror.py index 5dc05efeb0..5adfd457b3 100644 --- a/zerver/tests/test_email_mirror.py +++ b/zerver/tests/test_email_mirror.py @@ -1290,7 +1290,8 @@ class TestContentTypeUnspecifiedCharset(ZulipTestCase): message_as_string = message_as_string.replace("Content-Type: text/plain; charset=\"us-ascii\"", "Content-Type: text/plain") incoming_message = message_from_string(message_as_string, policy=email.policy.default) - assert isinstance(incoming_message, EmailMessage) # https://github.com/python/typeshed/issues/2417 + # https://github.com/python/typeshed/issues/2417 + assert isinstance(incoming_message, EmailMessage) user_profile = self.example_user('hamlet') self.login_user(user_profile) diff --git a/zerver/tests/test_retention.py b/zerver/tests/test_retention.py index 07d9b05fb5..261dfb6b71 100644 --- a/zerver/tests/test_retention.py +++ b/zerver/tests/test_retention.py @@ -285,7 +285,8 @@ class TestArchiveMessagesGeneral(ArchiveMessagesTestingBase): # Insert an exception near the end of the archiving process of a chunk: with mock.patch("zerver.lib.retention.delete_messages", side_effect=Exception): with self.assertRaises(Exception): - archive_messages(chunk_size=1000) # Specify large chunk_size to ensure things happen in a single batch + # Specify large chunk_size to ensure things happen in a single batch + archive_messages(chunk_size=1000) # Archiving code has been executed, but because we got an exception, things should have been rolled back: self._verify_archive_data([], []) @@ -373,7 +374,8 @@ class TestArchiveMessagesGeneral(ArchiveMessagesTestingBase): restore_all_data_from_archive() # Attachments should have been restored: self.assertEqual(Attachment.objects.count(), 3) - self.assertEqual(ArchivedAttachment.objects.count(), 3) # Archived data doesn't get deleted by restoring. + # Archived data doesn't get deleted by restoring. + self.assertEqual(ArchivedAttachment.objects.count(), 3) self.assertEqual( list(Attachment.objects.distinct('messages__id').order_by('messages__id').values_list( 'messages__id', flat=True)), diff --git a/zerver/tests/test_slack_message_conversion.py b/zerver/tests/test_slack_message_conversion.py index 103e9e32f0..a023f3eded 100644 --- a/zerver/tests/test_slack_message_conversion.py +++ b/zerver/tests/test_slack_message_conversion.py @@ -64,7 +64,8 @@ class SlackMessageConversion(ZulipTestCase): {"id": "U09TYF5Sk", "name": "Jane", "is_mirror_dummy": False, - "deleted": True}] # Deleted users don't have 'real_name' key in Slack + "deleted": True, # Deleted users don't have 'real_name' key in Slack + }] channel_map = {'general': ('C5Z73A7RA', 137)} message = 'Hi <@U08RGD1RD|john>: How are you? <#C5Z73A7RA|general>' text, mentioned_users, has_link = convert_to_zulip_markdown(message, users, channel_map, slack_user_map) diff --git a/zerver/tests/test_subs.py b/zerver/tests/test_subs.py index 22c23e380a..0a1e63660f 100644 --- a/zerver/tests/test_subs.py +++ b/zerver/tests/test_subs.py @@ -3392,7 +3392,8 @@ class SubscriptionAPITest(ZulipTestCase): self.assert_json_success(result) json = result.json() for key, val in json_dict.items(): - self.assertEqual(sorted(val), sorted(json[key])) # we don't care about the order of the items + # we don't care about the order of the items + self.assertEqual(sorted(val), sorted(json[key])) user = get_user(email, realm) new_streams = self.get_streams(user) self.assertEqual(sorted(new_streams), sorted(new_subs)) @@ -3425,7 +3426,8 @@ class SubscriptionAPITest(ZulipTestCase): """ random_streams = self.make_random_stream_names(self.streams) self.assertNotEqual(len(random_streams), 0) # necessary for full test coverage - streams_to_remove = random_streams[:1] # pick only one fake stream, to make checking the error message easy + # pick only one fake stream, to make checking the error message easy + streams_to_remove = random_streams[:1] result = self.client_delete("/json/users/me/subscriptions", {"subscriptions": orjson.dumps(streams_to_remove).decode()}) self.assert_json_error(result, f"Stream(s) ({random_streams[0]}) do not exist") diff --git a/zerver/tornado/event_queue.py b/zerver/tornado/event_queue.py index e54e51478a..e47798e149 100644 --- a/zerver/tornado/event_queue.py +++ b/zerver/tornado/event_queue.py @@ -256,7 +256,8 @@ class EventQueue: self.queue: Deque[Dict[str, Any]] = deque() self.next_event_id: int = 0 - self.newest_pruned_id: Optional[int] = -1 # will only be None for migration from old versions + # will only be None for migration from old versions + self.newest_pruned_id: Optional[int] = -1 self.id: str = id self.virtual_events: Dict[str, Dict[str, Any]] = {} diff --git a/zerver/views/auth.py b/zerver/views/auth.py index a1a5f27ba9..eca2c9f557 100644 --- a/zerver/views/auth.py +++ b/zerver/views/auth.py @@ -558,7 +558,8 @@ def log_into_subdomain(request: HttpRequest, token: str) -> HttpResponse: call login_or_register_remote_user, passing all the authentication result data that has been stored in redis, associated with this token. """ - if not has_api_key_format(token): # The tokens are intended to have the same format as API keys. + # The tokens are intended to have the same format as API keys. + if not has_api_key_format(token): logging.warning("log_into_subdomain: Malformed token given: %s", token) return HttpResponse(status=400) diff --git a/zerver/views/video_calls.py b/zerver/views/video_calls.py index ac5e4ff02e..b435717f7d 100644 --- a/zerver/views/video_calls.py +++ b/zerver/views/video_calls.py @@ -208,11 +208,14 @@ def join_bigbluebutton(request: HttpRequest, meeting_id: str = REQ(validator=che if payload.find("returncode").text != "SUCCESS": return json_error(_("Big Blue Button server returned an unexpected error.")) - join_params = urlencode({ # type: ignore[type-var] # https://github.com/python/typeshed/issues/4234 - "meetingID": meeting_id, - "password": password, - "fullName": request.user.full_name - }, quote_via=quote) + join_params = urlencode( # type: ignore[type-var] # https://github.com/python/typeshed/issues/4234 + { + "meetingID": meeting_id, + "password": password, + "fullName": request.user.full_name, + }, + quote_via=quote, + ) checksum = hashlib.sha1(("join" + join_params + settings.BIG_BLUE_BUTTON_SECRET).encode()).hexdigest() redirect_url_base = add_query_to_redirect_url(settings.BIG_BLUE_BUTTON_URL + "api/join", join_params) diff --git a/zerver/webhooks/bitbucket3/view.py b/zerver/webhooks/bitbucket3/view.py index e0a509392f..37b9b91905 100644 --- a/zerver/webhooks/bitbucket3/view.py +++ b/zerver/webhooks/bitbucket3/view.py @@ -71,7 +71,7 @@ def repo_comment_handler(payload: Dict[str, Any], action: str) -> List[Dict[str, repo_name = payload["repository"]["name"] subject = BITBUCKET_TOPIC_TEMPLATE.format(repository_name=repo_name) sha = payload["commit"] - commit_url = payload["repository"]["links"]["self"][0]["href"][:-6] # remove the "browse" at the end + commit_url = payload["repository"]["links"]["self"][0]["href"][: -len("browse")] commit_url += f"commits/{sha}" message = payload["comment"]["text"] if action == "deleted their comment": diff --git a/zerver/webhooks/gitlab/tests.py b/zerver/webhooks/gitlab/tests.py index 299d43f4b7..2dbeab5fad 100644 --- a/zerver/webhooks/gitlab/tests.py +++ b/zerver/webhooks/gitlab/tests.py @@ -238,7 +238,8 @@ class GitlabHookTests(WebhookTestCase): def test_note_merge_request_event_message_without_merge_request_title(self) -> None: expected_topic = "my-awesome-project / MR #1" expected_message = "Tomasz Kolek [commented](https://gitlab.com/tomaszkolek0/my-awesome-project/merge_requests/1#note_14171860) on [MR #1](https://gitlab.com/tomaszkolek0/my-awesome-project/merge_requests/1):\n\n~~~ quote\nNice merge request!\n~~~" - self.url = self.build_webhook_url(use_merge_request_title="false") # To keep things as valid JSON. + # To keep things as valid JSON. + self.url = self.build_webhook_url(use_merge_request_title="false") self.check_webhook("note_hook__merge_request_note", expected_topic, expected_message) def test_note_merge_request_with_custom_topic_in_url(self) -> None: diff --git a/zproject/backends.py b/zproject/backends.py index c6951c8ab3..8ee19e16a7 100644 --- a/zproject/backends.py +++ b/zproject/backends.py @@ -1045,7 +1045,8 @@ class ZulipRemoteUserBackend(RemoteUserBackend, ExternalAuthMethod): auth_backend_name = "RemoteUser" name = "remoteuser" display_icon = None - sort_order = 9000 # If configured, this backend should have its button near the top of the list. + # If configured, this backend should have its button near the top of the list. + sort_order = 9000 create_unknown_user = False @@ -1199,7 +1200,8 @@ def social_associate_user_helper(backend: BaseAuth, return_data: Dict[str, Any], # Some authentications methods like Apple and SAML send # first name and last name as separate attributes. In that case # we construct the full name from them. - return_data["full_name"] = f"{first_name or ''} {last_name or ''}".strip() # strip removes the unnecessary ' ' + # strip removes the unnecessary ' ' + return_data["full_name"] = f"{first_name or ''} {last_name or ''}".strip() return user_profile diff --git a/zproject/computed_settings.py b/zproject/computed_settings.py index 4431604b85..72b3529faa 100644 --- a/zproject/computed_settings.py +++ b/zproject/computed_settings.py @@ -469,19 +469,24 @@ TWITTER_ACCESS_TOKEN_SECRET = get_secret("twitter_access_token_secret") # These are the bots that Zulip sends automated messages as. INTERNAL_BOTS = [{'var_name': 'NOTIFICATION_BOT', 'email_template': 'notification-bot@%s', - 'name': 'Notification Bot'}, + 'name': 'Notification Bot', + }, {'var_name': 'EMAIL_GATEWAY_BOT', 'email_template': 'emailgateway@%s', - 'name': 'Email Gateway'}, + 'name': 'Email Gateway', + }, {'var_name': 'NAGIOS_SEND_BOT', 'email_template': 'nagios-send-bot@%s', - 'name': 'Nagios Send Bot'}, + 'name': 'Nagios Send Bot', + }, {'var_name': 'NAGIOS_RECEIVE_BOT', 'email_template': 'nagios-receive-bot@%s', - 'name': 'Nagios Receive Bot'}, + 'name': 'Nagios Receive Bot', + }, {'var_name': 'WELCOME_BOT', 'email_template': 'welcome-bot@%s', - 'name': 'Welcome Bot'}] + 'name': 'Welcome Bot', + }] # Bots that are created for each realm like the reminder-bot goes here. REALM_INTERNAL_BOTS: List[Dict[str, str]] = [] @@ -490,17 +495,20 @@ REALM_INTERNAL_BOTS: List[Dict[str, str]] = [] DISABLED_REALM_INTERNAL_BOTS = [ {'var_name': 'REMINDER_BOT', 'email_template': 'reminder-bot@%s', - 'name': 'Reminder Bot'}, + 'name': 'Reminder Bot', + }, ] if PRODUCTION: INTERNAL_BOTS += [ {'var_name': 'NAGIOS_STAGING_SEND_BOT', 'email_template': 'nagios-staging-send-bot@%s', - 'name': 'Nagios Staging Send Bot'}, + 'name': 'Nagios Staging Send Bot', + }, {'var_name': 'NAGIOS_STAGING_RECEIVE_BOT', 'email_template': 'nagios-staging-receive-bot@%s', - 'name': 'Nagios Staging Receive Bot'}, + 'name': 'Nagios Staging Receive Bot', + }, ] INTERNAL_BOT_DOMAIN = "zulip.com"