From 789ac3fc875aa26380fc7f0865dc5c89a7359473 Mon Sep 17 00:00:00 2001
From: Calen Pennington <calen.pennington@gmail.com>
Date: Fri, 4 Jan 2013 16:19:58 -0500
Subject: [PATCH] Use the XBlock library as the base for XModule, so that we
 can incrementally rely on more and more of the XBlock api

---
 cms/djangoapps/contentstore/views.py          |   6 +-
 cms/xmodule_namespace.py                      |   2 +-
 common/lib/xmodule/xmodule/abtest_module.py   |   2 +-
 common/lib/xmodule/xmodule/capa_module.py     |  10 +-
 common/lib/xmodule/xmodule/course_module.py   |   2 +-
 .../lib/xmodule/xmodule/discussion_module.py  |   2 +-
 common/lib/xmodule/xmodule/editing_module.py  |   2 +-
 common/lib/xmodule/xmodule/error_module.py    |   2 +-
 common/lib/xmodule/xmodule/fields.py          |   2 +-
 common/lib/xmodule/xmodule/html_module.py     |   2 +-
 common/lib/xmodule/xmodule/mako_module.py     |   2 +-
 common/lib/xmodule/xmodule/model.py           | 217 ------------------
 .../xmodule/modulestore/inheritance.py        |   2 +-
 .../lib/xmodule/xmodule/modulestore/mongo.py  |  12 +-
 common/lib/xmodule/xmodule/poll_module.py     |   6 +-
 common/lib/xmodule/xmodule/raw_module.py      |   2 +-
 common/lib/xmodule/xmodule/runtime.py         | 119 ----------
 .../xmodule/xmodule/self_assessment_module.py |  12 +-
 common/lib/xmodule/xmodule/seq_module.py      |   4 +-
 common/lib/xmodule/xmodule/tests/__init__.py  |   2 +-
 .../lib/xmodule/xmodule/tests/test_model.py   | 163 -------------
 .../lib/xmodule/xmodule/tests/test_runtime.py | 105 ---------
 common/lib/xmodule/xmodule/video_module.py    |   4 +-
 common/lib/xmodule/xmodule/x_module.py        |  20 +-
 common/lib/xmodule/xmodule/xml_module.py      |   2 +-
 github-requirements.txt                       |   1 +
 lms/djangoapps/courseware/model_data.py       |  19 +-
 lms/djangoapps/courseware/module_render.py    |   6 +-
 .../courseware/tests/test_model_data.py       |   8 +-
 lms/xmodule_namespace.py                      |   2 +-
 setup.py                                      |   4 +-
 31 files changed, 69 insertions(+), 675 deletions(-)
 delete mode 100644 common/lib/xmodule/xmodule/model.py
 delete mode 100644 common/lib/xmodule/xmodule/runtime.py
 delete mode 100644 common/lib/xmodule/xmodule/tests/test_model.py
 delete mode 100644 common/lib/xmodule/xmodule/tests/test_runtime.py

diff --git a/cms/djangoapps/contentstore/views.py b/cms/djangoapps/contentstore/views.py
index 2b650a525b6..2fd395cff91 100644
--- a/cms/djangoapps/contentstore/views.py
+++ b/cms/djangoapps/contentstore/views.py
@@ -29,8 +29,8 @@ from django.conf import settings
 from xmodule.modulestore import Location
 from xmodule.modulestore.exceptions import ItemNotFoundError, InvalidLocationError
 from xmodule.modulestore.inheritance import own_metadata
-from xmodule.model import Scope
-from xmodule.runtime import KeyValueStore, DbModel, InvalidScopeError
+from xblock.core import Scope
+from xblock.runtime import KeyValueStore, DbModel, InvalidScopeError
 from xmodule.x_module import ModuleSystem
 from xmodule.error_module import ErrorDescriptor
 from xmodule.errortracker import exc_info_to_str
@@ -472,7 +472,7 @@ def preview_module_system(request, preview_id, descriptor):
         debug=True,
         replace_urls=replace_urls,
         user=request.user,
-        xmodule_model_data=preview_model_data,
+        xblock_model_data=preview_model_data,
     )
 
 
diff --git a/cms/xmodule_namespace.py b/cms/xmodule_namespace.py
index 3ade59532af..9e30105abc8 100644
--- a/cms/xmodule_namespace.py
+++ b/cms/xmodule_namespace.py
@@ -1,6 +1,6 @@
 import datetime
 
-from xmodule.model import Namespace, Boolean, Scope, ModelType, String
+from xblock.core import Namespace, Boolean, Scope, ModelType, String
 
 
 class DateTuple(ModelType):
diff --git a/common/lib/xmodule/xmodule/abtest_module.py b/common/lib/xmodule/xmodule/abtest_module.py
index f33a3db91c7..f5115586939 100644
--- a/common/lib/xmodule/xmodule/abtest_module.py
+++ b/common/lib/xmodule/xmodule/abtest_module.py
@@ -6,7 +6,7 @@ from xmodule.x_module import XModule
 from xmodule.raw_module import RawDescriptor
 from xmodule.xml_module import XmlDescriptor
 from xmodule.exceptions import InvalidDefinitionError
-from .model import String, Scope, Object, ModuleScope
+from xblock.core import String, Scope, Object, BlockScope
 
 DEFAULT = "_DEFAULT_GROUP"
 
diff --git a/common/lib/xmodule/xmodule/capa_module.py b/common/lib/xmodule/xmodule/capa_module.py
index a41e634c368..0d04b419a52 100644
--- a/common/lib/xmodule/xmodule/capa_module.py
+++ b/common/lib/xmodule/xmodule/capa_module.py
@@ -17,13 +17,13 @@ from progress import Progress
 from xmodule.x_module import XModule
 from xmodule.raw_module import RawDescriptor
 from xmodule.exceptions import NotFoundError
-from .model import Int, Scope, ModuleScope, ModelType, String, Boolean, Object, Float
+from xblock.core import Integer, Scope, BlockScope, ModelType, String, Boolean, Object, Float
 from .fields import Timedelta
 
 log = logging.getLogger("mitx.courseware")
 
 
-class StringyInt(Int):
+class StringyInteger(Integer):
     """
     A model type that converts from strings to integers when reading from json
     """
@@ -57,8 +57,8 @@ class CapaModule(XModule):
     '''
     icon_class = 'problem'
 
-    attempts = Int(help="Number of attempts taken by the student on this problem", default=0, scope=Scope.student_state)
-    max_attempts = StringyInt(help="Maximum number of attempts that a student is allowed", scope=Scope.settings)
+    attempts = Integer(help="Number of attempts taken by the student on this problem", default=0, scope=Scope.student_state)
+    max_attempts = StringyInteger(help="Maximum number of attempts that a student is allowed", scope=Scope.settings)
     due = String(help="Date that this problem is due by", scope=Scope.settings)
     graceperiod = Timedelta(help="Amount of time after the due date that submissions will be accepted", scope=Scope.settings)
     showanswer = String(help="When to show the problem answer to the student", scope=Scope.settings, default="closed")
@@ -69,7 +69,7 @@ class CapaModule(XModule):
     student_answers = Object(help="Dictionary with the current student responses", scope=Scope.student_state)
     done = Boolean(help="Whether the student has answered the problem", scope=Scope.student_state)
     display_name = String(help="Display name for this module", scope=Scope.settings)
-    seed = Int(help="Random seed for this student", scope=Scope.student_state)
+    seed = Integer(help="Random seed for this student", scope=Scope.student_state)
 
     js = {'coffee': [resource_string(__name__, 'js/src/capa/display.coffee'),
                      resource_string(__name__, 'js/src/collapsible.coffee'),
diff --git a/common/lib/xmodule/xmodule/course_module.py b/common/lib/xmodule/xmodule/course_module.py
index 38cf81f3af9..3b73b6a4d18 100644
--- a/common/lib/xmodule/xmodule/course_module.py
+++ b/common/lib/xmodule/xmodule/course_module.py
@@ -12,7 +12,7 @@ import requests
 import time
 import copy
 
-from .model import Scope, ModelType, List, String, Object, Boolean
+from xblock.core import Scope, ModelType, List, String, Object, Boolean
 from .fields import Date
 
 log = logging.getLogger(__name__)
diff --git a/common/lib/xmodule/xmodule/discussion_module.py b/common/lib/xmodule/xmodule/discussion_module.py
index b373f337fbf..6a9edbbd704 100644
--- a/common/lib/xmodule/xmodule/discussion_module.py
+++ b/common/lib/xmodule/xmodule/discussion_module.py
@@ -3,7 +3,7 @@ from pkg_resources import resource_string, resource_listdir
 
 from xmodule.x_module import XModule
 from xmodule.raw_module import RawDescriptor
-from .model import String, Scope
+from xblock.core import String, Scope
 
 class DiscussionModule(XModule):
     js = {'coffee':
diff --git a/common/lib/xmodule/xmodule/editing_module.py b/common/lib/xmodule/xmodule/editing_module.py
index 531fd7d8b9f..9ff0124dc62 100644
--- a/common/lib/xmodule/xmodule/editing_module.py
+++ b/common/lib/xmodule/xmodule/editing_module.py
@@ -1,6 +1,6 @@
 from pkg_resources import resource_string
 from xmodule.mako_module import MakoModuleDescriptor
-from xmodule.model import Scope, String
+from xblock.core import Scope, String
 import logging
 
 log = logging.getLogger(__name__)
diff --git a/common/lib/xmodule/xmodule/error_module.py b/common/lib/xmodule/xmodule/error_module.py
index 6a06b3ad3af..d2f67d68a6e 100644
--- a/common/lib/xmodule/xmodule/error_module.py
+++ b/common/lib/xmodule/xmodule/error_module.py
@@ -8,7 +8,7 @@ from xmodule.x_module import XModule
 from xmodule.editing_module import JSONEditingDescriptor
 from xmodule.errortracker import exc_info_to_str
 from xmodule.modulestore import Location
-from .model import String, Scope
+from xblock.core import String, Scope
 
 
 log = logging.getLogger(__name__)
diff --git a/common/lib/xmodule/xmodule/fields.py b/common/lib/xmodule/xmodule/fields.py
index 21c360f9146..fb80752e56f 100644
--- a/common/lib/xmodule/xmodule/fields.py
+++ b/common/lib/xmodule/xmodule/fields.py
@@ -3,7 +3,7 @@ import logging
 import re
 
 from datetime import timedelta
-from .model import ModelType
+from xblock.core import ModelType
 
 log = logging.getLogger(__name__)
 
diff --git a/common/lib/xmodule/xmodule/html_module.py b/common/lib/xmodule/xmodule/html_module.py
index 55155810e98..f9221810467 100644
--- a/common/lib/xmodule/xmodule/html_module.py
+++ b/common/lib/xmodule/xmodule/html_module.py
@@ -15,7 +15,7 @@ from .html_checker import check_html
 from xmodule.modulestore import Location
 
 from xmodule.contentstore.content import XASSET_SRCREF_PREFIX, StaticContent
-from .model import Scope, String
+from xblock.core import Scope, String
 
 log = logging.getLogger("mitx.courseware")
 
diff --git a/common/lib/xmodule/xmodule/mako_module.py b/common/lib/xmodule/xmodule/mako_module.py
index 66a4b647d38..adfe28387d4 100644
--- a/common/lib/xmodule/xmodule/mako_module.py
+++ b/common/lib/xmodule/xmodule/mako_module.py
@@ -1,5 +1,5 @@
 from .x_module import XModuleDescriptor, DescriptorSystem
-from .model import Scope
+from xblock.core import Scope
 import logging
 
 
diff --git a/common/lib/xmodule/xmodule/model.py b/common/lib/xmodule/xmodule/model.py
deleted file mode 100644
index b8228cb417b..00000000000
--- a/common/lib/xmodule/xmodule/model.py
+++ /dev/null
@@ -1,217 +0,0 @@
-from collections import namedtuple
-from .plugin import Plugin
-
-
-class ModuleScope(object):
-    USAGE, DEFINITION, TYPE, ALL = xrange(4)
-
-
-class Scope(namedtuple('ScopeBase', 'student module')):
-    pass
-
-Scope.content = Scope(student=False, module=ModuleScope.DEFINITION)
-Scope.settings = Scope(student=False, module=ModuleScope.USAGE)
-Scope.student_state = Scope(student=True, module=ModuleScope.USAGE)
-Scope.student_preferences = Scope(student=True, module=ModuleScope.TYPE)
-Scope.student_info = Scope(student=True, module=ModuleScope.ALL)
-
-
-class ModelType(object):
-    """
-    A field class that can be used as a class attribute to define what data the class will want
-    to refer to.
-
-    When the class is instantiated, it will be available as an instance attribute of the same
-    name, by proxying through to self._model_data on the containing object.
-    """
-    sequence = 0
-
-    def __init__(self, help=None, default=None, scope=Scope.content, computed_default=None):
-        self._seq = self.sequence
-        self._name = "unknown"
-        self.help = help
-        self.default = default
-        self.computed_default = computed_default
-        self.scope = scope
-        ModelType.sequence += 1
-
-    @property
-    def name(self):
-        return self._name
-
-    def __get__(self, instance, owner):
-        if instance is None:
-            return self
-
-        try:
-            return self.from_json(instance._model_data[self.name])
-        except KeyError:
-            if self.default is None and self.computed_default is not None:
-                return self.computed_default(instance)
-
-            return self.default
-
-    def __set__(self, instance, value):
-        instance._model_data[self.name] = self.to_json(value)
-
-    def __delete__(self, instance):
-        del instance._model_data[self.name]
-
-    def __repr__(self):
-        return "<{0.__class__.__name__} {0._name}>".format(self)
-
-    def __lt__(self, other):
-        return self._seq < other._seq
-
-    def to_json(self, value):
-        """
-        Return value in the form of nested lists and dictionaries (suitable
-        for passing to json.dumps).
-
-        This is called during field writes to convert the native python
-        type to the value stored in the database
-        """
-        return value
-
-    def from_json(self, value):
-        """
-        Return value as a native full featured python type (the inverse of to_json)
-
-        Called during field reads to convert the stored value into a full featured python
-        object
-        """
-        return value
-
-    def read_from(self, model):
-        """
-        Retrieve the value for this field from the specified model object
-        """
-        return self.__get__(model, model.__class__)
-
-    def write_to(self, model, value):
-        """
-        Set the value for this field to value on the supplied model object
-        """
-        self.__set__(model, value)
-
-    def delete_from(self, model):
-        """
-        Delete the value for this field from the supplied model object
-        """
-        self.__delete__(model)
-
-Int = Float = Boolean = Object = List = String = Any = ModelType
-
-
-class ModelMetaclass(type):
-    """
-    A metaclass to be used for classes that want to use ModelTypes as class attributes
-    to define data access.
-
-    All class attributes that are ModelTypes will be added to the 'fields' attribute on
-    the instance.
-
-    Additionally, any namespaces registered in the `xmodule.namespace` will be added to
-    the instance
-    """
-    def __new__(cls, name, bases, attrs):
-        fields = []
-        for n, v in attrs.items():
-            if isinstance(v, ModelType):
-                v._name = n
-                fields.append(v)
-        fields.sort()
-        attrs['fields'] = sum([
-            base.fields
-            for base
-            in bases
-            if hasattr(base, 'fields')
-        ], fields)
-
-        return super(ModelMetaclass, cls).__new__(cls, name, bases, attrs)
-
-
-class NamespacesMetaclass(type):
-    """
-    A metaclass to be used for classes that want to include namespaced fields in their
-    instances.
-
-    Any namespaces registered in the `xmodule.namespace` will be added to
-    the instance
-    """
-    def __new__(cls, name, bases, attrs):
-        namespaces = []
-        for ns_name, namespace in Namespace.load_classes():
-            if issubclass(namespace, Namespace):
-                attrs[ns_name] = NamespaceDescriptor(namespace)
-                namespaces.append(ns_name)
-        attrs['namespaces'] = namespaces
-
-        return super(NamespacesMetaclass, cls).__new__(cls, name, bases, attrs)
-
-
-class ParentModelMetaclass(type):
-    """
-    A ModelMetaclass that transforms the attribute `has_children = True`
-    into a List field with an empty scope.
-    """
-    def __new__(cls, name, bases, attrs):
-        if attrs.get('has_children', False):
-            attrs['children'] = List(help='The children of this XModule', default=[], scope=None)
-        else:
-            attrs['has_children'] = False
-
-        return super(ParentModelMetaclass, cls).__new__(cls, name, bases, attrs)
-
-
-class NamespaceDescriptor(object):
-    def __init__(self, namespace):
-        self._namespace = namespace
-
-    def __get__(self, instance, owner):
-        return self._namespace(instance)
-
-
-class Namespace(Plugin):
-    """
-    A baseclass that sets up machinery for ModelType fields that makes those fields be called
-    with the container as the field instance
-    """
-    __metaclass__ = ModelMetaclass
-
-    entry_point = 'xmodule.namespace'
-
-    def __init__(self, container):
-        self._container = container
-
-    def __getattribute__(self, name):
-        container = super(Namespace, self).__getattribute__('_container')
-        namespace_attr = getattr(type(self), name, None)
-
-        if namespace_attr is None or not isinstance(namespace_attr, ModelType):
-            return super(Namespace, self).__getattribute__(name)
-
-        return namespace_attr.__get__(container, type(container))
-
-    def __setattr__(self, name, value):
-        try:
-            container = super(Namespace, self).__getattribute__('_container')
-        except AttributeError:
-            super(Namespace, self).__setattr__(name, value)
-            return
-
-        namespace_attr = getattr(type(self), name, None)
-
-        if namespace_attr is None or not isinstance(namespace_attr, ModelType):
-            return super(Namespace, self).__setattr__(name, value)
-
-        return namespace_attr.__set__(container, value)
-
-    def __delattr__(self, name):
-        container = super(Namespace, self).__getattribute__('_container')
-        namespace_attr = getattr(type(self), name, None)
-
-        if namespace_attr is None or not isinstance(namespace_attr, ModelType):
-            return super(Namespace, self).__detattr__(name)
-
-        return namespace_attr.__delete__(container)
diff --git a/common/lib/xmodule/xmodule/modulestore/inheritance.py b/common/lib/xmodule/xmodule/modulestore/inheritance.py
index 18cf0b33515..dd2ca7e346b 100644
--- a/common/lib/xmodule/xmodule/modulestore/inheritance.py
+++ b/common/lib/xmodule/xmodule/modulestore/inheritance.py
@@ -1,4 +1,4 @@
-from xmodule.model import Scope
+from xblock.core import Scope
 
 # A list of metadata that this module can inherit from its parent module
 INHERITABLE_METADATA = (
diff --git a/common/lib/xmodule/xmodule/modulestore/mongo.py b/common/lib/xmodule/xmodule/modulestore/mongo.py
index 52267d67341..201a2146218 100644
--- a/common/lib/xmodule/xmodule/modulestore/mongo.py
+++ b/common/lib/xmodule/xmodule/modulestore/mongo.py
@@ -13,8 +13,8 @@ from xmodule.errortracker import null_error_tracker, exc_info_to_str
 from xmodule.mako_module import MakoDescriptorSystem
 from xmodule.x_module import XModuleDescriptor
 from xmodule.error_module import ErrorDescriptor
-from xmodule.runtime import DbModel, KeyValueStore, InvalidScopeError
-from xmodule.model import Scope
+from xblock.runtime import DbModel, KeyValueStore, InvalidScopeError
+from xblock.core import Scope
 
 from . import ModuleStoreBase, Location
 from .draft import DraftModuleStore
@@ -41,8 +41,10 @@ class MongoKeyValueStore(KeyValueStore):
         self._metadata = metadata
 
     def get(self, key):
-        if key.field_name == 'children':
+        if key.scope == Scope.children:
             return self._children
+        elif key.scope == Scope.parent:
+            return None
         elif key.scope == Scope.settings:
             return self._metadata[key.field_name]
         elif key.scope == Scope.content:
@@ -54,7 +56,7 @@ class MongoKeyValueStore(KeyValueStore):
             raise InvalidScopeError(key.scope)
 
     def set(self, key, value):
-        if key.field_name == 'children':
+        if key.scope == Scope.children:
             self._children = value
         elif key.scope == Scope.settings:
             self._metadata[key.field_name] = value
@@ -67,7 +69,7 @@ class MongoKeyValueStore(KeyValueStore):
             raise InvalidScopeError(key.scope)
 
     def delete(self, key):
-        if key.field_name == 'children':
+        if key.scope == Scope.children:
             self._children = []
         elif key.scope == Scope.settings:
             if key.field_name in self._metadata:
diff --git a/common/lib/xmodule/xmodule/poll_module.py b/common/lib/xmodule/xmodule/poll_module.py
index db0b3fd0c42..eb5bef9e6d2 100644
--- a/common/lib/xmodule/xmodule/poll_module.py
+++ b/common/lib/xmodule/xmodule/poll_module.py
@@ -6,7 +6,7 @@ from pkg_resources import resource_string, resource_listdir
 
 from xmodule.x_module import XModule
 from xmodule.raw_module import RawDescriptor
-from .model import Int, Scope, Boolean
+from xblock.core import Integer, Scope, Boolean
 
 log = logging.getLogger(__name__)
 
@@ -16,8 +16,8 @@ class PollModule(XModule):
     js = {'coffee': [resource_string(__name__, 'js/src/poll/display.coffee')]}
     js_module_name = "PollModule"
 
-    upvotes = Int(help="Number of upvotes this poll has recieved", scope=Scope.content, default=0)
-    downvotes = Int(help="Number of downvotes this poll has recieved", scope=Scope.content, default=0)
+    upvotes = Integer(help="Number of upvotes this poll has recieved", scope=Scope.content, default=0)
+    downvotes = Integer(help="Number of downvotes this poll has recieved", scope=Scope.content, default=0)
     voted = Boolean(help="Whether this student has voted on the poll", scope=Scope.student_state, default=False)
 
     def handle_ajax(self, dispatch, get):
diff --git a/common/lib/xmodule/xmodule/raw_module.py b/common/lib/xmodule/xmodule/raw_module.py
index 5e50bdf6a02..c6d2ebf2b32 100644
--- a/common/lib/xmodule/xmodule/raw_module.py
+++ b/common/lib/xmodule/xmodule/raw_module.py
@@ -3,7 +3,7 @@ from xmodule.editing_module import XMLEditingDescriptor
 from xmodule.xml_module import XmlDescriptor
 import logging
 import sys
-from .model import String, Scope
+from xblock.core import String, Scope
 
 log = logging.getLogger(__name__)
 
diff --git a/common/lib/xmodule/xmodule/runtime.py b/common/lib/xmodule/xmodule/runtime.py
deleted file mode 100644
index 8cbfc3ae364..00000000000
--- a/common/lib/xmodule/xmodule/runtime.py
+++ /dev/null
@@ -1,119 +0,0 @@
-from collections import MutableMapping, namedtuple
-
-from .model import ModuleScope, ModelType
-
-
-class InvalidScopeError(Exception):
-    """
-    Raised to indicated that operating on the supplied scope isn't allowed by a KeyValueStore
-    """
-    pass
-
-
-class KeyValueStore(object):
-    """The abstract interface for Key Value Stores."""
-
-    # Keys are structured to retain information about the scope of the data.
-    # Stores can use this information however they like to store and retrieve
-    # data.
-    Key = namedtuple("Key", "scope, student_id, module_scope_id, field_name")
-
-    def get(self, key):
-        pass
-
-    def set(self, key, value):
-        pass
-
-    def delete(self, key):
-        pass
-
-
-class DbModel(MutableMapping):
-    """A dictionary-like interface to the fields on a module."""
-
-    def __init__(self, kvs, module_cls, student_id, usage):
-        self._kvs = kvs
-        self._student_id = student_id
-        self._module_cls = module_cls
-        self._usage = usage
-
-    def __repr__(self):
-        return "<{0.__class__.__name__} {0._module_cls!r}>".format(self)
-
-    def _getfield(self, name):
-        # First, get the field from the class, if defined
-        module_field = getattr(self._module_cls, name, None)
-        if module_field is not None and isinstance(module_field, ModelType):
-            return module_field
-
-        # If the class doesn't have the field, and it also
-        # doesn't have any namespaces, then the the name isn't a field
-        # so KeyError
-        if not hasattr(self._module_cls, 'namespaces'):
-            return KeyError(name)
-
-        # Resolve the field name in the first namespace where it's
-        # available
-        for namespace_name in self._module_cls.namespaces:
-            namespace = getattr(self._module_cls, namespace_name)
-            namespace_field = getattr(type(namespace), name, None)
-            if namespace_field is not None and isinstance(namespace_field, ModelType):
-                return namespace_field
-
-        # Not in the class or in any of the namespaces, so name
-        # really doesn't name a field
-        raise KeyError(name)
-
-    def _key(self, name):
-        field = self._getfield(name)
-        if field.scope is None:
-            module_id = None
-            student_id = None
-        else:
-            module = field.scope.module
-
-            if module == ModuleScope.ALL:
-                module_id = None
-            elif module == ModuleScope.USAGE:
-                module_id = self._usage.id
-            elif module == ModuleScope.DEFINITION:
-                module_id = self._usage.def_id
-            elif module == ModuleScope.TYPE:
-                module_id = self._module_cls.__name__
-
-            if field.scope.student:
-                student_id = self._student_id
-            else:
-                student_id = None
-
-        key = KeyValueStore.Key(
-            scope=field.scope,
-            student_id=student_id,
-            module_scope_id=module_id,
-            field_name=name
-            )
-        return key
-
-    def __getitem__(self, name):
-        return self._kvs.get(self._key(name))
-
-    def __setitem__(self, name, value):
-        self._kvs.set(self._key(name), value)
-
-    def __delitem__(self, name):
-        self._kvs.delete(self._key(name))
-
-    def __iter__(self):
-        return iter(self.keys())
-
-    def __len__(self):
-        return len(self.keys())
-
-    def __contains__(self, item):
-        return item in self.keys()
-
-    def keys(self):
-        fields = [field.name for field in self._module_cls.fields]
-        for namespace_name in self._module_cls.namespaces:
-            fields.extend(field.name for field in getattr(self._module_cls, namespace_name).fields)
-        return fields
diff --git a/common/lib/xmodule/xmodule/self_assessment_module.py b/common/lib/xmodule/xmodule/self_assessment_module.py
index ffcd86ba525..12f054eaa6d 100644
--- a/common/lib/xmodule/xmodule/self_assessment_module.py
+++ b/common/lib/xmodule/xmodule/self_assessment_module.py
@@ -23,7 +23,7 @@ from .editing_module import EditingDescriptor
 from .stringify import stringify_children
 from .x_module import XModule
 from .xml_module import XmlDescriptor
-from .model import List, String, Scope, Int
+from xblock.core import List, String, Scope, Integer
 
 log = logging.getLogger("mitx.courseware")
 
@@ -67,10 +67,10 @@ class SelfAssessmentModule(XModule):
 
     # Used for progress / grading.  Currently get credit just for
     # completion (doesn't matter if you self-assessed correct/incorrect).
-    max_score = Int(scope=Scope.settings, default=MAX_SCORE)
+    max_score = Integer(scope=Scope.settings, default=MAX_SCORE)
 
-    attempts = Int(scope=Scope.student_state, default=0), Int
-    max_attempts = Int(scope=Scope.settings, default=MAX_ATTEMPTS)
+    attempts = Integer(scope=Scope.student_state, default=0)
+    max_attempts = Integer(scope=Scope.settings, default=MAX_ATTEMPTS)
     rubric = String(scope=Scope.content)
     prompt = String(scope=Scope.content)
     submitmessage = String(scope=Scope.content)
@@ -392,9 +392,9 @@ class SelfAssessmentDescriptor(XmlDescriptor, EditingDescriptor):
 
     # Used for progress / grading.  Currently get credit just for
     # completion (doesn't matter if you self-assessed correct/incorrect).
-    max_score = Int(scope=Scope.settings, default=MAX_SCORE)
+    max_score = Integer(scope=Scope.settings, default=MAX_SCORE)
 
-    max_attempts = Int(scope=Scope.settings, default=MAX_ATTEMPTS)
+    max_attempts = Integer(scope=Scope.settings, default=MAX_ATTEMPTS)
     rubric = String(scope=Scope.content)
     prompt = String(scope=Scope.content)
     submitmessage = String(scope=Scope.content)
diff --git a/common/lib/xmodule/xmodule/seq_module.py b/common/lib/xmodule/xmodule/seq_module.py
index 3fc3a5dbaab..b3ceb7a2295 100644
--- a/common/lib/xmodule/xmodule/seq_module.py
+++ b/common/lib/xmodule/xmodule/seq_module.py
@@ -8,7 +8,7 @@ from xmodule.xml_module import XmlDescriptor
 from xmodule.x_module import XModule
 from xmodule.progress import Progress
 from xmodule.exceptions import NotFoundError
-from .model import Int, Scope
+from xblock.core import Integer, Scope
 from pkg_resources import resource_string
 
 log = logging.getLogger("mitx.common.lib.seq_module")
@@ -37,7 +37,7 @@ class SequenceModule(XModule):
 
     # NOTE: Position is 1-indexed.  This is silly, but there are now student
     # positions saved on prod, so it's not easy to fix.
-    position = Int(help="Last tab viewed in this sequence", scope=Scope.student_state)
+    position = Integer(help="Last tab viewed in this sequence", scope=Scope.student_state)
 
     def __init__(self, *args, **kwargs):
         XModule.__init__(self, *args, **kwargs)
diff --git a/common/lib/xmodule/xmodule/tests/__init__.py b/common/lib/xmodule/xmodule/tests/__init__.py
index c16c6d75963..e8b71b53fc2 100644
--- a/common/lib/xmodule/xmodule/tests/__init__.py
+++ b/common/lib/xmodule/xmodule/tests/__init__.py
@@ -31,7 +31,7 @@ i4xs = ModuleSystem(
     xqueue={'interface':None, 'callback_url':'/', 'default_queuename': 'testqueue', 'waittime': 10},
     node_path=os.environ.get("NODE_PATH", "/usr/local/lib/node_modules"),
     anonymous_student_id = 'student',
-    xmodule_model_data = lambda x: x,
+    xblock_model_data = lambda x: x,
 )
 
 
diff --git a/common/lib/xmodule/xmodule/tests/test_model.py b/common/lib/xmodule/xmodule/tests/test_model.py
deleted file mode 100644
index c5eaaaefc76..00000000000
--- a/common/lib/xmodule/xmodule/tests/test_model.py
+++ /dev/null
@@ -1,163 +0,0 @@
-from mock import patch
-from unittest import TestCase
-from nose.tools import assert_in, assert_equals, assert_raises
-
-from xmodule.model import *
-
-
-def test_model_metaclass():
-    class ModelMetaclassTester(object):
-        __metaclass__ = ModelMetaclass
-
-        field_a = Int(scope=Scope.settings)
-        field_b = Int(scope=Scope.content)
-
-        def __init__(self, model_data):
-            self._model_data = model_data
-
-    class ChildClass(ModelMetaclassTester):
-        pass
-
-    assert hasattr(ModelMetaclassTester, 'field_a')
-    assert hasattr(ModelMetaclassTester, 'field_b')
-
-    assert_in(ModelMetaclassTester.field_a, ModelMetaclassTester.fields)
-    assert_in(ModelMetaclassTester.field_b, ModelMetaclassTester.fields)
-
-    assert hasattr(ChildClass, 'field_a')
-    assert hasattr(ChildClass, 'field_b')
-
-    assert_in(ChildClass.field_a, ChildClass.fields)
-    assert_in(ChildClass.field_b, ChildClass.fields)
-
-
-def test_parent_metaclass():
-
-    class HasChildren(object):
-        __metaclass__ = ParentModelMetaclass
-
-        has_children = True
-
-    class WithoutChildren(object):
-        __metaclass = ParentModelMetaclass
-
-    assert hasattr(HasChildren, 'children')
-    assert not hasattr(WithoutChildren, 'children')
-
-    assert isinstance(HasChildren.children, List)
-    assert_equals(None, HasChildren.children.scope)
-
-
-def test_field_access():
-    class FieldTester(object):
-        __metaclass__ = ModelMetaclass
-
-        field_a = Int(scope=Scope.settings)
-        field_b = Int(scope=Scope.content, default=10)
-        field_c = Int(scope=Scope.student_state, computed_default=lambda s: s.field_a + s.field_b)
-
-        def __init__(self, model_data):
-            self._model_data = model_data
-
-    field_tester = FieldTester({'field_a': 5, 'field_x': 15})
-
-    assert_equals(5, field_tester.field_a)
-    assert_equals(10, field_tester.field_b)
-    assert_equals(15, field_tester.field_c)
-    assert not hasattr(field_tester, 'field_x')
-
-    field_tester.field_a = 20
-    assert_equals(20, field_tester._model_data['field_a'])
-    assert_equals(10, field_tester.field_b)
-    assert_equals(30, field_tester.field_c)
-
-    del field_tester.field_a
-    assert_equals(None, field_tester.field_a)
-    assert hasattr(FieldTester, 'field_a')
-
-
-class TestNamespace(Namespace):
-    field_x = List(scope=Scope.content)
-    field_y = String(scope=Scope.student_state, default="default_value")
-
-
-@patch('xmodule.model.Namespace.load_classes', return_value=[('test', TestNamespace)])
-def test_namespace_metaclass(mock_load_classes):
-    class TestClass(object):
-        __metaclass__ = NamespacesMetaclass
-
-    assert hasattr(TestClass, 'test')
-    assert hasattr(TestClass.test, 'field_x')
-    assert hasattr(TestClass.test, 'field_y')
-
-    assert_in(TestNamespace.field_x, TestClass.test.fields)
-    assert_in(TestNamespace.field_y, TestClass.test.fields)
-    assert isinstance(TestClass.test, Namespace)
-
-
-@patch('xmodule.model.Namespace.load_classes', return_value=[('test', TestNamespace)])
-def test_namespace_field_access(mock_load_classes):
-    class Metaclass(ModelMetaclass, NamespacesMetaclass):
-        pass
-
-    class FieldTester(object):
-        __metaclass__ = Metaclass
-
-        field_a = Int(scope=Scope.settings)
-        field_b = Int(scope=Scope.content, default=10)
-        field_c = Int(scope=Scope.student_state, computed_default=lambda s: s.field_a + s.field_b)
-
-        def __init__(self, model_data):
-            self._model_data = model_data
-
-    field_tester = FieldTester({
-        'field_a': 5,
-        'field_x': [1, 2, 3],
-    })
-
-    assert_equals(5, field_tester.field_a)
-    assert_equals(10, field_tester.field_b)
-    assert_equals(15, field_tester.field_c)
-    assert_equals([1, 2, 3], field_tester.test.field_x)
-    assert_equals('default_value', field_tester.test.field_y)
-
-    field_tester.test.field_x = ['a', 'b']
-    assert_equals(['a', 'b'], field_tester._model_data['field_x'])
-
-    del field_tester.test.field_x
-    assert_equals(None, field_tester.test.field_x)
-
-    assert_raises(AttributeError, getattr, field_tester.test, 'field_z')
-    assert_raises(AttributeError, delattr, field_tester.test, 'field_z')
-
-    # Namespaces are created on the fly, so setting a new attribute on one
-    # has no long-term effect
-    field_tester.test.field_z = 'foo'
-    assert_raises(AttributeError, getattr, field_tester.test, 'field_z')
-    assert 'field_z' not in field_tester._model_data
-
-
-def test_field_serialization():
-
-    class CustomField(ModelType):
-        def from_json(self, value):
-            return value['value']
-
-        def to_json(self, value):
-            return {'value': value}
-
-    class FieldTester(object):
-        __metaclass__ = ModelMetaclass
-
-        field = CustomField()
-
-        def __init__(self, model_data):
-            self._model_data = model_data
-
-    field_tester = FieldTester({
-        'field': {'value': 4}
-    })
-
-    assert_equals(4, field_tester.field)
-    field_tester.field = 5
-    assert_equals({'value': 5}, field_tester._model_data['field'])
diff --git a/common/lib/xmodule/xmodule/tests/test_runtime.py b/common/lib/xmodule/xmodule/tests/test_runtime.py
deleted file mode 100644
index e71c78e4af3..00000000000
--- a/common/lib/xmodule/xmodule/tests/test_runtime.py
+++ /dev/null
@@ -1,105 +0,0 @@
-from nose.tools import assert_equals
-from mock import patch
-
-from xmodule.model import *
-from xmodule.runtime import *
-
-
-class Metaclass(NamespacesMetaclass, ParentModelMetaclass, ModelMetaclass):
-    pass
-
-
-class TestNamespace(Namespace):
-    n_content = String(scope=Scope.content, default='nc')
-    n_settings = String(scope=Scope.settings, default='ns')
-    n_student_state = String(scope=Scope.student_state, default='nss')
-    n_student_preferences = String(scope=Scope.student_preferences, default='nsp')
-    n_student_info = String(scope=Scope.student_info, default='nsi')
-    n_by_type = String(scope=Scope(False, ModuleScope.TYPE), default='nbt')
-    n_for_all = String(scope=Scope(False, ModuleScope.ALL), default='nfa')
-    n_student_def = String(scope=Scope(True, ModuleScope.DEFINITION), default='nsd')
-
-
-with patch('xmodule.model.Namespace.load_classes', return_value=[('test', TestNamespace)]):
-    class TestModel(object):
-        __metaclass__ = Metaclass
-
-        content = String(scope=Scope.content, default='c')
-        settings = String(scope=Scope.settings, default='s')
-        student_state = String(scope=Scope.student_state, default='ss')
-        student_preferences = String(scope=Scope.student_preferences, default='sp')
-        student_info = String(scope=Scope.student_info, default='si')
-        by_type = String(scope=Scope(False, ModuleScope.TYPE), default='bt')
-        for_all = String(scope=Scope(False, ModuleScope.ALL), default='fa')
-        student_def = String(scope=Scope(True, ModuleScope.DEFINITION), default='sd')
-
-        def __init__(self, model_data):
-            self._model_data = model_data
-
-
-class DictKeyValueStore(KeyValueStore):
-    def __init__(self):
-        self.db = {}
-
-    def get(self, key):
-        return self.db[key]
-
-    def set(self, key, value):
-        self.db[key] = value
-
-    def delete(self, key):
-        del self.db[key]
-
-
-Usage = namedtuple('Usage', 'id, def_id')
-
-
-def check_field(collection, field):
-    print "Getting %s from %r" % (field.name, collection)
-    assert_equals(field.default, getattr(collection, field.name))
-    new_value = 'new ' + field.name
-    print "Setting %s to %s on %r" % (field.name, new_value, collection)
-    setattr(collection, field.name, new_value)
-    print "Checking %s on %r" % (field.name, collection)
-    assert_equals(new_value, getattr(collection, field.name))
-    print "Deleting %s from %r" % (field.name, collection)
-    delattr(collection, field.name)
-    print "Back to defaults for %s in %r" % (field.name, collection)
-    assert_equals(field.default, getattr(collection, field.name))
-
-
-def test_namespace_actions():
-    tester = TestModel(DbModel(DictKeyValueStore(), TestModel, 's0', Usage('u0', 'd0')))
-
-    for collection in (tester, tester.test):
-        for field in collection.fields:
-            yield check_field, collection, field
-
-
-def test_db_model_keys():
-    key_store = DictKeyValueStore()
-    tester = TestModel(DbModel(key_store, TestModel, 's0', Usage('u0', 'd0')))
-
-    for collection in (tester, tester.test):
-        for field in collection.fields:
-            new_value = 'new ' + field.name
-            setattr(collection, field.name, new_value)
-
-    print key_store.db
-    assert_equals('new content', key_store.db[KeyValueStore.Key(Scope.content, None, 'd0', 'content')])
-    assert_equals('new settings', key_store.db[KeyValueStore.Key(Scope.settings, None, 'u0', 'settings')])
-    assert_equals('new student_state', key_store.db[KeyValueStore.Key(Scope.student_state, 's0', 'u0', 'student_state')])
-    assert_equals('new student_preferences', key_store.db[KeyValueStore.Key(Scope.student_preferences, 's0', 'TestModel', 'student_preferences')])
-    assert_equals('new student_info', key_store.db[KeyValueStore.Key(Scope.student_info, 's0', None, 'student_info')])
-    assert_equals('new by_type', key_store.db[KeyValueStore.Key(Scope(False, ModuleScope.TYPE), None, 'TestModel', 'by_type')])
-    assert_equals('new for_all', key_store.db[KeyValueStore.Key(Scope(False, ModuleScope.ALL), None, None, 'for_all')])
-    assert_equals('new student_def', key_store.db[KeyValueStore.Key(Scope(True, ModuleScope.DEFINITION), 's0', 'd0', 'student_def')])
-
-    assert_equals('new n_content', key_store.db[KeyValueStore.Key(Scope.content, None, 'd0', 'n_content')])
-    assert_equals('new n_settings', key_store.db[KeyValueStore.Key(Scope.settings, None, 'u0', 'n_settings')])
-    assert_equals('new n_student_state', key_store.db[KeyValueStore.Key(Scope.student_state, 's0', 'u0', 'n_student_state')])
-    assert_equals('new n_student_preferences', key_store.db[KeyValueStore.Key(Scope.student_preferences, 's0', 'TestModel', 'n_student_preferences')])
-    assert_equals('new n_student_info', key_store.db[KeyValueStore.Key(Scope.student_info, 's0', None, 'n_student_info')])
-    assert_equals('new n_by_type', key_store.db[KeyValueStore.Key(Scope(False, ModuleScope.TYPE), None, 'TestModel', 'n_by_type')])
-    assert_equals('new n_for_all', key_store.db[KeyValueStore.Key(Scope(False, ModuleScope.ALL), None, None, 'n_for_all')])
-    assert_equals('new n_student_def', key_store.db[KeyValueStore.Key(Scope(True, ModuleScope.DEFINITION), 's0', 'd0', 'n_student_def')])
diff --git a/common/lib/xmodule/xmodule/video_module.py b/common/lib/xmodule/xmodule/video_module.py
index 34ce353afdb..e284c574d33 100644
--- a/common/lib/xmodule/xmodule/video_module.py
+++ b/common/lib/xmodule/xmodule/video_module.py
@@ -9,7 +9,7 @@ from xmodule.raw_module import RawDescriptor
 from xmodule.modulestore.mongo import MongoModuleStore
 from xmodule.modulestore.django import modulestore
 from xmodule.contentstore.content import StaticContent
-from .model import Int, Scope, String
+from xblock.core import Integer, Scope, String
 
 log = logging.getLogger(__name__)
 
@@ -29,7 +29,7 @@ class VideoModule(XModule):
     js_module_name = "Video"
 
     data = String(help="XML data for the problem", scope=Scope.content)
-    position = Int(help="Current position in the video", scope=Scope.student_state)
+    position = Integer(help="Current position in the video", scope=Scope.student_state)
     display_name = String(help="Display name for this module", scope=Scope.settings)
 
     def __init__(self, *args, **kwargs):
diff --git a/common/lib/xmodule/xmodule/x_module.py b/common/lib/xmodule/xmodule/x_module.py
index 86f9f5f189d..5ce74ffc46b 100644
--- a/common/lib/xmodule/xmodule/x_module.py
+++ b/common/lib/xmodule/xmodule/x_module.py
@@ -10,12 +10,7 @@ from pkg_resources import resource_listdir, resource_string, resource_isdir
 from xmodule.modulestore import Location
 from xmodule.modulestore.exceptions import ItemNotFoundError
 
-from .model import ModelMetaclass, ParentModelMetaclass, NamespacesMetaclass
-from .plugin import Plugin
-
-
-class XModuleMetaclass(ParentModelMetaclass, NamespacesMetaclass, ModelMetaclass):
-    pass
+from xblock.core import XBlock
 
 log = logging.getLogger(__name__)
 
@@ -88,7 +83,7 @@ class HTMLSnippet(object):
                                   .format(self.__class__))
 
 
-class XModule(HTMLSnippet):
+class XModule(HTMLSnippet, XBlock):
     ''' Implements a generic learning module.
 
         Subclasses must at a minimum provide a definition for get_html in order
@@ -97,8 +92,6 @@ class XModule(HTMLSnippet):
         See the HTML module for a simple example.
     '''
 
-    __metaclass__ = XModuleMetaclass
-
     # The default implementation of get_icon_class returns the icon_class
     # attribute of the class
     #
@@ -266,7 +259,7 @@ class ResourceTemplates(object):
         return templates
 
 
-class XModuleDescriptor(Plugin, HTMLSnippet, ResourceTemplates):
+class XModuleDescriptor(HTMLSnippet, ResourceTemplates, XBlock):
     """
     An XModuleDescriptor is a specification for an element of a course. This
     could be a problem, an organizational element (a group of content), or a
@@ -279,7 +272,6 @@ class XModuleDescriptor(Plugin, HTMLSnippet, ResourceTemplates):
     """
     entry_point = "xmodule.v1"
     module_class = XModule
-    __metaclass__ = XModuleMetaclass
 
     # Attributes for inspection of the descriptor
     
@@ -371,7 +363,7 @@ class XModuleDescriptor(Plugin, HTMLSnippet, ResourceTemplates):
             system,
             self.location,
             self,
-            system.xmodule_model_data(self._model_data),
+            system.xblock_model_data(self._model_data),
         )
     
     def has_dynamic_children(self):
@@ -608,7 +600,7 @@ class ModuleSystem(object):
                  get_module,
                  render_template,
                  replace_urls,
-                 xmodule_model_data,
+                 xblock_model_data,
                  user=None,
                  filestore=None,
                  debug=False,
@@ -663,7 +655,7 @@ class ModuleSystem(object):
         self.node_path = node_path
         self.anonymous_student_id = anonymous_student_id
         self.user_is_staff = user is not None and user.is_staff
-        self.xmodule_model_data = xmodule_model_data
+        self.xblock_model_data = xblock_model_data
 
         if publish is None:
             publish = lambda e: None
diff --git a/common/lib/xmodule/xmodule/xml_module.py b/common/lib/xmodule/xmodule/xml_module.py
index e50adeb364f..f510a40cc79 100644
--- a/common/lib/xmodule/xmodule/xml_module.py
+++ b/common/lib/xmodule/xmodule/xml_module.py
@@ -1,7 +1,7 @@
 from xmodule.x_module import (XModuleDescriptor, policy_key)
 from xmodule.modulestore import Location
 from xmodule.modulestore.inheritance import own_metadata
-from xmodule.model import Object, Scope
+from xblock.core import Object, Scope
 from lxml import etree
 import json
 import copy
diff --git a/github-requirements.txt b/github-requirements.txt
index 468d55ce65d..cf6f097aee8 100644
--- a/github-requirements.txt
+++ b/github-requirements.txt
@@ -3,3 +3,4 @@
 -e git://github.com/MITx/django-pipeline.git#egg=django-pipeline
 -e git://github.com/MITx/django-wiki.git@e2e84558#egg=django-wiki
 -e git://github.com/dementrock/pystache_custom.git@776973740bdaad83a3b029f96e415a7d1e8bec2f#egg=pystache_custom-dev
+-e git+ssh://git@github.com/MITx/xmodule-debugger@ada10f2991cdd61c60ec223b4e0b9b4e06d7cdc3#egg=XBlock
\ No newline at end of file
diff --git a/lms/djangoapps/courseware/model_data.py b/lms/djangoapps/courseware/model_data.py
index b2f2d3ef489..6ae75a2c710 100644
--- a/lms/djangoapps/courseware/model_data.py
+++ b/lms/djangoapps/courseware/model_data.py
@@ -8,8 +8,8 @@ from .models import (
     XModuleStudentInfoField
 )
 
-from xmodule.runtime import KeyValueStore, InvalidScopeError
-from xmodule.model import Scope
+from xblock.runtime import KeyValueStore, InvalidScopeError
+from xblock.core import Scope
 
 
 class InvalidWriteError(Exception):
@@ -45,20 +45,20 @@ class LmsKeyValueStore(KeyValueStore):
 
     def _student_module(self, key):
         student_module = self._student_module_cache.lookup(
-            self._course_id, key.module_scope_id.category, key.module_scope_id.url()
+            self._course_id, key.block_scope_id.category, key.block_scope_id.url()
         )
         return student_module
 
     def _field_object(self, key):
         if key.scope == Scope.content:
-            return XModuleContentField, {'field_name': key.field_name, 'definition_id': key.module_scope_id}
+            return XModuleContentField, {'field_name': key.field_name, 'definition_id': key.block_scope_id}
         elif key.scope == Scope.settings:
             return XModuleSettingsField, {
                 'field_name': key.field_name,
-                'usage_id': '%s-%s' % (self._course_id, key.module_scope_id)
+                'usage_id': '%s-%s' % (self._course_id, key.block_scope_id)
             }
         elif key.scope == Scope.student_preferences:
-            return XModuleStudentPrefsField, {'field_name': key.field_name, 'student': self._user, 'module_type': key.module_scope_id}
+            return XModuleStudentPrefsField, {'field_name': key.field_name, 'student': self._user, 'module_type': key.block_scope_id}
         elif key.scope == Scope.student_info:
             return XModuleStudentInfoField, {'field_name': key.field_name, 'student': self._user}
 
@@ -68,6 +68,9 @@ class LmsKeyValueStore(KeyValueStore):
         if key.field_name in self._descriptor_model_data:
             return self._descriptor_model_data[key.field_name]
 
+        if key.scope == Scope.parent:
+            return None
+
         if key.scope == Scope.student_state:
             student_module = self._student_module(key)
 
@@ -92,8 +95,8 @@ class LmsKeyValueStore(KeyValueStore):
                 student_module = StudentModule(
                     course_id=self._course_id,
                     student=self._user,
-                    module_type=key.module_scope_id.category,
-                    module_state_key=key.module_scope_id.url(),
+                    module_type=key.block_scope_id.category,
+                    module_state_key=key.block_scope_id.url(),
                     state=json.dumps({})
                 )
                 self._student_module_cache.append(student_module)
diff --git a/lms/djangoapps/courseware/module_render.py b/lms/djangoapps/courseware/module_render.py
index c2a8db0fabe..4d599d128d7 100644
--- a/lms/djangoapps/courseware/module_render.py
+++ b/lms/djangoapps/courseware/module_render.py
@@ -26,7 +26,7 @@ from xmodule.modulestore import Location
 from xmodule.modulestore.django import modulestore
 from xmodule.x_module import ModuleSystem
 from xmodule.error_module import ErrorDescriptor, NonStaffErrorDescriptor
-from xmodule.runtime import DbModel
+from xblock.runtime import DbModel
 from xmodule_modifiers import replace_course_urls, replace_static_urls, add_histogram, wrap_xmodule
 from .model_data import LmsKeyValueStore, LmsUsage
 
@@ -203,7 +203,7 @@ def _get_module(user, request, location, student_module_cache, course_id, positi
         return get_module(user, request, location,
                                        student_module_cache, course_id, position)
 
-    def xmodule_model_data(descriptor_model_data):
+    def xblock_model_data(descriptor_model_data):
         return DbModel(
             LmsKeyValueStore(course_id, user, descriptor_model_data, student_module_cache),
             descriptor.module_class,
@@ -260,7 +260,7 @@ def _get_module(user, request, location, student_module_cache, course_id, positi
                           replace_urls=replace_urls,
                           node_path=settings.NODE_PATH,
                           anonymous_student_id=anonymous_student_id,
-                          xmodule_model_data=xmodule_model_data,
+                          xblock_model_data=xblock_model_data,
                           publish=publish,
                           )
     # pass position specified in URL to module through ModuleSystem
diff --git a/lms/djangoapps/courseware/tests/test_model_data.py b/lms/djangoapps/courseware/tests/test_model_data.py
index ab9067ce710..f18e128984b 100644
--- a/lms/djangoapps/courseware/tests/test_model_data.py
+++ b/lms/djangoapps/courseware/tests/test_model_data.py
@@ -7,7 +7,7 @@ from functools import partial
 
 from courseware.model_data import LmsKeyValueStore, InvalidWriteError, InvalidScopeError
 from courseware.models import StudentModule, XModuleContentField, XModuleSettingsField, XModuleStudentInfoField, XModuleStudentPrefsField, StudentModuleCache
-from xmodule.model import Scope, ModuleScope
+from xblock.core import Scope, BlockScope
 from xmodule.modulestore import Location
 
 from django.test import TestCase
@@ -112,9 +112,9 @@ class TestInvalidScopes(TestCase):
         self.kvs = LmsKeyValueStore(course_id, UserFactory.build(), self.desc_md, None)
 
     def test_invalid_scopes(self):
-        for scope in (Scope(student=True, module=ModuleScope.DEFINITION),
-                      Scope(student=False, module=ModuleScope.TYPE),
-                      Scope(student=False, module=ModuleScope.ALL)):
+        for scope in (Scope(student=True, block=BlockScope.DEFINITION),
+                      Scope(student=False, block=BlockScope.TYPE),
+                      Scope(student=False, block=BlockScope.ALL)):
             self.assertRaises(InvalidScopeError, self.kvs.get, LmsKeyValueStore.Key(scope, None, None, 'field'))
             self.assertRaises(InvalidScopeError, self.kvs.set, LmsKeyValueStore.Key(scope, None, None, 'field'), 'value')
             self.assertRaises(InvalidScopeError, self.kvs.delete, LmsKeyValueStore.Key(scope, None, None, 'field'))
diff --git a/lms/xmodule_namespace.py b/lms/xmodule_namespace.py
index 5fd2c18bb74..8d587dfacb8 100644
--- a/lms/xmodule_namespace.py
+++ b/lms/xmodule_namespace.py
@@ -1,4 +1,4 @@
-from xmodule.model import Namespace, Boolean, Scope, String, List
+from xblock.core import Namespace, Boolean, Scope, String, List
 from xmodule.fields import Date, Timedelta
 
 
diff --git a/setup.py b/setup.py
index a07f8364133..48572de6def 100644
--- a/setup.py
+++ b/setup.py
@@ -7,11 +7,11 @@ setup(
     requires=[
         'xmodule',
     ],
-    py_modules=['lms.xmodule_namespace'],
+    py_modules=['lms.xmodule_namespace', 'cms.xmodule_namespace'],
     # See http://guide.python-distribute.org/creation.html#entry-points
     # for a description of entry_points
     entry_points={
-        'xmodule.namespace': [
+        'xblock.namespace': [
             'lms = lms.xmodule_namespace:LmsNamespace',
             'cms = cms.xmodule_namespace:CmsNamespace',
         ],
-- 
GitLab