python: Reformat with Ruff formatter.

https://docs.astral.sh/ruff/formatter/

Signed-off-by: Anders Kaseorg <anders@zulip.com>
This commit is contained in:
Anders Kaseorg 2023-12-05 09:45:07 -08:00 committed by Tim Abbott
parent c85b2edbd4
commit 570f3dd447
68 changed files with 137 additions and 184 deletions

View File

@ -1461,9 +1461,7 @@ class TestLoggingCountStats(AnalyticsTestCase):
), mock.patch("zilencer.views.send_apple_push_notification", return_value=1), mock.patch( ), mock.patch("zilencer.views.send_apple_push_notification", return_value=1), mock.patch(
"corporate.lib.stripe.RemoteServerBillingSession.current_count_for_billed_licenses", "corporate.lib.stripe.RemoteServerBillingSession.current_count_for_billed_licenses",
return_value=10, return_value=10,
), self.assertLogs( ), self.assertLogs("zilencer.views", level="INFO"):
"zilencer.views", level="INFO"
):
result = self.uuid_post( result = self.uuid_post(
self.server_uuid, self.server_uuid,
"/api/v1/remotes/push/notify", "/api/v1/remotes/push/notify",
@ -1522,9 +1520,7 @@ class TestLoggingCountStats(AnalyticsTestCase):
), mock.patch("zilencer.views.send_apple_push_notification", return_value=1), mock.patch( ), mock.patch("zilencer.views.send_apple_push_notification", return_value=1), mock.patch(
"corporate.lib.stripe.RemoteServerBillingSession.current_count_for_billed_licenses", "corporate.lib.stripe.RemoteServerBillingSession.current_count_for_billed_licenses",
return_value=10, return_value=10,
), self.assertLogs( ), self.assertLogs("zilencer.views", level="INFO"):
"zilencer.views", level="INFO"
):
result = self.uuid_post( result = self.uuid_post(
self.server_uuid, self.server_uuid,
"/api/v1/remotes/push/notify", "/api/v1/remotes/push/notify",
@ -1582,9 +1578,7 @@ class TestLoggingCountStats(AnalyticsTestCase):
), mock.patch("zilencer.views.send_apple_push_notification", return_value=1), mock.patch( ), mock.patch("zilencer.views.send_apple_push_notification", return_value=1), mock.patch(
"corporate.lib.stripe.RemoteRealmBillingSession.current_count_for_billed_licenses", "corporate.lib.stripe.RemoteRealmBillingSession.current_count_for_billed_licenses",
return_value=10, return_value=10,
), self.assertLogs( ), self.assertLogs("zilencer.views", level="INFO"):
"zilencer.views", level="INFO"
):
result = self.uuid_post( result = self.uuid_post(
self.server_uuid, self.server_uuid,
"/api/v1/remotes/push/notify", "/api/v1/remotes/push/notify",

View File

@ -38,7 +38,7 @@ def is_self_hosting_management_subdomain(request: HttpRequest) -> bool:
def self_hosting_management_endpoint( def self_hosting_management_endpoint(
view_func: Callable[Concatenate[HttpRequest, ParamT], HttpResponse] view_func: Callable[Concatenate[HttpRequest, ParamT], HttpResponse],
) -> Callable[Concatenate[HttpRequest, ParamT], HttpResponse]: ) -> Callable[Concatenate[HttpRequest, ParamT], HttpResponse]:
@wraps(view_func) @wraps(view_func)
def _wrapped_view_func( def _wrapped_view_func(
@ -52,7 +52,7 @@ def self_hosting_management_endpoint(
def authenticated_remote_realm_management_endpoint( def authenticated_remote_realm_management_endpoint(
view_func: Callable[Concatenate[HttpRequest, RemoteRealmBillingSession, ParamT], HttpResponse] view_func: Callable[Concatenate[HttpRequest, RemoteRealmBillingSession, ParamT], HttpResponse],
) -> Callable[Concatenate[HttpRequest, ParamT], HttpResponse]: ) -> Callable[Concatenate[HttpRequest, ParamT], HttpResponse]:
@wraps(view_func) @wraps(view_func)
def _wrapped_view_func( def _wrapped_view_func(
@ -152,7 +152,7 @@ def get_next_page_param_from_request_path(request: HttpRequest) -> Optional[str]
def authenticated_remote_server_management_endpoint( def authenticated_remote_server_management_endpoint(
view_func: Callable[Concatenate[HttpRequest, RemoteServerBillingSession, ParamT], HttpResponse] view_func: Callable[Concatenate[HttpRequest, RemoteServerBillingSession, ParamT], HttpResponse],
) -> Callable[Concatenate[HttpRequest, ParamT], HttpResponse]: ) -> Callable[Concatenate[HttpRequest, ParamT], HttpResponse]:
@wraps(view_func) @wraps(view_func)
def _wrapped_view_func( def _wrapped_view_func(

View File

@ -5,7 +5,6 @@ from django.db import migrations, models
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [
("corporate", "0037_customerplanoffer"), ("corporate", "0037_customerplanoffer"),
] ]

View File

@ -51,7 +51,6 @@ def backfill_end_date_for_fixed_price_plans(
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [
("corporate", "0038_customerplanoffer_sent_invoice_id_invoice"), ("corporate", "0038_customerplanoffer_sent_invoice_id_invoice"),
] ]

View File

@ -4,7 +4,6 @@ from django.db import migrations, models
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [
("corporate", "0039_backfill_end_date_for_fixed_price_plans"), ("corporate", "0039_backfill_end_date_for_fixed_price_plans"),
] ]

View File

@ -143,7 +143,7 @@ def get_identity_dict_from_signed_access_token(
def is_tos_consent_needed_for_user( def is_tos_consent_needed_for_user(
remote_user: Union[RemoteRealmBillingUser, RemoteServerBillingUser] remote_user: Union[RemoteRealmBillingUser, RemoteServerBillingUser],
) -> bool: ) -> bool:
assert settings.TERMS_OF_SERVICE_VERSION is not None assert settings.TERMS_OF_SERVICE_VERSION is not None
return int(settings.TERMS_OF_SERVICE_VERSION.split(".")[0]) > int( return int(settings.TERMS_OF_SERVICE_VERSION.split(".")[0]) > int(
@ -323,9 +323,9 @@ def remote_realm_billing_finalize_login(
identity_dict["remote_billing_user_id"] = remote_user.id identity_dict["remote_billing_user_id"] = remote_user.id
request.session["remote_billing_identities"] = {} request.session["remote_billing_identities"] = {}
request.session["remote_billing_identities"][ request.session["remote_billing_identities"][f"remote_realm:{remote_realm_uuid}"] = (
f"remote_realm:{remote_realm_uuid}" identity_dict
] = identity_dict )
next_page = identity_dict["next_page"] next_page = identity_dict["next_page"]
assert next_page in VALID_NEXT_PAGES assert next_page in VALID_NEXT_PAGES

View File

@ -8,6 +8,7 @@ This script works by just monitoring the files under
mirrors when they receive the messages sent every minute by mirrors when they receive the messages sent every minute by
/etc/cron.d/test_zephyr_personal_mirrors /etc/cron.d/test_zephyr_personal_mirrors
""" """
import os import os
import sys import sys
import time import time

View File

@ -6,6 +6,7 @@ Nagios plugin to check that our MIT users' Zephyr mirrors are running.
It must be run on a machine that is using the live database for the It must be run on a machine that is using the live database for the
Django ORM. Django ORM.
""" """
import os import os
import sys import sys
from datetime import timedelta from datetime import timedelta

View File

@ -9,6 +9,7 @@ run out of cron.
See puppet/kandra/files/cron.d/zephyr-mirror for the crontab details. See puppet/kandra/files/cron.d/zephyr-mirror for the crontab details.
""" """
import os import os
import sys import sys
import time import time

View File

@ -1,7 +1,9 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
""" Nagios plugin paired with a cron job. This just verifies that the """
Nagios plugin paired with a cron job. This just verifies that the
file output by the cron job is correct. file output by the cron job is correct.
""" """
import sys import sys
import time import time
from typing import Tuple from typing import Tuple

View File

@ -3,6 +3,7 @@
""" """
Nagios plugin to check that none of our queue workers have reported errors. Nagios plugin to check that none of our queue workers have reported errors.
""" """
import glob import glob
import os import os
import sys import sys

View File

@ -6,6 +6,7 @@ Script to provide information about send-receive times.
It must be run on a machine that is using the live database for the It must be run on a machine that is using the live database for the
Django ORM. Django ORM.
""" """
import argparse import argparse
import os import os
import random import random

View File

@ -6,6 +6,7 @@ connects to PostgreSQL as has been granted the `pg_monitor` role.
This can only use stdlib modules from python. This can only use stdlib modules from python.
""" """
import configparser import configparser
import re import re
import subprocess import subprocess

View File

@ -150,6 +150,7 @@ ignore = [
"E402", # Module level import not at top of file "E402", # Module level import not at top of file
"E501", # Line too long "E501", # Line too long
"E731", # Do not assign a lambda expression, use a def "E731", # Do not assign a lambda expression, use a def
"ISC001", # Implicitly concatenated string literals on one line
"N802", # Function name should be lowercase "N802", # Function name should be lowercase
"N806", # Variable in function should be lowercase "N806", # Variable in function should be lowercase
"PERF203", # `try`-`except` within a loop incurs performance overhead "PERF203", # `try`-`except` within a loop incurs performance overhead

View File

@ -38,8 +38,8 @@ Also you can use optional keys to configure the script and change default values
self-signed certificates. Default value: False. self-signed certificates. Default value: False.
-t Disable sending request to the Zulip server. Default value: False. -t Disable sending request to the Zulip server. Default value: False.
""" """
import argparse import argparse
import base64 import base64
import json import json

View File

@ -31,7 +31,7 @@ FAIL = "\033[91m"
ENDC = "\033[0m" ENDC = "\033[0m"
BLACKONYELLOW = "\x1b[0;30;43m" BLACKONYELLOW = "\x1b[0;30;43m"
WHITEONRED = "\x1b[0;37;41m" WHITEONRED = "\x1b[0;37;41m"
BOLDRED = "\x1B[1;31m" BOLDRED = "\x1b[1;31m"
BOLD = "\x1b[1m" BOLD = "\x1b[1m"
GRAY = "\x1b[90m" GRAY = "\x1b[90m"

View File

@ -239,8 +239,6 @@ if change_symlink and "PWD" in os.environ:
which has now changed. Your shell will not see this change until you run: which has now changed. Your shell will not see this change until you run:
cd {} cd {}
to traverse the symlink again.{} to traverse the symlink again.{}
""".format( """.format(WARNING, symlink, shlex.quote(os.environ["PWD"]), ENDC),
WARNING, symlink, shlex.quote(os.environ["PWD"]), ENDC
),
file=sys.stderr, file=sys.stderr,
) )

View File

@ -3,6 +3,7 @@
Fetch contributors data from GitHub using their API, convert it to structured Fetch contributors data from GitHub using their API, convert it to structured
JSON data for the /team/ page contributors section. JSON data for the /team/ page contributors section.
""" """
import argparse import argparse
import json import json
import logging import logging

View File

@ -1,7 +1,6 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import argparse import argparse
import os import os
import re
import sys import sys
tools_dir = os.path.dirname(os.path.abspath(__file__)) tools_dir = os.path.dirname(os.path.abspath(__file__))
@ -168,13 +167,11 @@ def run() -> None:
description="Formats CSS, JavaScript, YAML", description="Formats CSS, JavaScript, YAML",
) )
linter_config.external_linter( linter_config.external_linter(
"black", "ruff-format",
["black"], ["ruff", "format"],
["py", "pyi"], ["py", "pyi"],
description="Reformats Python code", description="Reformats Python code",
check_arg=["--check"], check_arg=["--check"],
suppress_line=lambda line: line == "All done! ✨ 🍰 ✨\n"
or re.fullmatch(r"\d+ files? would be left unchanged\.\n", line) is not None,
) )
semgrep_command = [ semgrep_command = [

View File

@ -107,7 +107,7 @@ def emoji_is_supported(emoji_dict: Dict[str, Any]) -> bool:
def generate_codepoint_to_names_map( def generate_codepoint_to_names_map(
emoji_name_maps: Dict[str, Dict[str, Any]] emoji_name_maps: Dict[str, Dict[str, Any]],
) -> Dict[str, List[str]]: ) -> Dict[str, List[str]]:
# The first element of the names list is always the canonical name. # The first element of the names list is always the canonical name.
return { return {

View File

@ -133,9 +133,7 @@ def do_update_user_presence(
# and also is under the risk of being shown by clients as offline before the next regular presence checkin # and also is under the risk of being shown by clients as offline before the next regular presence checkin
# (so at least `settings.OFFLINE_THRESHOLD_SECS - settings.PRESENCE_PING_INTERVAL_SECS - 10`). # (so at least `settings.OFFLINE_THRESHOLD_SECS - settings.PRESENCE_PING_INTERVAL_SECS - 10`).
# These two values happen to be the same in the default configuration. # These two values happen to be the same in the default configuration.
seconds=settings.OFFLINE_THRESHOLD_SECS seconds=settings.OFFLINE_THRESHOLD_SECS - settings.PRESENCE_PING_INTERVAL_SECS - 10
- settings.PRESENCE_PING_INTERVAL_SECS
- 10
) )
became_online = status == UserPresence.LEGACY_STATUS_ACTIVE_INT and now_online became_online = status == UserPresence.LEGACY_STATUS_ACTIVE_INT and now_online

View File

@ -93,9 +93,8 @@ def zulip_default_corporate_context(request: HttpRequest) -> Dict[str, Any]:
from corporate.lib.decorator import is_self_hosting_management_subdomain from corporate.lib.decorator import is_self_hosting_management_subdomain
# Check if view function is in corporate app. # Check if view function is in corporate app.
if ( if request.resolver_match is not None and not request.resolver_match.func.__module__.startswith(
request.resolver_match is not None "corporate"
and not request.resolver_match.func.__module__.startswith("corporate")
): ):
return { return {
"is_self_hosting_management_page": False, "is_self_hosting_management_page": False,

View File

@ -806,7 +806,7 @@ def write_emoticon_data(
def create_username_to_user_mapping( def create_username_to_user_mapping(
user_data_list: List[Dict[str, Any]] user_data_list: List[Dict[str, Any]],
) -> Dict[str, Dict[str, Any]]: ) -> Dict[str, Dict[str, Any]]:
username_to_user = {} username_to_user = {}
for user in user_data_list: for user in user_data_list:

View File

@ -105,7 +105,7 @@ def update_user_activity(
# Based on django.views.decorators.http.require_http_methods # Based on django.views.decorators.http.require_http_methods
def require_post( def require_post(
func: Callable[Concatenate[HttpRequest, ParamT], HttpResponse] func: Callable[Concatenate[HttpRequest, ParamT], HttpResponse],
) -> Callable[Concatenate[HttpRequest, ParamT], HttpResponse]: ) -> Callable[Concatenate[HttpRequest, ParamT], HttpResponse]:
# Arguments before ParamT needs to be positional-only as required by Concatenate # Arguments before ParamT needs to be positional-only as required by Concatenate
@wraps(func) @wraps(func)
@ -132,7 +132,7 @@ def require_post(
def require_realm_owner( def require_realm_owner(
func: Callable[Concatenate[HttpRequest, UserProfile, ParamT], HttpResponse] func: Callable[Concatenate[HttpRequest, UserProfile, ParamT], HttpResponse],
) -> Callable[Concatenate[HttpRequest, UserProfile, ParamT], HttpResponse]: ) -> Callable[Concatenate[HttpRequest, UserProfile, ParamT], HttpResponse]:
@wraps(func) @wraps(func)
def wrapper( def wrapper(
@ -150,7 +150,7 @@ def require_realm_owner(
def require_realm_admin( def require_realm_admin(
func: Callable[Concatenate[HttpRequest, UserProfile, ParamT], HttpResponse] func: Callable[Concatenate[HttpRequest, UserProfile, ParamT], HttpResponse],
) -> Callable[Concatenate[HttpRequest, UserProfile, ParamT], HttpResponse]: ) -> Callable[Concatenate[HttpRequest, UserProfile, ParamT], HttpResponse]:
@wraps(func) @wraps(func)
def wrapper( def wrapper(
@ -168,7 +168,7 @@ def require_realm_admin(
def require_organization_member( def require_organization_member(
func: Callable[Concatenate[HttpRequest, UserProfile, ParamT], HttpResponse] func: Callable[Concatenate[HttpRequest, UserProfile, ParamT], HttpResponse],
) -> Callable[Concatenate[HttpRequest, UserProfile, ParamT], HttpResponse]: ) -> Callable[Concatenate[HttpRequest, UserProfile, ParamT], HttpResponse]:
@wraps(func) @wraps(func)
def wrapper( def wrapper(
@ -186,7 +186,7 @@ def require_organization_member(
def require_billing_access( def require_billing_access(
func: Callable[Concatenate[HttpRequest, UserProfile, ParamT], HttpResponse] func: Callable[Concatenate[HttpRequest, UserProfile, ParamT], HttpResponse],
) -> Callable[Concatenate[HttpRequest, UserProfile, ParamT], HttpResponse]: ) -> Callable[Concatenate[HttpRequest, UserProfile, ParamT], HttpResponse]:
@wraps(func) @wraps(func)
def wrapper( def wrapper(
@ -429,7 +429,7 @@ def user_passes_test(
""" """
def decorator( def decorator(
view_func: Callable[Concatenate[HttpRequest, ParamT], HttpResponse] view_func: Callable[Concatenate[HttpRequest, ParamT], HttpResponse],
) -> Callable[Concatenate[HttpRequest, ParamT], HttpResponse]: ) -> Callable[Concatenate[HttpRequest, ParamT], HttpResponse]:
@wraps(view_func) @wraps(view_func)
def _wrapped_view( def _wrapped_view(
@ -481,9 +481,9 @@ def do_login(request: HttpRequest, user_profile: UserProfile) -> None:
assert isinstance(validated_user_profile, UserProfile) assert isinstance(validated_user_profile, UserProfile)
django_login(request, validated_user_profile) django_login(request, validated_user_profile)
RequestNotes.get_notes(request).requester_for_logs = ( RequestNotes.get_notes(
validated_user_profile.format_requester_for_logs() request
) ).requester_for_logs = validated_user_profile.format_requester_for_logs()
process_client(request, validated_user_profile, is_browser_view=True) process_client(request, validated_user_profile, is_browser_view=True)
if settings.TWO_FACTOR_AUTHENTICATION_ENABLED: if settings.TWO_FACTOR_AUTHENTICATION_ENABLED:
# Log in with two factor authentication as well. # Log in with two factor authentication as well.
@ -491,7 +491,7 @@ def do_login(request: HttpRequest, user_profile: UserProfile) -> None:
def log_view_func( def log_view_func(
view_func: Callable[Concatenate[HttpRequest, ParamT], HttpResponse] view_func: Callable[Concatenate[HttpRequest, ParamT], HttpResponse],
) -> Callable[Concatenate[HttpRequest, ParamT], HttpResponse]: ) -> Callable[Concatenate[HttpRequest, ParamT], HttpResponse]:
@wraps(view_func) @wraps(view_func)
def _wrapped_view_func( def _wrapped_view_func(
@ -504,7 +504,7 @@ def log_view_func(
def add_logging_data( def add_logging_data(
view_func: Callable[Concatenate[HttpRequest, ParamT], HttpResponse] view_func: Callable[Concatenate[HttpRequest, ParamT], HttpResponse],
) -> Callable[Concatenate[HttpRequest, ParamT], HttpResponse]: ) -> Callable[Concatenate[HttpRequest, ParamT], HttpResponse]:
@wraps(view_func) @wraps(view_func)
def _wrapped_view_func( def _wrapped_view_func(
@ -523,7 +523,7 @@ def add_logging_data(
def human_users_only( def human_users_only(
view_func: Callable[Concatenate[HttpRequest, ParamT], HttpResponse] view_func: Callable[Concatenate[HttpRequest, ParamT], HttpResponse],
) -> Callable[Concatenate[HttpRequest, ParamT], HttpResponse]: ) -> Callable[Concatenate[HttpRequest, ParamT], HttpResponse]:
@wraps(view_func) @wraps(view_func)
def _wrapped_view_func( def _wrapped_view_func(
@ -597,7 +597,7 @@ def web_public_view(
def require_server_admin( def require_server_admin(
view_func: Callable[Concatenate[HttpRequest, ParamT], HttpResponse] view_func: Callable[Concatenate[HttpRequest, ParamT], HttpResponse],
) -> Callable[Concatenate[HttpRequest, ParamT], HttpResponse]: ) -> Callable[Concatenate[HttpRequest, ParamT], HttpResponse]:
@zulip_login_required @zulip_login_required
@wraps(view_func) @wraps(view_func)
@ -613,7 +613,7 @@ def require_server_admin(
def require_server_admin_api( def require_server_admin_api(
view_func: Callable[Concatenate[HttpRequest, ParamT], HttpResponse] view_func: Callable[Concatenate[HttpRequest, ParamT], HttpResponse],
) -> Callable[Concatenate[HttpRequest, ParamT], HttpResponse]: ) -> Callable[Concatenate[HttpRequest, ParamT], HttpResponse]:
@zulip_login_required @zulip_login_required
@wraps(view_func) @wraps(view_func)
@ -631,7 +631,7 @@ def require_server_admin_api(
def require_non_guest_user( def require_non_guest_user(
view_func: Callable[Concatenate[HttpRequest, UserProfile, ParamT], HttpResponse] view_func: Callable[Concatenate[HttpRequest, UserProfile, ParamT], HttpResponse],
) -> Callable[Concatenate[HttpRequest, UserProfile, ParamT], HttpResponse]: ) -> Callable[Concatenate[HttpRequest, UserProfile, ParamT], HttpResponse]:
@wraps(view_func) @wraps(view_func)
def _wrapped_view_func( def _wrapped_view_func(
@ -649,7 +649,7 @@ def require_non_guest_user(
def require_member_or_admin( def require_member_or_admin(
view_func: Callable[Concatenate[HttpRequest, UserProfile, ParamT], HttpResponse] view_func: Callable[Concatenate[HttpRequest, UserProfile, ParamT], HttpResponse],
) -> Callable[Concatenate[HttpRequest, UserProfile, ParamT], HttpResponse]: ) -> Callable[Concatenate[HttpRequest, UserProfile, ParamT], HttpResponse]:
@wraps(view_func) @wraps(view_func)
def _wrapped_view_func( def _wrapped_view_func(
@ -669,7 +669,7 @@ def require_member_or_admin(
def require_user_group_edit_permission( def require_user_group_edit_permission(
view_func: Callable[Concatenate[HttpRequest, UserProfile, ParamT], HttpResponse] view_func: Callable[Concatenate[HttpRequest, UserProfile, ParamT], HttpResponse],
) -> Callable[Concatenate[HttpRequest, UserProfile, ParamT], HttpResponse]: ) -> Callable[Concatenate[HttpRequest, UserProfile, ParamT], HttpResponse]:
@require_member_or_admin @require_member_or_admin
@wraps(view_func) @wraps(view_func)
@ -756,7 +756,7 @@ def authenticated_rest_api_view(
allow_webhook_access = True allow_webhook_access = True
def _wrapped_view_func( def _wrapped_view_func(
view_func: Callable[Concatenate[HttpRequest, UserProfile, ParamT], HttpResponse] view_func: Callable[Concatenate[HttpRequest, UserProfile, ParamT], HttpResponse],
) -> Callable[Concatenate[HttpRequest, ParamT], HttpResponse]: ) -> Callable[Concatenate[HttpRequest, ParamT], HttpResponse]:
@csrf_exempt @csrf_exempt
@wraps(view_func) @wraps(view_func)
@ -809,7 +809,7 @@ def authenticated_rest_api_view(
def process_as_post( def process_as_post(
view_func: Callable[Concatenate[HttpRequest, ParamT], HttpResponse] view_func: Callable[Concatenate[HttpRequest, ParamT], HttpResponse],
) -> Callable[Concatenate[HttpRequest, ParamT], HttpResponse]: ) -> Callable[Concatenate[HttpRequest, ParamT], HttpResponse]:
@wraps(view_func) @wraps(view_func)
def _wrapped_view_func( def _wrapped_view_func(
@ -938,7 +938,7 @@ def internal_api_view(
the server.""" the server."""
def _wrapped_view_func( def _wrapped_view_func(
view_func: Callable[Concatenate[HttpRequest, ParamT], HttpResponse] view_func: Callable[Concatenate[HttpRequest, ParamT], HttpResponse],
) -> Callable[Concatenate[HttpRequest, ParamT], HttpResponse]: ) -> Callable[Concatenate[HttpRequest, ParamT], HttpResponse]:
@csrf_exempt @csrf_exempt
@require_post @require_post
@ -969,7 +969,7 @@ def to_utc_datetime(var_name: str, timestamp: str) -> datetime:
def return_success_on_head_request( def return_success_on_head_request(
view_func: Callable[Concatenate[HttpRequest, ParamT], HttpResponse] view_func: Callable[Concatenate[HttpRequest, ParamT], HttpResponse],
) -> Callable[Concatenate[HttpRequest, ParamT], HttpResponse]: ) -> Callable[Concatenate[HttpRequest, ParamT], HttpResponse]:
@wraps(view_func) @wraps(view_func)
def _wrapped_view_func( def _wrapped_view_func(
@ -1044,7 +1044,7 @@ def add_google_analytics_context(context: Dict[str, object]) -> None:
def add_google_analytics( def add_google_analytics(
view_func: Callable[Concatenate[HttpRequest, ParamT], HttpResponse] view_func: Callable[Concatenate[HttpRequest, ParamT], HttpResponse],
) -> Callable[Concatenate[HttpRequest, ParamT], HttpResponse]: ) -> Callable[Concatenate[HttpRequest, ParamT], HttpResponse]:
@wraps(view_func) @wraps(view_func)
def _wrapped_view_func( def _wrapped_view_func(

View File

@ -724,7 +724,8 @@ class IgnoreUnhashableLruCacheWrapper(Generic[ParamT, ReturnT]):
try: try:
return self.cached_function( return self.cached_function(
*args, **kwargs # type: ignore[arg-type] # might be unhashable *args,
**kwargs, # type: ignore[arg-type] # might be unhashable
) )
except TypeError: except TypeError:
# args or kwargs contains an element which is unhashable. In # args or kwargs contains an element which is unhashable. In
@ -750,7 +751,7 @@ def ignore_unhashable_lru_cache(
internal_decorator = lru_cache(maxsize=maxsize, typed=typed) internal_decorator = lru_cache(maxsize=maxsize, typed=typed)
def decorator( def decorator(
user_function: Callable[ParamT, ReturnT] user_function: Callable[ParamT, ReturnT],
) -> IgnoreUnhashableLruCacheWrapper[ParamT, ReturnT]: ) -> IgnoreUnhashableLruCacheWrapper[ParamT, ReturnT]:
return IgnoreUnhashableLruCacheWrapper(user_function, internal_decorator(user_function)) return IgnoreUnhashableLruCacheWrapper(user_function, internal_decorator(user_function))

View File

@ -60,7 +60,7 @@ def generate_dev_ldap_dir(mode: str, num_users: int = 8) -> Dict[str, Dict[str,
def init_fakeldap( def init_fakeldap(
directory: Optional[Dict[str, Dict[str, List[str]]]] = None directory: Optional[Dict[str, Dict[str, List[str]]]] = None,
) -> None: # nocoverage ) -> None: # nocoverage
# We only use this in development. Importing mock inside # We only use this in development. Importing mock inside
# this function is an import time optimization, which # this function is an import time optimization, which

View File

@ -79,7 +79,7 @@ def further_validated_draft_dict(
def draft_endpoint( def draft_endpoint(
view_func: Callable[Concatenate[HttpRequest, UserProfile, ParamT], HttpResponse] view_func: Callable[Concatenate[HttpRequest, UserProfile, ParamT], HttpResponse],
) -> Callable[Concatenate[HttpRequest, UserProfile, ParamT], HttpResponse]: ) -> Callable[Concatenate[HttpRequest, UserProfile, ParamT], HttpResponse]:
@wraps(view_func) @wraps(view_func)
def draft_view_func( def draft_view_func(

View File

@ -219,8 +219,7 @@ def fetch_initial_state_data(
# user_topic and muted_topics, and receive the duplicate # user_topic and muted_topics, and receive the duplicate
# muted_topics data only from older servers that don't yet # muted_topics data only from older servers that don't yet
# support user_topic. # support user_topic.
event_types is None event_types is None or not want("user_topic")
or not want("user_topic")
): ):
state["muted_topics"] = [] if user_profile is None else get_topic_mutes(user_profile) state["muted_topics"] = [] if user_profile is None else get_topic_mutes(user_profile)
@ -415,12 +414,12 @@ def fetch_initial_state_data(
realm_user_default, property_name realm_user_default, property_name
) )
state["realm_user_settings_defaults"][ state["realm_user_settings_defaults"]["emojiset_choices"] = (
"emojiset_choices" RealmUserDefault.emojiset_choices()
] = RealmUserDefault.emojiset_choices() )
state["realm_user_settings_defaults"][ state["realm_user_settings_defaults"]["available_notification_sounds"] = (
"available_notification_sounds" get_available_notification_sounds()
] = get_available_notification_sounds() )
if want("realm_domains"): if want("realm_domains"):
state["realm_domains"] = get_realm_domains(realm) state["realm_domains"] = get_realm_domains(realm)
@ -662,9 +661,9 @@ def fetch_initial_state_data(
state["user_settings"]["emojiset_choices"] = UserProfile.emojiset_choices() state["user_settings"]["emojiset_choices"] = UserProfile.emojiset_choices()
state["user_settings"]["timezone"] = canonicalize_timezone(settings_user.timezone) state["user_settings"]["timezone"] = canonicalize_timezone(settings_user.timezone)
state["user_settings"][ state["user_settings"]["available_notification_sounds"] = (
"available_notification_sounds" get_available_notification_sounds()
] = get_available_notification_sounds() )
if want("user_status"): if want("user_status"):
# We require creating an account to access statuses. # We require creating an account to access statuses.

View File

@ -565,9 +565,7 @@ def export_from_config(
if config.custom_tables: if config.custom_tables:
exported_tables = config.custom_tables exported_tables = config.custom_tables
else: else:
assert ( assert table is not None, """
table is not None
), """
You must specify config.custom_tables if you You must specify config.custom_tables if you
are not specifying config.table""" are not specifying config.table"""
exported_tables = [table] exported_tables = [table]

View File

@ -1,5 +1,5 @@
""" """
This module stores data for "external account" custom profile field. This module stores data for "external account" custom profile field.
""" """
from dataclasses import dataclass from dataclasses import dataclass

View File

@ -262,7 +262,7 @@ class MessageDict:
@staticmethod @staticmethod
def sew_submessages_and_reactions_to_msgs( def sew_submessages_and_reactions_to_msgs(
messages: List[Dict[str, Any]] messages: List[Dict[str, Any]],
) -> List[Dict[str, Any]]: ) -> List[Dict[str, Any]]:
msg_ids = [msg["id"] for msg in messages] msg_ids = [msg["id"] for msg in messages]
submessages = SubMessage.get_raw_db_rows(msg_ids) submessages = SubMessage.get_raw_db_rows(msg_ids)

View File

@ -968,7 +968,8 @@ def get_base_query_for_search(
# zerver_messages, since the user_profile_id limit in # zerver_messages, since the user_profile_id limit in
# usermessage is more selective, and the query planner # usermessage is more selective, and the query planner
# can't know about that cross-table correlation. # can't know about that cross-table correlation.
.where(column("user_profile_id", Integer) == literal(user_profile.id)).select_from( .where(column("user_profile_id", Integer) == literal(user_profile.id))
.select_from(
join( join(
table("zerver_usermessage"), table("zerver_usermessage"),
table("zerver_message"), table("zerver_message"),

View File

@ -880,7 +880,9 @@ def get_mobile_push_content(rendered_content: str) -> str:
def format_as_quote(quote_text: str) -> str: def format_as_quote(quote_text: str) -> str:
return "".join( return "".join(
f"> {line}\n" for line in quote_text.splitlines() if line # Remove empty lines f"> {line}\n"
for line in quote_text.splitlines()
if line # Remove empty lines
) )
def render_olist(ol: lxml.html.HtmlElement) -> str: def render_olist(ol: lxml.html.HtmlElement) -> str:

View File

@ -335,7 +335,7 @@ ReturnT = TypeVar("ReturnT")
# expected to call json_success or raise JsonableError, as it uses JsonableError # expected to call json_success or raise JsonableError, as it uses JsonableError
# internally when it encounters an error # internally when it encounters an error
def has_request_variables( def has_request_variables(
req_func: Callable[Concatenate[HttpRequest, ParamT], ReturnT] req_func: Callable[Concatenate[HttpRequest, ParamT], ReturnT],
) -> Callable[Concatenate[HttpRequest, ParamT], ReturnT]: ) -> Callable[Concatenate[HttpRequest, ParamT], ReturnT]:
num_params = req_func.__code__.co_argcount num_params = req_func.__code__.co_argcount
default_param_values = cast(FunctionType, req_func).__defaults__ default_param_values = cast(FunctionType, req_func).__defaults__

View File

@ -24,7 +24,7 @@ METHODS = ("GET", "HEAD", "POST", "PUT", "DELETE", "PATCH")
def default_never_cache_responses( def default_never_cache_responses(
view_func: Callable[Concatenate[HttpRequest, ParamT], HttpResponse] view_func: Callable[Concatenate[HttpRequest, ParamT], HttpResponse],
) -> Callable[Concatenate[HttpRequest, ParamT], HttpResponse]: ) -> Callable[Concatenate[HttpRequest, ParamT], HttpResponse]:
"""Patched version of the standard Django never_cache_responses """Patched version of the standard Django never_cache_responses
decorator that adds headers to a response so that it will never be decorator that adds headers to a response so that it will never be

View File

@ -272,7 +272,7 @@ def do_soft_deactivate_user(user_profile: UserProfile) -> None:
def do_soft_deactivate_users( def do_soft_deactivate_users(
users: Union[Sequence[UserProfile], QuerySet[UserProfile]] users: Union[Sequence[UserProfile], QuerySet[UserProfile]],
) -> List[UserProfile]: ) -> List[UserProfile]:
BATCH_SIZE = 100 BATCH_SIZE = 100
users_soft_deactivated = [] users_soft_deactivated = []

View File

@ -1544,9 +1544,7 @@ Output:
""" """
with mock.patch( with mock.patch(
"zerver.lib.markdown.timeout", side_effect=subprocess.CalledProcessError(1, []) "zerver.lib.markdown.timeout", side_effect=subprocess.CalledProcessError(1, [])
), self.assertLogs( ), self.assertLogs(level="ERROR"): # For markdown_logger.exception
level="ERROR"
): # For markdown_logger.exception
yield yield
def create_default_device( def create_default_device(

View File

@ -585,7 +585,7 @@ TestCaseT = TypeVar("TestCaseT", bound="MigrationsTestCase")
def use_db_models( def use_db_models(
method: Callable[[TestCaseT, StateApps], None] method: Callable[[TestCaseT, StateApps], None],
) -> Callable[[TestCaseT, StateApps], None]: # nocoverage ) -> Callable[[TestCaseT, StateApps], None]: # nocoverage
def method_patched_with_mock(self: TestCaseT, apps: StateApps) -> None: def method_patched_with_mock(self: TestCaseT, apps: StateApps) -> None:
ArchivedAttachment = apps.get_model("zerver", "ArchivedAttachment") ArchivedAttachment = apps.get_model("zerver", "ArchivedAttachment")

View File

@ -278,7 +278,7 @@ def parse_single_parameter(
def parse_view_func_signature( def parse_view_func_signature(
view_func: Callable[Concatenate[HttpRequest, ParamT], object] view_func: Callable[Concatenate[HttpRequest, ParamT], object],
) -> ViewFuncInfo: ) -> ViewFuncInfo:
"""This is responsible for inspecting the function signature and getting the """This is responsible for inspecting the function signature and getting the
metadata from the parameters. We want to keep this function as pure as metadata from the parameters. We want to keep this function as pure as

View File

@ -747,9 +747,9 @@ def get_subscribers_of_target_user_subscriptions(
for user_id in target_user_ids: for user_id in target_user_ids:
target_user_subbed_recipients = target_user_subscriptions_dict[user_id] target_user_subbed_recipients = target_user_subscriptions_dict[user_id]
for recipient_id in target_user_subbed_recipients: for recipient_id in target_user_subbed_recipients:
users_subbed_to_target_user_subscriptions_dict[ users_subbed_to_target_user_subscriptions_dict[user_id] |= (
user_id subscribers_dict_by_recipient_ids[recipient_id]
] |= subscribers_dict_by_recipient_ids[recipient_id] )
return users_subbed_to_target_user_subscriptions_dict return users_subbed_to_target_user_subscriptions_dict

View File

@ -117,7 +117,9 @@ def do_bulk_backfill_extra_data(
continue continue
new_value = ast.literal_eval(audit_log_entry.extra_data) # type: ignore[attr-defined] # Explained above. new_value = ast.literal_eval(audit_log_entry.extra_data) # type: ignore[attr-defined] # Explained above.
if old_value not in ({}, new_value): if old_value not in ({}, new_value):
inconsistent_extra_data_json.append((audit_log_entry.id, audit_log_entry.extra_data, old_value, new_value)) # type: ignore[attr-defined] # Explained above. inconsistent_extra_data_json.append(
(audit_log_entry.id, audit_log_entry.extra_data, old_value, new_value) # type: ignore[attr-defined] # Explained above.
)
audit_log_entry.extra_data_json = new_value # type: ignore[attr-defined] # Explained above. audit_log_entry.extra_data_json = new_value # type: ignore[attr-defined] # Explained above.
audit_log_model._default_manager.bulk_update( audit_log_model._default_manager.bulk_update(
python_valued_audit_log_entries, fields=["extra_data_json"] python_valued_audit_log_entries, fields=["extra_data_json"]

View File

@ -29,9 +29,7 @@ def populate_read_by_sender(apps: StateApps, schema_editor: BaseDatabaseSchemaEd
| Q(sending_client_name_lower__contains="desktop app"), | Q(sending_client_name_lower__contains="desktop app"),
~Q(recipient=F("sender__recipient")), ~Q(recipient=F("sender__recipient")),
read_by_sender=None, read_by_sender=None,
).update( ).update(read_by_sender=True)
read_by_sender=True
)
ScheduledMessage.objects.filter(read_by_sender=None).update(read_by_sender=False) ScheduledMessage.objects.filter(read_by_sender=None).update(read_by_sender=False)

View File

@ -2,7 +2,6 @@ from django.db import migrations
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [
("zerver", "0496_alter_scheduledmessage_read_by_sender"), ("zerver", "0496_alter_scheduledmessage_read_by_sender"),
] ]

View File

@ -4,7 +4,6 @@ from django.db import migrations
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [
("zerver", "0497_resort_edit_history"), ("zerver", "0497_resort_edit_history"),
] ]

View File

@ -4,7 +4,6 @@ from django.db import migrations
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [
("zerver", "0498_rename_notifications_stream_realm_new_stream_announcements_stream"), ("zerver", "0498_rename_notifications_stream_realm_new_stream_announcements_stream"),
] ]

View File

@ -17,7 +17,6 @@ def set_initial_value_for_zulip_update_announcements_stream(
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [
("zerver", "0499_rename_signup_notifications_stream_realm_signup_announcements_stream"), ("zerver", "0499_rename_signup_notifications_stream_realm_signup_announcements_stream"),
] ]

View File

@ -603,8 +603,9 @@ class UserProfile(AbstractBaseUser, PermissionsMixin, UserBaseSettings):
for field in custom_profile_fields_for_realm(self.realm_id): for field in custom_profile_fields_for_realm(self.realm_id):
field_values = user_data.get(field.id, None) field_values = user_data.get(field.id, None)
if field_values: if field_values:
value, rendered_value = field_values.get("value"), field_values.get( value, rendered_value = (
"rendered_value" field_values.get("value"),
field_values.get("rendered_value"),
) )
else: else:
value, rendered_value = None, None value, rendered_value = None, None

View File

@ -7256,9 +7256,7 @@ class LDAPBackendTest(ZulipTestCase):
"zproject.backends.ZulipLDAPAuthBackend.get_or_build_user", side_effect=error "zproject.backends.ZulipLDAPAuthBackend.get_or_build_user", side_effect=error
), mock.patch("django_auth_ldap.backend._LDAPUser._authenticate_user_dn"), self.assertLogs( ), mock.patch("django_auth_ldap.backend._LDAPUser._authenticate_user_dn"), self.assertLogs(
"django_auth_ldap", "WARNING" "django_auth_ldap", "WARNING"
) as warn_log, self.assertLogs( ) as warn_log, self.assertLogs("django.request", level="ERROR"):
"django.request", level="ERROR"
):
response = self.client_post("/login/", data) response = self.client_post("/login/", data)
self.assertEqual(response.status_code, 500) self.assertEqual(response.status_code, 500)
self.assert_in_response("Configuration error", response) self.assert_in_response("Configuration error", response)

View File

@ -10,10 +10,9 @@ from zerver.lib.test_classes import ZulipTestCase
class VersionTest(ZulipTestCase): class VersionTest(ZulipTestCase):
data = ( data = [
[ case.split()
case.split() for case in """
for case in """
1.2.3 < 1.2.4 1.2.3 < 1.2.4
1.2.3 = 1.2.3 1.2.3 = 1.2.3
1.4.1 > 1.2.3 1.4.1 > 1.2.3
@ -30,15 +29,11 @@ class VersionTest(ZulipTestCase):
15.1.95 < 16.2.96 15.1.95 < 16.2.96
16.2.96 = 16.2.96 16.2.96 = 16.2.96
20.0.103 > 16.2.96 20.0.103 > 16.2.96
""".strip().split( """.strip().split("\n")
"\n" ] + [
) ["", "?", "1"],
] ["", "?", "a"],
+ [ ]
["", "?", "1"],
["", "?", "a"],
]
)
def test_version_lt(self) -> None: def test_version_lt(self) -> None:
for ver1, cmp, ver2 in self.data: for ver1, cmp, ver2 in self.data:
@ -65,9 +60,7 @@ class VersionTest(ZulipTestCase):
ios ZulipMobile/1.2.3 (iPhone OS 2.1) ios ZulipMobile/1.2.3 (iPhone OS 2.1)
ios ZulipMobile/1.2.3 (iOS 6) ios ZulipMobile/1.2.3 (iOS 6)
None ZulipMobile/1.2.3 (Windows 8) None ZulipMobile/1.2.3 (Windows 8)
""".strip().split( """.strip().split("\n")
"\n"
)
] ]
def test_find_mobile_os(self) -> None: def test_find_mobile_os(self) -> None:
@ -97,9 +90,7 @@ class CompatibilityTest(ZulipTestCase):
ok ZulipMobile/1 CFNetwork/974.2.1 Darwin/18.0.0 ok ZulipMobile/1 CFNetwork/974.2.1 Darwin/18.0.0
ok ZulipMobile/20.0.103 (Android 6.0.1) ok ZulipMobile/20.0.103 (Android 6.0.1)
ok ZulipMobile/20.0.103 (iOS 12.1) ok ZulipMobile/20.0.103 (iOS 12.1)
""".strip().split( """.strip().split("\n")
"\n"
)
if case if case
] ]

View File

@ -196,9 +196,7 @@ class OpenGraphParserTestCase(ZulipTestCase):
<head> <head>
<meta property="og:title" content="中文" /> <meta property="og:title" content="中文" />
</head> </head>
</html>""".encode( </html>""".encode("big5")
"big5"
)
parser = OpenGraphParser(html, "text/html; charset=Big5") parser = OpenGraphParser(html, "text/html; charset=Big5")
result = parser.extract_data() result = parser.extract_data()
self.assertEqual(result.title, "中文") self.assertEqual(result.title, "中文")
@ -209,9 +207,7 @@ class OpenGraphParserTestCase(ZulipTestCase):
<meta content-type="text/html; charset=Big5" /> <meta content-type="text/html; charset=Big5" />
<meta property="og:title" content="中文" /> <meta property="og:title" content="中文" />
</head> </head>
</html>""".encode( </html>""".encode("big5")
"big5"
)
parser = OpenGraphParser(html, "text/html") parser = OpenGraphParser(html, "text/html")
result = parser.extract_data() result = parser.extract_data()
self.assertEqual(result.title, "中文") self.assertEqual(result.title, "中文")

View File

@ -1302,7 +1302,7 @@ class MarkdownTest(ZulipTestCase):
assert_conversion("Hello #123World", False) assert_conversion("Hello #123World", False)
assert_conversion("Hello#123 World", False) assert_conversion("Hello#123 World", False)
assert_conversion("Hello#123World", False) assert_conversion("Hello#123World", False)
assert_conversion("Hello\u00A0#123\u00A0World") assert_conversion("Hello\u00a0#123\u00a0World")
# Ideally, these should be converted, but Markdown doesn't # Ideally, these should be converted, but Markdown doesn't
# handle word boundary detection in languages that don't use # handle word boundary detection in languages that don't use
# whitespace for that correctly yet. # whitespace for that correctly yet.

View File

@ -924,7 +924,7 @@ class MessagePOSTTest(ZulipTestCase):
{ {
"type": "stream", "type": "stream",
"to": "Verona", "to": "Verona",
"topic": "Test\uFFFETopic", "topic": "Test\ufffeTopic",
"content": "Test message", "content": "Test message",
}, },
) )

View File

@ -256,9 +256,7 @@ class SendTestPushNotificationEndpointTest(BouncerTestCase):
"zerver.lib.push_notifications.send_apple_push_notification" "zerver.lib.push_notifications.send_apple_push_notification"
) as mock_send_apple_push_notification, mock.patch( ) as mock_send_apple_push_notification, mock.patch(
"zerver.lib.push_notifications.send_android_push_notification" "zerver.lib.push_notifications.send_android_push_notification"
) as mock_send_android_push_notification, time_machine.travel( ) as mock_send_android_push_notification, time_machine.travel(time_now, tick=False):
time_now, tick=False
):
result = self.api_post(user, endpoint, subdomain="zulip") result = self.api_post(user, endpoint, subdomain="zulip")
mock_send_android_push_notification.assert_called_once_with( mock_send_android_push_notification.assert_called_once_with(
@ -595,9 +593,7 @@ class PushBouncerNotificationTest(BouncerTestCase):
), mock.patch("zilencer.views.send_apple_push_notification", return_value=1), mock.patch( ), mock.patch("zilencer.views.send_apple_push_notification", return_value=1), mock.patch(
"corporate.lib.stripe.RemoteRealmBillingSession.current_count_for_billed_licenses", "corporate.lib.stripe.RemoteRealmBillingSession.current_count_for_billed_licenses",
return_value=10, return_value=10,
), self.assertLogs( ), self.assertLogs("zilencer.views", level="INFO"):
"zilencer.views", level="INFO"
):
result = self.uuid_post( result = self.uuid_post(
self.server_uuid, self.server_uuid,
"/api/v1/remotes/push/notify", "/api/v1/remotes/push/notify",
@ -669,9 +665,7 @@ class PushBouncerNotificationTest(BouncerTestCase):
) as apple_push, mock.patch( ) as apple_push, mock.patch(
"corporate.lib.stripe.RemoteRealmBillingSession.current_count_for_billed_licenses", "corporate.lib.stripe.RemoteRealmBillingSession.current_count_for_billed_licenses",
return_value=10, return_value=10,
), time_machine.travel( ), time_machine.travel(time_sent, tick=False), self.assertLogs(
time_sent, tick=False
), self.assertLogs(
"zilencer.views", level="INFO" "zilencer.views", level="INFO"
) as logger: ) as logger:
result = self.uuid_post( result = self.uuid_post(
@ -989,9 +983,7 @@ class PushBouncerNotificationTest(BouncerTestCase):
), mock.patch("zilencer.views.send_apple_push_notification", return_value=1), mock.patch( ), mock.patch("zilencer.views.send_apple_push_notification", return_value=1), mock.patch(
"corporate.lib.stripe.RemoteServerBillingSession.current_count_for_billed_licenses", "corporate.lib.stripe.RemoteServerBillingSession.current_count_for_billed_licenses",
return_value=10, return_value=10,
), self.assertLogs( ), self.assertLogs("zilencer.views", level="INFO") as logger:
"zilencer.views", level="INFO"
) as logger:
result = self.uuid_post( result = self.uuid_post(
self.server_uuid, self.server_uuid,
"/api/v1/remotes/push/notify", "/api/v1/remotes/push/notify",
@ -2774,9 +2766,7 @@ class HandlePushNotificationTest(PushNotificationTest):
return_value=10, return_value=10,
), self.assertLogs( ), self.assertLogs(
"zerver.lib.push_notifications", level="INFO" "zerver.lib.push_notifications", level="INFO"
) as pn_logger, self.assertLogs( ) as pn_logger, self.assertLogs("zilencer.views", level="INFO") as views_logger:
"zilencer.views", level="INFO"
) as views_logger:
apns_devices = [ apns_devices = [
(b64_to_hex(device.token), device.ios_app_id, device.token) (b64_to_hex(device.token), device.ios_app_id, device.token)
for device in RemotePushDeviceToken.objects.filter(kind=PushDeviceToken.APNS) for device in RemotePushDeviceToken.objects.filter(kind=PushDeviceToken.APNS)
@ -2867,9 +2857,7 @@ class HandlePushNotificationTest(PushNotificationTest):
return_value=100, return_value=100,
) as mock_current_count, self.assertLogs( ) as mock_current_count, self.assertLogs(
"zerver.lib.push_notifications", level="INFO" "zerver.lib.push_notifications", level="INFO"
) as pn_logger, self.assertLogs( ) as pn_logger, self.assertLogs("zilencer.views", level="INFO"):
"zilencer.views", level="INFO"
):
handle_push_notification(self.user_profile.id, missed_message) handle_push_notification(self.user_profile.id, missed_message)
self.assertEqual( self.assertEqual(
@ -2938,9 +2926,7 @@ class HandlePushNotificationTest(PushNotificationTest):
return_value=10, return_value=10,
), self.assertLogs( ), self.assertLogs(
"zerver.lib.push_notifications", level="INFO" "zerver.lib.push_notifications", level="INFO"
) as pn_logger, self.assertLogs( ) as pn_logger, self.assertLogs("zilencer.views", level="INFO") as views_logger:
"zilencer.views", level="INFO"
) as views_logger:
apns_devices = [ apns_devices = [
(b64_to_hex(device.token), device.ios_app_id, device.token) (b64_to_hex(device.token), device.ios_app_id, device.token)
for device in RemotePushDeviceToken.objects.filter(kind=PushDeviceToken.APNS) for device in RemotePushDeviceToken.objects.filter(kind=PushDeviceToken.APNS)

View File

@ -676,9 +676,7 @@ class WorkerTest(ZulipTestCase):
"zerver.lib.send_email.build_email", side_effect=EmailNotDeliveredError "zerver.lib.send_email.build_email", side_effect=EmailNotDeliveredError
), mock_queue_publish( ), mock_queue_publish(
"zerver.lib.queue.queue_json_publish", side_effect=fake_publish "zerver.lib.queue.queue_json_publish", side_effect=fake_publish
), self.assertLogs( ), self.assertLogs(level="ERROR") as m:
level="ERROR"
) as m:
worker.start() worker.start()
self.assertIn("failed due to exception EmailNotDeliveredError", m.output[0]) self.assertIn("failed due to exception EmailNotDeliveredError", m.output[0])

View File

@ -760,9 +760,7 @@ class MoveMessageToArchiveGeneral(MoveMessageToArchiveBase):
Some more.... http://{host}/user_uploads/{id}/31/4CBjtTLYZhk66pZrF8hnYGwc/abc.py ... Some more.... http://{host}/user_uploads/{id}/31/4CBjtTLYZhk66pZrF8hnYGwc/abc.py ...
http://{host}/user_uploads/{id}/31/4CBjtTLYZhk66pZrF8hnYGwc/new.py .... http://{host}/user_uploads/{id}/31/4CBjtTLYZhk66pZrF8hnYGwc/new.py ....
http://{host}/user_uploads/{id}/31/4CBjtTLYZhk66pZrF8hnYGwc/hello.txt .... http://{host}/user_uploads/{id}/31/4CBjtTLYZhk66pZrF8hnYGwc/hello.txt ....
""".format( """.format(id=realm_id, host=host)
id=realm_id, host=host
)
msg_id = self.send_personal_message(self.sender, self.recipient, body) msg_id = self.send_personal_message(self.sender, self.recipient, body)
# Simulate a reply with the same contents. # Simulate a reply with the same contents.
@ -821,9 +819,7 @@ class MoveMessageToArchiveGeneral(MoveMessageToArchiveBase):
Some more.... http://{host}/user_uploads/{id}/31/4CBjtTLYZhk66pZrF8hnYGwc/abc.py ... Some more.... http://{host}/user_uploads/{id}/31/4CBjtTLYZhk66pZrF8hnYGwc/abc.py ...
http://{host}/user_uploads/{id}/31/4CBjtTLYZhk66pZrF8hnYGwc/new.py .... http://{host}/user_uploads/{id}/31/4CBjtTLYZhk66pZrF8hnYGwc/new.py ....
http://{host}/user_uploads/{id}/31/4CBjtTLYZhk66pZrF8hnYGwc/hello.txt .... http://{host}/user_uploads/{id}/31/4CBjtTLYZhk66pZrF8hnYGwc/hello.txt ....
""".format( """.format(id=realm_id, host=host)
id=realm_id, host=host
)
msg_id = self.send_personal_message(self.sender, self.recipient, body) msg_id = self.send_personal_message(self.sender, self.recipient, body)

View File

@ -422,7 +422,7 @@ ParamT = ParamSpec("ParamT")
def for_all_bot_types( def for_all_bot_types(
test_func: Callable[Concatenate["TestServiceBotEventTriggers", ParamT], None] test_func: Callable[Concatenate["TestServiceBotEventTriggers", ParamT], None],
) -> Callable[Concatenate["TestServiceBotEventTriggers", ParamT], None]: ) -> Callable[Concatenate["TestServiceBotEventTriggers", ParamT], None]:
@wraps(test_func) @wraps(test_func)
def _wrapped( def _wrapped(
@ -443,7 +443,7 @@ def patch_queue_publish(
Callable[["TestServiceBotEventTriggers"], None], Callable[["TestServiceBotEventTriggers"], None],
]: ]:
def inner( def inner(
func: Callable[["TestServiceBotEventTriggers", mock.Mock], None] func: Callable[["TestServiceBotEventTriggers", mock.Mock], None],
) -> Callable[["TestServiceBotEventTriggers"], None]: ) -> Callable[["TestServiceBotEventTriggers"], None]:
@wraps(func) @wraps(func)
def _wrapped(self: "TestServiceBotEventTriggers") -> None: def _wrapped(self: "TestServiceBotEventTriggers") -> None:

View File

@ -3996,7 +3996,7 @@ class SubscriptionAPITest(ZulipTestCase):
# For Cn category # For Cn category
post_data_cn = { post_data_cn = {
"subscriptions": orjson.dumps( "subscriptions": orjson.dumps(
[{"name": "new\uFFFEstream", "description": "this is description"}] [{"name": "new\ufffestream", "description": "this is description"}]
).decode(), ).decode(),
"invite_only": orjson.dumps(False).decode(), "invite_only": orjson.dumps(False).decode(),
} }
@ -4023,7 +4023,7 @@ class SubscriptionAPITest(ZulipTestCase):
result = self.client_patch(f"/json/streams/{stream.id}", {"new_name": "test\n\rname"}) result = self.client_patch(f"/json/streams/{stream.id}", {"new_name": "test\n\rname"})
self.assert_json_error(result, "Invalid character in stream name, at position 5!") self.assert_json_error(result, "Invalid character in stream name, at position 5!")
# Check for Cn characters # Check for Cn characters
result = self.client_patch(f"/json/streams/{stream.id}", {"new_name": "test\uFFFEame"}) result = self.client_patch(f"/json/streams/{stream.id}", {"new_name": "test\ufffeame"})
self.assert_json_error(result, "Invalid character in stream name, at position 5!") self.assert_json_error(result, "Invalid character in stream name, at position 5!")
def test_successful_subscriptions_list(self) -> None: def test_successful_subscriptions_list(self) -> None:

View File

@ -631,7 +631,7 @@ def oauth_redirect_to_root(
def handle_desktop_flow( def handle_desktop_flow(
func: Callable[Concatenate[HttpRequest, ParamT], HttpResponse] func: Callable[Concatenate[HttpRequest, ParamT], HttpResponse],
) -> Callable[Concatenate[HttpRequest, ParamT], HttpResponse]: ) -> Callable[Concatenate[HttpRequest, ParamT], HttpResponse]:
@wraps(func) @wraps(func)
def wrapper( def wrapper(

View File

@ -120,7 +120,8 @@ def serve_local(
# the response to; serve it directly ourselves. FileResponse # the response to; serve it directly ourselves. FileResponse
# handles setting Content-Type, Content-Disposition, etc. # handles setting Content-Type, Content-Disposition, etc.
response: HttpResponseBase = FileResponse( response: HttpResponseBase = FileResponse(
open(local_path, "rb"), as_attachment=download # noqa: SIM115 open(local_path, "rb"), # noqa: SIM115
as_attachment=download,
) )
patch_cache_control(response, private=True, immutable=True) patch_cache_control(response, private=True, immutable=True)
return response return response

View File

@ -98,9 +98,7 @@ Requester Bob <requester-bob@example.com> updated [ticket #11](http://test1234zz
expected_message = """ expected_message = """
Requester Bob <requester-bob@example.com> added a {} note to \ Requester Bob <requester-bob@example.com> added a {} note to \
[ticket #11](http://test1234zzz.freshdesk.com/helpdesk/tickets/11). [ticket #11](http://test1234zzz.freshdesk.com/helpdesk/tickets/11).
""".strip().format( """.strip().format(note_type)
note_type
)
self.api_stream_message( self.api_stream_message(
self.test_user, self.test_user,
fixture, fixture,

View File

@ -189,7 +189,7 @@ def get_assignees(payload: WildValue) -> Union[List[WildValue], WildValue]:
def replace_assignees_username_with_name( def replace_assignees_username_with_name(
assignees: Union[List[WildValue], WildValue] assignees: Union[List[WildValue], WildValue],
) -> List[Dict[str, str]]: ) -> List[Dict[str, str]]:
"""Replace the username of each assignee with their (full) name. """Replace the username of each assignee with their (full) name.

View File

@ -164,9 +164,7 @@ def api_librato_webhook(
request: HttpRequest, request: HttpRequest,
user_profile: UserProfile, user_profile: UserProfile,
*, *,
payload: Json[ payload: Json[Mapping[str, Any]] = {}, # noqa: B006 # Mapping is indeed immutable, but Json's type annotation drops that information
Mapping[str, Any]
] = {}, # noqa: B006 # Mapping is indeed immutable, but Json's type annotation drops that information
) -> HttpResponse: ) -> HttpResponse:
try: try:
attachments = orjson.loads(request.body).get("attachments", []) attachments = orjson.loads(request.body).get("attachments", [])

View File

@ -103,7 +103,7 @@ def validate_remote_server(
def authenticated_remote_server_view( def authenticated_remote_server_view(
view_func: Callable[Concatenate[HttpRequest, RemoteZulipServer, ParamT], HttpResponse] view_func: Callable[Concatenate[HttpRequest, RemoteZulipServer, ParamT], HttpResponse],
) -> Callable[Concatenate[HttpRequest, ParamT], HttpResponse]: ) -> Callable[Concatenate[HttpRequest, ParamT], HttpResponse]:
@wraps(view_func) @wraps(view_func)
def _wrapped_view_func( def _wrapped_view_func(

View File

@ -979,8 +979,9 @@ class Command(BaseCommand):
"test": {"description": "For testing `code`"}, "test": {"description": "For testing `code`"},
"errors": {"description": "For errors"}, "errors": {"description": "For errors"},
# 조리법 - Recipes (Korean), Пельмени - Dumplings (Russian) # 조리법 - Recipes (Korean), Пельмени - Dumplings (Russian)
"조리법 " "조리법 " + raw_emojis[0]: {
+ raw_emojis[0]: {"description": "Everything cooking, from pasta to Пельмени"}, "description": "Everything cooking, from pasta to Пельмени"
},
} }
extra_stream_names = [ extra_stream_names = [
@ -1122,7 +1123,7 @@ def get_recipient_by_id(rid: int) -> Recipient:
# - multiple messages per subject # - multiple messages per subject
# - both single and multi-line content # - both single and multi-line content
def generate_and_send_messages( def generate_and_send_messages(
data: Tuple[int, Sequence[Sequence[int]], Mapping[str, Any], int] data: Tuple[int, Sequence[Sequence[int]], Mapping[str, Any], int],
) -> int: ) -> int:
realm = get_realm("zulip") realm = get_realm("zulip")
(tot_messages, personals_pairs, options, random_seed) = data (tot_messages, personals_pairs, options, random_seed) = data

View File

@ -72,7 +72,9 @@ def do_bulk_backfill_extra_data(
old_value = audit_log_entry.extra_data_json # type: ignore[attr-defined] # The migration cannot depend on zerver.models, which contains the real type of the RealmAuditLog model, so it cannot be properly typed. old_value = audit_log_entry.extra_data_json # type: ignore[attr-defined] # The migration cannot depend on zerver.models, which contains the real type of the RealmAuditLog model, so it cannot be properly typed.
new_value = ast.literal_eval(audit_log_entry.extra_data) # type: ignore[attr-defined] # Explained above. new_value = ast.literal_eval(audit_log_entry.extra_data) # type: ignore[attr-defined] # Explained above.
if old_value not in ({}, new_value): if old_value not in ({}, new_value):
inconsistent_extra_data_json.append((audit_log_entry.id, audit_log_entry.extra_data, old_value, new_value)) # type: ignore[attr-defined] # Explained above. inconsistent_extra_data_json.append(
(audit_log_entry.id, audit_log_entry.extra_data, old_value, new_value) # type: ignore[attr-defined] # Explained above.
)
audit_log_entry.extra_data_json = new_value # type: ignore[attr-defined] # Explained above. audit_log_entry.extra_data_json = new_value # type: ignore[attr-defined] # Explained above.
audit_log_model._default_manager.bulk_update( audit_log_model._default_manager.bulk_update(
python_valued_audit_log_entries, fields=["extra_data_json"] python_valued_audit_log_entries, fields=["extra_data_json"]

View File

@ -4,7 +4,6 @@ from django.db import migrations, models
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [
("zilencer", "0057_remoterealm_last_request_timestamp_and_more"), ("zilencer", "0057_remoterealm_last_request_timestamp_and_more"),
] ]

View File

@ -4,7 +4,6 @@ from django.db import migrations, models
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [
("zilencer", "0058_remoteinstallationcount_add_mobile_pushes_forwarded_index"), ("zilencer", "0058_remoteinstallationcount_add_mobile_pushes_forwarded_index"),
] ]

View File

@ -552,7 +552,8 @@ def get_remote_realm_guest_and_non_guest_count(
# bulk_create_users to create the users in the system bot # bulk_create_users to create the users in the system bot
# realm also generate such audit logs. Such audit logs should # realm also generate such audit logs. Such audit logs should
# never be the latest in a normal realm. # never be the latest in a normal realm.
.exclude(extra_data={}).last() .exclude(extra_data={})
.last()
) )
if latest_audit_log is not None: if latest_audit_log is not None: