Browse Source

Annotate string constants in `synapse.api.constants` with `Final` (#11356)

This change makes mypy complain if the constants are ever reassigned,
and, more usefully, makes mypy type them as `Literal`s instead of `str`s,
allowing code of the following form to pass mypy:
```py
def do_something(membership: Literal["join", "leave"], ...): ...

do_something(Membership.JOIN, ...)
```
Sean Quah 2 years ago
parent
commit
7862f821de
2 changed files with 101 additions and 98 deletions
  1. 1 0
      changelog.d/11356.misc
  2. 100 98
      synapse/api/constants.py

+ 1 - 0
changelog.d/11356.misc

@@ -0,0 +1 @@
+Add `Final` annotation to string constants in `synapse.api.constants` so that they get typed as `Literal`s.

+ 100 - 98
synapse/api/constants.py

@@ -17,6 +17,8 @@
 
 """Contains constants from the specification."""
 
+from typing_extensions import Final
+
 # the max size of a (canonical-json-encoded) event
 MAX_PDU_SIZE = 65536
 
@@ -39,125 +41,125 @@ class Membership:
 
     """Represents the membership states of a user in a room."""
 
-    INVITE = "invite"
-    JOIN = "join"
-    KNOCK = "knock"
-    LEAVE = "leave"
-    BAN = "ban"
-    LIST = (INVITE, JOIN, KNOCK, LEAVE, BAN)
+    INVITE: Final = "invite"
+    JOIN: Final = "join"
+    KNOCK: Final = "knock"
+    LEAVE: Final = "leave"
+    BAN: Final = "ban"
+    LIST: Final = (INVITE, JOIN, KNOCK, LEAVE, BAN)
 
 
 class PresenceState:
     """Represents the presence state of a user."""
 
-    OFFLINE = "offline"
-    UNAVAILABLE = "unavailable"
-    ONLINE = "online"
-    BUSY = "org.matrix.msc3026.busy"
+    OFFLINE: Final = "offline"
+    UNAVAILABLE: Final = "unavailable"
+    ONLINE: Final = "online"
+    BUSY: Final = "org.matrix.msc3026.busy"
 
 
 class JoinRules:
-    PUBLIC = "public"
-    KNOCK = "knock"
-    INVITE = "invite"
-    PRIVATE = "private"
+    PUBLIC: Final = "public"
+    KNOCK: Final = "knock"
+    INVITE: Final = "invite"
+    PRIVATE: Final = "private"
     # As defined for MSC3083.
-    RESTRICTED = "restricted"
+    RESTRICTED: Final = "restricted"
 
 
 class RestrictedJoinRuleTypes:
     """Understood types for the allow rules in restricted join rules."""
 
-    ROOM_MEMBERSHIP = "m.room_membership"
+    ROOM_MEMBERSHIP: Final = "m.room_membership"
 
 
 class LoginType:
-    PASSWORD = "m.login.password"
-    EMAIL_IDENTITY = "m.login.email.identity"
-    MSISDN = "m.login.msisdn"
-    RECAPTCHA = "m.login.recaptcha"
-    TERMS = "m.login.terms"
-    SSO = "m.login.sso"
-    DUMMY = "m.login.dummy"
-    REGISTRATION_TOKEN = "org.matrix.msc3231.login.registration_token"
+    PASSWORD: Final = "m.login.password"
+    EMAIL_IDENTITY: Final = "m.login.email.identity"
+    MSISDN: Final = "m.login.msisdn"
+    RECAPTCHA: Final = "m.login.recaptcha"
+    TERMS: Final = "m.login.terms"
+    SSO: Final = "m.login.sso"
+    DUMMY: Final = "m.login.dummy"
+    REGISTRATION_TOKEN: Final = "org.matrix.msc3231.login.registration_token"
 
 
 # This is used in the `type` parameter for /register when called by
 # an appservice to register a new user.
-APP_SERVICE_REGISTRATION_TYPE = "m.login.application_service"
+APP_SERVICE_REGISTRATION_TYPE: Final = "m.login.application_service"
 
 
 class EventTypes:
-    Member = "m.room.member"
-    Create = "m.room.create"
-    Tombstone = "m.room.tombstone"
-    JoinRules = "m.room.join_rules"
-    PowerLevels = "m.room.power_levels"
-    Aliases = "m.room.aliases"
-    Redaction = "m.room.redaction"
-    ThirdPartyInvite = "m.room.third_party_invite"
-    RelatedGroups = "m.room.related_groups"
-
-    RoomHistoryVisibility = "m.room.history_visibility"
-    CanonicalAlias = "m.room.canonical_alias"
-    Encrypted = "m.room.encrypted"
-    RoomAvatar = "m.room.avatar"
-    RoomEncryption = "m.room.encryption"
-    GuestAccess = "m.room.guest_access"
+    Member: Final = "m.room.member"
+    Create: Final = "m.room.create"
+    Tombstone: Final = "m.room.tombstone"
+    JoinRules: Final = "m.room.join_rules"
+    PowerLevels: Final = "m.room.power_levels"
+    Aliases: Final = "m.room.aliases"
+    Redaction: Final = "m.room.redaction"
+    ThirdPartyInvite: Final = "m.room.third_party_invite"
+    RelatedGroups: Final = "m.room.related_groups"
+
+    RoomHistoryVisibility: Final = "m.room.history_visibility"
+    CanonicalAlias: Final = "m.room.canonical_alias"
+    Encrypted: Final = "m.room.encrypted"
+    RoomAvatar: Final = "m.room.avatar"
+    RoomEncryption: Final = "m.room.encryption"
+    GuestAccess: Final = "m.room.guest_access"
 
     # These are used for validation
-    Message = "m.room.message"
-    Topic = "m.room.topic"
-    Name = "m.room.name"
+    Message: Final = "m.room.message"
+    Topic: Final = "m.room.topic"
+    Name: Final = "m.room.name"
 
-    ServerACL = "m.room.server_acl"
-    Pinned = "m.room.pinned_events"
+    ServerACL: Final = "m.room.server_acl"
+    Pinned: Final = "m.room.pinned_events"
 
-    Retention = "m.room.retention"
+    Retention: Final = "m.room.retention"
 
-    Dummy = "org.matrix.dummy_event"
+    Dummy: Final = "org.matrix.dummy_event"
 
-    SpaceChild = "m.space.child"
-    SpaceParent = "m.space.parent"
+    SpaceChild: Final = "m.space.child"
+    SpaceParent: Final = "m.space.parent"
 
-    MSC2716_INSERTION = "org.matrix.msc2716.insertion"
-    MSC2716_BATCH = "org.matrix.msc2716.batch"
-    MSC2716_MARKER = "org.matrix.msc2716.marker"
+    MSC2716_INSERTION: Final = "org.matrix.msc2716.insertion"
+    MSC2716_BATCH: Final = "org.matrix.msc2716.batch"
+    MSC2716_MARKER: Final = "org.matrix.msc2716.marker"
 
 
 class ToDeviceEventTypes:
-    RoomKeyRequest = "m.room_key_request"
+    RoomKeyRequest: Final = "m.room_key_request"
 
 
 class DeviceKeyAlgorithms:
     """Spec'd algorithms for the generation of per-device keys"""
 
-    ED25519 = "ed25519"
-    CURVE25519 = "curve25519"
-    SIGNED_CURVE25519 = "signed_curve25519"
+    ED25519: Final = "ed25519"
+    CURVE25519: Final = "curve25519"
+    SIGNED_CURVE25519: Final = "signed_curve25519"
 
 
 class EduTypes:
-    Presence = "m.presence"
+    Presence: Final = "m.presence"
 
 
 class RejectedReason:
-    AUTH_ERROR = "auth_error"
+    AUTH_ERROR: Final = "auth_error"
 
 
 class RoomCreationPreset:
-    PRIVATE_CHAT = "private_chat"
-    PUBLIC_CHAT = "public_chat"
-    TRUSTED_PRIVATE_CHAT = "trusted_private_chat"
+    PRIVATE_CHAT: Final = "private_chat"
+    PUBLIC_CHAT: Final = "public_chat"
+    TRUSTED_PRIVATE_CHAT: Final = "trusted_private_chat"
 
 
 class ThirdPartyEntityKind:
-    USER = "user"
-    LOCATION = "location"
+    USER: Final = "user"
+    LOCATION: Final = "location"
 
 
-ServerNoticeMsgType = "m.server_notice"
-ServerNoticeLimitReached = "m.server_notice.usage_limit_reached"
+ServerNoticeMsgType: Final = "m.server_notice"
+ServerNoticeLimitReached: Final = "m.server_notice.usage_limit_reached"
 
 
 class UserTypes:
@@ -165,91 +167,91 @@ class UserTypes:
     'admin' and 'guest' users should also be UserTypes. Normal users are type None
     """
 
-    SUPPORT = "support"
-    BOT = "bot"
-    ALL_USER_TYPES = (SUPPORT, BOT)
+    SUPPORT: Final = "support"
+    BOT: Final = "bot"
+    ALL_USER_TYPES: Final = (SUPPORT, BOT)
 
 
 class RelationTypes:
     """The types of relations known to this server."""
 
-    ANNOTATION = "m.annotation"
-    REPLACE = "m.replace"
-    REFERENCE = "m.reference"
-    THREAD = "io.element.thread"
+    ANNOTATION: Final = "m.annotation"
+    REPLACE: Final = "m.replace"
+    REFERENCE: Final = "m.reference"
+    THREAD: Final = "io.element.thread"
 
 
 class LimitBlockingTypes:
     """Reasons that a server may be blocked"""
 
-    MONTHLY_ACTIVE_USER = "monthly_active_user"
-    HS_DISABLED = "hs_disabled"
+    MONTHLY_ACTIVE_USER: Final = "monthly_active_user"
+    HS_DISABLED: Final = "hs_disabled"
 
 
 class EventContentFields:
     """Fields found in events' content, regardless of type."""
 
     # Labels for the event, cf https://github.com/matrix-org/matrix-doc/pull/2326
-    LABELS = "org.matrix.labels"
+    LABELS: Final = "org.matrix.labels"
 
     # Timestamp to delete the event after
     # cf https://github.com/matrix-org/matrix-doc/pull/2228
-    SELF_DESTRUCT_AFTER = "org.matrix.self_destruct_after"
+    SELF_DESTRUCT_AFTER: Final = "org.matrix.self_destruct_after"
 
     # cf https://github.com/matrix-org/matrix-doc/pull/1772
-    ROOM_TYPE = "type"
+    ROOM_TYPE: Final = "type"
 
     # Whether a room can federate.
-    FEDERATE = "m.federate"
+    FEDERATE: Final = "m.federate"
 
     # The creator of the room, as used in `m.room.create` events.
-    ROOM_CREATOR = "creator"
+    ROOM_CREATOR: Final = "creator"
 
     # Used in m.room.guest_access events.
-    GUEST_ACCESS = "guest_access"
+    GUEST_ACCESS: Final = "guest_access"
 
     # Used on normal messages to indicate they were historically imported after the fact
-    MSC2716_HISTORICAL = "org.matrix.msc2716.historical"
+    MSC2716_HISTORICAL: Final = "org.matrix.msc2716.historical"
     # For "insertion" events to indicate what the next batch ID should be in
     # order to connect to it
-    MSC2716_NEXT_BATCH_ID = "org.matrix.msc2716.next_batch_id"
+    MSC2716_NEXT_BATCH_ID: Final = "org.matrix.msc2716.next_batch_id"
     # Used on "batch" events to indicate which insertion event it connects to
-    MSC2716_BATCH_ID = "org.matrix.msc2716.batch_id"
+    MSC2716_BATCH_ID: Final = "org.matrix.msc2716.batch_id"
     # For "marker" events
-    MSC2716_MARKER_INSERTION = "org.matrix.msc2716.marker.insertion"
+    MSC2716_MARKER_INSERTION: Final = "org.matrix.msc2716.marker.insertion"
 
     # The authorising user for joining a restricted room.
-    AUTHORISING_USER = "join_authorised_via_users_server"
+    AUTHORISING_USER: Final = "join_authorised_via_users_server"
 
 
 class RoomTypes:
     """Understood values of the room_type field of m.room.create events."""
 
-    SPACE = "m.space"
+    SPACE: Final = "m.space"
 
 
 class RoomEncryptionAlgorithms:
-    MEGOLM_V1_AES_SHA2 = "m.megolm.v1.aes-sha2"
-    DEFAULT = MEGOLM_V1_AES_SHA2
+    MEGOLM_V1_AES_SHA2: Final = "m.megolm.v1.aes-sha2"
+    DEFAULT: Final = MEGOLM_V1_AES_SHA2
 
 
 class AccountDataTypes:
-    DIRECT = "m.direct"
-    IGNORED_USER_LIST = "m.ignored_user_list"
+    DIRECT: Final = "m.direct"
+    IGNORED_USER_LIST: Final = "m.ignored_user_list"
 
 
 class HistoryVisibility:
-    INVITED = "invited"
-    JOINED = "joined"
-    SHARED = "shared"
-    WORLD_READABLE = "world_readable"
+    INVITED: Final = "invited"
+    JOINED: Final = "joined"
+    SHARED: Final = "shared"
+    WORLD_READABLE: Final = "world_readable"
 
 
 class GuestAccess:
-    CAN_JOIN = "can_join"
+    CAN_JOIN: Final = "can_join"
     # anything that is not "can_join" is considered "forbidden", but for completeness:
-    FORBIDDEN = "forbidden"
+    FORBIDDEN: Final = "forbidden"
 
 
 class ReadReceiptEventFields:
-    MSC2285_HIDDEN = "org.matrix.msc2285.hidden"
+    MSC2285_HIDDEN: Final = "org.matrix.msc2285.hidden"