diff --git a/tools/lib/gitlint-rules.py b/tools/lib/gitlint-rules.py index 9149ddca59..da70b63f11 100644 --- a/tools/lib/gitlint-rules.py +++ b/tools/lib/gitlint-rules.py @@ -1,5 +1,5 @@ import re -from typing import List, Text +from typing import List from gitlint.git import GitCommit from gitlint.options import StrOption @@ -85,7 +85,7 @@ imperative_forms = [ imperative_forms.sort() -def head_binary_search(key: Text, words: List[str]) -> str: +def head_binary_search(key: str, words: List[str]) -> str: """ Find the imperative mood version of `word` by looking at the first 3 characters. """ @@ -124,7 +124,7 @@ class ImperativeMood(LineRule): error_msg = ('The first word in commit title should be in imperative mood ' '("{word}" -> "{imperative}"): "{title}"') - def validate(self, line: Text, commit: GitCommit) -> List[RuleViolation]: + def validate(self, line: str, commit: GitCommit) -> List[RuleViolation]: violations = [] # Ignore the section tag (ie `
: .`) @@ -152,7 +152,7 @@ class TitleMatchRegexAllowException(LineRule): target = CommitMessageTitle options_spec = [StrOption('regex', ".*", "Regex the title should match")] - def validate(self, title: Text, commit: GitCommit) -> List[RuleViolation]: + def validate(self, title: str, commit: GitCommit) -> List[RuleViolation]: regex = self.options['regex'].value pattern = re.compile(regex, re.UNICODE) diff --git a/tools/lib/template_parser.py b/tools/lib/template_parser.py index ad57df1aee..64b81707a6 100644 --- a/tools/lib/template_parser.py +++ b/tools/lib/template_parser.py @@ -1,4 +1,4 @@ -from typing import Callable, List, Optional, Text +from typing import Callable, List, Optional class FormattedException(Exception): @@ -306,7 +306,7 @@ OPTIONAL_CLOSING_TAGS = [ 'stop', ] -def is_self_closing_html_tag(s: Text, tag: Text) -> bool: +def is_self_closing_html_tag(s: str, tag: str) -> bool: if s.endswith('/>'): if tag in OPTIONAL_CLOSING_TAGS: return True diff --git a/tools/linter_lib/custom_check.py b/tools/linter_lib/custom_check.py index cc46a9005b..d20ecd491c 100644 --- a/tools/linter_lib/custom_check.py +++ b/tools/linter_lib/custom_check.py @@ -360,16 +360,6 @@ python_rules = RuleList( 'bad_lines': ['desc: Optional[Text] = models.TextField()', 'stream: Optional[Stream] = models.ForeignKey(Stream, on_delete=CASCADE)'], }, - {'pattern': r'[\s([]Text([^\s\w]|$)', - 'exclude': { - # We are likely to want to keep these dirs Python 2+3 compatible, - # since the plan includes extracting them to a separate project eventually. - 'tools/lib', - # TODO: Update our migrations from Text->str. - 'zerver/migrations/', - }, - 'description': "Now that we're a Python 3 only codebase, we don't need to use typing.Text. Please use str instead.", - }, {'pattern': 'exit[(]1[)]', 'include_only': {"/management/commands/"}, 'description': 'Raise CommandError to exit with failure in management commands', diff --git a/tools/semgrep.yml b/tools/semgrep.yml index a3b69d557b..b547b7908e 100644 --- a/tools/semgrep.yml +++ b/tools/semgrep.yml @@ -133,3 +133,9 @@ rules: pattern: eval severity: ERROR message: "Do not use eval under any circumstances; consider json.loads instead" + + - id: typing-text + languages: [python] + pattern: typing.Text + severity: ERROR + message: "Use str instead of typing.Text" diff --git a/zerver/migrations/0032_verify_all_medium_avatar_images.py b/zerver/migrations/0032_verify_all_medium_avatar_images.py index ceb86eeb5a..779997555a 100644 --- a/zerver/migrations/0032_verify_all_medium_avatar_images.py +++ b/zerver/migrations/0032_verify_all_medium_avatar_images.py @@ -1,5 +1,4 @@ import hashlib -from typing import Text from unittest.mock import patch from django.conf import settings @@ -18,7 +17,7 @@ from zerver.models import UserProfile # from zerver.lib.upload (which would pretty annoying, but would be a # pain) and just using the current version, which doesn't work # since we rearranged the avatars in Zulip 1.6. -def patched_user_avatar_path(user_profile: UserProfile) -> Text: +def patched_user_avatar_path(user_profile: UserProfile) -> str: email = user_profile.email user_key = email.lower() + settings.AVATAR_SALT return make_safe_digest(user_key, hashlib.sha1)