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