mypy: Update zerver directory to use Text

This commit is contained in:
Juan Verhook
2016-12-26 22:09:35 -08:00
committed by showell
parent 5639f21188
commit cfa9c2eaf2
9 changed files with 49 additions and 56 deletions

View File

@@ -29,8 +29,7 @@ from io import BytesIO
from zerver.lib.mandrill_client import get_mandrill_client
from six.moves import zip, urllib
from six import text_type
from typing import Union, Any, Callable, Sequence, Dict, Optional, TypeVar
from typing import Union, Any, Callable, Sequence, Dict, Optional, TypeVar, Text
from zerver.lib.str_utils import force_bytes
if settings.ZILENCER_ENABLED:
@@ -44,7 +43,7 @@ FuncT = TypeVar('FuncT', bound=Callable[..., Any])
ViewFuncT = TypeVar('ViewFuncT', bound=Callable[..., HttpResponse])
def get_deployment_or_userprofile(role):
# type: (text_type) -> Union[UserProfile, Deployment]
# type: (Text) -> Union[UserProfile, Deployment]
return get_user_profile_by_email(role) if "@" in role else get_deployment_by_domain(role)
class _RespondAsynchronously(object):
@@ -120,7 +119,7 @@ def require_realm_admin(func):
from zerver.lib.user_agent import parse_user_agent
def get_client_name(request, is_json_view):
# type: (HttpRequest, bool) -> text_type
# type: (HttpRequest, bool) -> Text
# If the API request specified a client in the request content,
# that has priority. Otherwise, extract the client from the
# User-Agent.
@@ -150,7 +149,7 @@ def get_client_name(request, is_json_view):
return "Unspecified"
def process_client(request, user_profile, is_json_view=False, client_name=None):
# type: (HttpRequest, UserProfile, bool, Optional[text_type]) -> None
# type: (HttpRequest, UserProfile, bool, Optional[Text]) -> None
if client_name is None:
client_name = get_client_name(request, is_json_view)
@@ -163,7 +162,7 @@ def process_client(request, user_profile, is_json_view=False, client_name=None):
update_user_activity(request, user_profile)
def validate_api_key(request, role, api_key, is_webhook=False):
# type: (HttpRequest, text_type, text_type, bool) -> Union[UserProfile, Deployment]
# type: (HttpRequest, Text, Text, bool) -> Union[UserProfile, Deployment]
# Remove whitespace to protect users from trivial errors.
role, api_key = role.strip(), api_key.strip()
@@ -204,7 +203,7 @@ def validate_api_key(request, role, api_key, is_webhook=False):
# Use this for webhook views that don't get an email passed in.
def api_key_only_webhook_view(client_name):
# type: (text_type) -> Callable[..., HttpResponse]
# type: (Text) -> Callable[..., HttpResponse]
# This function can't be typed perfectly because returning a generic function
# isn't supported in mypy - https://github.com/python/mypy/issues/1551.
def _wrapped_view_func(view_func):
@@ -214,7 +213,7 @@ def api_key_only_webhook_view(client_name):
@wraps(view_func)
def _wrapped_func_arguments(request, api_key=REQ(),
*args, **kwargs):
# type: (HttpRequest, text_type, *Any, **Any) -> HttpResponse
# type: (HttpRequest, Text, *Any, **Any) -> HttpResponse
try:
user_profile = UserProfile.objects.get(api_key=api_key)
except UserProfile.DoesNotExist:
@@ -241,7 +240,7 @@ def api_key_only_webhook_view(client_name):
# From Django 1.8, modified to leave off ?next=/
def redirect_to_login(next, login_url=None,
redirect_field_name=REDIRECT_FIELD_NAME):
# type: (text_type, Optional[text_type], text_type) -> HttpResponseRedirect
# type: (Text, Optional[Text], Text) -> HttpResponseRedirect
"""
Redirects the user to the login page, passing the given 'next' page
"""
@@ -259,7 +258,7 @@ def redirect_to_login(next, login_url=None,
# From Django 1.8
def user_passes_test(test_func, login_url=None, redirect_field_name=REDIRECT_FIELD_NAME):
# type: (Callable[[UserProfile], bool], Optional[text_type], text_type) -> Callable[[Callable[..., HttpResponse]], Callable[..., HttpResponse]]
# type: (Callable[[UserProfile], bool], Optional[Text], Text) -> Callable[[Callable[..., HttpResponse]], Callable[..., HttpResponse]]
"""
Decorator for views that checks that the user passes the given test,
redirecting to the log-in page if necessary. The test should be a callable
@@ -300,7 +299,7 @@ def logged_in_and_active(request):
def zulip_login_required(function=None,
redirect_field_name=REDIRECT_FIELD_NAME,
login_url=settings.HOME_NOT_LOGGED_IN):
# type: (Optional[Callable[..., HttpResponse]], text_type, text_type) -> Union[Callable[[Callable[..., HttpResponse]], Callable[..., HttpResponse]], Callable[..., HttpResponse]]
# type: (Optional[Callable[..., HttpResponse]], Text, Text) -> Union[Callable[[Callable[..., HttpResponse]], Callable[..., HttpResponse]], Callable[..., HttpResponse]]
actual_decorator = user_passes_test(
logged_in_and_active,
login_url=login_url,
@@ -340,7 +339,7 @@ def authenticated_api_view(is_webhook=False):
def _wrapped_func_arguments(request, email=REQ(), api_key=REQ(default=None),
api_key_legacy=REQ('api-key', default=None),
*args, **kwargs):
# type: (HttpRequest, text_type, Optional[text_type], Optional[text_type], *Any, **Any) -> HttpResponse
# type: (HttpRequest, Text, Optional[Text], Optional[Text], *Any, **Any) -> HttpResponse
if not api_key and not api_key_legacy:
raise RequestVariableMissingError("api_key")
elif not api_key:
@@ -478,7 +477,7 @@ def authenticated_json_view(view_func):
return _wrapped_view_func # type: ignore # https://github.com/python/mypy/issues/1927
def is_local_addr(addr):
# type: (text_type) -> bool
# type: (Text) -> bool
return addr in ('127.0.0.1', '::1')
# These views are used by the main Django server to notify the Tornado server
@@ -518,14 +517,14 @@ def internal_notify_view(view_func):
# Converter functions for use with has_request_variables
def to_non_negative_int(s):
# type: (text_type) -> int
# type: (Text) -> int
x = int(s)
if x < 0:
raise ValueError("argument is negative")
return x
def flexible_boolean(boolean):
# type: (text_type) -> bool
# type: (Text) -> bool
"""Returns True for any of "1", "true", or "True". Returns False otherwise."""
if boolean in ("1", "true", "True"):
return True
@@ -533,7 +532,7 @@ def flexible_boolean(boolean):
return False
def statsd_increment(counter, val=1):
# type: (text_type, int) -> Callable[[Callable[..., Any]], Callable[..., Any]]
# type: (Text, int) -> Callable[[Callable[..., Any]], Callable[..., Any]]
"""Increments a statsd counter on completion of the
decorated function.
@@ -550,7 +549,7 @@ def statsd_increment(counter, val=1):
return wrapper
def rate_limit_user(request, user, domain):
# type: (HttpRequest, UserProfile, text_type) -> None
# type: (HttpRequest, UserProfile, Text) -> None
"""Returns whether or not a user was rate limited. Will raise a RateLimited exception
if the user has been rate limited, otherwise returns and modifies request to contain
the rate limit information"""
@@ -571,7 +570,7 @@ def rate_limit_user(request, user, domain):
request._ratelimit_secs_to_freedom = time_reset
def rate_limit(domain='all'):
# type: (text_type) -> Callable[[Callable[..., HttpResponse]], Callable[..., HttpResponse]]
# type: (Text) -> Callable[[Callable[..., HttpResponse]], Callable[..., HttpResponse]]
"""Rate-limits a view. Takes an optional 'domain' param if you wish to rate limit different
types of API calls independently.

View File

@@ -22,8 +22,7 @@ import logging
import re
import DNS
from six import text_type
from typing import Any, Callable, Optional
from typing import Any, Callable, Optional, Text
MIT_VALIDATION_ERROR = u'That user does not exist at MIT or is a ' + \
u'<a href="https://ist.mit.edu/email-lists">mailing list</a>. ' + \
@@ -34,14 +33,14 @@ WRONG_SUBDOMAIN_ERROR = "Your Zulip account is not a member of the " + \
"Please contact %s with any questions!" % (settings.ZULIP_ADMINISTRATOR,)
def get_registration_string(domain):
# type: (text_type) -> text_type
# type: (Text) -> Text
register_url = reverse('register') + domain
register_account_string = _('The organization with the domain already exists. '
'Please register your account <a href=%(url)s>here</a>.') % {'url': register_url}
return register_account_string
def email_is_not_mit_mailing_list(email):
# type: (text_type) -> None
# type: (Text) -> None
"""Prevent MIT mailing lists from signing up for Zulip"""
if "@mit.edu" in email:
username = email.rsplit("@", 1)[0]
@@ -143,7 +142,7 @@ class HomepageForm(forms.Form):
return email
def email_is_not_disposable(email):
# type: (text_type) -> None
# type: (Text) -> None
if is_disposable_domain(email_to_domain(email)):
raise ValidationError(_("Please use your real email address."))

View File

@@ -21,7 +21,6 @@ import os
import os.path
import hashlib
import six
from six import text_type
if False:
from zerver.models import UserProfile, Realm, Message
@@ -79,7 +78,7 @@ def get_or_create_key_prefix():
filename = os.path.join(settings.DEPLOY_ROOT, "var", "remote_cache_prefix")
try:
fd = os.open(filename, os.O_CREAT | os.O_EXCL | os.O_RDWR, 0o444)
random_hash = hashlib.sha256(text_type(random.getrandbits(256)).encode('utf-8')).digest()
random_hash = hashlib.sha256(Text(random.getrandbits(256)).encode('utf-8')).digest()
prefix = base64.b16encode(random_hash)[:32].decode('utf-8').lower() + ':'
# This does close the underlying file
with os.fdopen(fd, 'w') as f:
@@ -107,7 +106,7 @@ KEY_PREFIX = get_or_create_key_prefix() # type: Text
def bounce_key_prefix_for_testing(test_name):
# type: (Text) -> None
global KEY_PREFIX
KEY_PREFIX = test_name + u':' + text_type(os.getpid()) + u':'
KEY_PREFIX = test_name + u':' + Text(os.getpid()) + u':'
def get_cache_backend(cache_name):
# type: (Optional[str]) -> BaseCache

View File

@@ -56,7 +56,7 @@ import time
import ujson
import unittest
from six.moves import urllib
from six import text_type, binary_type
from six import binary_type
from zerver.lib.str_utils import NonBinaryStr
from contextlib import contextmanager
@@ -250,7 +250,7 @@ class ZulipTestCase(TestCase):
user_profile=user_profile,
active=True,
recipient__type=Recipient.STREAM)
return [cast(text_type, get_display_recipient(sub.recipient)) for sub in subs]
return [cast(Text, get_display_recipient(sub.recipient)) for sub in subs]
def send_message(self, sender_name, raw_recipients, message_type,
content=u"test content", subject=u"test", **kwargs):

View File

@@ -1,7 +1,7 @@
from __future__ import absolute_import
from six import text_type, binary_type
from typing import Any, AnyStr, Callable, Iterable, MutableMapping, Optional
from six import binary_type
from typing import Any, AnyStr, Callable, Iterable, MutableMapping, Optional, Text
from django.conf import settings
from django.utils.translation import ugettext as _
@@ -85,7 +85,7 @@ def format_timedelta(timedelta):
return "%.0fms" % (timedelta_ms(timedelta),)
def is_slow_query(time_delta, path):
# type: (float, text_type) -> bool
# type: (float, Text) -> bool
if time_delta < 1.2:
return False
is_exempt = \
@@ -101,7 +101,7 @@ def is_slow_query(time_delta, path):
def write_log_line(log_data, path, method, remote_ip, email, client_name,
status_code=200, error_content=None, error_content_iter=None):
# type: (MutableMapping[str, Any], text_type, str, str, text_type, text_type, int, Optional[AnyStr], Optional[Iterable[AnyStr]]) -> None
# type: (MutableMapping[str, Any], Text, str, str, Text, Text, int, Optional[AnyStr], Optional[Iterable[AnyStr]]) -> None
assert error_content is None or error_content_iter is None
if error_content is not None:
error_content_iter = (error_content,)
@@ -219,7 +219,7 @@ def write_log_line(log_data, path, method, remote_ip, email, client_name,
error_content_list = list(error_content_iter)
if error_content_list:
error_data = u''
elif isinstance(error_content_list[0], text_type):
elif isinstance(error_content_list[0], Text):
error_data = u''.join(error_content_list)
elif isinstance(error_content_list[0], binary_type):
error_data = repr(b''.join(error_content_list))
@@ -308,7 +308,7 @@ class TagRequests(object):
request.error_format = "HTML"
def csrf_failure(request, reason=""):
# type: (HttpRequest, Optional[text_type]) -> HttpResponse
# type: (HttpRequest, Optional[Text]) -> HttpResponse
if request.error_format == "JSON":
return json_error(_("CSRF Error: %s") % (reason,), status=403)
else:

View File

@@ -1,5 +1,5 @@
from zerver.lib.test_classes import WebhookTestCase
from six import text_type
from typing import Text
class PapertrailHookTests(WebhookTestCase):
STREAM_NAME = 'papertrail'
@@ -42,5 +42,5 @@ May 18 20:30:02 abc cron OR server1:
content_type="application/x-www-form-urlencoded")
def get_body(self, fixture_name):
# type: (text_type) -> text_type
# type: (Text) -> Text
return self.fixture_data("papertrail", fixture_name, file_type="json")

View File

@@ -1,5 +1,5 @@
from __future__ import absolute_import
from typing import cast, AbstractSet, Any, Optional, Iterable, Sequence, Mapping, MutableMapping, Callable, Union
from typing import cast, AbstractSet, Any, Optional, Iterable, Sequence, Mapping, MutableMapping, Callable, Union, Text
from django.utils.translation import ugettext as _
from django.conf import settings
@@ -34,7 +34,6 @@ from zerver.lib.timestamp import timestamp_to_datetime
from zerver.tornado.descriptors import clear_descriptor_by_handler_id, set_descriptor_by_handler_id
import copy
import six
from six import text_type
requests_client = requests.Session()
for host in ['127.0.0.1', 'localhost']:
@@ -64,7 +63,7 @@ class ClientDescriptor(object):
def __init__(self, user_profile_id, user_profile_email, realm_id, event_queue,
event_types, client_type_name, apply_markdown=True,
all_public_streams=False, lifespan_secs=0, narrow=[]):
# type: (int, text_type, int, EventQueue, Optional[Sequence[str]], text_type, bool, bool, int, Iterable[Sequence[text_type]]) -> None
# type: (int, Text, int, EventQueue, Optional[Sequence[str]], Text, bool, bool, int, Iterable[Sequence[Text]]) -> None
# These objects are serialized on shutdown and restored on restart.
# If fields are added or semantics are changed, temporary code must be
# added to load_event_queues() to update the restored objects.
@@ -73,7 +72,7 @@ class ClientDescriptor(object):
self.user_profile_email = user_profile_email
self.realm_id = realm_id
self.current_handler_id = None # type: Optional[int]
self.current_client_name = None # type: Optional[text_type]
self.current_client_name = None # type: Optional[Text]
self.event_queue = event_queue
self.queue_timeout = lifespan_secs
self.event_types = event_types
@@ -176,7 +175,7 @@ class ClientDescriptor(object):
and now - self.last_connection_time >= self.queue_timeout)
def connect_handler(self, handler_id, client_name):
# type: (int, text_type) -> None
# type: (int, Text) -> None
self.current_handler_id = handler_id
self.current_client_name = client_name
set_descriptor_by_handler_id(handler_id, self)
@@ -494,8 +493,8 @@ def fetch_events(query):
last_event_id = query["last_event_id"] # type: int
user_profile_id = query["user_profile_id"] # type: int
new_queue_data = query.get("new_queue_data") # type: Optional[MutableMapping[str, Any]]
user_profile_email = query["user_profile_email"] # type: text_type
client_type_name = query["client_type_name"] # type: text_type
user_profile_email = query["user_profile_email"] # type: Text
client_type_name = query["client_type_name"] # type: Text
handler_id = query["handler_id"] # type: int
try:
@@ -562,7 +561,7 @@ def extract_json_response(resp):
def request_event_queue(user_profile, user_client, apply_markdown,
queue_lifespan_secs, event_types=None, all_public_streams=False,
narrow=[]):
# type: (UserProfile, Client, bool, int, Optional[Iterable[str]], bool, Iterable[Sequence[text_type]]) -> Optional[str]
# type: (UserProfile, Client, bool, int, Optional[Iterable[str]], bool, Iterable[Sequence[Text]]) -> Optional[str]
if settings.TORNADO_SERVER:
req = {'dont_block': 'true',
'apply_markdown': ujson.dumps(apply_markdown),
@@ -648,7 +647,7 @@ def missedmessage_hook(user_profile_id, queue, last_for_client):
queue_json_publish("missedmessage_emails", notice, lambda notice: None)
def receiver_is_idle(user_profile_id, realm_presences):
# type: (int, Optional[Dict[int, Dict[text_type, Dict[str, Any]]]]) -> bool
# type: (int, Optional[Dict[int, Dict[Text, Dict[str, Any]]]]) -> bool
# If a user has no message-receiving event queues, they've got no open zulip
# session so we notify them
all_client_descriptors = get_client_descriptors_for_user(user_profile_id)
@@ -684,14 +683,14 @@ def receiver_is_idle(user_profile_id, realm_presences):
def process_message_event(event_template, users):
# type: (Mapping[str, Any], Iterable[Mapping[str, Any]]) -> None
realm_presences = {int(k): v for k, v in event_template['presences'].items()} # type: Dict[int, Dict[text_type, Dict[str, Any]]]
realm_presences = {int(k): v for k, v in event_template['presences'].items()} # type: Dict[int, Dict[Text, Dict[str, Any]]]
sender_queue_id = event_template.get('sender_queue_id', None) # type: Optional[str]
message_dict_markdown = event_template['message_dict_markdown'] # type: Dict[str, Any]
message_dict_no_markdown = event_template['message_dict_no_markdown'] # type: Dict[str, Any]
sender_id = message_dict_markdown['sender_id'] # type: int
message_id = message_dict_markdown['id'] # type: int
message_type = message_dict_markdown['type'] # type: str
sending_client = message_dict_markdown['client'] # type: text_type
sending_client = message_dict_markdown['client'] # type: Text
# To remove duplicate clients: Maps queue ID to {'client': Client, 'flags': flags}
send_to_clients = {} # type: Dict[str, Dict[str, Any]]

View File

@@ -1,7 +1,6 @@
from __future__ import absolute_import
from six import text_type
from typing import Any, Union, Mapping, Optional
from typing import Any, Union, Mapping, Optional, Text
from django.conf import settings
from django.utils import timezone
@@ -35,7 +34,7 @@ from zerver.tornado.event_queue import get_client_descriptor
logger = logging.getLogger('zulip.socket')
def get_user_profile(session_id):
# type: (Optional[text_type]) -> Optional[UserProfile]
# type: (Optional[Text]) -> Optional[UserProfile]
if session_id is None:
return None
@@ -72,7 +71,7 @@ def deregister_connection(conn):
redis_client = get_redis_client()
def req_redis_key(req_id):
# type: (text_type) -> text_type
# type: (Text) -> Text
return u'socket_req_status:%s' % (req_id,)
class SocketAuthError(Exception):

View File

@@ -3,8 +3,6 @@ from __future__ import absolute_import
from django.utils.translation import ugettext as _
from django.http import HttpRequest, HttpResponse
from six import text_type
from zerver.models import get_client, UserProfile, Client
from zerver.decorator import asynchronous, \
@@ -17,7 +15,7 @@ from zerver.tornado.event_queue import get_client_descriptor, \
process_notification, fetch_events
from django.core.handlers.base import BaseHandler
from typing import Union, Optional, Iterable, Sequence, List
from typing import Union, Optional, Iterable, Sequence, List, Text
import time
import ujson
@@ -29,7 +27,7 @@ def notify(request):
@has_request_variables
def cleanup_event_queue(request, user_profile, queue_id=REQ()):
# type: (HttpRequest, UserProfile, text_type) -> HttpResponse
# type: (HttpRequest, UserProfile, Text) -> HttpResponse
client = get_client_descriptor(str(queue_id))
if client is None:
return json_error(_("Bad event queue id: %s") % (queue_id,))
@@ -51,7 +49,7 @@ def get_events_backend(request, user_profile, handler,
dont_block = REQ(default=False, validator=check_bool),
narrow = REQ(default=[], validator=check_list(None)),
lifespan_secs = REQ(default=0, converter=int)):
# type: (HttpRequest, UserProfile, BaseHandler, Optional[Client], Optional[int], Optional[List[text_type]], bool, bool, Optional[text_type], bool, Iterable[Sequence[text_type]], int) -> Union[HttpResponse, _RespondAsynchronously]
# type: (HttpRequest, UserProfile, BaseHandler, Optional[Client], Optional[int], Optional[List[Text]], bool, bool, Optional[Text], bool, Iterable[Sequence[Text]], int) -> Union[HttpResponse, _RespondAsynchronously]
if user_client is None:
user_client = request.client