management: Fix typing for management scripts.

There are some remaining errors related to the django `Manager[T]` and
the `List[T]` type that we use to annotate the `Manage[T]` objects.
This commit is contained in:
PIG208
2021-08-14 22:51:57 +08:00
committed by Tim Abbott
parent 50ce906f31
commit 460119986b
18 changed files with 51 additions and 39 deletions

View File

@@ -4,7 +4,7 @@ from typing import Any, Dict, List, Optional
from django.conf import settings
from django.core.exceptions import MultipleObjectsReturned
from django.core.management.base import BaseCommand, CommandError
from django.core.management.base import BaseCommand, CommandError, CommandParser
from zerver.models import Client, Realm, UserProfile, get_client
@@ -33,8 +33,8 @@ def check_config() -> None:
class ZulipBaseCommand(BaseCommand):
# Fix support for multi-line usage
def create_parser(self, *args: Any, **kwargs: Any) -> ArgumentParser:
parser = super().create_parser(*args, **kwargs)
def create_parser(self, prog_name: str, subcommand: str, **kwargs: Any) -> CommandParser:
parser = super().create_parser(prog_name, subcommand, **kwargs)
parser.formatter_class = RawTextHelpFormatter
return parser

View File

@@ -17,7 +17,7 @@ class Command(ZulipBaseCommand):
"-s", "--streams", required=True, help="A comma-separated list of stream names."
)
def handle(self, **options: Any) -> None:
def handle(self, *args: Any, **options: Any) -> None:
realm = self.get_realm(options)
assert realm is not None # Should be ensured by parser

View File

@@ -5,6 +5,7 @@ from argparse import ArgumentParser, RawTextHelpFormatter
from typing import Any
from django.conf import settings
from django.core.management.base import CommandParser
from django.db import connection
from django.utils.timezone import now as timezone_now
@@ -16,8 +17,8 @@ from zerver.logging_handlers import try_git_describe
class Command(ZulipBaseCommand):
# Fix support for multi-line usage strings
def create_parser(self, *args: Any, **kwargs: Any) -> ArgumentParser:
parser = super().create_parser(*args, **kwargs)
def create_parser(self, prog_name: str, subcommand: str, **kwargs: Any) -> CommandParser:
parser = super().create_parser(prog_name, subcommand, **kwargs)
parser.formatter_class = RawTextHelpFormatter
return parser

View File

@@ -12,7 +12,7 @@ from django.core.management.base import CommandParser
from django.core.management.commands import compilemessages
from django.utils.translation import gettext as _
from django.utils.translation import override as override_language
from django.utils.translation.trans_real import to_language
from django.utils.translation import to_language
from pyuca import Collator

View File

@@ -42,6 +42,19 @@ logger.addHandler(file_handler)
def get_imap_messages() -> Generator[EmailMessage, None, None]:
# We're probably running from cron, try to batch-process mail
if (
not settings.EMAIL_GATEWAY_BOT
or not settings.EMAIL_GATEWAY_LOGIN
or not settings.EMAIL_GATEWAY_PASSWORD
or not settings.EMAIL_GATEWAY_IMAP_SERVER
or not settings.EMAIL_GATEWAY_IMAP_PORT
or not settings.EMAIL_GATEWAY_IMAP_FOLDER
):
raise CommandError(
"Please configure the email mirror gateway in /etc/zulip/, "
"or specify $ORIGINAL_RECIPIENT if piping a single mail."
)
mbox = IMAP4_SSL(settings.EMAIL_GATEWAY_IMAP_SERVER, settings.EMAIL_GATEWAY_IMAP_PORT)
mbox.login(settings.EMAIL_GATEWAY_LOGIN, settings.EMAIL_GATEWAY_PASSWORD)
try:
@@ -68,18 +81,5 @@ class Command(BaseCommand):
help = __doc__
def handle(self, *args: Any, **options: str) -> None:
# We're probably running from cron, try to batch-process mail
if (
not settings.EMAIL_GATEWAY_BOT
or not settings.EMAIL_GATEWAY_LOGIN
or not settings.EMAIL_GATEWAY_PASSWORD
or not settings.EMAIL_GATEWAY_IMAP_SERVER
or not settings.EMAIL_GATEWAY_IMAP_PORT
or not settings.EMAIL_GATEWAY_IMAP_FOLDER
):
raise CommandError(
"Please configure the email mirror gateway in /etc/zulip/, "
"or specify $ORIGINAL_RECIPIENT if piping a single mail."
)
for message in get_imap_messages():
process_message(message)

View File

@@ -37,9 +37,9 @@ import json
import os
import re
import subprocess
from argparse import ArgumentParser
from typing import Any, Collection, Dict, Iterator, List, Mapping
from django.core.management.base import CommandParser
from django.core.management.commands import makemessages
from django.template.base import BLOCK_TAG_END, BLOCK_TAG_START
from django.utils.translation import template
@@ -80,7 +80,7 @@ class Command(makemessages.Command):
for func, tag in tags:
xgettext_options += [f'--keyword={func}:1,"{tag}"']
def add_arguments(self, parser: ArgumentParser) -> None:
def add_arguments(self, parser: CommandParser) -> None:
super().add_arguments(parser)
parser.add_argument(
"--frontend-source",

View File

@@ -1,6 +1,6 @@
import sys
from argparse import ArgumentParser
from typing import Any
from typing import Any, Union
from django.core.exceptions import ValidationError
from django.core.management.base import CommandError
@@ -24,7 +24,7 @@ class Command(ZulipBaseCommand):
parser.add_argument("domain", metavar="<domain>", nargs="?", help="domain to add or remove")
self.add_realm_args(parser, required=True)
def handle(self, *args: Any, **options: str) -> None:
def handle(self, *args: Any, **options: Union[str, bool]) -> None:
realm = self.get_realm(options)
assert realm is not None # Should be ensured by parser
if options["op"] == "show":
@@ -36,12 +36,14 @@ class Command(ZulipBaseCommand):
print(realm_domain["domain"] + " (subdomains not allowed)")
sys.exit(0)
assert isinstance(options["domain"], str)
domain = options["domain"].strip().lower()
try:
validate_domain(domain)
except ValidationError as e:
raise CommandError(e.messages[0])
if options["op"] == "add":
assert isinstance(options["allow_subdomains"], bool)
try:
RealmDomain.objects.create(
realm=realm, domain=domain, allow_subdomains=options["allow_subdomains"]

View File

@@ -30,7 +30,7 @@ class Command(ZulipBaseCommand):
help="Automatically rotate your server's zulip_org_key",
)
def handle(self, **options: Any) -> None:
def handle(self, *args: Any, **options: Any) -> None:
if not settings.DEVELOPMENT:
check_config()

View File

@@ -18,7 +18,7 @@ class Command(ZulipBaseCommand):
parser, all_users_help="Remove all users in realm from this stream."
)
def handle(self, **options: Any) -> None:
def handle(self, *args: Any, **options: Any) -> None:
realm = self.get_realm(options)
assert realm is not None # Should be ensured by parser
user_profiles = self.get_users(options, realm)

View File

@@ -49,7 +49,7 @@ To restore a specific ArchiveTransaction:
"(Does not restore manually deleted messages.)",
)
def handle(self, **options: Any) -> None:
def handle(self, *args: Any, **options: Any) -> None:
realm = self.get_realm(options)
if realm:
restore_data_from_archive_by_realm(realm)

View File

@@ -47,8 +47,10 @@ class Command(BaseCommand):
help="[port number or ipaddr:port]",
)
def handle(self, addrport: str, **options: bool) -> None:
def handle(self, *args: Any, **options: Any) -> None:
interactive_debug_listen()
addrport = options["addrport"]
assert isinstance(addrport, str)
import django
from tornado import httpserver

View File

@@ -3,7 +3,7 @@ import email
import email.policy
import os
from email.message import EmailMessage
from typing import Optional
from typing import Any, Optional
import orjson
from django.conf import settings
@@ -54,7 +54,7 @@ Example:
self.add_realm_args(parser, help="Specify which realm to connect to; default is zulip")
def handle(self, **options: Optional[str]) -> None:
def handle(self, *args: Any, **options: Optional[str]) -> None:
if options["fixture"] is None:
self.print_help("./manage.py", "send_to_email_mirror")
raise CommandError

View File

@@ -1,5 +1,5 @@
import os
from typing import Dict, Optional, Union
from typing import Any, Dict, Optional, Union
import orjson
from django.conf import settings
@@ -61,7 +61,7 @@ approach shown above.
)
return standardize_headers(custom_headers_dict)
def handle(self, **options: Optional[str]) -> None:
def handle(self, *args: Any, **options: Optional[str]) -> None:
if options["fixture"] is None or options["url"] is None:
self.print_help("./manage.py", "send_webhook_fixture_message")
raise CommandError
@@ -84,7 +84,7 @@ approach shown above.
json,
content_type="application/json",
HTTP_HOST=realm.host,
**headers,
extra=headers,
)
else:
result = client.post(

View File

@@ -9,7 +9,7 @@ from zerver.models import Realm, UserProfile
class Command(ZulipBaseCommand):
help = """Add a new realm and initial user for manual testing of the onboarding process."""
def handle(self, **options: Any) -> None:
def handle(self, *args: Any, **options: Any) -> None:
string_id = "realm{:02}".format(Realm.objects.filter(string_id__startswith="realm").count())
realm = do_create_realm(string_id, string_id)

View File

@@ -15,7 +15,7 @@ and will otherwise fall back to the zulip realm."""
def add_arguments(self, parser: CommandParser) -> None:
self.add_realm_args(parser)
def handle(self, **options: Any) -> None:
def handle(self, *args: Any, **options: Any) -> None:
realm = self.get_realm(options)
if realm is None:
realm = (

View File

@@ -17,7 +17,10 @@ class Command(ZulipBaseCommand):
)
group.add_argument("--email", "-e", required=True, help="a contact email address")
def handle(self, uuid: str, key: str, hostname: str, email: str, **options: Any) -> None:
def handle(self, *args: Any, **options: Any) -> None:
RemoteZulipServer.objects.create(
uuid=uuid, api_key=key, hostname=hostname, contact_email=email
uuid=options["uuid"],
api_key=options["key"],
hostname=options["hostname"],
contact_email=options["email"],
)

View File

@@ -1,4 +1,4 @@
from typing import Any
from typing import Any, Iterable
from django.core.management.base import CommandParser
@@ -24,7 +24,7 @@ class Command(ZulipBaseCommand):
target_realm = self.get_realm(options)
if target_realm is None:
realms = Realm.objects.all()
realms: Iterable[Realm] = Realm.objects.all()
else:
realms = [target_realm]

View File

@@ -1,12 +1,16 @@
import cProfile
import logging
import tempfile
from os import path
from typing import Any, Dict
from django.contrib.sessions.backends.base import SessionBase
from django.core.management.base import CommandParser
from django.http import HttpRequest, HttpResponse
from zerver.lib.management import ZulipBaseCommand
from zerver.lib.request import get_request_notes
from zerver.lib.test_helpers import HostRequestMock
from zerver.middleware import LogRequests
from zerver.models import UserMessage, UserProfile
from zerver.views.message_fetch import get_messages_backend