-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Annotate string constants in synapse.api.constants
with Final
#11356
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Add `Final` annotation to string constants in `synapse.api.constants` so that they get typed as `Literal`s. |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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,217 +41,217 @@ 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) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Actually, the earlier lines print things like Do we know why it says a question mark after each Literal? ... It makes me worry that something secret is going on. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good question. https://mypy.readthedocs.io/en/stable/literal_types.html#declaring-literal-variables says
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for the link David. It took me a few reads to see what it's going on about, but interesting — question is: do we want the behaviour given by There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I'm having trouble coming up with an example which demonstrates the difference. Do you have one in mind? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's really hard to come up with an example where it makes a difference. Here's one: T = TypeVar("T", bound=str)
def validate_or_throw(value: str, allowed_values: List[T]) -> T:
...
ACTIONS_IMPLICIT: Final = ["ban", "unban"]
ACTIONS_EXPLICIT: List[Literal["ban", "unban"]] = ["ban", "unban"]
def do_action(action: Literal["ban", "unban"]):
pass
def on_GET1(json: Dict):
action = validate_or_throw(json["action"], ACTIONS_IMPLICIT)
do_action(action) # Argument 1 to "do_action" has incompatible type "str"
def on_GET2(json: Dict):
action = validate_or_throw(json["action"], ACTIONS_EXPLICIT)
do_action(action) # ok I'm tempted to stick with There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I'm fine with this---no worse than the current situation as far as I can see There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. aye yeah, let's just stick with it |
||
|
||
|
||
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: | ||
"""Allows for user type specific behaviour. With the benefit of hindsight | ||
'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" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was wondering if this should say
Final[str]
. Answer seems to be a big fat NO.If you make it
Final[str]
, then it types asstr
rather thanLiteral['invite']
.So I think this is fine.