From f929050230059f8614f3f1c40a09a56e186d5824 Mon Sep 17 00:00:00 2001 From: Anders Kaseorg Date: Tue, 20 Sep 2022 13:45:56 -0700 Subject: [PATCH] external_accounts: Make ExternalAccount dataclass to fix typing. Commit 1a426fa6be0f77bd9debf3e6620ac646f6cc586b (#22977) changed name to be a StrPromise rather than a str. Signed-off-by: Anders Kaseorg --- zerver/actions/custom_profile_fields.py | 4 +- zerver/lib/external_accounts.py | 58 ++++++++++++++---------- zerver/tests/test_custom_profile_data.py | 4 +- 3 files changed, 38 insertions(+), 28 deletions(-) diff --git a/zerver/actions/custom_profile_fields.py b/zerver/actions/custom_profile_fields.py index 6834e5d872..a9a69a4994 100644 --- a/zerver/actions/custom_profile_fields.py +++ b/zerver/actions/custom_profile_fields.py @@ -31,9 +31,9 @@ def try_add_realm_default_custom_profile_field( field_data = DEFAULT_EXTERNAL_ACCOUNTS[field_subtype] custom_profile_field = CustomProfileField( realm=realm, - name=field_data["name"], + name=str(field_data.name), field_type=CustomProfileField.EXTERNAL_ACCOUNT, - hint=field_data["hint"], + hint=field_data.hint, field_data=orjson.dumps(dict(subtype=field_subtype)).decode(), ) custom_profile_field.save() diff --git a/zerver/lib/external_accounts.py b/zerver/lib/external_accounts.py index f22c23aa6e..13e3c7398f 100644 --- a/zerver/lib/external_accounts.py +++ b/zerver/lib/external_accounts.py @@ -1,8 +1,8 @@ """ This module stores data for "external account" custom profile field. """ -import copy -from typing import Dict +from dataclasses import dataclass +from typing import TYPE_CHECKING, Dict from django.core.exceptions import ValidationError from django.utils.translation import gettext as _ @@ -15,37 +15,47 @@ from zerver.lib.validator import ( check_required_string, ) +if TYPE_CHECKING: + from django.utils.functional import _StrPromise as StrPromise + # Default external account fields are by default available # to realm admins, where realm admin only need to select # the default field and other values(i.e. name, url) will be # fetch from this dictionary. -# text: Field text for admins - custom profile field in org settings view -# name: Field label or name - user profile in user settings view -# hint: Field hint for realm users -# url_pattern: Field URL linkifier +@dataclass +class ExternalAccount: + text: str # Field text for admins - custom profile field in org settings view + name: "StrPromise" # Field label or name - user profile in user settings view + hint: str # Field hint for realm users + url_pattern: str # Field URL linkifier + + DEFAULT_EXTERNAL_ACCOUNTS = { - "twitter": { - "text": "Twitter", - "url_pattern": "https://twitter.com/%(username)s", - "name": gettext_lazy("Twitter username"), - "hint": "", - }, - "github": { - "text": "GitHub", - "url_pattern": "https://github.com/%(username)s", - "name": gettext_lazy("GitHub username"), - "hint": "", - }, + "twitter": ExternalAccount( + text="Twitter", + url_pattern="https://twitter.com/%(username)s", + name=gettext_lazy("Twitter username"), + hint="", + ), + "github": ExternalAccount( + text="GitHub", + url_pattern="https://github.com/%(username)s", + name=gettext_lazy("GitHub username"), + hint="", + ), } def get_default_external_accounts() -> Dict[str, Dict[str, str]]: - translated_default_external_accounts = copy.deepcopy(DEFAULT_EXTERNAL_ACCOUNTS) - - for external_account in translated_default_external_accounts.values(): - external_account["name"] = str(external_account["name"]) - - return translated_default_external_accounts + return { + subtype: { + "text": external_account.text, + "url_pattern": external_account.url_pattern, + "name": str(external_account.name), + "hint": external_account.hint, + } + for subtype, external_account in DEFAULT_EXTERNAL_ACCOUNTS.items() + } def validate_external_account_field_data(field_data: ProfileFieldData) -> ProfileFieldData: diff --git a/zerver/tests/test_custom_profile_data.py b/zerver/tests/test_custom_profile_data.py index 9bdfe0d7d2..8386f4f77e 100644 --- a/zerver/tests/test_custom_profile_data.py +++ b/zerver/tests/test_custom_profile_data.py @@ -190,8 +190,8 @@ class CreateCustomProfileFieldTest(CustomProfileFieldTestCase): field = CustomProfileField.objects.get(name=invalid_field_name, realm=realm) # The field is created with 'Twitter username' name as per values in default fields dict field = CustomProfileField.objects.get(name="Twitter username") - self.assertEqual(field.name, DEFAULT_EXTERNAL_ACCOUNTS["twitter"]["name"]) - self.assertEqual(field.hint, DEFAULT_EXTERNAL_ACCOUNTS["twitter"]["hint"]) + self.assertEqual(field.name, DEFAULT_EXTERNAL_ACCOUNTS["twitter"].name) + self.assertEqual(field.hint, DEFAULT_EXTERNAL_ACCOUNTS["twitter"].hint) result = self.client_delete(f"/json/realm/profile_fields/{field.id}") self.assert_json_success(result)