types: Convert ProfileDataElement to Python 3.6 style and total.

The Python 3.6 style does support non-total and even partially-total
TypedDict, but total gives us better guarantees.

Signed-off-by: Anders Kaseorg <anders@zulip.com>
This commit is contained in:
Anders Kaseorg
2020-06-13 00:30:51 -07:00
committed by Tim Abbott
parent 686ae3eef4
commit 46d0018fbb
2 changed files with 24 additions and 15 deletions

View File

@@ -11,16 +11,18 @@ Validator = Callable[[str, object], Optional[str]]
ExtendedValidator = Callable[[str, str, object], Optional[str]]
RealmUserValidator = Callable[[int, List[int], bool], Optional[str]]
ProfileDataElement = TypedDict('ProfileDataElement', {
'id': int,
'name': str,
'type': int,
'hint': Optional[str],
'field_data': Optional[str],
'order': int,
'value': str,
'rendered_value': Optional[str],
}, total=False) # TODO: Can we remove this requirement?
class ProfileDataElementBase(TypedDict):
id: int
name: str
type: int
hint: Optional[str]
field_data: Optional[str]
order: int
class ProfileDataElement(ProfileDataElementBase):
value: str
rendered_value: Optional[str]
ProfileData = List[ProfileDataElement]
FieldElement = Tuple[int, str, Validator, Callable[[Any], Any], str]

View File

@@ -72,7 +72,7 @@ from zerver.lib.types import (
ExtendedValidator,
FieldElement,
ProfileData,
ProfileDataElement,
ProfileDataElementBase,
RealmUserValidator,
UserFieldElement,
Validator,
@@ -1127,9 +1127,16 @@ class UserProfile(AbstractBaseUser, PermissionsMixin):
value = converter(value)
field_data = field.as_dict()
field_data['value'] = value
field_data['rendered_value'] = rendered_value
data.append(field_data)
data.append({
'id': field_data['id'],
'name': field_data['name'],
'type': field_data['type'],
'hint': field_data['hint'],
'field_data': field_data['field_data'],
'order': field_data['order'],
'value': value,
'rendered_value': rendered_value,
})
return data
@@ -2823,7 +2830,7 @@ class CustomProfileField(models.Model):
class Meta:
unique_together = ('realm', 'name')
def as_dict(self) -> ProfileDataElement:
def as_dict(self) -> ProfileDataElementBase:
return {
'id': self.id,
'name': self.name,