diff --git a/cms/djangoapps/contentstore/views/component.py b/cms/djangoapps/contentstore/views/component.py index c1338d6230..ed955c1b32 100644 --- a/cms/djangoapps/contentstore/views/component.py +++ b/cms/djangoapps/contentstore/views/component.py @@ -23,7 +23,6 @@ from xblock.exceptions import NoSuchHandlerError from xblock.fields import Scope from xblock.plugin import PluginMissingError from xblock.runtime import Mixologist -from xmodule.x_module import prefer_xmodules from lms.lib.xblock.runtime import unquote_slashes diff --git a/cms/envs/bok_choy.py b/cms/envs/bok_choy.py index bc2a61a8ea..b088ccd880 100644 --- a/cms/envs/bok_choy.py +++ b/cms/envs/bok_choy.py @@ -16,8 +16,6 @@ os.environ['SERVICE_VARIANT'] = 'bok_choy' os.environ['CONFIG_ROOT'] = path(__file__).abspath().dirname() #pylint: disable=E1120 from .aws import * # pylint: disable=W0401, W0614 -from xmodule.x_module import prefer_xmodules - ######################### Testing overrides #################################### @@ -49,8 +47,5 @@ for log_name, log_level in LOG_OVERRIDES: # Use the auto_auth workflow for creating users and logging them in FEATURES['AUTOMATIC_AUTH_FOR_TESTING'] = True -# Enable XBlocks -XBLOCK_SELECT_FUNCTION = prefer_xmodules - # Unfortunately, we need to use debug mode to serve staticfiles DEBUG = True diff --git a/cms/envs/common.py b/cms/envs/common.py index 7452b2c5da..07fea0ed4e 100644 --- a/cms/envs/common.py +++ b/cms/envs/common.py @@ -24,6 +24,7 @@ Longer TODO: # want to import all variables from base settings files # pylint: disable=W0401, W0611, W0614 +import imp import sys import lms.envs.common from lms.envs.common import ( @@ -33,8 +34,6 @@ from path import path from lms.lib.xblock.mixin import LmsBlockMixin from cms.lib.xblock.mixin import CmsBlockMixin -from xmodule.modulestore.inheritance import InheritanceMixin -from xmodule.x_module import XModuleMixin, prefer_xmodules from dealer.git import git ############################ FEATURE CONFIGURATION ############################# @@ -218,6 +217,10 @@ X_FRAME_OPTIONS = 'ALLOW' ############# XBlock Configuration ########## +# Import after sys.path fixup +from xmodule.modulestore.inheritance import InheritanceMixin +from xmodule.x_module import XModuleMixin, prefer_xmodules + # This should be moved into an XBlock Runtime/Application object # once the responsibility of XBlock creation is moved out of modulestore - cpennington XBLOCK_MIXINS = (LmsBlockMixin, CmsBlockMixin, InheritanceMixin, XModuleMixin) @@ -467,9 +470,6 @@ INSTALLED_APPS = ( # for course creator table 'django.contrib.admin', - # XBlocks containing migrations - 'mentoring', - # for managing course modes 'course_modes', @@ -536,11 +536,22 @@ MAX_FAILED_LOGIN_ATTEMPTS_ALLOWED = 5 MAX_FAILED_LOGIN_ATTEMPTS_LOCKOUT_PERIOD_SECS = 15 * 60 -### JSdraw (only installed in some instances) +### Apps only installed in some instances -try: - import edx_jsdraw -except ImportError: - pass -else: - INSTALLED_APPS += ('edx_jsdraw',) +OPTIONAL_APPS = ( + 'edx_jsdraw', + 'mentoring', +) + +for app_name in OPTIONAL_APPS: + # First attempt to only find the module rather than actually importing it, + # to avoid circular references - only try to import if it can't be found + # by find_module, which doesn't work with import hooks + try: + imp.find_module(app_name) + except ImportError: + try: + __import__(app_name) + except ImportError: + continue + INSTALLED_APPS += (app_name,) diff --git a/cms/envs/test.py b/cms/envs/test.py index 8d60aff95c..64887e312c 100644 --- a/cms/envs/test.py +++ b/cms/envs/test.py @@ -157,11 +157,6 @@ INSTALLED_APPS += ('external_auth', ) filterwarnings('ignore', message='No request passed to the backend, unable to rate-limit') -################################# XBLOCK ###################################### -from xmodule.x_module import prefer_xmodules -XBLOCK_SELECT_FUNCTION = prefer_xmodules - - ################################# CELERY ###################################### CELERY_ALWAYS_EAGER = True diff --git a/common/lib/xmodule/xmodule/html_module.py b/common/lib/xmodule/xmodule/html_module.py index e245c91b31..98183ff537 100644 --- a/common/lib/xmodule/xmodule/html_module.py +++ b/common/lib/xmodule/xmodule/html_module.py @@ -229,7 +229,7 @@ class AboutFields(object): ) data = String( help="Html contents to display for this module", - default="", + default=u"", scope=Scope.content ) @@ -263,7 +263,7 @@ class StaticTabFields(object): default="Empty", ) data = String( - default=textwrap.dedent("""\ + default=textwrap.dedent(u"""\

This is where you can add additional pages to your courseware. Click the 'edit' button to begin editing.

"""), scope=Scope.content, @@ -300,7 +300,7 @@ class CourseInfoFields(object): ) data = String( help="Html contents to display for this module", - default="
    ", + default=u"
      ", scope=Scope.content ) diff --git a/common/lib/xmodule/xmodule/modulestore/mongo/base.py b/common/lib/xmodule/xmodule/modulestore/mongo/base.py index 381292064f..f4ea43fab2 100644 --- a/common/lib/xmodule/xmodule/modulestore/mongo/base.py +++ b/common/lib/xmodule/xmodule/modulestore/mongo/base.py @@ -60,7 +60,10 @@ class MongoKeyValueStore(InheritanceKeyValueStore): """ def __init__(self, data, children, metadata): super(MongoKeyValueStore, self).__init__() - self._data = data + if not isinstance(data, dict): + self._data = {'data': data} + else: + self._data = data self._children = children self._metadata = metadata @@ -72,10 +75,7 @@ class MongoKeyValueStore(InheritanceKeyValueStore): elif key.scope == Scope.settings: return self._metadata[key.field_name] elif key.scope == Scope.content: - if key.field_name == 'data' and not isinstance(self._data, dict): - return self._data - else: - return self._data[key.field_name] + return self._data[key.field_name] else: raise InvalidScopeError(key) @@ -85,10 +85,7 @@ class MongoKeyValueStore(InheritanceKeyValueStore): elif key.scope == Scope.settings: self._metadata[key.field_name] = value elif key.scope == Scope.content: - if key.field_name == 'data' and not isinstance(self._data, dict): - self._data = value - else: - self._data[key.field_name] = value + self._data[key.field_name] = value else: raise InvalidScopeError(key) @@ -99,9 +96,7 @@ class MongoKeyValueStore(InheritanceKeyValueStore): if key.field_name in self._metadata: del self._metadata[key.field_name] elif key.scope == Scope.content: - if key.field_name == 'data' and not isinstance(self._data, dict): - self._data = None - else: + if key.field_name in self._data: del self._data[key.field_name] else: raise InvalidScopeError(key) @@ -112,10 +107,7 @@ class MongoKeyValueStore(InheritanceKeyValueStore): elif key.scope == Scope.settings: return key.field_name in self._metadata elif key.scope == Scope.content: - if key.field_name == 'data' and not isinstance(self._data, dict): - return True - else: - return key.field_name in self._data + return key.field_name in self._data else: return False @@ -640,6 +632,10 @@ class MongoModuleStore(ModuleStoreWriteBase): # layer but added it here to enable quick conversion. I'll need to reconcile these. if metadata is None: metadata = {} + + if definition_data is None: + definition_data = {} + if system is None: services = {} if self.i18n_service: @@ -658,11 +654,6 @@ class MongoModuleStore(ModuleStoreWriteBase): services=services, ) xblock_class = system.load_block_type(location.category) - if definition_data is None: - if hasattr(xblock_class, 'data') and xblock_class.data.default is not None: - definition_data = xblock_class.data.default - else: - definition_data = {} dbmodel = self._create_new_field_data(location.category, location, definition_data, metadata) xmodule = system.construct_xblock_from_class( xblock_class, @@ -796,8 +787,6 @@ class MongoModuleStore(ModuleStoreWriteBase): """ try: definition_data = xblock.get_explicitly_set_fields_by_scope() - if len(definition_data) == 1 and 'data' in definition_data: - definition_data = definition_data['data'] payload = { 'definition.data': definition_data, 'metadata': own_metadata(xblock), diff --git a/common/lib/xmodule/xmodule/modulestore/split_mongo/split.py b/common/lib/xmodule/xmodule/modulestore/split_mongo/split.py index 2d717edd45..2f76703488 100644 --- a/common/lib/xmodule/xmodule/modulestore/split_mongo/split.py +++ b/common/lib/xmodule/xmodule/modulestore/split_mongo/split.py @@ -56,7 +56,6 @@ import copy from pytz import UTC from xmodule.errortracker import null_error_tracker -from xmodule.x_module import prefer_xmodules from xmodule.modulestore.locator import ( BlockUsageLocator, DefinitionLocator, CourseLocator, VersionTree, LocalId, Locator ) diff --git a/common/lib/xmodule/xmodule/modulestore/tests/test_mongo.py b/common/lib/xmodule/xmodule/modulestore/tests/test_mongo.py index f492c321d2..02ad07fdbe 100644 --- a/common/lib/xmodule/xmodule/modulestore/tests/test_mongo.py +++ b/common/lib/xmodule/xmodule/modulestore/tests/test_mongo.py @@ -299,7 +299,7 @@ class TestMongoKeyValueStore(object): assert_false(self.kvs.has(key)) def test_read_non_dict_data(self): - self.kvs._data = 'xml_data' + self.kvs = MongoKeyValueStore('xml_data', self.children, self.metadata) assert_equals('xml_data', self.kvs.get(KeyValueStore.Key(Scope.content, None, None, 'data'))) def _check_write(self, key, value): @@ -312,7 +312,7 @@ class TestMongoKeyValueStore(object): yield (self._check_write, KeyValueStore.Key(Scope.settings, None, None, 'meta'), 'new_settings') def test_write_non_dict_data(self): - self.kvs._data = 'xml_data' + self.kvs = MongoKeyValueStore('xml_data', self.children, self.metadata) self._check_write(KeyValueStore.Key(Scope.content, None, None, 'data'), 'new_data') def test_write_invalid_scope(self): diff --git a/lms/envs/bok_choy.py b/lms/envs/bok_choy.py index ae8f5bacf0..177bbdcdc4 100644 --- a/lms/envs/bok_choy.py +++ b/lms/envs/bok_choy.py @@ -4,8 +4,6 @@ Settings for bok choy tests import os from path import path -from xmodule.x_module import prefer_xmodules - CONFIG_ROOT = path(__file__).abspath().dirname() #pylint: disable=E1120 TEST_ROOT = CONFIG_ROOT.dirname().dirname() / "test_root" @@ -60,8 +58,5 @@ LOG_OVERRIDES = [ for log_name, log_level in LOG_OVERRIDES: logging.getLogger(log_name).setLevel(log_level) -# Enable XBlocks -XBLOCK_SELECT_FUNCTION = prefer_xmodules - # Unfortunately, we need to use debug mode to serve staticfiles DEBUG = True diff --git a/lms/envs/common.py b/lms/envs/common.py index e31a7bb115..ade8bc82e8 100644 --- a/lms/envs/common.py +++ b/lms/envs/common.py @@ -26,6 +26,7 @@ Longer TODO: import sys import os +import imp import json from path import path @@ -33,8 +34,6 @@ from path import path from .discussionsettings import * from lms.lib.xblock.mixin import LmsBlockMixin -from xmodule.modulestore.inheritance import InheritanceMixin -from xmodule.x_module import XModuleMixin, prefer_xmodules ################################### FEATURES ################################### # The display name of the platform to be used in templates/emails/etc. @@ -431,6 +430,10 @@ DOC_STORE_CONFIG = { ############# XBlock Configuration ########## +# Import after sys.path fixup +from xmodule.modulestore.inheritance import InheritanceMixin +from xmodule.x_module import XModuleMixin, prefer_xmodules + # This should be moved into an XBlock Runtime/Application object # once the responsibility of XBlock creation is moved out of modulestore - cpennington XBLOCK_MIXINS = (LmsBlockMixin, InheritanceMixin, XModuleMixin) @@ -1163,9 +1166,6 @@ INSTALLED_APPS = ( 'reverification', 'embargo', - - # XBlocks containing migrations - 'mentoring', ) ######################### MARKETING SITE ############################### @@ -1458,11 +1458,22 @@ ALL_LANGUAGES = ( ) -### JSdraw (only installed in some instances) +### Apps only installed in some instances -try: - import edx_jsdraw -except ImportError: - pass -else: - INSTALLED_APPS += ('edx_jsdraw',) +OPTIONAL_APPS = ( + 'edx_jsdraw', + 'mentoring', +) + +for app_name in OPTIONAL_APPS: + # First attempt to only find the module rather than actually importing it, + # to avoid circular references - only try to import if it can't be found + # by find_module, which doesn't work with import hooks + try: + imp.find_module(app_name) + except ImportError: + try: + __import__(app_name) + except ImportError: + continue + INSTALLED_APPS += (app_name,)