Skip to content

Commit 8a71c01

Browse files
committed
Merge branch 'master' into fix-extracted-xblocks-legacy-mixins
2 parents 3984704 + d626012 commit 8a71c01

29 files changed

Lines changed: 214 additions & 73 deletions

File tree

cms/djangoapps/contentstore/helpers.py

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
Only Studio-specfic helper functions should be added here.
77
Platform-wide Python APIs should be added to an appropriate api.py file instead.
88
"""
9+
910
from __future__ import annotations
1011

1112
import json
@@ -33,10 +34,12 @@
3334
from cms.djangoapps.models.settings.course_grading import CourseGradingModel
3435
from cms.lib.xblock.upstream_sync import UpstreamLink, UpstreamLinkException
3536
from cms.lib.xblock.upstream_sync_block import fetch_customizable_fields_from_block
37+
from openedx.core.djangoapps.content_staging.api import StagedContentID
3638
from openedx.core.djangoapps.content_staging.data import LIBRARY_SYNC_PURPOSE
3739
from openedx.core.djangoapps.content_tagging.types import TagValuesByObjectIdDict
3840
from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers
3941
from openedx.core.djangoapps.video_config.transcripts_utils import Transcript, build_components_import_path
42+
from openedx.core.types import AuthUser as UserType
4043
from xmodule.contentstore.content import StaticContent
4144
from xmodule.contentstore.django import contentstore
4245
from xmodule.exceptions import NotFoundError
@@ -280,7 +283,10 @@ def create_usage(self, def_id) -> UsageKey:
280283
def create_definition(self, block_type, slug=None) -> DefinitionLocator:
281284
""" Generate a new definition_id for an XBlock """
282285
# Note: Split modulestore will detect this temporary ID and create a new definition ID when the XBlock is saved.
283-
return DefinitionLocator(block_type, LocalId(block_type))
286+
# FIXME: The DefinitionLocator technically only accepts an ObjectId (or a str representing an ObjectId), but
287+
# this code relies on passing a LocalId and having it save the LocalId object as its `definition_id`. We should
288+
# either change this in the future or update DefinitionLocator to support LocalId-typed definition IDs.
289+
return DefinitionLocator(block_type, LocalId(block_type)) # type: ignore[arg-type]
284290

285291

286292
@frozen
@@ -312,7 +318,7 @@ def _rewrite_static_asset_references(downstream_xblock: XBlock, substitutions: d
312318

313319

314320
def _insert_static_files_into_downstream_xblock(
315-
downstream_xblock: XBlock, staged_content_id: int, request
321+
downstream_xblock: XBlock, staged_content_id: StagedContentID, request
316322
) -> StaticFileNotices:
317323
"""
318324
Gets static files from staged content, and inserts them into the downstream XBlock.
@@ -452,7 +458,7 @@ def _fetch_and_set_upstream_link(
452458
copied_from_block: str,
453459
copied_from_version_num: int,
454460
temp_xblock: XBlock,
455-
user: User
461+
user: UserType,
456462
):
457463
"""
458464
Fetch and set upstream link for the given xblock which is being pasted. This function handles following cases:
@@ -513,7 +519,7 @@ def _import_xml_node_to_parent(
513519
# The modulestore we're using
514520
store,
515521
# The user who is performing this operation
516-
user: User,
522+
user: UserType,
517523
# Hint to use as usage ID (block_id) for the new XBlock
518524
slug_hint: str | None = None,
519525
# Content tags applied to the source XBlock(s)
@@ -635,7 +641,7 @@ def _import_xml_node_to_parent(
635641

636642
def _import_files_into_course(
637643
course_key: CourseKey,
638-
staged_content_id: int,
644+
staged_content_id: StagedContentID,
639645
static_files: list[content_staging_api.StagedContentFileData],
640646
usage_key: UsageKey,
641647
) -> tuple[StaticFileNotices, dict[str, str]]:
@@ -700,7 +706,7 @@ def _import_files_into_course(
700706

701707
def _import_file_into_course(
702708
course_key: CourseKey,
703-
staged_content_id: int,
709+
staged_content_id: StagedContentID,
704710
file_data_obj: content_staging_api.StagedContentFileData,
705711
usage_key: UsageKey,
706712
) -> tuple[bool | None, dict]:
@@ -760,7 +766,7 @@ def _import_file_into_course(
760766

761767
def _import_transcripts(
762768
block: XBlock,
763-
staged_content_id: int,
769+
staged_content_id: StagedContentID,
764770
static_files: list[content_staging_api.StagedContentFileData],
765771
):
766772
"""

cms/djangoapps/contentstore/models.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -485,7 +485,7 @@ def _annotate_query_with_ready_to_sync(cls, query_set: QuerySet["EntityLinkBase"
485485
@classmethod
486486
def update_or_create(
487487
cls,
488-
upstream_container_id: int | None,
488+
upstream_container_id: Container.ID | None,
489489
/,
490490
upstream_container_key: LibraryContainerLocator,
491491
upstream_context_key: str,

cms/djangoapps/contentstore/utils.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2425,7 +2425,7 @@ def _create_or_update_container_link(created: datetime | None, xblock):
24252425
"""
24262426
upstream_container_key = LibraryContainerLocator.from_string(xblock.upstream)
24272427
try:
2428-
lib_component = get_container(upstream_container_key).container_pk
2428+
lib_component = get_container(upstream_container_key).container_id
24292429
except ObjectDoesNotExist:
24302430
log.error(f"Library component not found for {upstream_container_key}")
24312431
lib_component = None

cms/djangoapps/modulestore_migrator/api/write_api.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from celery.result import AsyncResult
77
from opaque_keys.edx.locator import LibraryLocatorV2
88
from openedx_content.api import get_collection
9+
from openedx_content.models_api import LearningPackage
910

1011
from openedx.core.djangoapps.content_libraries.api import get_library
1112
from openedx.core.types.user import AuthUser
@@ -64,7 +65,8 @@ def start_bulk_migration_to_library(
6465
"""
6566
target_library = get_library(target_library_key)
6667
# get_library ensures that the library is connected to a learning package.
67-
target_package_id: int = target_library.learning_package_id # type: ignore[assignment]
68+
assert target_library.learning_package_id is not None
69+
target_package_id: LearningPackage.ID = target_library.learning_package_id
6870

6971
sources_pks: list[int] = []
7072
for source_key in source_key_list:

cms/djangoapps/modulestore_migrator/tasks.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ class _MigrationContext:
120120

121121
# Fields that remain constant
122122
previous_block_migrations: dict[UsageKey, data.ModulestoreBlockMigrationResult]
123-
target_package_id: int
123+
target_package_id: LearningPackage.ID
124124
target_library_key: LibraryLocatorV2
125125
source_context_key: SourceContextKey
126126
content_by_filename: dict[str, int]
@@ -345,21 +345,21 @@ def _import_structure(
345345
used_component_keys=set(
346346
LibraryUsageLocatorV2(target_library.key, block_type, block_id) # type: ignore[abstract]
347347
for block_type, block_id
348-
in content_api.get_components(migration.target.pk).values_list(
348+
in content_api.get_components(migration.target.id).values_list(
349349
"component_type__name", "local_key"
350350
)
351351
),
352352
used_container_slugs=set(
353353
content_api.get_containers(
354-
migration.target.pk
354+
migration.target.id
355355
).values_list("publishable_entity__key", flat=True)
356356
),
357357
previous_block_migrations=(
358358
get_migration_blocks(source_data.previous_migration.pk)
359359
if source_data.previous_migration
360360
else {}
361361
),
362-
target_package_id=migration.target.pk,
362+
target_package_id=migration.target.id,
363363
target_library_key=target_library.key,
364364
source_context_key=source_data.source_root_usage_key.course_key,
365365
content_by_filename=content_by_filename,
@@ -882,12 +882,12 @@ def _migrate_container(
882882
)
883883
if container_exists and context.should_skip_strategy:
884884
return PublishableEntityVersion.objects.get(
885-
entity_id=container.container_pk,
885+
entity_id=container.container_id,
886886
version_num=container.draft_version_num,
887887
), None
888888

889889
container_publishable_entity_version = content_api.create_next_container_version(
890-
container.container_pk,
890+
container.container_id,
891891
title=title,
892892
entities=[child.entity for child in children],
893893
created=context.created_at,

cms/pytest.ini

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ filterwarnings =
1717
# ABC deprecation Warning comes from libsass
1818
ignore:Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated.*:DeprecationWarning:sass
1919
ignore:'etree' is deprecated. Use 'xml.etree.ElementTree' instead.:DeprecationWarning:wiki
20+
# We sometimes use DeprecationWarning to enourage `.id` instead of `.pk` since there are some cases where we cannot
21+
# override the type of `.pk`, but we can always customize `.id` (e.g. using TypedBigAutoField). But we don't want to
22+
# see those warnings when Django is using `.pk` internally, which is fine.
23+
ignore:Use \.id instead:DeprecationWarning:django\..*
2024

2125
norecursedirs = envs
2226
python_classes =

mypy.ini

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ files =
99
cms/lib/xblock,
1010
cms/djangoapps/contentstore/rest_api/v2/views,
1111
cms/djangoapps/contentstore/xblock_storage_handlers,
12+
cms/djangoapps/contentstore/helpers.py,
1213
cms/djangoapps/modulestore_migrator,
1314
openedx/core/djangoapps/content/learning_sequences,
1415
# FIXME: need to solve type issues and add 'search' app here:

openedx/core/djangoapps/content_libraries/api/blocks.py

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
)
4242
from xblock.core import XBlock
4343

44+
from openedx.core.djangoapps.content_staging.data import StagedContentID
4445
from openedx.core.djangoapps.xblock.api import (
4546
get_component_from_usage_key,
4647
get_xblock_app_config,
@@ -243,7 +244,7 @@ def set_library_block_olx(usage_key: LibraryUsageLocatorV2, new_olx_str: str) ->
243244
created=now,
244245
)
245246
new_component_version = content_api.create_next_component_version(
246-
component.pk,
247+
component.id,
247248
title=new_title,
248249
media_to_replace={
249250
'block.xml': new_content.pk,
@@ -382,7 +383,7 @@ def _import_staged_block(
382383
library_key: LibraryLocatorV2,
383384
source_context_key: LearningContextKey,
384385
user,
385-
staged_content_id: int,
386+
staged_content_id: StagedContentID,
386387
staged_content_files: list[StagedContentFileData],
387388
now: datetime,
388389
) -> LibraryXBlockMetadata:
@@ -517,7 +518,7 @@ def _import_staged_block_as_container(
517518
library_key: LibraryLocatorV2,
518519
source_context_key: LearningContextKey,
519520
user,
520-
staged_content_id: int,
521+
staged_content_id: StagedContentID,
521522
staged_content_files: list[StagedContentFileData],
522523
now: datetime,
523524
*,
@@ -727,7 +728,7 @@ def send_block_deleted_signal():
727728
affected_collections = content_api.get_entity_collections(component.learning_package_id, component.key)
728729
affected_containers = get_containers_contains_item(usage_key)
729730

730-
content_api.soft_delete_draft(component.pk, deleted_by=user_id)
731+
content_api.soft_delete_draft(component.id, deleted_by=user_id)
731732

732733
send_block_deleted_signal()
733734

@@ -773,7 +774,7 @@ def restore_library_block(usage_key: LibraryUsageLocatorV2, user_id: int | None
773774

774775
# Set draft version back to the latest available component version id.
775776
content_api.set_draft_version(
776-
component.pk,
777+
component.id,
777778
component.versioning.latest.pk,
778779
set_by=user_id,
779780
)
@@ -909,7 +910,7 @@ def add_library_block_static_asset_file(
909910

910911
with transaction.atomic():
911912
component_version = content_api.create_next_component_version(
912-
component.pk,
913+
component.id,
913914
media_to_replace={file_path: file_content},
914915
created=datetime.now(tz=timezone.utc), # noqa: UP017
915916
created_by=user.id if user else None,
@@ -956,8 +957,8 @@ def delete_library_block_static_asset_file(usage_key, file_path, user=None):
956957
now = datetime.now(tz=timezone.utc) # noqa: UP017
957958

958959
with transaction.atomic():
959-
component_version = content_api.create_next_component_version( # noqa: F841
960-
component.pk,
960+
content_api.create_next_component_version(
961+
component.id,
961962
media_to_replace={file_path: None},
962963
created=now,
963964
created_by=user.id if user else None,

openedx/core/djangoapps/content_libraries/api/container_metadata.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ class ContainerMetadata(PublishableItem):
7171

7272
container_key: LibraryContainerLocator
7373
container_type_code: str
74-
container_pk: int
74+
container_id: Container.ID
7575

7676
@classmethod
7777
def from_container(cls, library_key, container: Container, associated_collections=None):
@@ -99,7 +99,7 @@ def from_container(cls, library_key, container: Container, associated_collection
9999
return cls(
100100
container_key=container_key,
101101
container_type_code=container_key.container_type,
102-
container_pk=container.pk,
102+
container_id=container.id,
103103
display_name=draft.title,
104104
created=container.created,
105105
modified=draft.created,
@@ -110,7 +110,7 @@ def from_container(cls, library_key, container: Container, associated_collection
110110
published_by=published_by,
111111
last_draft_created=last_draft_created,
112112
last_draft_created_by=last_draft_created_by,
113-
has_unpublished_changes=content_api.contains_unpublished_changes(container.pk),
113+
has_unpublished_changes=content_api.contains_unpublished_changes(container.id),
114114
tags_count=tags.get(str(container_key), 0),
115115
collections=associated_collections or [],
116116
)
@@ -260,7 +260,7 @@ def _get_containers_with_entities(
260260
for member in members:
261261
qs = qs.union(
262262
content_api.get_containers_with_entity(
263-
member.entity.pk,
263+
member.entity.id,
264264
ignore_pinned=ignore_pinned,
265265
)
266266
)
@@ -338,7 +338,7 @@ def create(
338338
container=entity,
339339
),
340340
display_name=entity.versioning.draft.title,
341-
has_unpublished_changes=content_api.contains_unpublished_changes(entity.pk),
341+
has_unpublished_changes=content_api.contains_unpublished_changes(entity.id),
342342
container=entity,
343343
component=None,
344344
)

openedx/core/djangoapps/content_libraries/api/containers.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ def send_container_deleted_signal():
234234
container_key,
235235
published=False,
236236
)
237-
content_api.soft_delete_draft(container.pk)
237+
content_api.soft_delete_draft(container.id)
238238

239239
send_container_deleted_signal()
240240

@@ -294,7 +294,7 @@ def restore_container(container_key: LibraryContainerLocator) -> None:
294294
container.key,
295295
)
296296

297-
content_api.set_draft_version(container.pk, container.versioning.latest.pk)
297+
content_api.set_draft_version(container.id, container.versioning.latest.pk)
298298
# Fetch related containers after restore
299299
affected_containers = get_containers_contains_item(container_key)
300300
# Get children containers or components to update their index data
@@ -441,7 +441,7 @@ def get_containers_contains_item(key: LibraryUsageLocatorV2 | LibraryContainerLo
441441
[ 🛑 UNSTABLE ] Get containers that contains the item, that can be a component or another container.
442442
"""
443443
entity = get_entity_from_key(key)
444-
containers = content_api.get_containers_with_entity(entity.pk).select_related("container_type")
444+
containers = content_api.get_containers_with_entity(entity.id).select_related("container_type")
445445
return [ContainerMetadata.from_container(key.lib_key, container) for container in containers]
446446

447447

@@ -460,7 +460,7 @@ def publish_container_changes(
460460
learning_package = content_library.learning_package
461461
assert learning_package
462462
# The core publishing API is based on draft objects, so find the draft that corresponds to this container:
463-
drafts_to_publish = content_api.get_all_drafts(learning_package.id).filter(entity__pk=container.pk)
463+
drafts_to_publish = content_api.get_all_drafts(learning_package.id).filter(entity__pk=container.id)
464464
# Publish the container, which will also auto-publish any unpublished child components:
465465
publish_log = content_api.publish_from_drafts(
466466
learning_package.id,

0 commit comments

Comments
 (0)