From 5289c7e828ddca1ac9a745bb1a84e0133d3ce77d Mon Sep 17 00:00:00 2001
From: Jeremy Bowman
Date: Wed, 31 Jan 2018 14:16:42 -0500
Subject: [PATCH] PLAT-1915 Stop using deprecated BaseException.message
---
.../management/commands/git_export.py | 2 +-
.../contentstore/push_notification.py | 3 ++-
.../tests/test_transcripts_utils.py | 5 ++--
cms/djangoapps/contentstore/views/assets.py | 3 ++-
.../contentstore/views/certificates.py | 5 ++--
cms/djangoapps/contentstore/views/course.py | 19 ++++++-------
cms/djangoapps/contentstore/views/item.py | 5 ++--
cms/djangoapps/contentstore/views/library.py | 5 ++--
.../contentstore/views/transcripts_ajax.py | 13 ++++-----
cms/djangoapps/maintenance/views.py | 5 ++--
.../models/settings/course_metadata.py | 5 ++--
.../tests/test_rerun_manager.py | 3 ++-
.../djangoapps/django_comment_common/tests.py | 3 ++-
common/djangoapps/enrollment/data.py | 9 ++++---
common/djangoapps/enrollment/views.py | 3 ++-
.../management/commands/change_enrollment.py | 3 ++-
.../management/commands/create_user.py | 4 ++-
.../student/management/commands/set_staff.py | 4 ++-
.../management/commands/set_superuser.py | 4 ++-
common/djangoapps/student/tests/test_email.py | 5 ++--
common/djangoapps/student/views/management.py | 2 +-
common/djangoapps/third_party_auth/lti.py | 3 ++-
common/djangoapps/third_party_auth/models.py | 3 ++-
common/djangoapps/third_party_auth/saml.py | 3 ++-
common/djangoapps/third_party_auth/tasks.py | 7 ++---
common/djangoapps/util/tests/test_file.py | 3 ++-
common/lib/capa/capa/inputtypes.py | 3 ++-
common/lib/capa/capa/responsetypes.py | 16 +++++------
common/lib/capa/capa/safe_exec/safe_exec.py | 3 ++-
.../capa/safe_exec/tests/test_safe_exec.py | 7 ++---
.../lib/capa/capa/tests/test_responsetypes.py | 3 ++-
common/lib/xmodule/xmodule/capa_base.py | 6 ++---
common/lib/xmodule/xmodule/course_module.py | 3 ++-
common/lib/xmodule/xmodule/exceptions.py | 3 ---
common/lib/xmodule/xmodule/fields.py | 3 ++-
common/lib/xmodule/xmodule/lti_2_util.py | 7 ++---
common/lib/xmodule/xmodule/lti_module.py | 4 +--
.../modulestore/draft_and_published.py | 3 ++-
.../xmodule/xmodule/tests/test_capa_module.py | 2 +-
.../lib/xmodule/xmodule/tests/test_graders.py | 3 ++-
.../xmodule/video_module/transcripts_utils.py | 7 ++---
.../xmodule/video_module/video_handlers.py | 4 +--
common/lib/xmodule/xmodule/x_module.py | 5 ++--
lms/djangoapps/commerce/api/v0/views.py | 3 ++-
lms/djangoapps/completion/api/v1/views.py | 5 ++--
lms/djangoapps/course_api/blocks/views.py | 3 ++-
.../courseware/courseware_access_exception.py | 3 +--
.../courseware/tests/test_courses.py | 3 ++-
lms/djangoapps/courseware/views/views.py | 2 +-
lms/djangoapps/dashboard/git_import.py | 2 +-
.../dashboard/tests/test_sysadmin.py | 2 +-
.../django_comment_client/middleware.py | 6 +++--
.../tests/test_middleware.py | 5 ++--
lms/djangoapps/edxnotes/views.py | 3 ++-
lms/djangoapps/grades/course_grade_factory.py | 3 ++-
.../grades/tests/test_course_grade_factory.py | 4 ++-
lms/djangoapps/instructor/views/api.py | 20 +++++++-------
lms/djangoapps/instructor_task/api_helper.py | 4 +--
lms/djangoapps/instructor_task/models.py | 2 +-
.../instructor_task/tasks_helper/grades.py | 5 ++--
lms/djangoapps/notification_prefs/views.py | 3 ++-
.../management/commands/retire_order.py | 3 ++-
.../shoppingcart/processors/CyberSource.py | 7 ++---
.../shoppingcart/processors/CyberSource2.py | 7 ++---
lms/djangoapps/support/tests/test_views.py | 2 +-
lms/djangoapps/support/views/enrollments.py | 5 ++--
lms/lib/comment_client/utils.py | 6 +----
.../commands/generate_course_blocks.py | 3 ++-
.../content/course_overviews/models.py | 3 ++-
.../commands/generate_course_structure.py | 2 +-
.../content/course_structures/tasks.py | 4 ++-
.../djangoapps/contentserver/middleware.py | 10 ++++---
.../course_groups/tests/test_cohorts.py | 4 ++-
openedx/core/djangoapps/credit/views.py | 3 ++-
.../djangoapps/profile_images/exceptions.py | 3 ++-
.../profile_images/tests/test_images.py | 7 ++---
.../core/djangoapps/profile_images/views.py | 3 ++-
.../djangoapps/safe_sessions/middleware.py | 3 ++-
.../core/djangoapps/user_api/accounts/api.py | 27 +++++++++++--------
.../user_api/accounts/serializers.py | 5 ++--
.../djangoapps/user_api/preferences/api.py | 4 ++-
.../djangoapps/user_api/tests/test_helpers.py | 4 ++-
.../user_api/validation/tests/test_views.py | 17 ++++++------
openedx/core/djangoapps/user_api/views.py | 3 ++-
openedx/core/lib/api/view_utils.py | 3 ++-
openedx/core/lib/command_utils.py | 3 ++-
scripts/xblock/xblock_counts.py | 5 ++--
87 files changed, 255 insertions(+), 180 deletions(-)
diff --git a/cms/djangoapps/contentstore/management/commands/git_export.py b/cms/djangoapps/contentstore/management/commands/git_export.py
index 1fe60068fb..27f646ea3a 100644
--- a/cms/djangoapps/contentstore/management/commands/git_export.py
+++ b/cms/djangoapps/contentstore/management/commands/git_export.py
@@ -61,4 +61,4 @@ class Command(BaseCommand):
options.get('rdir', None)
)
except git_export_utils.GitExportError as ex:
- raise CommandError(text_type(ex.message))
+ raise CommandError(text_type(ex))
diff --git a/cms/djangoapps/contentstore/push_notification.py b/cms/djangoapps/contentstore/push_notification.py
index ed038e07dd..e7ee741c44 100644
--- a/cms/djangoapps/contentstore/push_notification.py
+++ b/cms/djangoapps/contentstore/push_notification.py
@@ -6,6 +6,7 @@ from logging import exception as log_exception
from uuid import uuid4
from django.conf import settings
+from six import text_type
from contentstore.models import PushNotificationConfig
from contentstore.tasks import push_course_update_task
@@ -80,4 +81,4 @@ def send_push_course_update(course_key_string, course_subscription_id, course_di
)
except ParseError as error:
- log_exception(error.message)
+ log_exception(text_type(error))
diff --git a/cms/djangoapps/contentstore/tests/test_transcripts_utils.py b/cms/djangoapps/contentstore/tests/test_transcripts_utils.py
index 603cc23246..84e9a497c9 100644
--- a/cms/djangoapps/contentstore/tests/test_transcripts_utils.py
+++ b/cms/djangoapps/contentstore/tests/test_transcripts_utils.py
@@ -12,6 +12,7 @@ from django.test.utils import override_settings
from django.utils import translation
from mock import Mock, patch
from nose.plugins.skip import SkipTest
+from six import text_type
from contentstore.tests.utils import mock_requests_get
from xmodule.contentstore.content import StaticContent
@@ -425,7 +426,7 @@ class TestGenerateSubsFromSource(TestDownloadYoutubeSubs):
with self.assertRaises(transcripts_utils.TranscriptsGenerationException) as cm:
transcripts_utils.generate_subs_from_source(youtube_subs, 'BAD_FORMAT', srt_filedata, self.course)
- exception_message = cm.exception.message
+ exception_message = text_type(cm.exception)
self.assertEqual(exception_message, "We support only SubRip (*.srt) transcripts format.")
def test_fail_bad_subs_filedata(self):
@@ -439,7 +440,7 @@ class TestGenerateSubsFromSource(TestDownloadYoutubeSubs):
with self.assertRaises(transcripts_utils.TranscriptsGenerationException) as cm:
transcripts_utils.generate_subs_from_source(youtube_subs, 'srt', srt_filedata, self.course)
- exception_message = cm.exception.message
+ exception_message = text_type(cm.exception)
self.assertEqual(exception_message, "Something wrong with SubRip transcripts file during parsing.")
diff --git a/cms/djangoapps/contentstore/views/assets.py b/cms/djangoapps/contentstore/views/assets.py
index 472d729c9b..b24b74b9a7 100644
--- a/cms/djangoapps/contentstore/views/assets.py
+++ b/cms/djangoapps/contentstore/views/assets.py
@@ -13,6 +13,7 @@ from django.views.decorators.csrf import ensure_csrf_cookie
from django.views.decorators.http import require_POST, require_http_methods
from opaque_keys.edx.keys import AssetKey, CourseKey
from pymongo import ASCENDING, DESCENDING
+from six import text_type
from xmodule.contentstore.content import StaticContent
from xmodule.contentstore.django import contentstore
from xmodule.exceptions import NotFoundError
@@ -402,7 +403,7 @@ def _upload_asset(request, course_key):
try:
content = update_course_run_asset(course_key, upload_file)
except AssetSizeTooLargeException as exception:
- return JsonResponse({'error': exception.message}, status=413)
+ return JsonResponse({'error': text_type(exception)}, status=413)
# readback the saved content - we need the database timestamp
readback = contentstore().find(content.location)
diff --git a/cms/djangoapps/contentstore/views/certificates.py b/cms/djangoapps/contentstore/views/certificates.py
index f3354ac18b..fd2e17d756 100644
--- a/cms/djangoapps/contentstore/views/certificates.py
+++ b/cms/djangoapps/contentstore/views/certificates.py
@@ -33,6 +33,7 @@ from django.views.decorators.csrf import ensure_csrf_cookie
from django.views.decorators.http import require_http_methods
from opaque_keys import InvalidKeyError
from opaque_keys.edx.keys import AssetKey, CourseKey
+from six import text_type
from contentstore.utils import get_lms_link_for_certificate_web_view, reverse_course_url
from contentstore.views.assets import delete_asset
@@ -423,7 +424,7 @@ def certificates_list_handler(request, course_key_string):
try:
new_certificate = CertificateManager.deserialize_certificate(course, request.body)
except CertificateValidationError as err:
- return JsonResponse({"error": err.message}, status=400)
+ return JsonResponse({"error": text_type(err)}, status=400)
if course.certificates.get('certificates') is None:
course.certificates['certificates'] = []
course.certificates['certificates'].append(new_certificate.certificate_data)
@@ -480,7 +481,7 @@ def certificates_detail_handler(request, course_key_string, certificate_id):
try:
new_certificate = CertificateManager.deserialize_certificate(course, request.body)
except CertificateValidationError as err:
- return JsonResponse({"error": err.message}, status=400)
+ return JsonResponse({"error": text_type(err)}, status=400)
serialized_certificate = CertificateManager.serialize_certificate(new_certificate)
cert_event_type = 'created'
diff --git a/cms/djangoapps/contentstore/views/course.py b/cms/djangoapps/contentstore/views/course.py
index 16f13b8a41..b747a8bdc9 100644
--- a/cms/djangoapps/contentstore/views/course.py
+++ b/cms/djangoapps/contentstore/views/course.py
@@ -24,6 +24,7 @@ from opaque_keys.edx.keys import CourseKey
from opaque_keys.edx.locations import Location
from openedx.core.djangoapps.content.course_overviews.models import CourseOverview
from openedx.core.djangoapps.waffle_utils import WaffleSwitchNamespace
+from six import text_type
from contentstore.course_group_config import (
COHORT_SCHEME,
@@ -812,7 +813,7 @@ def _create_or_rerun_course(request):
'course_key': unicode(new_course.id),
})
except ValidationError as ex:
- return JsonResponse({'error': ex.message}, status=400)
+ return JsonResponse({'error': text_type(ex)}, status=400)
except DuplicateCourseError:
return JsonResponse({
'ErrMsg': _(
@@ -829,7 +830,7 @@ def _create_or_rerun_course(request):
})
except InvalidKeyError as error:
return JsonResponse({
- "ErrMsg": _("Unable to create course '{name}'.\n\n{err}").format(name=display_name, err=error.message)}
+ "ErrMsg": _("Unable to create course '{name}'.\n\n{err}").format(name=display_name, err=text_type(error))}
)
@@ -1297,7 +1298,7 @@ def advanced_settings_handler(request, course_key_string):
# update the course tabs if required by any setting changes
_refresh_course_tabs(request, course_module)
except InvalidTabsException as err:
- log.exception(err.message)
+ log.exception(text_type(err))
response_message = [
{
'message': _('An error occurred while trying to save your tabs'),
@@ -1316,7 +1317,7 @@ def advanced_settings_handler(request, course_key_string):
# Handle all errors that validation doesn't catch
except (TypeError, ValueError, InvalidTabsException) as err:
return HttpResponseBadRequest(
- django.utils.html.escape(err.message),
+ django.utils.html.escape(text_type(err)),
content_type="text/plain"
)
@@ -1418,7 +1419,7 @@ def textbooks_list_handler(request, course_key_string):
try:
textbooks = validate_textbooks_json(request.body)
except TextbookValidationError as err:
- return JsonResponse({"error": err.message}, status=400)
+ return JsonResponse({"error": text_type(err)}, status=400)
tids = set(t["id"] for t in textbooks if "id" in t)
for textbook in textbooks:
@@ -1437,7 +1438,7 @@ def textbooks_list_handler(request, course_key_string):
try:
textbook = validate_textbook_json(request.body)
except TextbookValidationError as err:
- return JsonResponse({"error": err.message}, status=400)
+ return JsonResponse({"error": text_type(err)}, status=400)
if not textbook.get("id"):
tids = set(t["id"] for t in course.pdf_textbooks if "id" in t)
textbook["id"] = assign_textbook_id(textbook, tids)
@@ -1491,7 +1492,7 @@ def textbooks_detail_handler(request, course_key_string, textbook_id):
try:
new_textbook = validate_textbook_json(request.body)
except TextbookValidationError as err:
- return JsonResponse({"error": err.message}, status=400)
+ return JsonResponse({"error": text_type(err)}, status=400)
new_textbook["id"] = textbook_id
if textbook:
i = course_module.pdf_textbooks.index(textbook)
@@ -1621,7 +1622,7 @@ def group_configurations_list_handler(request, course_key_string):
try:
new_configuration = GroupConfiguration(request.body, course).get_user_partition()
except GroupConfigurationsValidationError as err:
- return JsonResponse({"error": err.message}, status=400)
+ return JsonResponse({"error": text_type(err)}, status=400)
course.user_partitions.append(new_configuration)
response = JsonResponse(new_configuration.to_json(), status=201)
@@ -1664,7 +1665,7 @@ def group_configurations_detail_handler(request, course_key_string, group_config
try:
new_configuration = GroupConfiguration(request.body, course, group_configuration_id).get_user_partition()
except GroupConfigurationsValidationError as err:
- return JsonResponse({"error": err.message}, status=400)
+ return JsonResponse({"error": text_type(err)}, status=400)
if configuration:
index = course.user_partitions.index(configuration)
diff --git a/cms/djangoapps/contentstore/views/item.py b/cms/djangoapps/contentstore/views/item.py
index ff972465fc..1f22a5b77b 100644
--- a/cms/djangoapps/contentstore/views/item.py
+++ b/cms/djangoapps/contentstore/views/item.py
@@ -18,6 +18,7 @@ from django.views.decorators.http import require_http_methods
from opaque_keys.edx.keys import CourseKey
from opaque_keys.edx.locator import LibraryUsageLocator
from pytz import UTC
+from six import text_type
from web_fragments.fragment import Fragment
from xblock.core import XBlock
from xblock.fields import Scope
@@ -574,8 +575,8 @@ def _save_xblock(user, xblock, data=None, children_strings=None, metadata=None,
value = field.from_json(value)
except ValueError as verr:
reason = _("Invalid data")
- if verr.message:
- reason = _("Invalid data ({details})").format(details=verr.message)
+ if text_type(verr):
+ reason = _("Invalid data ({details})").format(details=text_type(verr))
return JsonResponse({"error": reason}, 400)
field.write_to(xblock, value)
diff --git a/cms/djangoapps/contentstore/views/library.py b/cms/djangoapps/contentstore/views/library.py
index 1f0d497fa9..63080edab5 100644
--- a/cms/djangoapps/contentstore/views/library.py
+++ b/cms/djangoapps/contentstore/views/library.py
@@ -17,6 +17,7 @@ from django.views.decorators.http import require_http_methods
from opaque_keys import InvalidKeyError
from opaque_keys.edx.keys import CourseKey
from opaque_keys.edx.locator import LibraryLocator, LibraryUsageLocator
+from six import text_type
from contentstore.utils import add_instructor, reverse_library_url
from contentstore.views.item import create_xblock_info
@@ -164,12 +165,12 @@ def _create_library(request):
except KeyError as error:
log.exception("Unable to create library - missing required JSON key.")
return JsonResponseBadRequest({
- "ErrMsg": _("Unable to create library - missing required field '{field}'").format(field=error.message)
+ "ErrMsg": _("Unable to create library - missing required field '{field}'").format(field=text_type(error))
})
except InvalidKeyError as error:
log.exception("Unable to create library - invalid key.")
return JsonResponseBadRequest({
- "ErrMsg": _("Unable to create library '{name}'.\n\n{err}").format(name=display_name, err=error.message)
+ "ErrMsg": _("Unable to create library '{name}'.\n\n{err}").format(name=display_name, err=text_type(error))
})
except DuplicateCourseError:
log.exception("Unable to create library - one already exists with the same key.")
diff --git a/cms/djangoapps/contentstore/views/transcripts_ajax.py b/cms/djangoapps/contentstore/views/transcripts_ajax.py
index ff238aa18e..247f7e798c 100644
--- a/cms/djangoapps/contentstore/views/transcripts_ajax.py
+++ b/cms/djangoapps/contentstore/views/transcripts_ajax.py
@@ -18,6 +18,7 @@ from django.http import Http404, HttpResponse
from django.utils.translation import ugettext as _
from opaque_keys import InvalidKeyError
from opaque_keys.edx.keys import UsageKey
+from six import text_type
from student.auth import has_course_author_access
from util.json_request import JsonResponse
@@ -133,7 +134,7 @@ def upload_transcripts(request):
response['subs'] = item.sub
response['status'] = 'Success'
except Exception as ex:
- return error_response(response, ex.message)
+ return error_response(response, text_type(ex))
else:
return error_response(response, 'Empty video sources.')
@@ -242,7 +243,7 @@ def check_transcripts(request):
try:
__, videos, item = _validate_transcripts_data(request)
except TranscriptsRequestValidationException as e:
- return error_response(transcripts_presence, e.message)
+ return error_response(transcripts_presence, text_type(e))
transcripts_presence['status'] = 'Success'
@@ -400,7 +401,7 @@ def choose_transcripts(request):
try:
data, videos, item = _validate_transcripts_data(request)
except TranscriptsRequestValidationException as e:
- return error_response(response, e.message)
+ return error_response(response, text_type(e))
html5_id = data.get('html5_id') # html5_id chosen by user
@@ -433,7 +434,7 @@ def replace_transcripts(request):
try:
__, videos, item = _validate_transcripts_data(request)
except TranscriptsRequestValidationException as e:
- return error_response(response, e.message)
+ return error_response(response, text_type(e))
youtube_id = videos['youtube']
if not youtube_id:
@@ -442,7 +443,7 @@ def replace_transcripts(request):
try:
download_youtube_subs(youtube_id, item, settings)
except GetTranscriptsFromYouTubeException as e:
- return error_response(response, e.message)
+ return error_response(response, text_type(e))
item.sub = youtube_id
item.save_with_metadata(request.user)
@@ -504,7 +505,7 @@ def rename_transcripts(request):
try:
__, videos, item = _validate_transcripts_data(request)
except TranscriptsRequestValidationException as e:
- return error_response(response, e.message)
+ return error_response(response, text_type(e))
old_name = item.sub
diff --git a/cms/djangoapps/maintenance/views.py b/cms/djangoapps/maintenance/views.py
index fe6555008e..4e38dec9c1 100644
--- a/cms/djangoapps/maintenance/views.py
+++ b/cms/djangoapps/maintenance/views.py
@@ -10,6 +10,7 @@ from django.utils.translation import ugettext as _
from django.views.generic import View
from opaque_keys import InvalidKeyError
from opaque_keys.edx.keys import CourseKey
+from six import text_type
from contentstore.management.commands.utils import get_course_versions
from edxmako.shortcuts import render_to_response
@@ -169,10 +170,10 @@ class ForcePublishCourseView(MaintenanceBaseView):
self.context['msg'] = COURSE_KEY_ERROR_MESSAGES['invalid_course_key']
except ItemNotFoundError as exc:
self.context['error'] = True
- self.context['msg'] = exc.message
+ self.context['msg'] = text_type(exc)
except ValidationError as exc:
self.context['error'] = True
- self.context['msg'] = exc.message
+ self.context['msg'] = text_type(exc)
if self.context['error']:
return self.render_response()
diff --git a/cms/djangoapps/models/settings/course_metadata.py b/cms/djangoapps/models/settings/course_metadata.py
index a437539e6e..5aaf9c5f67 100644
--- a/cms/djangoapps/models/settings/course_metadata.py
+++ b/cms/djangoapps/models/settings/course_metadata.py
@@ -3,6 +3,7 @@ Django module for Course Metadata class -- manages advanced settings and related
"""
from django.conf import settings
from django.utils.translation import ugettext as _
+from six import text_type
from xblock.fields import Scope
from xblock_django.models import XBlockStudioConfigurationFlag
@@ -176,7 +177,7 @@ class CourseMetadata(object):
key_values[key] = descriptor.fields[key].from_json(val)
except (TypeError, ValueError) as err:
raise ValueError(_("Incorrect format for field '{name}'. {detailed_message}").format(
- name=model['display_name'], detailed_message=err.message))
+ name=model['display_name'], detailed_message=text_type(err)))
return cls.update_from_dict(key_values, descriptor, user)
@@ -211,7 +212,7 @@ class CourseMetadata(object):
key_values[key] = descriptor.fields[key].from_json(val)
except (TypeError, ValueError) as err:
did_validate = False
- errors.append({'message': err.message, 'model': model})
+ errors.append({'message': text_type(err), 'model': model})
# If did validate, go ahead and update the metadata
if did_validate:
diff --git a/common/djangoapps/course_action_state/tests/test_rerun_manager.py b/common/djangoapps/course_action_state/tests/test_rerun_manager.py
index 3f5ab762f8..d5b4a22c5c 100644
--- a/common/djangoapps/course_action_state/tests/test_rerun_manager.py
+++ b/common/djangoapps/course_action_state/tests/test_rerun_manager.py
@@ -4,6 +4,7 @@ Tests specific to the CourseRerunState Model and Manager.
from django.test import TestCase
from opaque_keys.edx.locations import CourseLocator
+from six import text_type
from course_action_state.managers import CourseRerunUIStateManager
from course_action_state.models import CourseRerunState
@@ -103,7 +104,7 @@ class TestCourseRerunStateManager(TestCase):
)
self.expected_rerun_state.pop('message')
rerun = self.verify_rerun_state()
- self.assertIn(exception.message, rerun.message)
+ self.assertIn(text_type(exception), rerun.message)
# dismiss ui and verify
self.dismiss_ui_and_verify(rerun)
diff --git a/common/djangoapps/django_comment_common/tests.py b/common/djangoapps/django_comment_common/tests.py
index c543ec6014..db5a9fc656 100644
--- a/common/djangoapps/django_comment_common/tests.py
+++ b/common/djangoapps/django_comment_common/tests.py
@@ -1,6 +1,7 @@
from django.test import TestCase
from nose.plugins.attrib import attr
from opaque_keys.edx.locator import CourseLocator
+from six import text_type
from django_comment_common.models import Role
from models import CourseDiscussionSettings
@@ -131,6 +132,6 @@ class CourseDiscussionSettingsTest(ModuleStoreTestCase):
set_course_discussion_settings(self.course.id, **{field['name']: invalid_value})
self.assertEqual(
- value_error.exception.message,
+ text_type(value_error.exception),
exception_msg_template.format(field['name'], field['type'].__name__)
)
diff --git a/common/djangoapps/enrollment/data.py b/common/djangoapps/enrollment/data.py
index 004f339218..444db564b4 100644
--- a/common/djangoapps/enrollment/data.py
+++ b/common/djangoapps/enrollment/data.py
@@ -6,6 +6,7 @@ import logging
from django.contrib.auth.models import User
from opaque_keys.edx.keys import CourseKey
+from six import text_type
from enrollment.errors import (
CourseEnrollmentClosedError,
@@ -125,14 +126,14 @@ def create_course_enrollment(username, course_id, mode, is_active):
enrollment = CourseEnrollment.enroll(user, course_key, check_access=True)
return _update_enrollment(enrollment, is_active=is_active, mode=mode)
except NonExistentCourseError as err:
- raise CourseNotFoundError(err.message)
+ raise CourseNotFoundError(text_type(err))
except EnrollmentClosedError as err:
- raise CourseEnrollmentClosedError(err.message)
+ raise CourseEnrollmentClosedError(text_type(err))
except CourseFullError as err:
- raise CourseEnrollmentFullError(err.message)
+ raise CourseEnrollmentFullError(text_type(err))
except AlreadyEnrolledError as err:
enrollment = get_course_enrollment(username, course_id)
- raise CourseEnrollmentExistsError(err.message, enrollment)
+ raise CourseEnrollmentExistsError(text_type(err), enrollment)
def update_course_enrollment(username, course_id, mode=None, is_active=None):
diff --git a/common/djangoapps/enrollment/views.py b/common/djangoapps/enrollment/views.py
index 3dfdbd7cc3..2d3cd93156 100644
--- a/common/djangoapps/enrollment/views.py
+++ b/common/djangoapps/enrollment/views.py
@@ -14,6 +14,7 @@ from rest_framework import status
from rest_framework.response import Response
from rest_framework.throttling import UserRateThrottle
from rest_framework.views import APIView
+from six import text_type
from course_modes.models import CourseMode
from enrollment import api
@@ -604,7 +605,7 @@ class EnrollmentListView(APIView, ApiKeyPermissionMixIn):
except EnterpriseApiException as error:
log.exception("An unexpected error occurred while creating the new EnterpriseCourseEnrollment "
"for user [%s] in course run [%s]", username, course_id)
- raise CourseEnrollmentError(error.message)
+ raise CourseEnrollmentError(text_type(error))
kwargs = {
'username': username,
'course_id': unicode(course_id),
diff --git a/common/djangoapps/student/management/commands/change_enrollment.py b/common/djangoapps/student/management/commands/change_enrollment.py
index efd0e51b6c..e646cf1983 100644
--- a/common/djangoapps/student/management/commands/change_enrollment.py
+++ b/common/djangoapps/student/management/commands/change_enrollment.py
@@ -6,6 +6,7 @@ from django.core.management.base import BaseCommand, CommandError
from django.db import transaction
from opaque_keys import InvalidKeyError
from opaque_keys.edx.keys import CourseKey
+from six import text_type
from student.models import CourseEnrollment, User
@@ -135,4 +136,4 @@ class Command(BaseCommand):
if len(error_users) > 0:
logger.info('The following %i user(s) not saved:', len(error_users))
for user, error in error_users:
- logger.info('user: [%s] reason: [%s] %s', user, type(error).__name__, error.message)
+ logger.info('user: [%s] reason: [%s] %s', user, type(error).__name__, text_type(error))
diff --git a/common/djangoapps/student/management/commands/create_user.py b/common/djangoapps/student/management/commands/create_user.py
index 51ecb12043..4bcfe7e4b4 100644
--- a/common/djangoapps/student/management/commands/create_user.py
+++ b/common/djangoapps/student/management/commands/create_user.py
@@ -5,6 +5,8 @@ from django.contrib.auth.models import User
from django.utils import translation
from opaque_keys.edx.keys import CourseKey
+from six import text_type
+
from student.forms import AccountCreationForm
from student.models import CourseEnrollment, create_comments_service_user
from student.views import _do_create_account, AccountValidationError
@@ -81,7 +83,7 @@ class Command(TrackedCommand):
reg.save()
create_comments_service_user(user)
except AccountValidationError as e:
- print(e.message)
+ print(text_type(e))
user = User.objects.get(email=options['email'])
if course:
diff --git a/common/djangoapps/student/management/commands/set_staff.py b/common/djangoapps/student/management/commands/set_staff.py
index cf8134c36a..011d3b3f25 100644
--- a/common/djangoapps/student/management/commands/set_staff.py
+++ b/common/djangoapps/student/management/commands/set_staff.py
@@ -3,6 +3,7 @@ import re
from django.contrib.auth.models import User
from django.core.management.base import BaseCommand
+from six import text_type
class Command(BaseCommand):
@@ -40,6 +41,7 @@ class Command(BaseCommand):
print('Modified {} sucessfully.'.format(user))
except Exception as err: # pylint: disable=broad-except
- print("Error modifying user with identifier {}: {}: {}".format(user, type(err).__name__, err.message))
+ print("Error modifying user with identifier {}: {}: {}".format(user, type(err).__name__,
+ text_type(err)))
print('Complete!')
diff --git a/common/djangoapps/student/management/commands/set_superuser.py b/common/djangoapps/student/management/commands/set_superuser.py
index ee65cbd09f..1795d773f3 100644
--- a/common/djangoapps/student/management/commands/set_superuser.py
+++ b/common/djangoapps/student/management/commands/set_superuser.py
@@ -3,6 +3,7 @@ from __future__ import print_function
from django.contrib.auth.models import User
from django.core.management.base import BaseCommand
+from six import text_type
class Command(BaseCommand):
@@ -41,6 +42,7 @@ class Command(BaseCommand):
print('Modified {} sucessfully.'.format(user))
except Exception as err: # pylint: disable=broad-except
- print("Error modifying user with identifier {}: {}: {}".format(user, type(err).__name__, err.message))
+ print("Error modifying user with identifier {}: {}: {}".format(user, type(err).__name__,
+ text_type(err)))
print('Complete!')
diff --git a/common/djangoapps/student/tests/test_email.py b/common/djangoapps/student/tests/test_email.py
index 67478c0eea..d70ddfd2b9 100644
--- a/common/djangoapps/student/tests/test_email.py
+++ b/common/djangoapps/student/tests/test_email.py
@@ -12,6 +12,7 @@ from django.http import HttpResponse
from django.test import override_settings, TestCase, TransactionTestCase
from django.test.client import RequestFactory
from mock import Mock, patch
+from six import text_type
from edxmako.shortcuts import render_to_string
from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers
@@ -266,7 +267,7 @@ class EmailChangeRequestTests(EventTestMixin, CacheIsolationTestCase):
try:
validate_new_email(self.request.user, email)
except ValueError as err:
- return err.message
+ return text_type(err)
def do_email_change(self, user, email, activation_key=None):
"""
@@ -275,7 +276,7 @@ class EmailChangeRequestTests(EventTestMixin, CacheIsolationTestCase):
try:
do_email_change_request(user, email, activation_key)
except ValueError as err:
- return err.message
+ return text_type(err)
def assertFailedRequest(self, response_data, expected_error):
"""
diff --git a/common/djangoapps/student/views/management.py b/common/djangoapps/student/views/management.py
index 28227b8e03..fa82e83d68 100644
--- a/common/djangoapps/student/views/management.py
+++ b/common/djangoapps/student/views/management.py
@@ -958,7 +958,7 @@ def create_account(request, post_override=None):
try:
user = create_account_with_params(request, post_override or request.POST)
except AccountValidationError as exc:
- return JsonResponse({'success': False, 'value': exc.message, 'field': exc.field}, status=400)
+ return JsonResponse({'success': False, 'value': text_type(exc), 'field': exc.field}, status=400)
except ValidationError as exc:
field, error_list = next(iteritems(exc.message_dict))
return JsonResponse(
diff --git a/common/djangoapps/third_party_auth/lti.py b/common/djangoapps/third_party_auth/lti.py
index 523a01e9fb..c383506712 100644
--- a/common/djangoapps/third_party_auth/lti.py
+++ b/common/djangoapps/third_party_auth/lti.py
@@ -14,6 +14,7 @@ from oauthlib.oauth1.rfc5849.signature import (
normalize_parameters,
sign_hmac_sha1
)
+from six import text_type
from social_core.backends.base import BaseAuth
from social_core.exceptions import AuthFailed
from social_core.utils import sanitize_redirect
@@ -185,7 +186,7 @@ class LTIAuthBackend(BaseAuth):
if valid:
return data
except AttributeError as error:
- log.error("'{}' not found.".format(error.message))
+ log.error("'{}' not found.".format(text_type(error)))
return None
@classmethod
diff --git a/common/djangoapps/third_party_auth/models.py b/common/djangoapps/third_party_auth/models.py
index e43c5b2e4f..b2947d4a75 100644
--- a/common/djangoapps/third_party_auth/models.py
+++ b/common/djangoapps/third_party_auth/models.py
@@ -18,6 +18,7 @@ from django.utils import timezone
from django.utils.translation import ugettext_lazy as _
from provider.oauth2.models import Client
from provider.utils import long_token
+from six import text_type
from social_core.backends.base import BaseAuth
from social_core.backends.oauth import OAuthAuth
from social_core.backends.saml import SAMLAuth
@@ -60,7 +61,7 @@ def clean_json(value, of_type):
try:
value_python = json.loads(value)
except ValueError as err:
- raise ValidationError("Invalid JSON: {}".format(err.message))
+ raise ValidationError("Invalid JSON: {}".format(text_type(err)))
if not isinstance(value_python, of_type):
raise ValidationError("Expected a JSON {}".format(of_type))
return json.dumps(value_python, indent=4)
diff --git a/common/djangoapps/third_party_auth/saml.py b/common/djangoapps/third_party_auth/saml.py
index 71a4bc7a2b..35a786e6c5 100644
--- a/common/djangoapps/third_party_auth/saml.py
+++ b/common/djangoapps/third_party_auth/saml.py
@@ -10,6 +10,7 @@ from django.http import Http404
from django.utils.functional import cached_property
from django_countries import countries
from onelogin.saml2.settings import OneLogin_Saml2_Settings
+from six import text_type
from social_core.backends.saml import OID_EDU_PERSON_ENTITLEMENT, SAMLAuth, SAMLIdentityProvider
from social_core.exceptions import AuthForbidden
@@ -337,7 +338,7 @@ class SapSuccessFactorsIdentityProvider(EdXSAMLIdentityProvider):
url=transaction_data['endpoint_url'],
company_id=transaction_data['company_id'],
user_id=transaction_data['user_id'],
- err_msg=err.message,
+ err_msg=text_type(err),
sys_msg=sys_msg,
headers=headers,
token_data=token_data,
diff --git a/common/djangoapps/third_party_auth/tasks.py b/common/djangoapps/third_party_auth/tasks.py
index c7a1b8acde..be62d13892 100644
--- a/common/djangoapps/third_party_auth/tasks.py
+++ b/common/djangoapps/third_party_auth/tasks.py
@@ -14,6 +14,7 @@ from django.utils.timezone import now
from lxml import etree
from onelogin.saml2.utils import OneLogin_Saml2_Utils
from requests import exceptions
+from six import text_type
from third_party_auth.models import SAMLConfiguration, SAMLProviderConfig, SAMLProviderData
@@ -105,11 +106,11 @@ def fetch_saml_metadata():
# RequestException is the base exception for any request related error that "requests" lib raises.
# MetadataParseError is raised if there is error in the fetched meta data (e.g. missing @entityID etc.)
- log.exception(error.message)
+ log.exception(text_type(error))
failure_messages.append(
"{error_type}: {error_message}\nMetadata Source: {url}\nEntity IDs: \n{entity_ids}.".format(
error_type=type(error).__name__,
- error_message=error.message,
+ error_message=text_type(error),
url=url,
entity_ids="\n".join(
["\t{}: {}".format(count, item) for count, item in enumerate(entity_ids, start=1)],
@@ -117,7 +118,7 @@ def fetch_saml_metadata():
)
)
except etree.XMLSyntaxError as error:
- log.exception(error.message)
+ log.exception(text_type(error))
failure_messages.append(
"XMLSyntaxError: {error_message}\nMetadata Source: {url}\nEntity IDs: \n{entity_ids}.".format(
error_message=str(error.error_log),
diff --git a/common/djangoapps/util/tests/test_file.py b/common/djangoapps/util/tests/test_file.py
index 1ae7cabc29..44044d819e 100644
--- a/common/djangoapps/util/tests/test_file.py
+++ b/common/djangoapps/util/tests/test_file.py
@@ -15,6 +15,7 @@ from pytz import UTC
from mock import Mock, patch
from opaque_keys.edx.keys import CourseKey
from opaque_keys.edx.locations import CourseLocator
+from six import text_type
import util.file
from util.file import (
@@ -95,7 +96,7 @@ class StoreUploadedFileTestCase(TestCase):
"""
Helper method to verify exception text.
"""
- self.assertEqual(expected_message, error.exception.message)
+ self.assertEqual(expected_message, text_type(error.exception))
def test_error_conditions(self):
"""
diff --git a/common/lib/capa/capa/inputtypes.py b/common/lib/capa/capa/inputtypes.py
index 29cc634b13..2b9cf89747 100644
--- a/common/lib/capa/capa/inputtypes.py
+++ b/common/lib/capa/capa/inputtypes.py
@@ -50,6 +50,7 @@ import bleach
import html5lib
import pyparsing
from lxml import etree
+from six import text_type
import xqueue_interface
from calc.preview import latex_preview
@@ -251,7 +252,7 @@ class InputTypeBase(object):
except Exception as err:
# Something went wrong: add xml to message, but keep the traceback
msg = u"Error in xml '{x}': {err} ".format(
- x=etree.tostring(xml), err=err.message)
+ x=etree.tostring(xml), err=text_type(err))
raise Exception, msg, sys.exc_info()[2]
@classmethod
diff --git a/common/lib/capa/capa/responsetypes.py b/common/lib/capa/capa/responsetypes.py
index 1873b32345..993b8dc0f2 100644
--- a/common/lib/capa/capa/responsetypes.py
+++ b/common/lib/capa/capa/responsetypes.py
@@ -1601,14 +1601,14 @@ class NumericalResponse(LoncapaResponse):
except UndefinedVariable as undef_var:
raise StudentInputError(
_(u"You may not use variables ({bad_variables}) in numerical problems.").format(
- bad_variables=undef_var.message,
+ bad_variables=text_type(undef_var),
)
)
except ValueError as val_err:
- if 'factorial' in val_err.message:
+ if 'factorial' in text_type(val_err):
# This is thrown when fact() or factorial() is used in an answer
# that evaluates on negative and/or non-integer inputs
- # ve.message will be: `factorial() only accepts integral values` or
+ # text_type(ve) will be: `factorial() only accepts integral values` or
# `factorial() not defined for negative values`
raise StudentInputError(
_("Factorial function evaluated outside its domain:"
@@ -2038,7 +2038,7 @@ class StringResponse(LoncapaResponse):
except Exception as err:
msg = u'[courseware.capa.responsetypes.stringresponse] {error}: {message}'.format(
error=_('error'),
- message=err.message
+ message=text_type(err)
)
log.error(msg, exc_info=True)
raise ResponseError(msg)
@@ -2511,7 +2511,7 @@ class CustomResponse(LoncapaResponse):
# Notify student with a student input error
_, _, traceback_obj = sys.exc_info()
- raise ResponseError(err.message, traceback_obj)
+ raise ResponseError(text_type(err), traceback_obj)
#-----------------------------------------------------------------------------
@@ -3106,13 +3106,13 @@ class FormulaResponse(LoncapaResponse):
cgi.escape(answer)
)
raise StudentInputError(
- _("Invalid input: {bad_input} not permitted in answer.").format(bad_input=err.message)
+ _("Invalid input: {bad_input} not permitted in answer.").format(bad_input=text_type(err))
)
except ValueError as err:
- if 'factorial' in err.message:
+ if 'factorial' in text_type(err):
# This is thrown when fact() or factorial() is used in a formularesponse answer
# that tests on negative and/or non-integer inputs
- # err.message will be: `factorial() only accepts integral values` or
+ # text_type(err) will be: `factorial() only accepts integral values` or
# `factorial() not defined for negative values`
log.debug(
('formularesponse: factorial function used in response '
diff --git a/common/lib/capa/capa/safe_exec/safe_exec.py b/common/lib/capa/capa/safe_exec/safe_exec.py
index cf7863b058..25cd603e35 100644
--- a/common/lib/capa/capa/safe_exec/safe_exec.py
+++ b/common/lib/capa/capa/safe_exec/safe_exec.py
@@ -5,6 +5,7 @@ from codejail.safe_exec import not_safe_exec as codejail_not_safe_exec
from codejail.safe_exec import json_safe, SafeExecException
from . import lazymod
from dogapi import dog_stats_api
+from six import text_type
import hashlib
@@ -143,7 +144,7 @@ def safe_exec(
python_path=python_path, extra_files=extra_files, slug=slug,
)
except SafeExecException as e:
- emsg = e.message
+ emsg = text_type(e)
else:
emsg = None
diff --git a/common/lib/capa/capa/safe_exec/tests/test_safe_exec.py b/common/lib/capa/capa/safe_exec/tests/test_safe_exec.py
index 068fcea908..4011fee6bf 100644
--- a/common/lib/capa/capa/safe_exec/tests/test_safe_exec.py
+++ b/common/lib/capa/capa/safe_exec/tests/test_safe_exec.py
@@ -8,6 +8,7 @@ import textwrap
import unittest
from nose.plugins.skip import SkipTest
+from six import text_type
from capa.safe_exec import safe_exec, update_hash
from codejail.safe_exec import SafeExecException
@@ -69,7 +70,7 @@ class TestSafeExec(unittest.TestCase):
g = {}
with self.assertRaises(SafeExecException) as cm:
safe_exec("1/0", g)
- self.assertIn("ZeroDivisionError", cm.exception.message)
+ self.assertIn("ZeroDivisionError", text_type(cm.exception))
class TestSafeOrNot(unittest.TestCase):
@@ -81,8 +82,8 @@ class TestSafeOrNot(unittest.TestCase):
g = {}
with self.assertRaises(SafeExecException) as cm:
safe_exec("import os; files = os.listdir('/')", g)
- self.assertIn("OSError", cm.exception.message)
- self.assertIn("Permission denied", cm.exception.message)
+ assert "OSError" in text_type(cm.exception)
+ assert "Permission denied" in text_type(cm.exception)
def test_can_do_something_forbidden_if_run_unsafely(self):
g = {}
diff --git a/common/lib/capa/capa/tests/test_responsetypes.py b/common/lib/capa/capa/tests/test_responsetypes.py
index 02f87c7d9c..676746a56f 100644
--- a/common/lib/capa/capa/tests/test_responsetypes.py
+++ b/common/lib/capa/capa/tests/test_responsetypes.py
@@ -15,6 +15,7 @@ import zipfile
import mock
from pytz import UTC
+from six import text_type
import requests
from capa.tests.helpers import new_loncapa_problem, test_capa_system, load_fixture
@@ -798,7 +799,7 @@ class StringResponseTest(ResponseTest): # pylint: disable=missing-docstring
problem = self.build_problem(answer="a2", case_sensitive=False, regexp=True, additional_answers=['?\\d?'])
with self.assertRaises(Exception) as cm:
self.assert_grade(problem, "a3", "correct")
- exception_message = cm.exception.message
+ exception_message = text_type(cm.exception)
self.assertIn("nothing to repeat", exception_message)
def test_hints(self):
diff --git a/common/lib/xmodule/xmodule/capa_base.py b/common/lib/xmodule/xmodule/capa_base.py
index 82b2858335..8729ac038a 100644
--- a/common/lib/xmodule/xmodule/capa_base.py
+++ b/common/lib/xmodule/xmodule/capa_base.py
@@ -544,7 +544,7 @@ class CapaMixin(ScorableXBlockMixin, CapaFields):
`err` is the Exception encountered while rendering the problem HTML.
"""
- log.exception(err.message)
+ log.exception(text_type(err))
# TODO (vshnayder): another switch on DEBUG.
if self.runtime.DEBUG:
@@ -553,7 +553,7 @@ class CapaMixin(ScorableXBlockMixin, CapaFields):
u'Failed to generate HTML for problem {url}'.format(
url=cgi.escape(text_type(self.location)))
)
- msg += u'Error:
{msg}
'.format(msg=cgi.escape(err.message))
+ msg += u'Error:
{msg}'.format(msg=cgi.escape(text_type(err)))
msg += u'{tb}'.format(tb=cgi.escape(traceback.format_exc()))
html = msg
@@ -1258,7 +1258,7 @@ class CapaMixin(ScorableXBlockMixin, CapaFields):
self.set_score(self.score_from_lcp())
if self.runtime.DEBUG:
- msg = u"Error checking problem: {}".format(err.message)
+ msg = u"Error checking problem: {}".format(text_type(err))
msg += u'\nTraceback:\n{}'.format(traceback.format_exc())
return {'success': msg}
raise
diff --git a/common/lib/xmodule/xmodule/course_module.py b/common/lib/xmodule/xmodule/course_module.py
index 673d7c1ac1..e5b0e05c10 100644
--- a/common/lib/xmodule/xmodule/course_module.py
+++ b/common/lib/xmodule/xmodule/course_module.py
@@ -16,6 +16,7 @@ from openedx.core.djangoapps.video_pipeline.models import VideoUploadsEnabledByD
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 xmodule import course_metadata_utils
@@ -943,7 +944,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=err.message, course_id=unicode(self.id)))
+ raise type(err)('{msg} For course: {course_id}'.format(msg=text_type(err), course_id=unicode(self.id)))
self.set_default_certificate_available_date()
diff --git a/common/lib/xmodule/xmodule/exceptions.py b/common/lib/xmodule/xmodule/exceptions.py
index d1f05171da..f9a0ad597c 100644
--- a/common/lib/xmodule/xmodule/exceptions.py
+++ b/common/lib/xmodule/xmodule/exceptions.py
@@ -45,9 +45,6 @@ class HeartbeatFailure(Exception):
Raised when heartbeat fails.
"""
- def __unicode__(self, *args, **kwargs):
- return self.message
-
def __init__(self, msg, service):
"""
In addition to a msg, provide the name of the service.
diff --git a/common/lib/xmodule/xmodule/fields.py b/common/lib/xmodule/xmodule/fields.py
index d022340107..ffe707833d 100644
--- a/common/lib/xmodule/xmodule/fields.py
+++ b/common/lib/xmodule/xmodule/fields.py
@@ -5,6 +5,7 @@ import time
import dateutil.parser
from pytz import UTC
+from six import text_type
from xblock.fields import JSONField
from xblock.scorable import Score
@@ -175,7 +176,7 @@ class RelativeTime(JSONField):
except ValueError as e:
raise ValueError(
"Incorrect RelativeTime value {!r} was set in XML or serialized. "
- "Original parse message is {}".format(value, e.message)
+ "Original parse message is {}".format(value, text_type(e))
)
return datetime.timedelta(
hours=obj_time.tm_hour,
diff --git a/common/lib/xmodule/xmodule/lti_2_util.py b/common/lib/xmodule/xmodule/lti_2_util.py
index 27c6a22952..e57a6bdbfb 100644
--- a/common/lib/xmodule/xmodule/lti_2_util.py
+++ b/common/lib/xmodule/xmodule/lti_2_util.py
@@ -12,6 +12,7 @@ import urllib
import mock
from oauthlib.oauth1 import Client
+from six import text_type
from webob import Response
from xblock.core import XBlock
@@ -290,8 +291,8 @@ class LTI20ModuleMixin(object):
try:
self.verify_oauth_body_sign(request, content_type=LTI_2_0_JSON_CONTENT_TYPE)
except (ValueError, LTIError) as err:
- log.info("[LTI]: v2.0 result service -- OAuth body verification failed: {}".format(err.message))
- raise LTIError(err.message)
+ log.info("[LTI]: v2.0 result service -- OAuth body verification failed: {}".format(text_type(err)))
+ raise LTIError(text_type(err))
def parse_lti_2_0_result_json(self, json_str):
"""
@@ -360,7 +361,7 @@ class LTI20ModuleMixin(object):
log.info("[LTI] {}".format(msg))
raise LTIError(msg)
except (TypeError, ValueError) as err:
- msg = "Could not convert resultScore to float: {}".format(err.message)
+ msg = "Could not convert resultScore to float: {}".format(text_type(err))
log.info("[LTI] {}".format(msg))
raise LTIError(msg)
diff --git a/common/lib/xmodule/xmodule/lti_module.py b/common/lib/xmodule/xmodule/lti_module.py
index fdf6f1b98a..15aae2db56 100644
--- a/common/lib/xmodule/xmodule/lti_module.py
+++ b/common/lib/xmodule/xmodule/lti_module.py
@@ -734,7 +734,7 @@ oauth_consumer_key="", oauth_signature="frVp4JuvT1mVXlxktiAUjQ7%2F1cw%3D"'}
try:
imsx_messageIdentifier, sourcedId, score, action = self.parse_grade_xml_body(request.body)
except Exception as e:
- error_message = "Request body XML parsing error: " + escape(e.message)
+ error_message = "Request body XML parsing error: " + escape(text_type(e))
log.debug("[LTI]: " + error_message)
failure_values['imsx_description'] = error_message
return Response(response_xml_template.format(**failure_values), content_type="application/xml")
@@ -744,7 +744,7 @@ oauth_consumer_key="", oauth_signature="frVp4JuvT1mVXlxktiAUjQ7%2F1cw%3D"'}
self.verify_oauth_body_sign(request)
except (ValueError, LTIError) as e:
failure_values['imsx_messageIdentifier'] = escape(imsx_messageIdentifier)
- error_message = "OAuth verification error: " + escape(e.message)
+ error_message = "OAuth verification error: " + escape(text_type(e))
failure_values['imsx_description'] = error_message
log.debug("[LTI]: " + error_message)
return Response(response_xml_template.format(**failure_values), content_type="application/xml")
diff --git a/common/lib/xmodule/xmodule/modulestore/draft_and_published.py b/common/lib/xmodule/xmodule/modulestore/draft_and_published.py
index 82701418e7..409ec9c721 100644
--- a/common/lib/xmodule/xmodule/modulestore/draft_and_published.py
+++ b/common/lib/xmodule/xmodule/modulestore/draft_and_published.py
@@ -6,6 +6,7 @@ import threading
import logging
from abc import ABCMeta, abstractmethod
from contextlib import contextmanager
+from six import text_type
from . import ModuleStoreEnum, BulkOperationsMixin
from .exceptions import ItemNotFoundError
@@ -157,7 +158,7 @@ class ModuleStoreDraftAndPublished(BranchSettingMixin, BulkOperationsMixin):
old_parent_item = self.get_item(old_parent_location) # pylint: disable=no-member
new_parent_item = self.get_item(new_parent_location) # pylint: disable=no-member
except ItemNotFoundError as exception:
- log.error('Unable to find the item : %s', exception.message)
+ log.error('Unable to find the item : %s', text_type(exception))
return
# Remove item from the list of children of old parent.
diff --git a/common/lib/xmodule/xmodule/tests/test_capa_module.py b/common/lib/xmodule/xmodule/tests/test_capa_module.py
index 4d8ba9b00f..81c29787aa 100644
--- a/common/lib/xmodule/xmodule/tests/test_capa_module.py
+++ b/common/lib/xmodule/xmodule/tests/test_capa_module.py
@@ -880,7 +880,7 @@ class CapaModuleTest(unittest.TestCase):
' File "", line 65, in check_func\\n'
'Exception: test error\\n\' with status code: 1',)
except ResponseError as err:
- mock_grade.side_effect = exception_class(err.message)
+ mock_grade.side_effect = exception_class(six.text_type(err))
get_request_dict = {CapaFactory.input_key(): '3.14'}
result = module.submit_problem(get_request_dict)
diff --git a/common/lib/xmodule/xmodule/tests/test_graders.py b/common/lib/xmodule/xmodule/tests/test_graders.py
index aab9e65ab1..e7d1475850 100644
--- a/common/lib/xmodule/xmodule/tests/test_graders.py
+++ b/common/lib/xmodule/xmodule/tests/test_graders.py
@@ -8,6 +8,7 @@ from datetime import datetime, timedelta
import ddt
from pytz import UTC
from lms.djangoapps.grades.scores import compute_percent
+from six import text_type
from xmodule import graders
from xmodule.graders import (
AggregatedScore, ProblemScore, ShowCorrectness, aggregate_scores
@@ -321,7 +322,7 @@ class GraderTest(unittest.TestCase):
def test_grader_with_invalid_conf(self, invalid_conf, expected_error_message):
with self.assertRaises(ValueError) as error:
graders.grader_from_conf([invalid_conf])
- self.assertIn(expected_error_message, error.exception.message)
+ self.assertIn(expected_error_message, text_type(error.exception))
@ddt.ddt
diff --git a/common/lib/xmodule/xmodule/video_module/transcripts_utils.py b/common/lib/xmodule/xmodule/video_module/transcripts_utils.py
index 3318f5670d..e49ae981c9 100644
--- a/common/lib/xmodule/xmodule/video_module/transcripts_utils.py
+++ b/common/lib/xmodule/xmodule/video_module/transcripts_utils.py
@@ -12,6 +12,7 @@ from pysrt import SubRipTime, SubRipItem, SubRipFile
from pysrt.srtexc import Error
from lxml import etree
from HTMLParser import HTMLParser
+from six import text_type
from xmodule.exceptions import NotFoundError
from xmodule.contentstore.content import StaticContent
@@ -226,7 +227,7 @@ def generate_subs_from_source(speed_subs, subs_type, subs_filedata, item, langua
srt_subs_obj = SubRipFile.from_string(subs_filedata)
except Exception as ex:
msg = _("Something wrong with SubRip transcripts file during parsing. Inner message is {error_message}").format(
- error_message=ex.message
+ error_message=text_type(ex)
)
raise TranscriptsGenerationException(msg)
if not srt_subs_obj:
@@ -459,7 +460,7 @@ def generate_sjson_for_all_speeds(item, user_filename, result_subs_dict, lang):
srt_transcripts = contentstore().find(Transcript.asset_location(item.location, user_filename))
except NotFoundError as ex:
raise TranscriptException(_("{exception_message}: Can't find uploaded transcripts: {user_filename}").format(
- exception_message=ex.message,
+ exception_message=text_type(ex),
user_filename=user_filename
))
@@ -612,7 +613,7 @@ class Transcript(object):
error_handling=SubRipFile.ERROR_RAISE
)
except Error as ex: # Base exception from pysrt
- raise TranscriptsGenerationException(ex.message)
+ raise TranscriptsGenerationException(text_type(ex))
return generate_sjson_from_srt(srt_subs)
diff --git a/common/lib/xmodule/xmodule/video_module/video_handlers.py b/common/lib/xmodule/xmodule/video_module/video_handlers.py
index 224da13f48..2212ed6e9d 100644
--- a/common/lib/xmodule/xmodule/video_module/video_handlers.py
+++ b/common/lib/xmodule/xmodule/video_module/video_handlers.py
@@ -291,7 +291,7 @@ class VideoStudentViewHandlers(object):
except (TypeError, TranscriptException, NotFoundError) as ex:
# Catching `TranscriptException` because its also getting raised at places
# when transcript is not found in contentstore.
- log.debug(ex.message)
+ log.debug(six.text_type(ex))
# Try to return static URL redirection as last resort
# if no translation is required
response = self.get_static_transcript(request, transcripts)
@@ -313,7 +313,7 @@ class VideoStudentViewHandlers(object):
return response
except (UnicodeDecodeError, TranscriptsGenerationException) as ex:
- log.info(ex.message)
+ log.info(six.text_type(ex))
response = Response(status=404)
else:
response = Response(transcript, headerlist=[('Content-Language', language)])
diff --git a/common/lib/xmodule/xmodule/x_module.py b/common/lib/xmodule/xmodule/x_module.py
index 6a554b14a5..84ae3349ce 100644
--- a/common/lib/xmodule/xmodule/x_module.py
+++ b/common/lib/xmodule/xmodule/x_module.py
@@ -14,6 +14,7 @@ from pkg_resources import (
resource_string,
resource_isdir,
)
+from six import text_type
from web_fragments.fragment import Fragment
from webob import Response
from webob.multidict import MultiDict
@@ -420,8 +421,8 @@ class XModuleMixin(XModuleFields, XBlock):
result[field.name] = field.read_json(self)
except TypeError as exception:
exception_message = "{message}, Block-location:{location}, Field-name:{field_name}".format(
- message=exception.message,
- location=unicode(self.location),
+ message=text_type(exception),
+ location=text_type(self.location),
field_name=field.name
)
raise TypeError(exception_message)
diff --git a/lms/djangoapps/commerce/api/v0/views.py b/lms/djangoapps/commerce/api/v0/views.py
index 1d2db22b2f..99acb87226 100644
--- a/lms/djangoapps/commerce/api/v0/views.py
+++ b/lms/djangoapps/commerce/api/v0/views.py
@@ -8,6 +8,7 @@ from rest_framework.authentication import SessionAuthentication
from rest_framework.permissions import IsAuthenticated
from rest_framework.status import HTTP_406_NOT_ACCEPTABLE, HTTP_409_CONFLICT
from rest_framework.views import APIView
+from six import text_type
from course_modes.models import CourseMode
from courseware import courses
@@ -54,7 +55,7 @@ class BasketsView(APIView):
courses.get_course(course_key)
except (InvalidKeyError, ValueError)as ex:
log.exception(u'Unable to locate course matching %s.', course_id)
- return False, None, ex.message
+ return False, None, text_type(ex)
return True, course_key, None
diff --git a/lms/djangoapps/completion/api/v1/views.py b/lms/djangoapps/completion/api/v1/views.py
index 48096b3109..5c0cd03e5a 100644
--- a/lms/djangoapps/completion/api/v1/views.py
+++ b/lms/djangoapps/completion/api/v1/views.py
@@ -11,6 +11,7 @@ from rest_framework import status
from opaque_keys.edx.keys import CourseKey, UsageKey
from opaque_keys import InvalidKeyError
+from six import text_type
from lms.djangoapps.completion.models import BlockCompletion
from openedx.core.djangoapps.content.course_structures.models import CourseStructure
@@ -126,11 +127,11 @@ class CompletionBatchView(APIView):
}, status=status.HTTP_400_BAD_REQUEST)
except ObjectDoesNotExist as exc:
return Response({
- "detail": exc.message,
+ "detail": text_type(exc),
}, status=status.HTTP_404_NOT_FOUND)
except DatabaseError as exc:
return Response({
- "detail": exc.message,
+ "detail": text_type(exc),
}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
return Response({"detail": _("ok")}, status=status.HTTP_200_OK)
diff --git a/lms/djangoapps/course_api/blocks/views.py b/lms/djangoapps/course_api/blocks/views.py
index 05e80f7ceb..8684e03d08 100644
--- a/lms/djangoapps/course_api/blocks/views.py
+++ b/lms/djangoapps/course_api/blocks/views.py
@@ -7,6 +7,7 @@ from opaque_keys import InvalidKeyError
from opaque_keys.edx.keys import CourseKey
from rest_framework.generics import ListAPIView
from rest_framework.response import Response
+from six import text_type
from openedx.core.lib.api.view_utils import DeveloperErrorViewMixin, view_auth_classes
from xmodule.modulestore.django import modulestore
@@ -215,7 +216,7 @@ class BlocksView(DeveloperErrorViewMixin, ListAPIView):
)
)
except ItemNotFoundError as exception:
- raise Http404("Block not found: {}".format(exception.message))
+ raise Http404("Block not found: {}".format(text_type(exception)))
@view_auth_classes()
diff --git a/lms/djangoapps/courseware/courseware_access_exception.py b/lms/djangoapps/courseware/courseware_access_exception.py
index d3a47d0c12..931782f98c 100644
--- a/lms/djangoapps/courseware/courseware_access_exception.py
+++ b/lms/djangoapps/courseware/courseware_access_exception.py
@@ -10,9 +10,8 @@ class CoursewareAccessException(Http404):
"""
def __init__(self, access_response):
- super(CoursewareAccessException, self).__init__()
+ super(CoursewareAccessException, self).__init__("Course not found.")
self.access_response = access_response
- self.message = "Course not found."
def to_json(self):
"""
diff --git a/lms/djangoapps/courseware/tests/test_courses.py b/lms/djangoapps/courseware/tests/test_courses.py
index ef277557b8..de5b7c5d66 100644
--- a/lms/djangoapps/courseware/tests/test_courses.py
+++ b/lms/djangoapps/courseware/tests/test_courses.py
@@ -13,6 +13,7 @@ from django.core.urlresolvers import reverse
from django.test.client import RequestFactory
from django.test.utils import override_settings
from nose.plugins.attrib import attr
+from six import text_type
from courseware.courses import (
course_open_for_self_enrollment,
@@ -78,7 +79,7 @@ class CoursesTest(ModuleStoreTestCase):
with self.assertRaises(CoursewareAccessException) as error:
course_access_func(user, 'load', course.id)
- self.assertEqual(error.exception.message, "Course not found.")
+ self.assertEqual(text_type(error.exception), "Course not found.")
self.assertEqual(error.exception.access_response.error_code, "not_visible_to_user")
self.assertFalse(error.exception.access_response.has_access)
diff --git a/lms/djangoapps/courseware/views/views.py b/lms/djangoapps/courseware/views/views.py
index 348e65fb06..675e6f95e4 100644
--- a/lms/djangoapps/courseware/views/views.py
+++ b/lms/djangoapps/courseware/views/views.py
@@ -1518,7 +1518,7 @@ def financial_assistance_request(request):
return HttpResponseBadRequest(u'Could not parse request course key.')
except KeyError as err:
# Thrown if fields are missing
- return HttpResponseBadRequest(u'The field {} is required.'.format(err.message))
+ return HttpResponseBadRequest(u'The field {} is required.'.format(text_type(err)))
zendesk_submitted = _record_feedback_in_zendesk(
legal_name,
diff --git a/lms/djangoapps/dashboard/git_import.py b/lms/djangoapps/dashboard/git_import.py
index 2472b37430..347cfdec54 100644
--- a/lms/djangoapps/dashboard/git_import.py
+++ b/lms/djangoapps/dashboard/git_import.py
@@ -33,7 +33,7 @@ class GitImportError(Exception):
def __init__(self, message=None):
if message is None:
- message = self.message
+ message = self.MESSAGE
super(GitImportError, self).__init__(message)
diff --git a/lms/djangoapps/dashboard/tests/test_sysadmin.py b/lms/djangoapps/dashboard/tests/test_sysadmin.py
index 2b03fb289e..10a65e27c7 100644
--- a/lms/djangoapps/dashboard/tests/test_sysadmin.py
+++ b/lms/djangoapps/dashboard/tests/test_sysadmin.py
@@ -153,7 +153,7 @@ class TestSysAdminMongoCourseImport(SysadminBaseTestCase):
# Create git loaded course
response = self._add_edx4edx()
- self.assertIn(GitImportErrorNoDir(settings.GIT_REPO_DIR).message,
+ self.assertIn(text_type(GitImportErrorNoDir(settings.GIT_REPO_DIR)),
response.content.decode('UTF-8'))
def test_mongo_course_add_delete(self):
diff --git a/lms/djangoapps/django_comment_client/middleware.py b/lms/djangoapps/django_comment_client/middleware.py
index 9dce7bc012..84d033566e 100644
--- a/lms/djangoapps/django_comment_client/middleware.py
+++ b/lms/djangoapps/django_comment_client/middleware.py
@@ -1,6 +1,8 @@
import json
import logging
+from six import text_type
+
from django_comment_client.utils import JsonError
from lms.lib.comment_client import CommentClientRequestError
@@ -19,7 +21,7 @@ class AjaxExceptionMiddleware(object):
"""
if isinstance(exception, CommentClientRequestError) and request.is_ajax():
try:
- return JsonError(json.loads(exception.message), exception.status_code)
+ return JsonError(json.loads(text_type(exception)), exception.status_code)
except ValueError:
- return JsonError(exception.message, exception.status_code)
+ return JsonError(text_type(exception), exception.status_code)
return None
diff --git a/lms/djangoapps/django_comment_client/tests/test_middleware.py b/lms/djangoapps/django_comment_client/tests/test_middleware.py
index 4849cfa3d0..80803bea7e 100644
--- a/lms/djangoapps/django_comment_client/tests/test_middleware.py
+++ b/lms/djangoapps/django_comment_client/tests/test_middleware.py
@@ -3,6 +3,7 @@ import json
import django.http
from django.test import TestCase
from nose.plugins.attrib import attr
+from six import text_type
import django_comment_client.middleware as middleware
import lms.lib.comment_client
@@ -26,7 +27,7 @@ class AjaxExceptionTestCase(TestCase):
self.assertIsInstance(response1, middleware.JsonError)
self.assertEqual(self.exception1.status_code, response1.status_code)
self.assertEqual(
- {"errors": json.loads(self.exception1.message)},
+ {"errors": json.loads(text_type(self.exception1))},
json.loads(response1.content)
)
@@ -34,7 +35,7 @@ class AjaxExceptionTestCase(TestCase):
self.assertIsInstance(response2, middleware.JsonError)
self.assertEqual(self.exception2.status_code, response2.status_code)
self.assertEqual(
- {"errors": [self.exception2.message]},
+ {"errors": [text_type(self.exception2)]},
json.loads(response2.content)
)
diff --git a/lms/djangoapps/edxnotes/views.py b/lms/djangoapps/edxnotes/views.py
index 1c0a889ae2..5d90040276 100644
--- a/lms/djangoapps/edxnotes/views.py
+++ b/lms/djangoapps/edxnotes/views.py
@@ -10,6 +10,7 @@ from django.core.urlresolvers import reverse
from django.http import Http404, HttpResponse
from django.views.decorators.http import require_GET
from opaque_keys.edx.keys import CourseKey
+from six import text_type
from courseware.courses import get_course_with_access
from courseware.model_data import FieldDataCache
@@ -165,7 +166,7 @@ def notes(request, course_id):
text=text
)
except (EdxNotesParseError, EdxNotesServiceUnavailable) as err:
- return JsonResponseBadRequest({"error": err.message}, status=500)
+ return JsonResponseBadRequest({"error": text_type(err)}, status=500)
return HttpResponse(json.dumps(notes_info, cls=NoteJSONEncoder), content_type="application/json")
diff --git a/lms/djangoapps/grades/course_grade_factory.py b/lms/djangoapps/grades/course_grade_factory.py
index 275b450d38..455417bc6b 100644
--- a/lms/djangoapps/grades/course_grade_factory.py
+++ b/lms/djangoapps/grades/course_grade_factory.py
@@ -5,6 +5,7 @@ from collections import namedtuple
from logging import getLogger
import dogstats_wrapper as dog_stats_api
+from six import text_type
from openedx.core.djangoapps.signals.signals import COURSE_GRADE_CHANGED, COURSE_GRADE_NOW_PASSED
@@ -126,7 +127,7 @@ class CourseGradeFactory(object):
'Cannot grade student %s in course %s because of exception: %s',
user.id,
course_data.course_key,
- exc.message
+ text_type(exc)
)
return self.GradeResult(user, None, exc)
diff --git a/lms/djangoapps/grades/tests/test_course_grade_factory.py b/lms/djangoapps/grades/tests/test_course_grade_factory.py
index c762899bb1..ecde6b7521 100644
--- a/lms/djangoapps/grades/tests/test_course_grade_factory.py
+++ b/lms/djangoapps/grades/tests/test_course_grade_factory.py
@@ -8,6 +8,8 @@ from django.conf import settings
from lms.djangoapps.grades.config.tests.utils import persistent_grades_feature_flags
from mock import patch
from openedx.core.djangoapps.content.block_structure.factory import BlockStructureFactory
+from six import text_type
+
from student.tests.factories import UserFactory
from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory
@@ -342,7 +344,7 @@ class TestGradeIteration(SharedModuleStoreTestCase):
with self.assertNumQueries(4):
all_course_grades, all_errors = self._course_grades_and_errors_for(self.course, self.students)
self.assertEqual(
- {student: all_errors[student].message for student in all_errors},
+ {student: text_type(all_errors[student]) for student in all_errors},
{
student3: "Error for student3.",
student4: "Error for student4.",
diff --git a/lms/djangoapps/instructor/views/api.py b/lms/djangoapps/instructor/views/api.py
index c431e17607..0fb7cd0461 100644
--- a/lms/djangoapps/instructor/views/api.py
+++ b/lms/djangoapps/instructor/views/api.py
@@ -2091,7 +2091,7 @@ def rescore_problem(request, course_id):
only_if_higher,
)
except NotImplementedError as exc:
- return HttpResponseBadRequest(exc.message)
+ return HttpResponseBadRequest(text_type(exc))
elif all_students:
try:
@@ -2101,7 +2101,7 @@ def rescore_problem(request, course_id):
only_if_higher,
)
except NotImplementedError as exc:
- return HttpResponseBadRequest(exc.message)
+ return HttpResponseBadRequest(text_type(exc))
else:
return HttpResponseBadRequest()
@@ -2157,10 +2157,10 @@ def override_problem_score(request, course_id):
score,
)
except NotImplementedError as exc: # if we try to override the score of a non-scorable block, catch it here
- return _create_error_response(request, exc.message)
+ return _create_error_response(request, text_type(exc))
except ValueError as exc:
- return _create_error_response(request, exc.message)
+ return _create_error_response(request, text_type(exc))
response_payload['task'] = TASK_SUBMISSION_OK
return JsonResponse(response_payload)
@@ -2951,14 +2951,14 @@ def certificate_exception_view(request, course_id):
try:
certificate_exception, student = parse_request_data_and_get_user(request, course_key)
except ValueError as error:
- return JsonResponse({'success': False, 'message': error.message}, status=400)
+ return JsonResponse({'success': False, 'message': text_type(error)}, status=400)
# Add new Certificate Exception for the student passed in request data
if request.method == 'POST':
try:
exception = add_certificate_exception(course_key, student, certificate_exception)
except ValueError as error:
- return JsonResponse({'success': False, 'message': error.message}, status=400)
+ return JsonResponse({'success': False, 'message': text_type(error)}, status=400)
return JsonResponse(exception)
# Remove Certificate Exception for the student passed in request data
@@ -2966,7 +2966,7 @@ def certificate_exception_view(request, course_id):
try:
remove_certificate_exception(course_key, student)
except ValueError as error:
- return JsonResponse({'success': False, 'message': error.message}, status=400)
+ return JsonResponse({'success': False, 'message': text_type(error)}, status=400)
return JsonResponse({}, status=204)
@@ -3264,14 +3264,14 @@ def certificate_invalidation_view(request, course_id):
certificate_invalidation_data = parse_request_data(request)
certificate = validate_request_data_and_get_certificate(certificate_invalidation_data, course_key)
except ValueError as error:
- return JsonResponse({'message': error.message}, status=400)
+ return JsonResponse({'message': text_type(error)}, status=400)
# Invalidate certificate of the given student for the course course
if request.method == 'POST':
try:
certificate_invalidation = invalidate_certificate(request, certificate, certificate_invalidation_data)
except ValueError as error:
- return JsonResponse({'message': error.message}, status=400)
+ return JsonResponse({'message': text_type(error)}, status=400)
return JsonResponse(certificate_invalidation)
# Re-Validate student certificate for the course course
@@ -3279,7 +3279,7 @@ def certificate_invalidation_view(request, course_id):
try:
re_validate_certificate(request, course_key, certificate)
except ValueError as error:
- return JsonResponse({'message': error.message}, status=400)
+ return JsonResponse({'message': text_type(error)}, status=400)
return JsonResponse({}, status=204)
diff --git a/lms/djangoapps/instructor_task/api_helper.py b/lms/djangoapps/instructor_task/api_helper.py
index abdadcb5b9..eb61b67f87 100644
--- a/lms/djangoapps/instructor_task/api_helper.py
+++ b/lms/djangoapps/instructor_task/api_helper.py
@@ -256,8 +256,8 @@ def _handle_instructor_task_failure(instructor_task, error):
"""
Do required operations if task creation was not complete.
"""
- log.info("instructor task (%s) failed, result: %s", instructor_task.task_id, error.message)
- _update_instructor_task_state(instructor_task, FAILURE, error.message)
+ log.info("instructor task (%s) failed, result: %s", instructor_task.task_id, text_type(error))
+ _update_instructor_task_state(instructor_task, FAILURE, text_type(error))
raise QueueConnectionError()
diff --git a/lms/djangoapps/instructor_task/models.py b/lms/djangoapps/instructor_task/models.py
index 23920fe94a..5e69eede10 100644
--- a/lms/djangoapps/instructor_task/models.py
+++ b/lms/djangoapps/instructor_task/models.py
@@ -149,7 +149,7 @@ class InstructorTask(models.Model):
Truncation is indicated by adding "..." to the end of the value.
"""
tag = '...'
- task_progress = {'exception': type(exception).__name__, 'message': unicode(exception.message)}
+ task_progress = {'exception': type(exception).__name__, 'message': text_type(exception)}
if traceback_string is not None:
# truncate any traceback that goes into the InstructorTask model:
task_progress['traceback'] = traceback_string
diff --git a/lms/djangoapps/instructor_task/tasks_helper/grades.py b/lms/djangoapps/instructor_task/tasks_helper/grades.py
index a82d2e5bef..cea887f75b 100644
--- a/lms/djangoapps/instructor_task/tasks_helper/grades.py
+++ b/lms/djangoapps/instructor_task/tasks_helper/grades.py
@@ -10,6 +10,7 @@ from time import time
from lazy import lazy
from pytz import UTC
+from six import text_type
from courseware.courses import get_course_by_id
from instructor_analytics.basic import list_problem_responses
@@ -435,7 +436,7 @@ class CourseGradeReport(object):
):
if not course_grade:
# An empty gradeset means we failed to grade a student.
- error_rows.append([user.id, user.username, error.message])
+ error_rows.append([user.id, user.username, text_type(error)])
else:
success_rows.append(
[user.id, user.email, user.username] +
@@ -485,7 +486,7 @@ class ProblemGradeReport(object):
task_progress.attempted += 1
if not course_grade:
- err_msg = error.message
+ err_msg = text_type(error)
# There was an error grading this student.
if not err_msg:
err_msg = u'Unknown error'
diff --git a/lms/djangoapps/notification_prefs/views.py b/lms/djangoapps/notification_prefs/views.py
index 7f6416d302..181947f835 100644
--- a/lms/djangoapps/notification_prefs/views.py
+++ b/lms/djangoapps/notification_prefs/views.py
@@ -19,6 +19,7 @@ from django.contrib.auth.models import User
from django.core.exceptions import PermissionDenied
from django.http import Http404, HttpResponse
from django.views.decorators.http import require_GET, require_POST
+from six import text_type
from edxmako.shortcuts import render_to_response
from notification_prefs import NOTIFICATION_PREF_KEY
@@ -185,7 +186,7 @@ def set_subscription(request, token, subscribe): # pylint: disable=unused-argum
except UnicodeDecodeError:
raise Http404("base64url")
except UsernameDecryptionException as exn:
- raise Http404(exn.message)
+ raise Http404(text_type(exn))
except User.DoesNotExist:
raise Http404("username")
diff --git a/lms/djangoapps/shoppingcart/management/commands/retire_order.py b/lms/djangoapps/shoppingcart/management/commands/retire_order.py
index a48925b28d..495809bd5f 100644
--- a/lms/djangoapps/shoppingcart/management/commands/retire_order.py
+++ b/lms/djangoapps/shoppingcart/management/commands/retire_order.py
@@ -4,6 +4,7 @@ marked as "purchased" in the db
"""
from django.core.management.base import BaseCommand
+from six import text_type
from shoppingcart.exceptions import InvalidStatusToRetire, UnexpectedOrderItemStatus
from shoppingcart.models import Order
@@ -36,7 +37,7 @@ class Command(BaseCommand):
order.retire()
except (UnexpectedOrderItemStatus, InvalidStatusToRetire) as err:
print "Did not retire order {order}: {message}".format(
- order=order.id, message=err.message
+ order=order.id, message=text_type(err)
)
else:
print "retired order {order_id} from status {old_status} to status {new_status}".format(
diff --git a/lms/djangoapps/shoppingcart/processors/CyberSource.py b/lms/djangoapps/shoppingcart/processors/CyberSource.py
index 305d3ffd7c..1133b6311b 100644
--- a/lms/djangoapps/shoppingcart/processors/CyberSource.py
+++ b/lms/djangoapps/shoppingcart/processors/CyberSource.py
@@ -30,6 +30,7 @@ from textwrap import dedent
from django.conf import settings
from django.utils.translation import ugettext as _
+from six import text_type
from edxmako.shortcuts import render_to_string
from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers
@@ -283,7 +284,7 @@ def get_processor_exception_html(exception):
)
formatted = msg.format(
error_message='{msg}'.format(
- msg=exception.message,
+ msg=text_type(exception),
),
email=payment_support_email,
)
@@ -298,7 +299,7 @@ def get_processor_exception_html(exception):
)
formatted = msg.format(
error_message='{msg}'.format(
- msg=exception.message,
+ msg=text_type(exception),
),
email=payment_support_email,
)
@@ -316,7 +317,7 @@ def get_processor_exception_html(exception):
)
formatted = msg.format(
error_message='{msg}'.format(
- msg=exception.message,
+ msg=text_type(exception),
),
email=payment_support_email,
)
diff --git a/lms/djangoapps/shoppingcart/processors/CyberSource2.py b/lms/djangoapps/shoppingcart/processors/CyberSource2.py
index 5a3aadd736..e12d7aa123 100644
--- a/lms/djangoapps/shoppingcart/processors/CyberSource2.py
+++ b/lms/djangoapps/shoppingcart/processors/CyberSource2.py
@@ -35,6 +35,7 @@ from textwrap import dedent
from django.conf import settings
from django.utils.translation import ugettext as _
from django.utils.translation import ugettext_noop
+from six import text_type
from edxmako.shortcuts import render_to_string
from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers
@@ -503,7 +504,7 @@ def _get_processor_exception_html(exception):
u"The specific error message is: {msg} "
u"Your credit card may possibly have been charged. Contact us with payment-specific questions at {email}."
).format(
- msg=u'{msg}'.format(msg=exception.message),
+ msg=u'{msg}'.format(msg=text_type(exception)),
email=payment_support_email
)
)
@@ -514,7 +515,7 @@ def _get_processor_exception_html(exception):
u"The specific error message is: {msg}. "
u"Your credit card has probably been charged. Contact us with payment-specific questions at {email}."
).format(
- msg=u'{msg}'.format(msg=exception.message),
+ msg=u'{msg}'.format(msg=text_type(exception)),
email=payment_support_email
)
)
@@ -527,7 +528,7 @@ def _get_processor_exception_html(exception):
u"We apologize that we cannot verify whether the charge went through and take further action on your order. "
u"Your credit card may possibly have been charged. Contact us with payment-specific questions at {email}."
).format(
- msg=u'{msg}'.format(msg=exception.message),
+ msg=u'{msg}'.format(msg=text_type(exception)),
email=payment_support_email
)
)
diff --git a/lms/djangoapps/support/tests/test_views.py b/lms/djangoapps/support/tests/test_views.py
index 05cf547969..a67886668c 100644
--- a/lms/djangoapps/support/tests/test_views.py
+++ b/lms/djangoapps/support/tests/test_views.py
@@ -296,7 +296,7 @@ class SupportViewEnrollmentsTests(SharedModuleStoreTestCase, SupportViewTestCase
self.assert_enrollment(CourseMode.VERIFIED)
@ddt.data(
- ({}, r"The field '\w+' is required."),
+ ({}, r"The field \"'\w+'\" is required."), # The double quoting goes away in Django 2.0.1
({'course_id': 'bad course key'}, 'Could not parse course key.'),
({
'course_id': 'course-v1:TestX+T101+2015',
diff --git a/lms/djangoapps/support/views/enrollments.py b/lms/djangoapps/support/views/enrollments.py
index 5bed96e696..c5b716e79a 100644
--- a/lms/djangoapps/support/views/enrollments.py
+++ b/lms/djangoapps/support/views/enrollments.py
@@ -11,6 +11,7 @@ from django.views.generic import View
from opaque_keys import InvalidKeyError
from opaque_keys.edx.keys import CourseKey
from rest_framework.generics import GenericAPIView
+from six import text_type
from course_modes.models import CourseMode
from edxmako.shortcuts import render_to_response
@@ -89,7 +90,7 @@ class EnrollmentSupportListView(GenericAPIView):
if new_mode == CourseMode.CREDIT_MODE:
return HttpResponseBadRequest(u'Enrollment cannot be changed to credit mode.')
except KeyError as err:
- return HttpResponseBadRequest(u'The field {} is required.'.format(err.message))
+ return HttpResponseBadRequest(u'The field {} is required.'.format(text_type(err)))
except InvalidKeyError:
return HttpResponseBadRequest(u'Could not parse course key.')
except (CourseEnrollment.DoesNotExist, User.DoesNotExist):
@@ -113,7 +114,7 @@ class EnrollmentSupportListView(GenericAPIView):
)
return JsonResponse(ManualEnrollmentSerializer(instance=manual_enrollment).data)
except CourseModeNotFoundError as err:
- return HttpResponseBadRequest(err.message)
+ return HttpResponseBadRequest(text_type(err))
@staticmethod
def include_verified_mode_info(enrollment_data, course_key):
diff --git a/lms/lib/comment_client/utils.py b/lms/lib/comment_client/utils.py
index 36fd1cf98f..062989c7d2 100644
--- a/lms/lib/comment_client/utils.py
+++ b/lms/lib/comment_client/utils.py
@@ -142,11 +142,7 @@ def perform_request(method, url, data_or_params=None, raw=False,
class CommentClientError(Exception):
- def __init__(self, msg):
- self.message = msg
-
- def __str__(self):
- return repr(self.message)
+ pass
class CommentClientRequestError(CommentClientError):
diff --git a/openedx/core/djangoapps/content/block_structure/management/commands/generate_course_blocks.py b/openedx/core/djangoapps/content/block_structure/management/commands/generate_course_blocks.py
index 147025c793..4d7bef61ef 100644
--- a/openedx/core/djangoapps/content/block_structure/management/commands/generate_course_blocks.py
+++ b/openedx/core/djangoapps/content/block_structure/management/commands/generate_course_blocks.py
@@ -4,6 +4,7 @@ Command to load course blocks.
import logging
from django.core.management.base import BaseCommand
+from six import text_type
from xmodule.modulestore.django import modulestore
import openedx.core.djangoapps.content.block_structure.api as api
@@ -136,7 +137,7 @@ class Command(BaseCommand):
log.exception(
u'BlockStructure: An error occurred while generating course blocks for %s: %s',
unicode(course_key),
- ex.message,
+ text_type(ex),
)
def _generate_for_course(self, options, course_key):
diff --git a/openedx/core/djangoapps/content/course_overviews/models.py b/openedx/core/djangoapps/content/course_overviews/models.py
index 53520611aa..824c6c7f83 100644
--- a/openedx/core/djangoapps/content/course_overviews/models.py
+++ b/openedx/core/djangoapps/content/course_overviews/models.py
@@ -13,6 +13,7 @@ from django.template import defaultfilters
from ccx_keys.locator import CCXLocator
from model_utils.models import TimeStampedModel
+from six import text_type
from config_models.models import ConfigurationModel
from lms.djangoapps import django_comment_client
@@ -528,7 +529,7 @@ class CourseOverview(TimeStampedModel):
log.exception(
'An error occurred while generating course overview for %s: %s',
unicode(course_key),
- ex.message,
+ text_type(ex),
)
log.info('Finished generating course overviews.')
diff --git a/openedx/core/djangoapps/content/course_structures/management/commands/generate_course_structure.py b/openedx/core/djangoapps/content/course_structures/management/commands/generate_course_structure.py
index 5d2e164a28..2e09ecf154 100644
--- a/openedx/core/djangoapps/content/course_structures/management/commands/generate_course_structure.py
+++ b/openedx/core/djangoapps/content/course_structures/management/commands/generate_course_structure.py
@@ -51,6 +51,6 @@ class Command(BaseCommand):
update_course_structure.apply(args=[text_type(course_key)])
except Exception as ex:
log.exception('An error occurred while generating course structure for %s: %s',
- text_type(course_key), ex.message)
+ text_type(course_key), text_type(ex))
log.info('Finished generating course structures.')
diff --git a/openedx/core/djangoapps/content/course_structures/tasks.py b/openedx/core/djangoapps/content/course_structures/tasks.py
index aa56ff01cf..bccf529c55 100644
--- a/openedx/core/djangoapps/content/course_structures/tasks.py
+++ b/openedx/core/djangoapps/content/course_structures/tasks.py
@@ -6,6 +6,8 @@ import logging
from celery.task import task
from opaque_keys.edx.keys import CourseKey
+from six import text_type
+
from xmodule.modulestore.django import modulestore
@@ -78,7 +80,7 @@ def update_course_structure(course_key):
try:
structure = _generate_course_structure(course_key)
except Exception as ex:
- log.exception('An error occurred while generating course structure: %s', ex.message)
+ log.exception('An error occurred while generating course structure: %s', text_type(ex))
raise
structure_json = json.dumps(structure['structure'])
diff --git a/openedx/core/djangoapps/contentserver/middleware.py b/openedx/core/djangoapps/contentserver/middleware.py
index 8f6fe3eea8..5eda4a9091 100644
--- a/openedx/core/djangoapps/contentserver/middleware.py
+++ b/openedx/core/djangoapps/contentserver/middleware.py
@@ -12,6 +12,7 @@ except ImportError:
from django.http import (
HttpResponse, HttpResponseNotModified, HttpResponseForbidden,
HttpResponseBadRequest, HttpResponseNotFound, HttpResponsePermanentRedirect)
+from six import text_type
from student.models import CourseEnrollment
from xmodule.assetstore.assetmgr import AssetManager
@@ -132,18 +133,18 @@ class StaticContentServer(object):
except ValueError as exception:
# If the header field is syntactically invalid it should be ignored.
log.exception(
- u"%s in Range header: %s for content: %s", exception.message, header_value, unicode(loc)
+ u"%s in Range header: %s for content: %s", text_type(exception), header_value, unicode(loc)
)
else:
if unit != 'bytes':
# Only accept ranges in bytes
- log.warning(u"Unknown unit in Range header: %s for content: %s", header_value, unicode(loc))
+ log.warning(u"Unknown unit in Range header: %s for content: %s", header_value, text_type(loc))
elif len(ranges) > 1:
# According to Http/1.1 spec content for multiple ranges should be sent as a multipart message.
# http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.16
# But we send back the full content.
log.warning(
- u"More than 1 ranges in Range header: %s for content: %s", header_value, unicode(loc)
+ u"More than 1 ranges in Range header: %s for content: %s", header_value, text_type(loc)
)
else:
first, last = ranges[0]
@@ -161,7 +162,8 @@ class StaticContentServer(object):
newrelic.agent.add_custom_parameter('contentserver.ranged', True)
else:
log.warning(
- u"Cannot satisfy ranges in Range header: %s for content: %s", header_value, unicode(loc)
+ u"Cannot satisfy ranges in Range header: %s for content: %s",
+ header_value, text_type(loc)
)
return HttpResponse(status=416) # Requested Range Not Satisfiable
diff --git a/openedx/core/djangoapps/course_groups/tests/test_cohorts.py b/openedx/core/djangoapps/course_groups/tests/test_cohorts.py
index cee543f396..5eb8084ad3 100644
--- a/openedx/core/djangoapps/course_groups/tests/test_cohorts.py
+++ b/openedx/core/djangoapps/course_groups/tests/test_cohorts.py
@@ -12,6 +12,8 @@ from django.db import IntegrityError
from django.http import Http404
from django.test import TestCase
from opaque_keys.edx.locator import CourseLocator
+from six import text_type
+
from student.models import CourseEnrollment
from student.tests.factories import UserFactory
from xmodule.modulestore.django import modulestore
@@ -720,7 +722,7 @@ class TestCohorts(ModuleStoreTestCase):
with self.assertRaises(ValueError) as value_error:
cohorts.set_course_cohorted(course.id, 'not a boolean')
- self.assertEqual("Cohorted must be a boolean", value_error.exception.message)
+ self.assertEqual("Cohorted must be a boolean", text_type(value_error.exception))
@attr(shard=2)
diff --git a/openedx/core/djangoapps/credit/views.py b/openedx/core/djangoapps/credit/views.py
index 0dce4a102e..06ab088fba 100644
--- a/openedx/core/djangoapps/credit/views.py
+++ b/openedx/core/djangoapps/credit/views.py
@@ -18,6 +18,7 @@ from rest_framework.authentication import SessionAuthentication
from rest_framework.exceptions import ValidationError
from rest_framework.response import Response
from rest_framework_oauth.authentication import OAuth2Authentication
+from six import text_type
from openedx.core.djangoapps.credit.api import create_credit_request
from openedx.core.djangoapps.credit.exceptions import (
@@ -101,7 +102,7 @@ class CreditProviderRequestCreateView(views.APIView):
credit_request = create_credit_request(course_key, provider.provider_id, username)
return Response(credit_request)
except CreditApiBadRequest as ex:
- raise InvalidCreditRequest(ex.message)
+ raise InvalidCreditRequest(text_type(ex))
class CreditProviderCallbackView(views.APIView):
diff --git a/openedx/core/djangoapps/profile_images/exceptions.py b/openedx/core/djangoapps/profile_images/exceptions.py
index ca63fced8b..2977a75900 100644
--- a/openedx/core/djangoapps/profile_images/exceptions.py
+++ b/openedx/core/djangoapps/profile_images/exceptions.py
@@ -1,6 +1,7 @@
"""
Exceptions related to the handling of profile images.
"""
+from six import text_type
class ImageValidationError(Exception):
@@ -12,4 +13,4 @@ class ImageValidationError(Exception):
"""
Translate the developer-facing exception message for API clients.
"""
- return self.message
+ return text_type(self)
diff --git a/openedx/core/djangoapps/profile_images/tests/test_images.py b/openedx/core/djangoapps/profile_images/tests/test_images.py
index 40e3474092..17c3e40db5 100644
--- a/openedx/core/djangoapps/profile_images/tests/test_images.py
+++ b/openedx/core/djangoapps/profile_images/tests/test_images.py
@@ -14,6 +14,7 @@ import mock
from nose.plugins.attrib import attr
import piexif
from PIL import Image
+from six import text_type
from openedx.core.djangolib.testing.utils import skip_unless_lms
from ..exceptions import ImageValidationError
@@ -48,7 +49,7 @@ class TestValidateUploadedImage(TestCase):
if expected_failure_message is not None:
with self.assertRaises(ImageValidationError) as ctx:
validate_uploaded_image(uploaded_file)
- self.assertEqual(ctx.exception.message, expected_failure_message)
+ self.assertEqual(text_type(ctx.exception), expected_failure_message)
else:
validate_uploaded_image(uploaded_file)
self.assertEqual(uploaded_file.tell(), 0)
@@ -107,7 +108,7 @@ class TestValidateUploadedImage(TestCase):
)
with self.assertRaises(ImageValidationError) as ctx:
validate_uploaded_image(uploaded_file)
- self.assertEqual(ctx.exception.message, file_upload_bad_ext)
+ self.assertEqual(text_type(ctx.exception), file_upload_bad_ext)
def test_content_type(self):
"""
@@ -121,7 +122,7 @@ class TestValidateUploadedImage(TestCase):
with make_uploaded_file(extension=".jpeg", content_type="image/gif") as uploaded_file:
with self.assertRaises(ImageValidationError) as ctx:
validate_uploaded_image(uploaded_file)
- self.assertEqual(ctx.exception.message, file_upload_bad_mimetype)
+ self.assertEqual(text_type(ctx.exception), file_upload_bad_mimetype)
@attr(shard=2)
diff --git a/openedx/core/djangoapps/profile_images/views.py b/openedx/core/djangoapps/profile_images/views.py
index 43bb324022..a907f34f7a 100644
--- a/openedx/core/djangoapps/profile_images/views.py
+++ b/openedx/core/djangoapps/profile_images/views.py
@@ -12,6 +12,7 @@ from rest_framework import permissions, status
from rest_framework.parsers import FormParser, MultiPartParser
from rest_framework.response import Response
from rest_framework.views import APIView
+from six import text_type
from openedx.core.djangoapps.user_api.accounts.image_helpers import get_profile_image_names, set_has_profile_image
from openedx.core.djangoapps.user_api.errors import UserNotFound
@@ -145,7 +146,7 @@ class ProfileImageView(DeveloperErrorViewMixin, APIView):
validate_uploaded_image(uploaded_file)
except ImageValidationError as error:
return Response(
- {"developer_message": error.message, "user_message": error.user_message},
+ {"developer_message": text_type(error), "user_message": error.user_message},
status=status.HTTP_400_BAD_REQUEST,
)
diff --git a/openedx/core/djangoapps/safe_sessions/middleware.py b/openedx/core/djangoapps/safe_sessions/middleware.py
index 2b8869e405..7ba898af03 100644
--- a/openedx/core/djangoapps/safe_sessions/middleware.py
+++ b/openedx/core/djangoapps/safe_sessions/middleware.py
@@ -67,6 +67,7 @@ from django.contrib.sessions.middleware import SessionMiddleware
from django.core import signing
from django.http import HttpResponse
from django.utils.crypto import get_random_string
+from six import text_type
from openedx.core.lib.mobile_utils import is_request_from_mobile_app
@@ -186,7 +187,7 @@ class SafeCookieData(object):
log.error(
"SafeCookieData signature error for cookie data {0!r}: {1}".format( # pylint: disable=logging-format-interpolation
unicode(self),
- sig_error.message,
+ text_type(sig_error),
)
)
return False
diff --git a/openedx/core/djangoapps/user_api/accounts/api.py b/openedx/core/djangoapps/user_api/accounts/api.py
index 35c54a2185..8d491589d4 100644
--- a/openedx/core/djangoapps/user_api/accounts/api.py
+++ b/openedx/core/djangoapps/user_api/accounts/api.py
@@ -13,6 +13,7 @@ from django.core.validators import validate_email, ValidationError
from django.http import HttpResponseForbidden
from openedx.core.djangoapps.user_api.preferences.api import update_user_preferences
from openedx.core.djangoapps.user_api.errors import PreferenceValidationError, AccountValidationError
+from six import text_type
from student.models import User, UserProfile, Registration
from student import forms as student_forms
@@ -168,8 +169,8 @@ def update_account_settings(requesting_user, update, username=None):
student_views.validate_new_email(existing_user, new_email)
except ValueError as err:
field_errors["email"] = {
- "developer_message": u"Error thrown from validate_new_email: '{}'".format(err.message),
- "user_message": err.message
+ "developer_message": u"Error thrown from validate_new_email: '{}'".format(text_type(err)),
+ "user_message": text_type(err)
}
# If the user asked to change full name, validate it
@@ -245,7 +246,7 @@ def update_account_settings(requesting_user, update, username=None):
raise err
except Exception as err:
raise errors.AccountUpdateError(
- u"Error thrown when saving account updates: '{}'".format(err.message)
+ u"Error thrown when saving account updates: '{}'".format(text_type(err))
)
# And try to send the email change request if necessary.
@@ -256,8 +257,8 @@ def update_account_settings(requesting_user, update, username=None):
student_views.do_email_change_request(existing_user, new_email)
except ValueError as err:
raise errors.AccountUpdateError(
- u"Error thrown from do_email_change_request: '{}'".format(err.message),
- user_message=err.message
+ u"Error thrown from do_email_change_request: '{}'".format(text_type(err)),
+ user_message=text_type(err)
)
@@ -552,7 +553,7 @@ def _validate(validation_func, err, *args):
try:
validation_func(*args)
except err as validation_err:
- return validation_err.message
+ return text_type(validation_err)
return ''
@@ -582,8 +583,10 @@ def _validate_username(username):
# `validate_username` provides a proper localized message, however the API needs only the English
# message by convention.
student_forms.validate_username(username)
- except (UnicodeError, errors.AccountDataBadType, errors.AccountDataBadLength, ValidationError) as username_err:
- raise errors.AccountUsernameInvalid(username_err.message)
+ except (UnicodeError, errors.AccountDataBadType, errors.AccountDataBadLength) as username_err:
+ raise errors.AccountUsernameInvalid(text_type(username_err))
+ except ValidationError as validation_err:
+ raise errors.AccountUsernameInvalid(validation_err.message)
def _validate_email(email):
@@ -605,8 +608,10 @@ def _validate_email(email):
_validate_length(email, accounts.EMAIL_MIN_LENGTH, accounts.EMAIL_MAX_LENGTH, accounts.EMAIL_BAD_LENGTH_MSG)
validate_email.message = accounts.EMAIL_INVALID_MSG.format(email=email)
validate_email(email)
- except (UnicodeError, errors.AccountDataBadType, errors.AccountDataBadLength, ValidationError) as invalid_email_err:
- raise errors.AccountEmailInvalid(invalid_email_err.message)
+ except (UnicodeError, errors.AccountDataBadType, errors.AccountDataBadLength) as invalid_email_err:
+ raise errors.AccountEmailInvalid(text_type(invalid_email_err))
+ except ValidationError as validation_err:
+ raise errors.AccountEmailInvalid(validation_err.message)
def _validate_confirm_email(confirm_email, email):
@@ -650,7 +655,7 @@ def _validate_password(password, username=None):
_validate_password_works_with_username(password, username)
except (errors.AccountDataBadType, errors.AccountDataBadLength) as invalid_password_err:
- raise errors.AccountPasswordInvalid(invalid_password_err.message)
+ raise errors.AccountPasswordInvalid(text_type(invalid_password_err))
def _validate_country(country):
diff --git a/openedx/core/djangoapps/user_api/accounts/serializers.py b/openedx/core/djangoapps/user_api/accounts/serializers.py
index 5516a1e363..ceb69d0257 100644
--- a/openedx/core/djangoapps/user_api/accounts/serializers.py
+++ b/openedx/core/djangoapps/user_api/accounts/serializers.py
@@ -9,6 +9,7 @@ from django.contrib.auth.models import User
from django.conf import settings
from django.core.exceptions import ObjectDoesNotExist
from django.core.urlresolvers import reverse
+from six import text_type
from lms.djangoapps.badges.utils import badges_enabled
from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers
@@ -313,8 +314,8 @@ class AccountLegacyProfileSerializer(serializers.HyperlinkedModelSerializer, Rea
# If we have encountered any validation errors, return them to the user.
raise errors.AccountValidationError({
'social_links': {
- "developer_message": u"Error thrown from adding new social link: '{}'".format(err.message),
- "user_message": err.message
+ "developer_message": u"Error thrown from adding new social link: '{}'".format(text_type(err)),
+ "user_message": text_type(err)
}
})
diff --git a/openedx/core/djangoapps/user_api/preferences/api.py b/openedx/core/djangoapps/user_api/preferences/api.py
index ec96abcb74..5408018349 100644
--- a/openedx/core/djangoapps/user_api/preferences/api.py
+++ b/openedx/core/djangoapps/user_api/preferences/api.py
@@ -14,6 +14,8 @@ from django.utils.translation import ugettext_noop
from openedx.core.lib.time_zone_utils import get_display_time_zone
from pytz import common_timezones, common_timezones_set, country_timezones
+from six import text_type
+
from student.models import User, UserProfile
from ..errors import (
UserAPIInternalError, UserAPIRequestError, UserNotFound, UserNotAuthorized,
@@ -266,7 +268,7 @@ def update_email_opt_in(user, org, opt_in):
if hasattr(settings, 'LMS_SEGMENT_KEY') and settings.LMS_SEGMENT_KEY:
_track_update_email_opt_in(user.id, org, opt_in)
except IntegrityError as err:
- log.warn(u"Could not update organization wide preference due to IntegrityError: {}".format(err.message))
+ log.warning(u"Could not update organization wide preference due to IntegrityError: {}".format(text_type(err)))
def _track_update_email_opt_in(user_id, organization, opt_in):
diff --git a/openedx/core/djangoapps/user_api/tests/test_helpers.py b/openedx/core/djangoapps/user_api/tests/test_helpers.py
index d5babff60c..f55459a864 100644
--- a/openedx/core/djangoapps/user_api/tests/test_helpers.py
+++ b/openedx/core/djangoapps/user_api/tests/test_helpers.py
@@ -9,6 +9,8 @@ from django import forms
from django.http import HttpRequest, HttpResponse
from django.test import TestCase
from nose.tools import raises
+from six import text_type
+
from ..helpers import (
intercept_errors, shim_student_view,
FormDescription, InvalidFieldError
@@ -66,7 +68,7 @@ class InterceptErrorsTest(TestCase):
try:
intercepted_function(raise_error=FakeInputException)
except FakeOutputException as ex:
- actual_message = re.sub(r'line \d+', 'line XXX', ex.message, flags=re.MULTILINE)
+ actual_message = re.sub(r'line \d+', 'line XXX', text_type(ex), flags=re.MULTILINE)
self.assertEqual(actual_message, expected_log_msg)
# Verify that the error logger is called
diff --git a/openedx/core/djangoapps/user_api/validation/tests/test_views.py b/openedx/core/djangoapps/user_api/validation/tests/test_views.py
index 4796cc8f60..0e77e49004 100644
--- a/openedx/core/djangoapps/user_api/validation/tests/test_views.py
+++ b/openedx/core/djangoapps/user_api/validation/tests/test_views.py
@@ -9,6 +9,7 @@ import ddt
from django.conf import settings
from django.contrib.auth.models import User
from django.core.urlresolvers import reverse
+from six import text_type
from openedx.core.djangoapps.user_api import accounts
from openedx.core.djangoapps.user_api.accounts.tests import testutils
@@ -140,7 +141,7 @@ class RegistrationValidationViewTests(test_utils.ApiTestCase):
def test_confirm_email_doesnt_equal_email(self, confirm_email):
self.assertValidationDecision(
{'email': 'user@email.com', 'confirm_email': confirm_email},
- {'email': '', 'confirm_email': accounts.REQUIRED_FIELD_CONFIRM_EMAIL_MSG}
+ {'email': '', 'confirm_email': text_type(accounts.REQUIRED_FIELD_CONFIRM_EMAIL_MSG)}
)
@ddt.data(
@@ -150,7 +151,7 @@ class RegistrationValidationViewTests(test_utils.ApiTestCase):
def test_username_bad_length_validation_decision(self, username):
self.assertValidationDecision(
{'username': username},
- {'username': accounts.USERNAME_BAD_LENGTH_MSG}
+ {'username': text_type(accounts.USERNAME_BAD_LENGTH_MSG)}
)
@unittest.skipUnless(settings.FEATURES.get("ENABLE_UNICODE_USERNAME"), "Unicode usernames disabled.")
@@ -158,7 +159,7 @@ class RegistrationValidationViewTests(test_utils.ApiTestCase):
def test_username_invalid_unicode_validation_decision(self, username):
self.assertValidationDecision(
{'username': username},
- {'username': accounts.USERNAME_INVALID_CHARS_UNICODE}
+ {'username': text_type(accounts.USERNAME_INVALID_CHARS_UNICODE)}
)
@unittest.skipIf(settings.FEATURES.get("ENABLE_UNICODE_USERNAME"), "Unicode usernames enabled.")
@@ -166,31 +167,31 @@ class RegistrationValidationViewTests(test_utils.ApiTestCase):
def test_username_invalid_ascii_validation_decision(self, username):
self.assertValidationDecision(
{'username': username},
- {"username": accounts.USERNAME_INVALID_CHARS_ASCII}
+ {"username": text_type(accounts.USERNAME_INVALID_CHARS_ASCII)}
)
def test_password_empty_validation_decision(self):
self.assertValidationDecision(
{'password': ''},
- {"password": accounts.PASSWORD_EMPTY_MSG}
+ {"password": text_type(accounts.PASSWORD_EMPTY_MSG)}
)
def test_password_bad_min_length_validation_decision(self):
password = 'p' * (accounts.PASSWORD_MIN_LENGTH - 1)
self.assertValidationDecision(
{'password': password},
- {"password": accounts.PASSWORD_BAD_MIN_LENGTH_MSG}
+ {"password": text_type(accounts.PASSWORD_BAD_MIN_LENGTH_MSG)}
)
def test_password_bad_max_length_validation_decision(self):
password = 'p' * (accounts.PASSWORD_MAX_LENGTH + 1)
self.assertValidationDecision(
{'password': password},
- {"password": accounts.PASSWORD_BAD_MAX_LENGTH_MSG}
+ {"password": text_type(accounts.PASSWORD_BAD_MAX_LENGTH_MSG)}
)
def test_password_equals_username_validation_decision(self):
self.assertValidationDecision(
{"username": "somephrase", "password": "somephrase"},
- {"username": "", "password": accounts.PASSWORD_CANT_EQUAL_USERNAME_MSG}
+ {"username": "", "password": text_type(accounts.PASSWORD_CANT_EQUAL_USERNAME_MSG)}
)
diff --git a/openedx/core/djangoapps/user_api/views.py b/openedx/core/djangoapps/user_api/views.py
index e7341eb69a..de05b435a0 100644
--- a/openedx/core/djangoapps/user_api/views.py
+++ b/openedx/core/djangoapps/user_api/views.py
@@ -14,6 +14,7 @@ from opaque_keys.edx.keys import CourseKey
from rest_framework import authentication, generics, status, viewsets
from rest_framework.exceptions import ParseError
from rest_framework.views import APIView
+from six import text_type
import accounts
from django_comment_common.models import Role
@@ -150,7 +151,7 @@ class RegistrationView(APIView):
user = create_account_with_params(request, data)
except AccountValidationError as err:
errors = {
- err.field: [{"user_message": err.message}]
+ err.field: [{"user_message": text_type(err)}]
}
return JsonResponse(errors, status=409)
except ValidationError as err:
diff --git a/openedx/core/lib/api/view_utils.py b/openedx/core/lib/api/view_utils.py
index 0ee5c63a42..ed552ae11c 100644
--- a/openedx/core/lib/api/view_utils.py
+++ b/openedx/core/lib/api/view_utils.py
@@ -12,6 +12,7 @@ from rest_framework.mixins import RetrieveModelMixin, UpdateModelMixin
from rest_framework.permissions import IsAuthenticated
from rest_framework.request import clone_request
from rest_framework.response import Response
+from six import text_type
from openedx.core.lib.api.authentication import (
OAuth2AuthenticationAllowInactiveUser,
@@ -66,7 +67,7 @@ class DeveloperErrorViewMixin(object):
if isinstance(exc, APIException):
return self.make_error_response(exc.status_code, exc.detail)
elif isinstance(exc, Http404) or isinstance(exc, ObjectDoesNotExist):
- return self.make_error_response(404, exc.message or "Not found.")
+ return self.make_error_response(404, text_type(exc) or "Not found.")
elif isinstance(exc, ValidationError):
return self.make_validation_error_response(exc)
else:
diff --git a/openedx/core/lib/command_utils.py b/openedx/core/lib/command_utils.py
index e68a3e6ba1..85e8f433c0 100644
--- a/openedx/core/lib/command_utils.py
+++ b/openedx/core/lib/command_utils.py
@@ -5,6 +5,7 @@ Useful utilities for management commands.
from django.core.management.base import CommandError
from opaque_keys import InvalidKeyError
from opaque_keys.edx.keys import CourseKey
+from six import text_type
def get_mutually_exclusive_required_option(options, *selections):
@@ -45,4 +46,4 @@ def parse_course_keys(course_key_strings):
try:
return [CourseKey.from_string(course_key_string) for course_key_string in course_key_strings]
except InvalidKeyError as error:
- raise CommandError('Invalid key specified: {}'.format(error.message))
+ raise CommandError('Invalid key specified: {}'.format(text_type(error)))
diff --git a/scripts/xblock/xblock_counts.py b/scripts/xblock/xblock_counts.py
index c58036c861..41eb39a46c 100644
--- a/scripts/xblock/xblock_counts.py
+++ b/scripts/xblock/xblock_counts.py
@@ -6,6 +6,7 @@ import sys
from datetime import datetime
import requests
+from six import text_type
# Keys for the CSV and JSON interpretation
PAGINATION_KEY = 'pagination'
@@ -164,10 +165,10 @@ def _get_block_types_from_json_file(xblock_json_file):
type_set = set()
try:
json_data = json.loads(json_file.read())
- except ValueError, e:
+ except ValueError as e:
print 'xBlock configuration file does not match the expected layout and is ' \
'missing "data" list: %s' % xblock_json_file
- sys.exit(e.message)
+ sys.exit(text_type(e))
if 'data' in json_data:
xblock_type_list = json_data['data']
for xblock in xblock_type_list: