From d4cbcfd5d504b6a56cd37376d498bcd53bf0ac6d Mon Sep 17 00:00:00 2001 From: Kyle Mulka Date: Thu, 9 May 2019 00:57:09 -0400 Subject: [PATCH] INCR-229 ran modernize and isort on some files (#20463) * INCR-229 ran modernize on common/lib/xmodule/xmodule/[a-g]*.py except for graders.py * fix a couple xss-commit-linter issues --- .../lib/xmodule/xmodule/annotatable_module.py | 9 ++++-- common/lib/xmodule/xmodule/annotator_mixin.py | 6 ++-- common/lib/xmodule/xmodule/annotator_token.py | 2 ++ .../lib/xmodule/xmodule/backcompat_module.py | 2 ++ common/lib/xmodule/xmodule/capa_base.py | 28 ++++++++++--------- common/lib/xmodule/xmodule/capa_module.py | 19 +++++++++---- .../lib/xmodule/xmodule/conditional_module.py | 17 ++++++----- .../xmodule/xmodule/course_metadata_utils.py | 5 +++- common/lib/xmodule/xmodule/course_module.py | 25 +++++++++-------- common/lib/xmodule/xmodule/editing_module.py | 2 ++ common/lib/xmodule/xmodule/edxnotes_utils.py | 2 ++ common/lib/xmodule/xmodule/error_module.py | 5 +++- common/lib/xmodule/xmodule/errortracker.py | 2 ++ common/lib/xmodule/xmodule/fields.py | 11 +++++--- 14 files changed, 87 insertions(+), 48 deletions(-) diff --git a/common/lib/xmodule/xmodule/annotatable_module.py b/common/lib/xmodule/xmodule/annotatable_module.py index c974da2157..004484ddee 100644 --- a/common/lib/xmodule/xmodule/annotatable_module.py +++ b/common/lib/xmodule/xmodule/annotatable_module.py @@ -1,3 +1,5 @@ +from __future__ import absolute_import + import logging import textwrap @@ -5,6 +7,7 @@ from lxml import etree from pkg_resources import resource_string from xblock.fields import Scope, String +from openedx.core.djangolib.markup import HTML, Text from xmodule.raw_module import RawDescriptor from xmodule.x_module import XModule @@ -19,11 +22,11 @@ class AnnotatableFields(object): data = String( help=_("XML data for the annotation"), scope=Scope.content, - default=textwrap.dedent(""" + default=textwrap.dedent(HTML(u"""

Enter your (optional) instructions for the exercise in HTML format.

-

Annotations are specified by an <annotation> tag which may may have the following attributes:

+

Annotations are specified by an {}annotation{} tag which may may have the following attributes:

  • title (optional). Title of the annotation. Defaults to Commentary if omitted.
  • body (required). Text of the annotation.
  • @@ -35,7 +38,7 @@ class AnnotatableFields(object):

    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut sodales laoreet est, egestas gravida felis egestas nec. Aenean at volutpat erat. Cras commodo viverra nibh in aliquam.

    Nulla facilisi. Pellentesque id vestibulum libero. Suspendisse potenti. Morbi scelerisque nisi vitae felis dictum mattis. Nam sit amet magna elit. Nullam volutpat cursus est, sit amet sagittis odio vulputate et. Curabitur euismod, orci in vulputate imperdiet, augue lorem tempor purus, id aliquet augue turpis a est. Aenean a sagittis libero. Praesent fringilla pretium magna, non condimentum risus elementum nec. Pellentesque faucibus elementum pharetra. Pellentesque vitae metus eros.

    - """) + """).format(Text('<'), Text('>'))) ) display_name = String( display_name=_("Display Name"), diff --git a/common/lib/xmodule/xmodule/annotator_mixin.py b/common/lib/xmodule/xmodule/annotator_mixin.py index 48e75d9ba0..f8bf3c19d0 100644 --- a/common/lib/xmodule/xmodule/annotator_mixin.py +++ b/common/lib/xmodule/xmodule/annotator_mixin.py @@ -2,11 +2,13 @@ Annotations Tool Mixin This file contains global variables and functions used in the various Annotation Tools. """ -from HTMLParser import HTMLParser +from __future__ import absolute_import + from os.path import basename, splitext -from urlparse import urlparse from lxml import etree +from six.moves.html_parser import HTMLParser +from six.moves.urllib.parse import urlparse def get_instructions(xmltree): diff --git a/common/lib/xmodule/xmodule/annotator_token.py b/common/lib/xmodule/xmodule/annotator_token.py index 5822727cf8..282f13e367 100644 --- a/common/lib/xmodule/xmodule/annotator_token.py +++ b/common/lib/xmodule/xmodule/annotator_token.py @@ -5,6 +5,8 @@ without having to create a view, but just returning a string instead. It can be called from other files by using the following: from xmodule.annotator_token import retrieve_token """ +from __future__ import absolute_import + import datetime from firebase_token_generator import create_token diff --git a/common/lib/xmodule/xmodule/backcompat_module.py b/common/lib/xmodule/xmodule/backcompat_module.py index 7b0fa690fa..680f8b4781 100644 --- a/common/lib/xmodule/xmodule/backcompat_module.py +++ b/common/lib/xmodule/xmodule/backcompat_module.py @@ -1,6 +1,8 @@ """ These modules exist to translate old format XML into newer, semantic forms """ +from __future__ import absolute_import + import logging import traceback from functools import wraps diff --git a/common/lib/xmodule/xmodule/capa_base.py b/common/lib/xmodule/xmodule/capa_base.py index b0e06614cd..1f6c5dce76 100644 --- a/common/lib/xmodule/xmodule/capa_base.py +++ b/common/lib/xmodule/xmodule/capa_base.py @@ -1,4 +1,6 @@ """Implements basics of Capa, including class CapaModule.""" +from __future__ import absolute_import + import copy import datetime import hashlib @@ -10,25 +12,25 @@ import struct import sys import traceback +import six from django.conf import settings from django.core.exceptions import ImproperlyConfigured -from pytz import utc from django.utils.encoding import smart_text from django.utils.functional import cached_property +from pytz import utc from six import text_type +from xblock.fields import Boolean, Dict, Float, Integer, Scope, String, XMLString +from xblock.scorable import ScorableXBlockMixin, Score from capa.capa_problem import LoncapaProblem, LoncapaSystem from capa.inputtypes import Status -from capa.responsetypes import StudentInputError, ResponseError, LoncapaProblemError +from capa.responsetypes import LoncapaProblemError, ResponseError, StudentInputError from capa.util import convert_files_to_filenames, get_inner_html_from_xpath -from xblock.fields import Boolean, Dict, Float, Integer, Scope, String, XMLString - from openedx.core.djangolib.markup import HTML, Text -from xblock.fields import String -from xblock.scorable import ScorableXBlockMixin, Score from xmodule.exceptions import NotFoundError from xmodule.graders import ShowCorrectness -from .fields import Date, Timedelta, ScoreField + +from .fields import Date, ScoreField, Timedelta from .progress import Progress log = logging.getLogger("edx.courseware") @@ -294,7 +296,7 @@ class CapaMixin(ScorableXBlockMixin, CapaFields): except Exception as err: # pylint: disable=broad-except msg = u'cannot create LoncapaProblem {loc}: {err}'.format( loc=text_type(self.location), err=err) - raise Exception(msg), None, sys.exc_info()[2] + six.reraise(Exception(msg), None, sys.exc_info()[2]) if self.score is None: self.set_score(self.score_from_lcp(lcp)) @@ -310,7 +312,7 @@ class CapaMixin(ScorableXBlockMixin, CapaFields): self.seed = 1 elif self.rerandomize == RANDOMIZATION.PER_STUDENT and hasattr(self.runtime, 'seed'): # see comment on randomization_bin - self.seed = randomization_bin(self.runtime.seed, unicode(self.location).encode('utf-8')) + self.seed = randomization_bin(self.runtime.seed, six.text_type(self.location).encode('utf-8')) else: self.seed = struct.unpack('i', os.urandom(4))[0] @@ -563,7 +565,7 @@ class CapaMixin(ScorableXBlockMixin, CapaFields): # Presumably, student submission has corrupted LoncapaProblem HTML. # First, pull down all student answers student_answers = self.lcp.student_answers - answer_ids = student_answers.keys() + answer_ids = list(student_answers.keys()) # Some inputtypes, such as dynamath, have additional "hidden" state that # is not exposed to the student. Keep those hidden @@ -771,7 +773,7 @@ class CapaMixin(ScorableXBlockMixin, CapaFields): if render_notifications: progress = self.get_progress() - id_list = self.lcp.correct_map.keys() + id_list = list(self.lcp.correct_map.keys()) # Show only a generic message if hiding correctness if not self.correctness_available(): @@ -1416,14 +1418,14 @@ class CapaMixin(ScorableXBlockMixin, CapaFields): strings ''. """ input_metadata = {} - for input_id, internal_answer in answers.iteritems(): + for input_id, internal_answer in six.iteritems(answers): answer_input = self.lcp.inputs.get(input_id) if answer_input is None: log.warning('Input id %s is not mapped to an input type.', input_id) answer_response = None - for responder in self.lcp.responders.itervalues(): + for responder in six.itervalues(self.lcp.responders): if input_id in responder.answer_ids: answer_response = responder diff --git a/common/lib/xmodule/xmodule/capa_module.py b/common/lib/xmodule/xmodule/capa_module.py index 5f9e7bf087..53778a2a59 100644 --- a/common/lib/xmodule/xmodule/capa_module.py +++ b/common/lib/xmodule/xmodule/capa_module.py @@ -1,29 +1,36 @@ """Implements basics of Capa, including class CapaModule.""" +from __future__ import absolute_import + import json import logging import re import sys +import six from lxml import etree from pkg_resources import resource_string from web_fragments.fragment import Fragment from xblock.core import XBlock from capa import responsetypes +from xmodule.contentstore.django import contentstore from xmodule.editing_module import EditingMixin from xmodule.exceptions import NotFoundError, ProcessingError from xmodule.raw_module import RawMixin -from xmodule.contentstore.django import contentstore from xmodule.util.misc import escape_html_characters from xmodule.util.sandboxing import get_python_lib_zip from xmodule.util.xmodule_django import add_webpack_to_fragment from xmodule.x_module import ( - HTMLSnippet, ResourceTemplates, shim_xmodule_js, - XModuleMixin, XModuleToXBlockMixin, XModuleDescriptorToXBlockMixin, + HTMLSnippet, + ResourceTemplates, + XModuleDescriptorToXBlockMixin, + XModuleMixin, + XModuleToXBlockMixin, + shim_xmodule_js ) from xmodule.xml_module import XmlMixin -from .capa_base import _, CapaMixin, ComplexEncoder +from .capa_base import CapaMixin, ComplexEncoder, _ log = logging.getLogger("edx.courseware") @@ -178,7 +185,7 @@ class ProblemBlock( self.scope_ids.user_id ) _, _, traceback_obj = sys.exc_info() # pylint: disable=redefined-outer-name - raise ProcessingError(not_found_error_message), None, traceback_obj + six.reraise(ProcessingError(not_found_error_message), None, traceback_obj) except Exception: log.exception( @@ -188,7 +195,7 @@ class ProblemBlock( self.scope_ids.user_id ) _, _, traceback_obj = sys.exc_info() # pylint: disable=redefined-outer-name - raise ProcessingError(generic_error_message), None, traceback_obj + six.reraise(ProcessingError(generic_error_message), None, traceback_obj) after = self.get_progress() after_attempts = self.attempts diff --git a/common/lib/xmodule/xmodule/conditional_module.py b/common/lib/xmodule/xmodule/conditional_module.py index 7167a106fe..dabe8e6fd7 100644 --- a/common/lib/xmodule/xmodule/conditional_module.py +++ b/common/lib/xmodule/xmodule/conditional_module.py @@ -2,18 +2,21 @@ some xmodules by conditions. """ +from __future__ import absolute_import + import json import logging +import six from lazy import lazy from lxml import etree +from opaque_keys.edx.locator import BlockUsageLocator from pkg_resources import resource_string from six import text_type - -from opaque_keys.edx.locator import BlockUsageLocator from web_fragments.fragment import Fragment from xblock.fields import ReferenceList, Scope, String +from openedx.core.djangolib.markup import HTML, Text from xmodule.modulestore.exceptions import ItemNotFoundError from xmodule.seq_module import SequenceDescriptor from xmodule.studio_editable import StudioEditableDescriptor, StudioEditableModule @@ -264,7 +267,7 @@ class ConditionalDescriptor(ConditionalFields, SequenceDescriptor, StudioEditabl # Convert sources xml_attribute to a ReferenceList field type so Location/Locator # substitution can be done. if not self.sources_list: - if 'sources' in self.xml_attributes and isinstance(self.xml_attributes['sources'], basestring): + if 'sources' in self.xml_attributes and isinstance(self.xml_attributes['sources'], six.string_types): self.sources_list = [ # TODO: it is not clear why we are replacing the run here (which actually is a no-op # for old-style course locators. However, this is the implementation of @@ -302,7 +305,7 @@ class ConditionalDescriptor(ConditionalFields, SequenceDescriptor, StudioEditabl children = [] show_tag_list = [] definition = {} - for conditional_attr in ConditionalModule.conditions_map.iterkeys(): + for conditional_attr in six.iterkeys(ConditionalModule.conditions_map): conditional_value = xml_object.get(conditional_attr) if conditional_value is not None: definition.update({ @@ -336,13 +339,13 @@ class ConditionalDescriptor(ConditionalFields, SequenceDescriptor, StudioEditabl self.runtime.add_block_as_child_node(child, xml_object) if self.show_tag_list: - show_str = u'<{tag_name} sources="{sources}" />'.format( - tag_name='show', sources=';'.join(text_type(location) for location in self.show_tag_list)) + show_str = HTML(u'').format( + sources=Text(';'.join(text_type(location) for location in self.show_tag_list))) xml_object.append(etree.fromstring(show_str)) # Overwrite the original sources attribute with the value from sources_list, as # Locations may have been changed to Locators. - stringified_sources_list = map(lambda loc: text_type(loc), self.sources_list) + stringified_sources_list = [text_type(loc) for loc in self.sources_list] self.xml_attributes['sources'] = ';'.join(stringified_sources_list) self.xml_attributes[self.conditional_attr] = self.conditional_value self.xml_attributes['message'] = self.conditional_message diff --git a/common/lib/xmodule/xmodule/course_metadata_utils.py b/common/lib/xmodule/xmodule/course_metadata_utils.py index 317f18d961..faa43f37b3 100644 --- a/common/lib/xmodule/xmodule/course_metadata_utils.py +++ b/common/lib/xmodule/xmodule/course_metadata_utils.py @@ -5,11 +5,14 @@ This is a place to put simple functions that operate on course metadata. It allows us to share code between the CourseDescriptor and CourseOverview classes, which both need these type of functions. """ +from __future__ import absolute_import + from base64 import b32encode from datetime import datetime, timedelta from math import exp import dateutil.parser +import six from pytz import utc DEFAULT_START_DATE = datetime(2030, 1, 1, tzinfo=utc) @@ -64,7 +67,7 @@ def clean_course_key(course_key, padding_char): string. The standard value for this is '='. """ return "course_{}".format( - b32encode(unicode(course_key)).replace('=', padding_char) + b32encode(six.text_type(course_key)).replace('=', padding_char) ) diff --git a/common/lib/xmodule/xmodule/course_module.py b/common/lib/xmodule/xmodule/course_module.py index bbcd6f2873..b8e91bbffc 100644 --- a/common/lib/xmodule/xmodule/course_module.py +++ b/common/lib/xmodule/xmodule/course_module.py @@ -1,29 +1,32 @@ """ Django module container for classes and operations related to the "Course Module" content type """ +from __future__ import absolute_import + import json import logging from datetime import datetime, timedelta from io import BytesIO + import dateutil.parser - -from django.conf import settings - import requests +import six +from django.conf import settings from lazy import lazy from lxml import etree -from openedx.core.djangoapps.video_pipeline.models import VideoUploadsEnabledByDefault -from openedx.core.lib.license import LicenseMixin from path import Path as path from pytz import utc from six import text_type -from xblock.fields import Scope, List, String, Dict, Boolean, Integer, Float +from xblock.fields import Boolean, Dict, Float, Integer, List, Scope, String +from openedx.core.djangoapps.video_pipeline.models import VideoUploadsEnabledByDefault +from openedx.core.lib.license import LicenseMixin from xmodule import course_metadata_utils -from xmodule.course_metadata_utils import DEFAULT_START_DATE, DEFAULT_GRADING_POLICY +from xmodule.course_metadata_utils import DEFAULT_GRADING_POLICY, DEFAULT_START_DATE from xmodule.graders import grader_from_conf from xmodule.seq_module import SequenceDescriptor, SequenceModule from xmodule.tabs import CourseTabList, InvalidTabsException + from .fields import Date log = logging.getLogger(__name__) @@ -1043,7 +1046,7 @@ class CourseDescriptor(CourseFields, SequenceDescriptor, LicenseMixin): if not getattr(self, "tabs", []): CourseTabList.initialize_default(self) except InvalidTabsException as err: - raise type(err)('{msg} For course: {course_id}'.format(msg=text_type(err), course_id=unicode(self.id))) + raise type(err)('{msg} For course: {course_id}'.format(msg=text_type(err), course_id=six.text_type(self.id))) self.set_default_certificate_available_date() @@ -1331,7 +1334,7 @@ class CourseDescriptor(CourseFields, SequenceDescriptor, LicenseMixin): return True else: return False - elif isinstance(flag, basestring): + elif isinstance(flag, six.string_types): return flag.lower() in ['true', 'yes', 'y'] else: return bool(flag) @@ -1383,7 +1386,7 @@ class CourseDescriptor(CourseFields, SequenceDescriptor, LicenseMixin): ret = [ {"start": date_proxy.from_json(start), "end": date_proxy.from_json(end)} for start, end - in filter(None, blackout_dates) + in [blackout_date for blackout_date in blackout_dates if blackout_date] ] for blackout in ret: if not blackout["start"] or not blackout["end"]: @@ -1587,7 +1590,7 @@ class CourseSummary(object): except TypeError as e: log.warning( "Course '{course_id}' has an improperly formatted end date '{end_date}'. Error: '{err}'.".format( - course_id=unicode(self.id), end_date=self.end, err=e + course_id=six.text_type(self.id), end_date=self.end, err=e ) ) modified_end = self.end.replace(tzinfo=utc) diff --git a/common/lib/xmodule/xmodule/editing_module.py b/common/lib/xmodule/xmodule/editing_module.py index 9a0883672b..f6988731f0 100644 --- a/common/lib/xmodule/xmodule/editing_module.py +++ b/common/lib/xmodule/xmodule/editing_module.py @@ -1,5 +1,7 @@ """Descriptors for XBlocks/Xmodules, that provide editing of atrributes""" +from __future__ import absolute_import + import logging from pkg_resources import resource_string diff --git a/common/lib/xmodule/xmodule/edxnotes_utils.py b/common/lib/xmodule/xmodule/edxnotes_utils.py index 70324d6539..4bf0699283 100644 --- a/common/lib/xmodule/xmodule/edxnotes_utils.py +++ b/common/lib/xmodule/xmodule/edxnotes_utils.py @@ -1,6 +1,8 @@ """ Utilities related to edXNotes. """ +from __future__ import absolute_import + import sys diff --git a/common/lib/xmodule/xmodule/error_module.py b/common/lib/xmodule/xmodule/error_module.py index 73052918c1..f861d32419 100644 --- a/common/lib/xmodule/xmodule/error_module.py +++ b/common/lib/xmodule/xmodule/error_module.py @@ -3,11 +3,14 @@ Modules that get shown to the users when an error has occurred while loading or rendering other modules """ +from __future__ import absolute_import + import hashlib import json import logging import sys +import six from lxml import etree from xblock.field_data import DictFieldData from xblock.fields import Scope, ScopeIds, String @@ -111,7 +114,7 @@ class ErrorDescriptor(ErrorFields, XModuleDescriptor): # real metadata stays in the content, but add a display name field_data = DictFieldData({ - 'error_msg': unicode(error_msg), + 'error_msg': six.text_type(error_msg), 'contents': contents, 'location': location, 'category': 'error' diff --git a/common/lib/xmodule/xmodule/errortracker.py b/common/lib/xmodule/xmodule/errortracker.py index 282fb71e35..ac6c73e8ca 100644 --- a/common/lib/xmodule/xmodule/errortracker.py +++ b/common/lib/xmodule/xmodule/errortracker.py @@ -1,3 +1,5 @@ +from __future__ import absolute_import + import logging import sys import traceback diff --git a/common/lib/xmodule/xmodule/fields.py b/common/lib/xmodule/xmodule/fields.py index 634cf325d6..85ca94931f 100644 --- a/common/lib/xmodule/xmodule/fields.py +++ b/common/lib/xmodule/xmodule/fields.py @@ -1,9 +1,12 @@ +from __future__ import absolute_import + import datetime import logging import re import time import dateutil.parser +import six from pytz import UTC from six import text_type from xblock.fields import JSONField @@ -50,9 +53,9 @@ class Date(JSONField): return field elif field == "": return None - elif isinstance(field, basestring): + elif isinstance(field, six.string_types): return self._parse_date_wo_default_month_day(field) - elif isinstance(field, (int, long, float)): + elif isinstance(field, six.integer_types) or isinstance(field, float): return datetime.datetime.fromtimestamp(field / 1000, UTC) elif isinstance(field, time.struct_time): return datetime.datetime.fromtimestamp(time.mktime(field), UTC) @@ -115,7 +118,7 @@ class Timedelta(JSONField): return parts = parts.groupdict() time_params = {} - for (name, param) in parts.iteritems(): + for (name, param) in six.iteritems(parts): if param: time_params[name] = int(param) return datetime.timedelta(**time_params) @@ -201,7 +204,7 @@ class RelativeTime(JSONField): if isinstance(value, float): return datetime.timedelta(seconds=value) - if isinstance(value, basestring): + if isinstance(value, six.string_types): return self.isotime_to_timedelta(value) msg = "RelativeTime Field {0} has bad value '{1!r}'".format(self.name, value)