mypy: Convert several directories to use typing.Text.

Specifically, these directories are converted: [analytics/, scripts/,
tools/, zerver/management/, zilencer/, zproject/]
This commit is contained in:
anirudhjain75 2016-12-08 09:36:51 +05:30 committed by Tim Abbott
parent 2288120155
commit beaa62cafa
16 changed files with 82 additions and 95 deletions

View File

@ -8,8 +8,7 @@ from analytics.models import InstallationCount, RealmCount, \
from zerver.models import Realm, UserProfile, Message, Stream, models
from zerver.lib.timestamp import floor_to_day
from typing import Any, Optional, Type, Tuple
from six import text_type
from typing import Any, Optional, Type, Tuple, Text
import logging
import time
@ -37,7 +36,7 @@ class CountStat(object):
GAUGE = 'gauge'
def __init__(self, property, zerver_count_query, filter_args, group_by, frequency, is_gauge):
# type: (text_type, ZerverCountQuery, Dict[str, bool], Optional[Tuple[models.Model, str]], str, bool) -> None
# type: (Text, ZerverCountQuery, Dict[str, bool], Optional[Tuple[models.Model, str]], str, bool) -> None
self.property = property
self.zerver_count_query = zerver_count_query
# might have to do something different for bitfields
@ -50,7 +49,7 @@ class CountStat(object):
class ZerverCountQuery(object):
def __init__(self, zerver_table, analytics_table, query):
# type: (Type[models.Model], Type[BaseCount], text_type) -> None
# type: (Type[models.Model], Type[BaseCount], Text) -> None
self.zerver_table = zerver_table
self.analytics_table = analytics_table
self.query = query

View File

@ -7,11 +7,10 @@ from zerver.lib.timestamp import datetime_to_UTC, floor_to_day
import datetime
from six import text_type
from typing import Optional, Tuple, Union, Dict, Any
from typing import Optional, Tuple, Union, Dict, Any, Text
class FillState(ModelReprMixin, models.Model):
property = models.CharField(max_length=40, unique=True) # type: text_type
property = models.CharField(max_length=40, unique=True) # type: Text
end_time = models.DateTimeField() # type: datetime.datetime
# Valid states are {DONE, STARTED}
@ -22,11 +21,11 @@ class FillState(ModelReprMixin, models.Model):
last_modified = models.DateTimeField(auto_now=True) # type: datetime.datetime
def __unicode__(self):
# type: () -> text_type
# type: () -> Text
return u"<FillState: %s %s %s>" % (self.property, self.end_time, self.state)
def get_fill_state(property):
# type: (text_type) -> Optional[Dict[str, Any]]
# type: (Text) -> Optional[Dict[str, Any]]
try:
return FillState.objects.filter(property = property).values('end_time', 'state')[0]
except IndexError:
@ -41,20 +40,20 @@ def installation_epoch():
# would only ever make entries here by hand
class Anomaly(ModelReprMixin, models.Model):
info = models.CharField(max_length=1000) # type: text_type
info = models.CharField(max_length=1000) # type: Text
def __unicode__(self):
# type: () -> text_type
# type: () -> Text
return u"<Anomaly: %s... %s>" % (self.info, self.id)
class BaseCount(ModelReprMixin, models.Model):
# Note: When inheriting from BaseCount, you may want to rearrange
# the order of the columns in the migration to make sure they
# match how you'd like the table to be arranged.
property = models.CharField(max_length=32) # type: text_type
subgroup = models.CharField(max_length=16, null=True) # type: text_type
property = models.CharField(max_length=32) # type: Text
subgroup = models.CharField(max_length=16, null=True) # type: Text
end_time = models.DateTimeField() # type: datetime.datetime
interval = models.CharField(max_length=8) # type: text_type
interval = models.CharField(max_length=8) # type: Text
value = models.BigIntegerField() # type: int
anomaly = models.ForeignKey(Anomaly, null=True) # type: Optional[Anomaly]
@ -87,7 +86,7 @@ class InstallationCount(BaseCount):
return None
def __unicode__(self):
# type: () -> text_type
# type: () -> Text
return u"<InstallationCount: %s %s>" % (self.property, self.value)
class RealmCount(BaseCount):
@ -107,7 +106,7 @@ class RealmCount(BaseCount):
return Realm
def __unicode__(self):
# type: () -> text_type
# type: () -> Text
return u"<RealmCount: %s %s %s>" % (self.realm, self.property, self.value)
class UserCount(BaseCount):
@ -128,7 +127,7 @@ class UserCount(BaseCount):
return UserProfile
def __unicode__(self):
# type: () -> text_type
# type: () -> Text
return u"<UserCount: %s %s %s>" % (self.user, self.property, self.value)
class StreamCount(BaseCount):
@ -149,5 +148,5 @@ class StreamCount(BaseCount):
return Stream
def __unicode__(self):
# type: () -> text_type
# type: () -> Text
return u"<StreamCount: %s %s %s %s>" % (self.stream, self.property, self.value, self.id)

View File

@ -14,8 +14,7 @@ from zerver.models import Realm, UserProfile, Message, Stream, Recipient, \
from datetime import datetime, timedelta
from typing import Any, Type, Optional
from six import text_type
from typing import Any, Type, Optional, Text
class AnalyticsTestCase(TestCase):
MINUTE = timedelta(seconds = 60)
@ -71,7 +70,7 @@ class AnalyticsTestCase(TestCase):
# kwargs should only ever be a UserProfile or Stream.
def assertCountEquals(self, table, property, value, end_time = TIME_ZERO, interval = CountStat.HOUR,
realm = None, **kwargs):
# type: (Type[BaseCount], text_type, int, datetime, str, Optional[Realm], **models.Model) -> None
# type: (Type[BaseCount], Text, int, datetime, str, Optional[Realm], **models.Model) -> None
if realm is None:
realm = self.default_realm
self.assertEqual(table.objects.filter(realm=realm,
@ -134,7 +133,7 @@ class TestProcessCountStat(AnalyticsTestCase):
return count_stat
def assertFillStateEquals(self, end_time, state = FillState.DONE, property = None):
# type: (datetime, int, Optional[text_type]) -> None
# type: (datetime, int, Optional[Text]) -> None
count_stat = self.make_dummy_count_stat(end_time)
if property is None:
property = count_stat.property

View File

@ -1,7 +1,6 @@
from __future__ import absolute_import
from __future__ import division
from six import text_type
from typing import Any, Dict, List, Tuple, Optional, Sequence, Callable, Union
from typing import Any, Dict, List, Tuple, Optional, Sequence, Callable, Union, Text
from django.db import connection
from django.db.models.query import QuerySet
@ -789,7 +788,7 @@ def user_activity_summary_table(user_summary):
return make_table(title, cols, rows)
def realm_user_summary_table(all_records, admin_emails):
# type: (List[QuerySet], Set[text_type]) -> Tuple[Dict[str, Dict[str, Any]], str]
# type: (List[QuerySet], Set[Text]) -> Tuple[Dict[str, Dict[str, Any]], str]
user_records = {}
def by_email(record):

View File

@ -5,7 +5,7 @@ from __future__ import print_function
import sys, os, os.path
from os.path import dirname, abspath
if False:
from typing import Dict, Optional
from typing import Dict, Optional, Text
BASE_DIR = dirname(dirname(dirname(abspath(__file__))))
sys.path.append(BASE_DIR)
@ -14,7 +14,6 @@ import scripts.lib.setup_path_on_import
os.environ['DJANGO_SETTINGS_MODULE'] = 'zproject.settings'
from django.utils.crypto import get_random_string
from six import text_type
import six
import argparse
from zerver.lib.str_utils import force_str
@ -30,7 +29,7 @@ AUTOGENERATED_SETTINGS = ['shared_secret', 'avatar_salt', 'rabbitmq_password', '
# TODO: We can eliminate this function if we refactor the install
# script to run generate_secrets before zulip-puppet-apply.
def generate_camo_config_file(camo_key):
# type: (text_type) -> None
# type: (Text) -> None
camo_config = """ENABLED=yes
PORT=9292
CAMO_KEY=%s
@ -40,13 +39,13 @@ CAMO_KEY=%s
print("Generated Camo config file %s" % (CAMO_CONFIG_FILENAME,))
def generate_django_secretkey():
# type: () -> text_type
# type: () -> Text
"""Secret key generation taken from Django's startproject.py"""
chars = 'abcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*(-_=+)'
return get_random_string(50, chars)
def get_old_conf(output_filename):
# type: (text_type) -> Dict[str, text_type]
# type: (Text) -> Dict[str, Text]
if not os.path.exists(output_filename):
return {}
@ -54,7 +53,7 @@ def get_old_conf(output_filename):
secrets_file.read(output_filename)
def get_secret(key):
# type: (text_type) -> Optional[text_type]
# type: (Text) -> Optional[Text]
if secrets_file.has_option('secrets', key):
return secrets_file.get('secrets', key)
return None
@ -72,7 +71,7 @@ def generate_secrets(development=False):
lines = [u'[secrets]\n']
def config_line(var, value):
# type: (text_type, text_type) -> text_type
# type: (Text, Text) -> Text
return "%s = %s\n" % (var, value)
old_conf = get_old_conf(OUTPUT_SETTINGS_FILENAME)

View File

@ -8,8 +8,8 @@ import json
import sys
import hashlib
import xml.etree.ElementTree as ET
from six import unichr, text_type
from typing import Union
from six import unichr
from typing import Union, Text
from os.path import dirname
from PIL import Image, ImageDraw, ImageFont
@ -40,7 +40,7 @@ class MissingGlyphError(Exception):
pass
def color_font(name, code_point, code_point_to_fname_map):
# type: (str, str, Dict[int, Union[text_type, bytes]]) -> None
# type: (str, str, Dict[int, Union[Text, bytes]]) -> None
glyph_name = code_point_to_fname_map[int(code_point, 16)]
in_name = 'bitmaps/strike0/{}.png'.format(glyph_name)
@ -75,11 +75,11 @@ def bw_font(name, code_point):
)
def code_point_to_file_name_map(ttx):
# type: (str) -> Dict[int, Union[text_type, bytes]]
# type: (str) -> Dict[int, Union[Text, bytes]]
"""Given the NotoColorEmoji.ttx file, parse it to generate a map from
codepoint to filename (a la glyph0****.png)
"""
result = {} # type: Dict[int, Union[text_type, bytes]]
result = {} # type: Dict[int, Union[Text, bytes]]
xml = ET.parse(ttx)
for elem in xml.find("*cmap_format_12"):
code_point = int(elem.attrib["code"], 16)

View File

@ -4,8 +4,7 @@ import os
import re
import ujson
from six import text_type
from typing import Any, Dict, List
from typing import Any, Dict, List, Text
from django.core.management.commands import compilemessages
from django.conf import settings
@ -20,12 +19,12 @@ class Command(compilemessages.Command):
self.extract_language_options()
def get_po_filename(self, locale_path, locale):
# type: (text_type, text_type) -> text_type
# type: (Text, Text) -> Text
po_template = '{}/{}/LC_MESSAGES/django.po'
return po_template.format(locale_path, locale)
def get_json_filename(self, locale_path, locale):
# type: (text_type, text_type) -> text_type
# type: (Text, Text) -> Text
return "{}/{}/translations.json".format(locale_path, locale)
def extract_language_options(self):
@ -81,7 +80,7 @@ class Command(compilemessages.Command):
ujson.dump(data, writer, indent=2)
def get_translation_percentage(self, locale_path, locale):
# type: (text_type, text_type) -> int
# type: (Text, Text) -> int
# backend stats
po = polib.pofile(self.get_po_filename(locale_path, locale))

View File

@ -1,7 +1,6 @@
from __future__ import absolute_import
from __future__ import print_function
from six import text_type
from typing import Any
from django.core.management.base import BaseCommand

View File

@ -1,6 +1,6 @@
from __future__ import absolute_import
from typing import Any, Iterable, Tuple
from typing import Any, Iterable, Tuple, Text
from django.core.management.base import BaseCommand
@ -12,12 +12,11 @@ from zerver.lib.bulk_create import bulk_create_users
from zerver.lib.actions import set_default_streams, do_create_realm
from argparse import ArgumentParser
from six import text_type
settings.TORNADO_SERVER = None
def create_users(name_list, bot_type=None):
# type: (Iterable[Tuple[text_type, text_type]], int) -> None
# type: (Iterable[Tuple[Text, Text]], int) -> None
realms = {}
for realm in Realm.objects.all():
realms[realm.domain] = realm

View File

@ -30,14 +30,13 @@ http://stackoverflow.com/questions/2090717/getting-translation-strings-for-jinja
"""
from __future__ import absolute_import
from typing import Any, Dict, Iterable, Optional, Mapping, Set, Tuple
from typing import Any, Dict, Iterable, Optional, Mapping, Set, Tuple, Text
from argparse import ArgumentParser
import os
import re
import glob
import json
from six import text_type
from six.moves import filter
from six.moves import map
from six.moves import zip
@ -65,7 +64,7 @@ multiline_js_comment = re.compile("/\*.*?\*/", re.DOTALL)
singleline_js_comment = re.compile("//.*?\n")
def strip_whitespaces(src):
# type: (text_type) -> text_type
# type: (Text) -> Text
src = strip_whitespace_left.sub(u'\\1', src)
src = strip_whitespace_right.sub(u'\\1', src)
return src
@ -120,7 +119,7 @@ class Command(makemessages.Command):
trans_real.constant_re = re.compile(r"""_\(((?:".*?")|(?:'.*?')).*\)""")
def my_templatize(src, origin=None):
# type: (text_type, Optional[text_type]) -> text_type
# type: (Text, Optional[Text]) -> Text
new_src = strip_whitespaces(src)
return old_templatize(new_src, origin)

View File

@ -19,15 +19,14 @@ from zilencer.models import Deployment
import random
import os
from optparse import make_option
from six import text_type
from six.moves import range
from typing import Any, Callable, Dict, List, Iterable, Mapping, Sequence, Set, Tuple
from typing import Any, Callable, Dict, List, Iterable, Mapping, Sequence, Set, Tuple, Text
settings.TORNADO_SERVER = None
def create_users(realms, name_list, bot_type=None):
# type: (Mapping[text_type, Realm], Iterable[Tuple[text_type, text_type]], int) -> None
user_set = set() # type: Set[Tuple[text_type, text_type, text_type, bool]]
# type: (Mapping[Text, Realm], Iterable[Tuple[Text, Text]], int) -> None
user_set = set() # type: Set[Tuple[Text, Text, Text, bool]]
for full_name, email in name_list:
short_name = email_to_username(email)
user_set.add((email, full_name, short_name, True))
@ -35,8 +34,8 @@ def create_users(realms, name_list, bot_type=None):
bulk_create_users(realms, user_set, bot_type=bot_type, tos_version=tos_version)
def create_streams(realms, realm, stream_list):
# type: (Mapping[text_type, Realm], Realm, Iterable[text_type]) -> None
stream_set = set() # type: Set[Tuple[text_type, text_type]]
# type: (Mapping[Text, Realm], Realm, Iterable[Text]) -> None
stream_set = set() # type: Set[Tuple[Text, Text]]
for stream_name in stream_list:
stream_set.add((realm.domain, stream_name))
bulk_create_streams(realms, stream_set)
@ -127,7 +126,7 @@ class Command(BaseCommand):
string_id="mit", name="MIT", restricted_to_domain=True,
invite_required=False, org_type=Realm.CORPORATE, domain="mit.edu")
RealmAlias.objects.create(realm=mit_realm, domain="mit.edu")
realms = {} # type: Dict[text_type, Realm]
realms = {} # type: Dict[Text, Realm]
for realm in Realm.objects.all():
realms[realm.domain] = realm
@ -363,7 +362,7 @@ def send_messages(data):
# Pick a random subscriber to the stream
message.sender = random.choice(Subscription.objects.filter(
recipient=message.recipient)).user_profile
message.subject = stream.name + text_type(random.randint(1, 3))
message.subject = stream.name + Text(random.randint(1, 3))
saved_data['subject'] = message.subject
message.pub_date = now()

View File

@ -1,11 +1,11 @@
from django.db import models
from django.db.models import Manager
from six import text_type
from typing import Text
import zerver.models
def get_deployment_by_domain(domain):
# type: (text_type) -> Deployment
# type: (Text) -> Deployment
return Deployment.objects.get(realms__domain=domain)
class Deployment(models.Model):
@ -15,19 +15,19 @@ class Deployment(models.Model):
# TODO: This should really become the public portion of a keypair, and
# it should be settable only with an initial bearer "activation key"
api_key = models.CharField(max_length=32, null=True) # type: text_type
api_key = models.CharField(max_length=32, null=True) # type: Text
base_api_url = models.CharField(max_length=128) # type: text_type
base_site_url = models.CharField(max_length=128) # type: text_type
base_api_url = models.CharField(max_length=128) # type: Text
base_site_url = models.CharField(max_length=128) # type: Text
@property
def endpoints(self):
# type: () -> Dict[str, text_type]
# type: () -> Dict[str, Text]
return {'base_api_url': self.base_api_url, 'base_site_url': self.base_site_url}
@property
def name(self):
# type: () -> text_type
# type: () -> Text
# TODO: This only does the right thing for prod because prod authenticates to
# staging with the zulip.com deployment key, while staging is technically the

View File

@ -19,13 +19,12 @@ from .error_notify import notify_server_error, notify_browser_error
import time
from six import text_type
from typing import Dict, Optional, Any
from typing import Dict, Optional, Any, Text
client = get_redis_client()
def has_enough_time_expired_since_last_message(sender_email, min_delay):
# type: (text_type, float) -> bool
# type: (Text, float) -> bool
# This function returns a boolean, but it also has the side effect
# of noting that a new message was received.
key = 'zilencer:feedback:%s' % (sender_email,)
@ -48,7 +47,7 @@ def get_ticket_number():
@has_request_variables
def submit_feedback(request, deployment, message=REQ(validator=check_dict([]))):
# type: (HttpRequest, Deployment, Dict[str, text_type]) -> HttpResponse
# type: (HttpRequest, Deployment, Dict[str, Text]) -> HttpResponse
domainish = message["sender_domain"]
if get_realm_by_string_id("zulip") not in deployment.realms.all():
domainish += u" via " + deployment.name
@ -84,11 +83,11 @@ def submit_feedback(request, deployment, message=REQ(validator=check_dict([]))):
@has_request_variables
def report_error(request, deployment, type=REQ(), report=REQ(validator=check_dict([]))):
# type: (HttpRequest, Deployment, text_type, Dict[str, Any]) -> HttpResponse
# type: (HttpRequest, Deployment, Text, Dict[str, Any]) -> HttpResponse
return do_report_error(deployment.name, type, report)
def do_report_error(deployment_name, type, report):
# type: (text_type, text_type, Dict[str, Any]) -> HttpResponse
# type: (Text, Text, Dict[str, Any]) -> HttpResponse
report['deployment'] = deployment_name
if type == 'browser':
notify_browser_error(report)

View File

@ -1,8 +1,7 @@
from __future__ import absolute_import
import logging
from typing import Any, Set, Tuple, Optional
from six import text_type
from typing import Any, Set, Tuple, Optional, Text
from django.contrib.auth.backends import RemoteUserBackend
from django.conf import settings
@ -25,7 +24,7 @@ from django.contrib.auth import authenticate
from zerver.lib.utils import check_subdomain, get_subdomain
def pad_method_dict(method_dict):
# type: (Dict[text_type, bool]) -> Dict[text_type, bool]
# type: (Dict[Text, bool]) -> Dict[Text, bool]
"""Pads an authentication methods dict to contain all auth backends
supported by the software, regardless of whether they are
configured on this server"""
@ -35,7 +34,7 @@ def pad_method_dict(method_dict):
return method_dict
def auth_enabled_helper(backends_to_check, realm):
# type: (List[text_type], Optional[Realm]) -> bool
# type: (List[Text], Optional[Realm]) -> bool
if realm is not None:
enabled_method_dict = realm.authentication_methods_dict()
pad_method_dict(enabled_method_dict)
@ -74,7 +73,7 @@ def github_auth_enabled(realm=None):
return auth_enabled_helper([u'GitHub'], realm)
def common_get_active_user_by_email(email, return_data=None):
# type: (text_type, Optional[Dict[str, Any]]) -> Optional[UserProfile]
# type: (Text, Optional[Dict[str, Any]]) -> Optional[UserProfile]
try:
user_profile = get_user_profile_by_email(email)
except UserProfile.DoesNotExist:
@ -99,14 +98,14 @@ class ZulipAuthMixin(object):
return None
class SocialAuthMixin(ZulipAuthMixin):
auth_backend_name = None # type: text_type
auth_backend_name = None # type: Text
def get_email_address(self, *args, **kwargs):
# type: (*Any, **Any) -> text_type
# type: (*Any, **Any) -> Text
raise NotImplementedError
def get_full_name(self, *args, **kwargs):
# type: (*Any, **Any) -> text_type
# type: (*Any, **Any) -> Text
raise NotImplementedError
def authenticate(self, *args, **kwargs):
@ -172,7 +171,7 @@ class ZulipDummyBackend(ZulipAuthMixin):
def authenticate(self, username=None, realm_subdomain=None, use_dummy_backend=False,
return_data=None):
# type: (Optional[text_type], Optional[text_type], bool, Optional[Dict[str, Any]]) -> Optional[UserProfile]
# type: (Optional[Text], Optional[Text], bool, Optional[Dict[str, Any]]) -> Optional[UserProfile]
if use_dummy_backend:
user_profile = common_get_active_user_by_email(username)
if user_profile is None:
@ -192,7 +191,7 @@ class EmailAuthBackend(ZulipAuthMixin):
"""
def authenticate(self, username=None, password=None, realm_subdomain=None, return_data=None):
# type: (Optional[text_type], Optional[str], Optional[text_type], Optional[Dict[str, Any]]) -> Optional[UserProfile]
# type: (Optional[Text], Optional[str], Optional[Text], Optional[Dict[str, Any]]) -> Optional[UserProfile]
""" Authenticate a user based on email address as the user name. """
if username is None or password is None:
# Return immediately. Otherwise we will look for a SQL row with
@ -231,7 +230,7 @@ class GoogleMobileOauth2Backend(ZulipAuthMixin):
"""
def authenticate(self, google_oauth2_token=None, realm_subdomain=None, return_data={}):
# type: (Optional[str], Optional[text_type], Dict[str, Any]) -> Optional[UserProfile]
# type: (Optional[str], Optional[Text], Dict[str, Any]) -> Optional[UserProfile]
try:
token_payload = googleapiclient.verify_id_token(google_oauth2_token, settings.GOOGLE_CLIENT_ID)
except AppIdentityError:
@ -262,7 +261,7 @@ class ZulipRemoteUserBackend(RemoteUserBackend):
create_unknown_user = False
def authenticate(self, remote_user, realm_subdomain=None):
# type: (str, Optional[text_type]) -> Optional[UserProfile]
# type: (str, Optional[Text]) -> Optional[UserProfile]
if not remote_user:
return None
@ -304,7 +303,7 @@ class ZulipLDAPAuthBackendBase(ZulipAuthMixin, LDAPBackend):
return set()
def django_to_ldap_username(self, username):
# type: (text_type) -> text_type
# type: (Text) -> Text
if settings.LDAP_APPEND_DOMAIN:
if not username.endswith("@" + settings.LDAP_APPEND_DOMAIN):
raise ZulipLDAPException("Username does not match LDAP domain.")
@ -319,7 +318,7 @@ class ZulipLDAPAuthBackendBase(ZulipAuthMixin, LDAPBackend):
class ZulipLDAPAuthBackend(ZulipLDAPAuthBackendBase):
def authenticate(self, username, password, realm_subdomain=None, return_data=None):
# type: (text_type, str, Optional[text_type], Optional[Dict[str, Any]]) -> Optional[UserProfile]
# type: (Text, str, Optional[Text], Optional[Dict[str, Any]]) -> Optional[UserProfile]
try:
username = self.django_to_ldap_username(username)
user_profile = ZulipLDAPAuthBackendBase.authenticate(self, username, password)
@ -360,14 +359,14 @@ class ZulipLDAPAuthBackend(ZulipLDAPAuthBackendBase):
# Just like ZulipLDAPAuthBackend, but doesn't let you log in.
class ZulipLDAPUserPopulator(ZulipLDAPAuthBackendBase):
def authenticate(self, username, password, realm_subdomain=None):
# type: (text_type, str, Optional[text_type]) -> None
# type: (Text, str, Optional[Text]) -> None
return None
class DevAuthBackend(ZulipAuthMixin):
# Allow logging in as any user without a password.
# This is used for convenience when developing Zulip.
def authenticate(self, username, realm_subdomain=None, return_data=None):
# type: (text_type, Optional[text_type], Optional[Dict[str, Any]]) -> Optional[UserProfile]
# type: (Text, Optional[Text], Optional[Dict[str, Any]]) -> Optional[UserProfile]
user_profile = common_get_active_user_by_email(username, return_data=return_data)
if user_profile is None:
return None
@ -379,14 +378,14 @@ class GitHubAuthBackend(SocialAuthMixin, GithubOAuth2):
auth_backend_name = u"GitHub"
def get_email_address(self, *args, **kwargs):
# type: (*Any, **Any) -> Optional[text_type]
# type: (*Any, **Any) -> Optional[Text]
try:
return kwargs['response']['email']
except KeyError:
return None
def get_full_name(self, *args, **kwargs):
# type: (*Any, **Any) -> text_type
# type: (*Any, **Any) -> Text
try:
return kwargs['response']['name']
except KeyError:
@ -432,4 +431,4 @@ AUTH_BACKEND_NAME_MAP = {
u'Google': GoogleMobileOauth2Backend,
u'LDAP': ZulipLDAPAuthBackend,
u'RemoteUser': ZulipRemoteUserBackend,
} # type: Dict[text_type, Any]
} # type: Dict[Text, Any]

View File

@ -1,8 +1,7 @@
from __future__ import absolute_import
import sys
from typing import Any, Optional, Union
from six import text_type
from typing import Any, Optional, Union, Text
import jinja2
from django.utils import six
@ -60,7 +59,7 @@ class Template(django_jinja2.Template):
super(Template, self).__init__(template, *args, **kwargs)
def render(self, context=None, request=None):
# type: (Optional[Union[Dict[str, Any], Context]], Optional[HttpRequest]) -> text_type
# type: (Optional[Union[Dict[str, Any], Context]], Optional[HttpRequest]) -> Text
if context is None:
context = {}

View File

@ -3,7 +3,7 @@
"""
from __future__ import absolute_import # Python 2 only
from six import text_type
from typing import Text
from django.conf import settings
from django.template import TemplateSyntaxError
@ -12,7 +12,7 @@ from zerver.templatetags.minified_js import MinifiedJSNode
def minified_js(sourcefile):
# type: (str) -> text_type
# type: (str) -> Text
if sourcefile not in settings.JS_SPECS:
raise TemplateSyntaxError(
"Invalid argument: no JS file %s".format(sourcefile))