77from opaque_keys import InvalidKeyError
88from opaque_keys .edx .locator import LibraryLocatorV2
99
10-
1110AUTHZ_POLICY_ATTRIBUTES_SEPARATOR = "^"
1211
1312
@@ -77,14 +76,14 @@ def __attrs_post_init__(self):
7776class ScopeMeta (type ):
7877 """Metaclass for ScopeData to handle dynamic subclass instantiation based on namespace."""
7978
80- _scope_registry : ClassVar [dict [str , Type ["ScopeData" ]]] = {}
79+ scope_registry : ClassVar [dict [str , Type ["ScopeData" ]]] = {}
8180
8281 def __init__ (cls , name , bases , attrs ):
8382 """Initialize the metaclass and register subclasses."""
8483 super ().__init__ (name , bases , attrs )
85- if not hasattr (cls , "_scope_registry " ):
86- cls ._scope_registry = {}
87- cls ._scope_registry [cls .NAMESPACE ] = cls
84+ if not hasattr (cls , "scope_registry " ):
85+ cls .scope_registry = {}
86+ cls .scope_registry [cls .NAMESPACE ] = cls
8887
8988 def __call__ (cls , * args , ** kwargs ):
9089 """Instantiate the appropriate subclass based on the namespace in namespaced_key.
@@ -115,7 +114,8 @@ def __call__(cls, *args, **kwargs):
115114
116115 return super ().__call__ (* args , ** kwargs )
117116
118- def get_subclass_by_namespaced_key (cls , namespaced_key : str ) -> Type ["ScopeData" ]:
117+ @classmethod
118+ def get_subclass_by_namespaced_key (mcs , namespaced_key : str ) -> Type ["ScopeData" ]:
119119 """Get the appropriate subclass based on the namespace in namespaced_key.
120120
121121 Args:
@@ -126,9 +126,10 @@ def get_subclass_by_namespaced_key(cls, namespaced_key: str) -> Type["ScopeData"
126126 """
127127 # TODO: Default separator, can't access directly from class so made it a constant
128128 namespace = namespaced_key .split (AUTHZ_POLICY_ATTRIBUTES_SEPARATOR , 1 )[0 ]
129- return cls . _scope_registry .get (namespace , ScopeData )
129+ return mcs . scope_registry .get (namespace , ScopeData )
130130
131- def get_subclass_by_external_key (cls , external_key : str ) -> Type ["ScopeData" ]:
131+ @classmethod
132+ def get_subclass_by_external_key (mcs , external_key : str ) -> Type ["ScopeData" ]:
132133 """Get the appropriate subclass based on the format of external_key.
133134
134135 Args:
@@ -145,12 +146,13 @@ def get_subclass_by_external_key(cls, external_key: str) -> Type["ScopeData"]:
145146 # 3. If the namespace is not recognized, we return the base ScopeData class
146147 # 4. The subclass implements a validation method to validate the entire key
147148 namespace = external_key .split (":" , 1 )[0 ]
148- scope_subclass = cls . _scope_registry .get (namespace )
149+ scope_subclass = mcs . scope_registry .get (namespace )
149150 if not scope_subclass or not scope_subclass .validate_external_key (external_key ):
150151 return ScopeData # Fallback to base class if not found or invalid
151152 return scope_subclass
152153
153- def validate_external_key (cls , external_key : str ) -> bool :
154+ @classmethod
155+ def validate_external_key (mcs , external_key : str ) -> bool :
154156 """Validate the external_key format for the subclass.
155157
156158 Args:
@@ -217,14 +219,14 @@ def validate_external_key(cls, external_key: str) -> bool:
217219class SubjectMeta (type ):
218220 """Metaclass for SubjectData to handle dynamic subclass instantiation based on namespace."""
219221
220- _subject_registry : ClassVar [dict [str , Type ["SubjectData" ]]] = {}
222+ subject_registry : ClassVar [dict [str , Type ["SubjectData" ]]] = {}
221223
222224 def __init__ (cls , name , bases , attrs ):
223225 """Initialize the metaclass and register subclasses."""
224226 super ().__init__ (name , bases , attrs )
225- if not hasattr (cls , "_subject_registry " ):
226- cls ._subject_registry = {}
227- cls ._subject_registry [cls .NAMESPACE ] = cls
227+ if not hasattr (cls , "subject_registry " ):
228+ cls .subject_registry = {}
229+ cls .subject_registry [cls .NAMESPACE ] = cls
228230
229231 def __call__ (cls , * args , ** kwargs ):
230232 """Instantiate the appropriate subclass based on the namespace in namespaced_key.
@@ -244,7 +246,8 @@ def __call__(cls, *args, **kwargs):
244246
245247 return super ().__call__ (* args , ** kwargs )
246248
247- def get_subclass_by_namespaced_key (cls , namespaced_key : str ) -> Type ["SubjectData" ]:
249+ @classmethod
250+ def get_subclass_by_namespaced_key (mcs , namespaced_key : str ) -> Type ["SubjectData" ]:
248251 """Get the appropriate subclass based on the namespace in namespaced_key.
249252
250253 Args:
@@ -254,7 +257,7 @@ def get_subclass_by_namespaced_key(cls, namespaced_key: str) -> Type["SubjectDat
254257 The subclass of SubjectData corresponding to the namespace, or SubjectData if not found.
255258 """
256259 namespace = namespaced_key .split (AUTHZ_POLICY_ATTRIBUTES_SEPARATOR , 1 )[0 ]
257- return cls . _subject_registry .get (namespace , SubjectData )
260+ return mcs . subject_registry .get (namespace , SubjectData )
258261
259262
260263@define
0 commit comments