partial: Replace returns plugin with an annotation.

The returns plugin hasn’t been updated for mypy ≥ 1.6.  This
annotation is more limited in that it only supports a fixed number of
positional arguments and no keyword arguments, but is good enough for
our purposes.

Signed-off-by: Anders Kaseorg <anders@zulip.com>
This commit is contained in:
Anders Kaseorg 2024-04-29 14:20:36 -07:00 committed by Tim Abbott
parent 87f228fcb0
commit d32d4434dd
18 changed files with 52 additions and 17 deletions

View File

@ -48,7 +48,6 @@ local_partial_types = true
plugins = [ plugins = [
"mypy_django_plugin.main", "mypy_django_plugin.main",
"pydantic.mypy", "pydantic.mypy",
"returns.contrib.mypy.returns_plugin",
] ]
[[tool.mypy.overrides]] [[tool.mypy.overrides]]

View File

@ -21,9 +21,9 @@ sanity_check.check_venv(__file__)
import aiohttp import aiohttp
from aiohttp import hdrs, web from aiohttp import hdrs, web
from aiohttp.http_exceptions import BadStatusLine from aiohttp.http_exceptions import BadStatusLine
from returns.curry import partial
from tools.lib.test_script import add_provision_check_override_param, assert_provisioning_status_ok from tools.lib.test_script import add_provision_check_override_param, assert_provisioning_status_ok
from zerver.lib.partial import partial
if "posix" in os.name and os.geteuid() == 0: if "posix" in os.name and os.geteuid() == 0:
raise RuntimeError("run-dev should not be run as root.") raise RuntimeError("run-dev should not be run as root.")

View File

@ -318,7 +318,7 @@ rules:
- id: functools-partial - id: functools-partial
pattern: functools.partial pattern: functools.partial
message: "Replace functools.partial with returns.curry.partial for type safety" message: "Replace functools.partial with zerver.lib.partial.partial for type safety"
languages: [python] languages: [python]
severity: ERROR severity: ERROR

View File

@ -24,11 +24,11 @@ import orjson
import requests import requests
from django.forms.models import model_to_dict from django.forms.models import model_to_dict
from django.utils.timezone import now as timezone_now from django.utils.timezone import now as timezone_now
from returns.curry import partial
from typing_extensions import TypeAlias from typing_extensions import TypeAlias
from zerver.data_import.sequencer import NEXT_ID from zerver.data_import.sequencer import NEXT_ID
from zerver.lib.avatar_hash import user_avatar_path_from_ids from zerver.lib.avatar_hash import user_avatar_path_from_ids
from zerver.lib.partial import partial
from zerver.lib.stream_color import STREAM_ASSIGNMENT_COLORS as STREAM_COLORS from zerver.lib.stream_color import STREAM_ASSIGNMENT_COLORS as STREAM_COLORS
from zerver.models import ( from zerver.models import (
Attachment, Attachment,

View File

@ -23,7 +23,6 @@ from django.utils.timezone import now as timezone_now
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
from django_stubs_ext import ValuesQuerySet from django_stubs_ext import ValuesQuerySet
from psycopg2.sql import SQL from psycopg2.sql import SQL
from returns.curry import partial
from analytics.lib.counts import COUNT_STATS from analytics.lib.counts import COUNT_STATS
from analytics.models import RealmCount from analytics.models import RealmCount
@ -33,6 +32,7 @@ from zerver.lib.exceptions import JsonableError, MissingAuthenticationError
from zerver.lib.markdown import MessageRenderingResult from zerver.lib.markdown import MessageRenderingResult
from zerver.lib.mention import MentionData from zerver.lib.mention import MentionData
from zerver.lib.message_cache import MessageDict, extract_message_dict, stringify_message_dict from zerver.lib.message_cache import MessageDict, extract_message_dict, stringify_message_dict
from zerver.lib.partial import partial
from zerver.lib.request import RequestVariableConversionError from zerver.lib.request import RequestVariableConversionError
from zerver.lib.stream_subscription import ( from zerver.lib.stream_subscription import (
get_stream_subscriptions_for_user, get_stream_subscriptions_for_user,

36
zerver/lib/partial.py Normal file
View File

@ -0,0 +1,36 @@
# Workaround for missing functools.partial support in mypy
# (https://github.com/python/mypy/issues/1484).
from typing import TYPE_CHECKING, Callable, TypeVar, overload
if TYPE_CHECKING:
from typing_extensions import Concatenate, ParamSpec
P = ParamSpec("P")
T1 = TypeVar("T1")
T2 = TypeVar("T2")
T3 = TypeVar("T3")
T4 = TypeVar("T4")
R = TypeVar("R")
@overload
def partial(func: Callable[P, R], /) -> Callable[P, R]: ...
@overload
def partial(func: Callable[Concatenate[T1, P], R], arg1: T1, /) -> Callable[P, R]: ...
@overload
def partial(
func: Callable[Concatenate[T1, T2, P], R], arg1: T1, arg2: T2, /
) -> Callable[P, R]: ...
@overload
def partial(
func: Callable[Concatenate[T1, T2, T3, P], R], arg1: T1, arg2: T2, arg3: T3, /
) -> Callable[P, R]: ...
@overload
def partial(
func: Callable[Concatenate[T1, T2, T3, T4, P], R], arg1: T1, arg2: T2, arg3: T3, arg4: T4, /
) -> Callable[P, R]: ...
def partial(func: Callable[..., R], /, *args: object) -> Callable[..., R]: ...
else:
from functools import partial as partial

View File

@ -13,7 +13,6 @@ from django.db import ProgrammingError, connections
from django.test import runner as django_runner from django.test import runner as django_runner
from django.test.runner import DiscoverRunner from django.test.runner import DiscoverRunner
from django.test.signals import template_rendered from django.test.signals import template_rendered
from returns.curry import partial
from typing_extensions import TypeAlias, override from typing_extensions import TypeAlias, override
from scripts.lib.zulip_tools import ( from scripts.lib.zulip_tools import (
@ -22,6 +21,7 @@ from scripts.lib.zulip_tools import (
get_or_create_dev_uuid_var_path, get_or_create_dev_uuid_var_path,
) )
from zerver.lib import test_helpers from zerver.lib import test_helpers
from zerver.lib.partial import partial
from zerver.lib.sqlalchemy_utils import get_sqlalchemy_connection from zerver.lib.sqlalchemy_utils import get_sqlalchemy_connection
from zerver.lib.test_fixtures import BACKEND_DATABASE_TEMPLATE from zerver.lib.test_fixtures import BACKEND_DATABASE_TEMPLATE
from zerver.lib.test_helpers import append_instrumentation_data, write_instrumentation_reports from zerver.lib.test_helpers import append_instrumentation_data, write_instrumentation_reports

View File

@ -4,9 +4,9 @@ from typing import Any, Callable, Optional
from django.conf import settings from django.conf import settings
from django.core.management.base import BaseCommand, CommandError, CommandParser from django.core.management.base import BaseCommand, CommandError, CommandParser
from returns.curry import partial
from typing_extensions import override from typing_extensions import override
from zerver.lib.partial import partial
from zerver.lib.rate_limiter import RateLimitedUser, client from zerver.lib.rate_limiter import RateLimitedUser, client
from zerver.models.users import get_user_profile_by_id from zerver.models.users import get_user_profile_by_id

View File

@ -9,10 +9,10 @@ from django.conf import settings
from django.db import transaction from django.db import transaction
from requests.adapters import ConnectionError, HTTPAdapter from requests.adapters import ConnectionError, HTTPAdapter
from requests.models import PreparedRequest, Response from requests.models import PreparedRequest, Response
from returns.curry import partial
from typing_extensions import override from typing_extensions import override
from urllib3.util import Retry from urllib3.util import Retry
from zerver.lib.partial import partial
from zerver.lib.queue import queue_json_publish from zerver.lib.queue import queue_json_publish
from zerver.models import Client, Realm, UserProfile from zerver.models import Client, Realm, UserProfile
from zerver.tornado.sharding import ( from zerver.tornado.sharding import (

View File

@ -20,12 +20,12 @@ from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.http import require_POST from django.views.decorators.http import require_POST
from oauthlib.oauth2 import OAuth2Error from oauthlib.oauth2 import OAuth2Error
from requests_oauthlib import OAuth2Session from requests_oauthlib import OAuth2Session
from returns.curry import partial
from zerver.actions.video_calls import do_set_zoom_token from zerver.actions.video_calls import do_set_zoom_token
from zerver.decorator import zulip_login_required from zerver.decorator import zulip_login_required
from zerver.lib.exceptions import ErrorCode, JsonableError from zerver.lib.exceptions import ErrorCode, JsonableError
from zerver.lib.outgoing_http import OutgoingSession from zerver.lib.outgoing_http import OutgoingSession
from zerver.lib.partial import partial
from zerver.lib.pysa import mark_sanitized from zerver.lib.pysa import mark_sanitized
from zerver.lib.request import REQ, has_request_variables from zerver.lib.request import REQ, has_request_variables
from zerver.lib.response import json_success from zerver.lib.response import json_success

View File

@ -4,10 +4,10 @@ import string
from typing import Dict, List, Optional, Protocol from typing import Dict, List, Optional, Protocol
from django.http import HttpRequest, HttpResponse from django.http import HttpRequest, HttpResponse
from returns.curry import partial
from zerver.decorator import log_unsupported_webhook_event, webhook_view from zerver.decorator import log_unsupported_webhook_event, webhook_view
from zerver.lib.exceptions import UnsupportedWebhookEventTypeError from zerver.lib.exceptions import UnsupportedWebhookEventTypeError
from zerver.lib.partial import partial
from zerver.lib.response import json_success from zerver.lib.response import json_success
from zerver.lib.typed_endpoint import JsonBodyPayload, typed_endpoint from zerver.lib.typed_endpoint import JsonBodyPayload, typed_endpoint
from zerver.lib.validator import WildValue, check_bool, check_int, check_string from zerver.lib.validator import WildValue, check_bool, check_int, check_string

View File

@ -2,10 +2,10 @@ import string
from typing import Dict, List, Optional, Protocol from typing import Dict, List, Optional, Protocol
from django.http import HttpRequest, HttpResponse from django.http import HttpRequest, HttpResponse
from returns.curry import partial
from zerver.decorator import webhook_view from zerver.decorator import webhook_view
from zerver.lib.exceptions import UnsupportedWebhookEventTypeError from zerver.lib.exceptions import UnsupportedWebhookEventTypeError
from zerver.lib.partial import partial
from zerver.lib.response import json_success from zerver.lib.response import json_success
from zerver.lib.typed_endpoint import JsonBodyPayload, typed_endpoint from zerver.lib.typed_endpoint import JsonBodyPayload, typed_endpoint
from zerver.lib.validator import WildValue, check_int, check_none_or, check_string from zerver.lib.validator import WildValue, check_int, check_none_or, check_string

View File

@ -1,10 +1,10 @@
from typing import Callable, Dict, Iterable, Iterator, List, Optional from typing import Callable, Dict, Iterable, Iterator, List, Optional
from django.http import HttpRequest, HttpResponse from django.http import HttpRequest, HttpResponse
from returns.curry import partial
from zerver.decorator import webhook_view from zerver.decorator import webhook_view
from zerver.lib.exceptions import UnsupportedWebhookEventTypeError from zerver.lib.exceptions import UnsupportedWebhookEventTypeError
from zerver.lib.partial import partial
from zerver.lib.response import json_success from zerver.lib.response import json_success
from zerver.lib.typed_endpoint import JsonBodyPayload, typed_endpoint from zerver.lib.typed_endpoint import JsonBodyPayload, typed_endpoint
from zerver.lib.validator import ( from zerver.lib.validator import (

View File

@ -3,10 +3,10 @@ from datetime import datetime, timezone
from typing import Callable, Dict, Optional from typing import Callable, Dict, Optional
from django.http import HttpRequest, HttpResponse from django.http import HttpRequest, HttpResponse
from returns.curry import partial
from zerver.decorator import log_unsupported_webhook_event, webhook_view from zerver.decorator import log_unsupported_webhook_event, webhook_view
from zerver.lib.exceptions import UnsupportedWebhookEventTypeError from zerver.lib.exceptions import UnsupportedWebhookEventTypeError
from zerver.lib.partial import partial
from zerver.lib.response import json_success from zerver.lib.response import json_success
from zerver.lib.typed_endpoint import JsonBodyPayload, typed_endpoint from zerver.lib.typed_endpoint import JsonBodyPayload, typed_endpoint
from zerver.lib.validator import WildValue, check_bool, check_int, check_none_or, check_string from zerver.lib.validator import WildValue, check_bool, check_int, check_none_or, check_string

View File

@ -3,10 +3,10 @@ from typing import Dict, List, Optional, Protocol, Union
from django.http import HttpRequest, HttpResponse from django.http import HttpRequest, HttpResponse
from pydantic import Json from pydantic import Json
from returns.curry import partial
from zerver.decorator import webhook_view from zerver.decorator import webhook_view
from zerver.lib.exceptions import UnsupportedWebhookEventTypeError from zerver.lib.exceptions import UnsupportedWebhookEventTypeError
from zerver.lib.partial import partial
from zerver.lib.response import json_success from zerver.lib.response import json_success
from zerver.lib.typed_endpoint import JsonBodyPayload, typed_endpoint from zerver.lib.typed_endpoint import JsonBodyPayload, typed_endpoint
from zerver.lib.validator import WildValue, check_int, check_none_or, check_string from zerver.lib.validator import WildValue, check_int, check_none_or, check_string

View File

@ -2,10 +2,10 @@
from typing import Callable, Dict, Optional from typing import Callable, Dict, Optional
from django.http import HttpRequest, HttpResponse from django.http import HttpRequest, HttpResponse
from returns.curry import partial
from zerver.decorator import webhook_view from zerver.decorator import webhook_view
from zerver.lib.exceptions import UnsupportedWebhookEventTypeError from zerver.lib.exceptions import UnsupportedWebhookEventTypeError
from zerver.lib.partial import partial
from zerver.lib.response import json_success from zerver.lib.response import json_success
from zerver.lib.typed_endpoint import JsonBodyPayload, typed_endpoint from zerver.lib.typed_endpoint import JsonBodyPayload, typed_endpoint
from zerver.lib.validator import WildValue, check_int, check_none_or, check_string, check_url from zerver.lib.validator import WildValue, check_int, check_none_or, check_string, check_url

View File

@ -2,11 +2,11 @@ from html.parser import HTMLParser
from typing import Callable, Dict, List, Tuple from typing import Callable, Dict, List, Tuple
from django.http import HttpRequest, HttpResponse from django.http import HttpRequest, HttpResponse
from returns.curry import partial
from typing_extensions import override from typing_extensions import override
from zerver.decorator import return_success_on_head_request, webhook_view from zerver.decorator import return_success_on_head_request, webhook_view
from zerver.lib.exceptions import UnsupportedWebhookEventTypeError from zerver.lib.exceptions import UnsupportedWebhookEventTypeError
from zerver.lib.partial import partial
from zerver.lib.response import json_success from zerver.lib.response import json_success
from zerver.lib.typed_endpoint import JsonBodyPayload, typed_endpoint from zerver.lib.typed_endpoint import JsonBodyPayload, typed_endpoint
from zerver.lib.validator import WildValue, check_int, check_none_or, check_string from zerver.lib.validator import WildValue, check_int, check_none_or, check_string

View File

@ -12,11 +12,11 @@ import orjson
import sentry_sdk import sentry_sdk
from django.conf import settings from django.conf import settings
from django.db import connection from django.db import connection
from returns.curry import partial
from typing_extensions import override from typing_extensions import override
from zerver.lib.context_managers import lockfile from zerver.lib.context_managers import lockfile
from zerver.lib.db_connections import reset_queries from zerver.lib.db_connections import reset_queries
from zerver.lib.partial import partial
from zerver.lib.per_request_cache import flush_per_request_caches from zerver.lib.per_request_cache import flush_per_request_caches
from zerver.lib.pysa import mark_sanitized from zerver.lib.pysa import mark_sanitized
from zerver.lib.queue import SimpleQueueClient from zerver.lib.queue import SimpleQueueClient