diff --git a/zerver/decorator.py b/zerver/decorator.py
index 4f6cb00a85..4f5440d70a 100644
--- a/zerver/decorator.py
+++ b/zerver/decorator.py
@@ -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.
diff --git a/zerver/forms.py b/zerver/forms.py
index 7d326558c1..b2be52e7bd 100644
--- a/zerver/forms.py
+++ b/zerver/forms.py
@@ -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'mailing list. ' + \
@@ -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 here.') % {'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."))
diff --git a/zerver/lib/cache.py b/zerver/lib/cache.py
index 4ff891a415..d898bd683e 100644
--- a/zerver/lib/cache.py
+++ b/zerver/lib/cache.py
@@ -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
diff --git a/zerver/lib/test_classes.py b/zerver/lib/test_classes.py
index 5249c72c3b..bc18272820 100644
--- a/zerver/lib/test_classes.py
+++ b/zerver/lib/test_classes.py
@@ -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):
diff --git a/zerver/middleware.py b/zerver/middleware.py
index a087c3d1c1..f981afc0db 100644
--- a/zerver/middleware.py
+++ b/zerver/middleware.py
@@ -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:
diff --git a/zerver/tests/webhooks/test_papertrail.py b/zerver/tests/webhooks/test_papertrail.py
index ee3663b9d5..a80d70cf65 100644
--- a/zerver/tests/webhooks/test_papertrail.py
+++ b/zerver/tests/webhooks/test_papertrail.py
@@ -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")
diff --git a/zerver/tornado/event_queue.py b/zerver/tornado/event_queue.py
index f95cd21b6c..b6ba4f0fa2 100644
--- a/zerver/tornado/event_queue.py
+++ b/zerver/tornado/event_queue.py
@@ -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]]
diff --git a/zerver/tornado/socket.py b/zerver/tornado/socket.py
index b5a3679ba0..ec0703db1d 100644
--- a/zerver/tornado/socket.py
+++ b/zerver/tornado/socket.py
@@ -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):
diff --git a/zerver/tornado/views.py b/zerver/tornado/views.py
index 2bbab52872..ebde512143 100644
--- a/zerver/tornado/views.py
+++ b/zerver/tornado/views.py
@@ -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