Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat!: Assume that scope IDs are opaque key objects (WIP) #809

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions xblock/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -799,6 +799,7 @@ def __init__(
"""
if scope_ids is UNSET:
raise TypeError('scope_ids are required')
scope_ids.validate_types()

# A cache of the parent block, retrieved from .parent
self._parent_block = None
Expand Down
26 changes: 25 additions & 1 deletion xblock/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@
**scopes** to associate each field with particular sets of blocks and users.
The hosting runtime application decides what actual storage mechanism to use
for each scope.

"""
from __future__ import annotations

from collections import namedtuple
import copy
import datetime
Expand All @@ -15,6 +16,8 @@
import traceback
import warnings

from opaque_keys.edx.keys import UsageKey, DefinitionKey

import dateutil.parser
from lxml import etree
import pytz
Expand Down Expand Up @@ -242,6 +245,27 @@ class ScopeIds(namedtuple('ScopeIds', 'user_id block_type def_id usage_id')):
"""
__slots__ = ()

def validate_types(self):
"""
Raise an AssertionError if any of the ids are an unexpected type.

Originally, these fields were all freely-typed; but in practice,
edx-platform's XBlock runtime would fail if the ids did not match the
types below. In order to make the XBlock library reflect the
edx-platform reality and improve type-safety, we've decided to actually
enforce the types here, per:
https://github.com/openedx/XBlock/issues/708
"""
if self.user_id is not None:
if not isinstance(self.user_id, (int, str)):
raise TypeError(f"got {self.user_id=}; should be an int, str, or None")
if not isinstance(self.block_type, str):
raise TypeError(f"got {self.block_type=}; should be a str")
if not isinstance(self.def_id, DefinitionKey):
raise TypeError(f"got {self.def_id=}; should be a DefinitionKey")
if not isinstance(self.usage_id, UsageKey):
raise TypeError(f"got {self.usage_id=}; should be a UsageKey")


# Define special reference that can be used as a field's default in field
# definition to signal that the field should default to a unique string value
Expand Down
Loading