Commit 63f34f2e by Victor Shnayder

Line length and doc string cleanups

* no functionality changed in this commit.
parent d43831e1
......@@ -12,8 +12,8 @@ log = logging.getLogger(__name__)
def process_includes(fn):
"""
Wraps a XModuleDescriptor.from_xml method, and modifies xml_data to replace
any immediate child <include> items with the contents of the file that they are
supposed to include
any immediate child <include> items with the contents of the file that they
are supposed to include
"""
@wraps(fn)
def from_xml(cls, xml_data, system, org=None, course=None):
......@@ -25,15 +25,19 @@ def process_includes(fn):
try:
ifp = system.resources_fs.open(file)
except Exception:
log.exception('Error in problem xml include: %s' % (etree.tostring(next_include, pretty_print=True)))
log.exception('Cannot find file %s in %s' % (file, dir))
msg = 'Error in problem xml include: %s\n' % (
etree.tostring(next_include, pretty_print=True))
msg += 'Cannot find file %s in %s' % (file, dir)
log.exception(msg)
raise
try:
# read in and convert to XML
incxml = etree.XML(ifp.read())
except Exception:
log.exception('Error in problem xml include: %s' % (etree.tostring(next_include, pretty_print=True)))
log.exception('Cannot parse XML in %s' % (file))
msg = 'Error in problem xml include: %s\n' % (
etree.tostring(next_include, pretty_print=True))
msg += 'Cannot parse XML in %s' % (file)
log.exception(msg)
raise
# insert new XML into tree in place of inlcude
parent = next_include.getparent()
......@@ -50,8 +54,8 @@ class SemanticSectionDescriptor(XModuleDescriptor):
@process_includes
def from_xml(cls, xml_data, system, org=None, course=None):
"""
Removes sections single child elements in favor of just embedding the child element
Removes sections with single child elements in favor of just embedding
the child element
"""
xml_object = etree.fromstring(xml_data)
......
......@@ -67,7 +67,8 @@ class ComplexEncoder(json.JSONEncoder):
class CapaModule(XModule):
'''
An XModule implementing LonCapa format problems, implemented by way of capa.capa_problem.LoncapaProblem
An XModule implementing LonCapa format problems, implemented by way of
capa.capa_problem.LoncapaProblem
'''
icon_class = 'problem'
......@@ -77,8 +78,10 @@ class CapaModule(XModule):
js_module_name = "Problem"
css = {'scss': [resource_string(__name__, 'css/capa/display.scss')]}
def __init__(self, system, location, definition, instance_state=None, shared_state=None, **kwargs):
XModule.__init__(self, system, location, definition, instance_state, shared_state, **kwargs)
def __init__(self, system, location, definition, instance_state=None,
shared_state=None, **kwargs):
XModule.__init__(self, system, location, definition, instance_state,
shared_state, **kwargs)
self.attempts = 0
self.max_attempts = None
......@@ -133,7 +136,8 @@ class CapaModule(XModule):
seed = None
try:
self.lcp = LoncapaProblem(self.definition['data'], self.location.html_id(), instance_state, seed=seed, system=self.system)
self.lcp = LoncapaProblem(self.definition['data'], self.location.html_id(),
instance_state, seed=seed, system=self.system)
except Exception:
msg = 'cannot create LoncapaProblem %s' % self.location.url()
log.exception(msg)
......@@ -141,15 +145,20 @@ class CapaModule(XModule):
msg = '<p>%s</p>' % msg.replace('<', '&lt;')
msg += '<p><pre>%s</pre></p>' % traceback.format_exc().replace('<', '&lt;')
# create a dummy problem with error message instead of failing
problem_text = '<problem><text><font color="red" size="+2">Problem %s has an error:</font>%s</text></problem>' % (self.location.url(), msg)
self.lcp = LoncapaProblem(problem_text, self.location.html_id(), instance_state, seed=seed, system=self.system)
problem_text = ('<problem><text><font color="red" size="+2">'
'Problem %s has an error:</font>%s</text></problem>' %
(self.location.url(), msg))
self.lcp = LoncapaProblem(
problem_text, self.location.html_id(),
instance_state, seed=seed, system=self.system)
else:
raise
@property
def rerandomize(self):
"""
Property accessor that returns self.metadata['rerandomize'] in a canonical form
Property accessor that returns self.metadata['rerandomize'] in a
canonical form
"""
rerandomize = self.metadata.get('rerandomize', 'always')
if rerandomize in ("", "always", "true"):
......@@ -203,7 +212,10 @@ class CapaModule(XModule):
except Exception, err:
if self.system.DEBUG:
log.exception(err)
msg = '[courseware.capa.capa_module] <font size="+1" color="red">Failed to generate HTML for problem %s</font>' % (self.location.url())
msg = (
'[courseware.capa.capa_module] <font size="+1" color="red">'
'Failed to generate HTML for problem %s</font>' %
(self.location.url()))
msg += '<p>Error:</p><p><pre>%s</pre></p>' % str(err).replace('<', '&lt;')
msg += '<p><pre>%s</pre></p>' % traceback.format_exc().replace('<', '&lt;')
html = msg
......@@ -215,8 +227,8 @@ class CapaModule(XModule):
'weight': self.weight,
}
# We using strings as truthy values, because the terminology of the check button
# is context-specific.
# We using strings as truthy values, because the terminology of the
# check button is context-specific.
check_button = "Grade" if self.max_attempts else "Check"
reset_button = True
save_button = True
......@@ -242,7 +254,8 @@ class CapaModule(XModule):
if not self.lcp.done:
reset_button = False
# We don't need a "save" button if infinite number of attempts and non-randomized
# We don't need a "save" button if infinite number of attempts and
# non-randomized
if self.max_attempts is None and self.rerandomize != "always":
save_button = False
......
......@@ -17,11 +17,12 @@ class CourseDescriptor(SequenceDescriptor):
try:
self.start = time.strptime(self.metadata["start"], "%Y-%m-%dT%H:%M")
except KeyError:
self.start = time.gmtime(0) # The epoch
log.critical("Course loaded without a start date. " + str(self.id))
except ValueError, e:
self.start = time.gmtime(0) # The epoch
log.critical("Course loaded with a bad start date. " + str(self.id) + " '" + str(e) + "'")
self.start = time.gmtime(0) #The epoch
log.critical("Course loaded without a start date. %s", self.id)
except ValueError as e:
self.start = time.gmtime(0) #The epoch
log.critical("Course loaded with a bad start date. %s '%s'",
self.id, e)
def has_started(self):
return time.gmtime() > self.start
......
......@@ -19,7 +19,9 @@ class MakoModuleDescriptor(XModuleDescriptor):
def __init__(self, system, definition=None, **kwargs):
if getattr(system, 'render_template', None) is None:
raise TypeError('{system} must have a render_template function in order to use a MakoDescriptor'.format(system=system))
raise TypeError('{system} must have a render_template function'
' in order to use a MakoDescriptor'.format(
system=system))
super(MakoModuleDescriptor, self).__init__(system, definition, **kwargs)
def get_context(self):
......@@ -29,4 +31,5 @@ class MakoModuleDescriptor(XModuleDescriptor):
return {'module': self}
def get_html(self):
return self.system.render_template(self.mako_template, self.get_context())
return self.system.render_template(
self.mako_template, self.get_context())
......@@ -45,13 +45,17 @@ class Location(_LocationBase):
"""
return re.sub('_+', '_', INVALID_CHARS.sub('_', value))
def __new__(_cls, loc_or_tag=None, org=None, course=None, category=None, name=None, revision=None):
def __new__(_cls, loc_or_tag=None, org=None, course=None, category=None,
name=None, revision=None):
"""
Create a new location that is a clone of the specifed one.
location - Can be any of the following types:
string: should be of the form {tag}://{org}/{course}/{category}/{name}[/{revision}]
string: should be of the form
{tag}://{org}/{course}/{category}/{name}[/{revision}]
list: should be of the form [tag, org, course, category, name, revision]
dict: should be of the form {
'tag': tag,
'org': org,
......@@ -62,16 +66,19 @@ class Location(_LocationBase):
}
Location: another Location object
In both the dict and list forms, the revision is optional, and can be ommitted.
In both the dict and list forms, the revision is optional, and can be
ommitted.
Components must be composed of alphanumeric characters, or the characters '_', '-', and '.'
Components must be composed of alphanumeric characters, or the
characters '_', '-', and '.'
Components may be set to None, which may be interpreted by some contexts to mean
wildcard selection
Components may be set to None, which may be interpreted by some contexts
to mean wildcard selection
"""
if org is None and course is None and category is None and name is None and revision is None:
if (org is None and course is None and category is None and
name is None and revision is None):
location = loc_or_tag
else:
location = (loc_or_tag, org, course, category, name, revision)
......@@ -131,9 +138,11 @@ class Location(_LocationBase):
def html_id(self):
"""
Return a string with a version of the location that is safe for use in html id attributes
Return a string with a version of the location that is safe for use in
html id attributes
"""
return "-".join(str(v) for v in self.list() if v is not None).replace('.', '_')
return "-".join(str(v) for v in self.list()
if v is not None).replace('.', '_')
def dict(self):
"""
......@@ -154,7 +163,8 @@ class Location(_LocationBase):
class ModuleStore(object):
"""
An abstract interface for a database backend that stores XModuleDescriptor instances
An abstract interface for a database backend that stores XModuleDescriptor
instances
"""
def get_item(self, location, depth=0):
"""
......@@ -164,13 +174,16 @@ class ModuleStore(object):
If any segment of the location is None except revision, raises
xmodule.modulestore.exceptions.InsufficientSpecificationError
If no object is found at that location, raises xmodule.modulestore.exceptions.ItemNotFoundError
If no object is found at that location, raises
xmodule.modulestore.exceptions.ItemNotFoundError
location: Something that can be passed to Location
depth (int): An argument that some module stores may use to prefetch descendents of the queried modules
for more efficient results later in the request. The depth is counted in the number of
calls to get_children() to cache. None indicates to cache all descendents
depth (int): An argument that some module stores may use to prefetch
descendents of the queried modules for more efficient results later
in the request. The depth is counted in the number of calls to
get_children() to cache. None indicates to cache all descendents
"""
raise NotImplementedError
......@@ -182,9 +195,10 @@ class ModuleStore(object):
location: Something that can be passed to Location
depth: An argument that some module stores may use to prefetch descendents of the queried modules
for more efficient results later in the request. The depth is counted in the number of calls
to get_children() to cache. None indicates to cache all descendents
depth: An argument that some module stores may use to prefetch
descendents of the queried modules for more efficient results later
in the request. The depth is counted in the number of calls to
get_children() to cache. None indicates to cache all descendents
"""
raise NotImplementedError
......@@ -228,4 +242,3 @@ class ModuleStore(object):
in this modulestore.
'''
raise NotImplementedError
......@@ -8,7 +8,7 @@ log = logging.getLogger(__name__)
class RawDescriptor(MakoModuleDescriptor, XmlDescriptor):
"""
Module that provides a raw editing view of it's data and children
Module that provides a raw editing view of its data and children
"""
mako_template = "widgets/raw-edit.html"
......
......@@ -20,12 +20,15 @@ class_priority = ['video', 'problem']
class SequenceModule(XModule):
''' Layout module which lays out content in a temporal sequence
'''
js = {'coffee': [resource_string(__name__, 'js/src/sequence/display.coffee')]}
js = {'coffee': [resource_string(__name__,
'js/src/sequence/display.coffee')]}
css = {'scss': [resource_string(__name__, 'css/sequence/display.scss')]}
js_module_name = "Sequence"
def __init__(self, system, location, definition, instance_state=None, shared_state=None, **kwargs):
XModule.__init__(self, system, location, definition, instance_state, shared_state, **kwargs)
def __init__(self, system, location, definition, instance_state=None,
shared_state=None, **kwargs):
XModule.__init__(self, system, location, definition,
instance_state, shared_state, **kwargs)
self.position = 1
if instance_state is not None:
......@@ -92,7 +95,8 @@ class SequenceModule(XModule):
self.rendered = True
def get_icon_class(self):
child_classes = set(child.get_icon_class() for child in self.get_children())
child_classes = set(child.get_icon_class()
for child in self.get_children())
new_class = 'other'
for c in class_priority:
if c in child_classes:
......@@ -114,5 +118,6 @@ class SequenceDescriptor(MakoModuleDescriptor, XmlDescriptor):
def definition_to_xml(self, resource_fs):
xml_object = etree.Element('sequential')
for child in self.get_children():
xml_object.append(etree.fromstring(child.export_to_xml(resource_fs)))
xml_object.append(
etree.fromstring(child.export_to_xml(resource_fs)))
return xml_object
......@@ -13,13 +13,19 @@ log = logging.getLogger(__name__)
# TODO (cpennington): This was implemented in an attempt to improve performance,
# but the actual improvement wasn't measured (and it was implemented late at night).
# We should check if it hurts, and whether there's a better way of doing lazy loading
class LazyLoadingDict(MutableMapping):
"""
A dictionary object that lazily loads it's contents from a provided
function on reads (of members that haven't already been set)
A dictionary object that lazily loads its contents from a provided
function on reads (of members that haven't already been set).
"""
def __init__(self, loader):
'''
On the first read from this dictionary, it will call loader() to
populate its contents. loader() must return something dict-like. Any
elements set before the first read will be preserved.
'''
self._contents = {}
self._loaded = False
self._loader = loader
......@@ -70,10 +76,12 @@ _AttrMapBase = namedtuple('_AttrMap', 'metadata_key to_metadata from_metadata')
class AttrMap(_AttrMapBase):
"""
A class that specifies a metadata_key, a function to transform an xml attribute to be placed in that key,
and to transform that key value
A class that specifies a metadata_key, a function to transform an xml
attribute to be placed in that key, and to transform that key value
"""
def __new__(_cls, metadata_key, to_metadata=lambda x: x, from_metadata=lambda x: x):
def __new__(_cls, metadata_key,
to_metadata=lambda x: x,
from_metadata=lambda x: x):
return _AttrMapBase.__new__(_cls, metadata_key, to_metadata, from_metadata)
......@@ -93,7 +101,9 @@ class XmlDescriptor(XModuleDescriptor):
# A dictionary mapping xml attribute names to functions of the value
# that return the metadata key and value
xml_attribute_map = {
'graded': AttrMap('graded', lambda val: val == 'true', lambda val: str(val).lower()),
'graded': AttrMap('graded',
lambda val: val == 'true',
lambda val: str(val).lower()),
'name': AttrMap('display_name'),
}
......@@ -105,12 +115,14 @@ class XmlDescriptor(XModuleDescriptor):
xml_object: An etree Element
"""
raise NotImplementedError("%s does not implement definition_from_xml" % cls.__name__)
raise NotImplementedError(
"%s does not implement definition_from_xml" % cls.__name__)
@classmethod
def clean_metadata_from_xml(cls, xml_object):
"""
Remove any attribute named in self.metadata_attributes from the supplied xml_object
Remove any attribute named in cls.metadata_attributes from the supplied
xml_object
"""
for attr in cls.metadata_attributes:
if xml_object.get(attr) is not None:
......@@ -134,7 +146,7 @@ class XmlDescriptor(XModuleDescriptor):
xml_data: A string of xml that will be translated into data and children for
this module
system: An XModuleSystem for interacting with external resources
system: A DescriptorSystem for interacting with external resources
org and course are optional strings that will be used in the generated modules
url identifiers
"""
......@@ -157,6 +169,7 @@ class XmlDescriptor(XModuleDescriptor):
else:
filepath = cls._format_filepath(xml_object.tag, filename)
# VS[compat]
# TODO (cpennington): If the file doesn't exist at the right path,
# give the class a chance to fix it up. The file will be written out again
# in the correct format.
......@@ -243,4 +256,5 @@ class XmlDescriptor(XModuleDescriptor):
"""
Return a new etree Element object created from this modules definition.
"""
raise NotImplementedError("%s does not implement definition_to_xml" % self.__class__.__name__)
raise NotImplementedError(
"%s does not implement definition_to_xml" % self.__class__.__name__)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment