refactor: pyupgrade in common/util + xblock_django (#26724)

This commit is contained in:
M. Zulqarnain
2021-03-09 16:49:51 +05:00
committed by GitHub
parent 6259a82059
commit 42eacaf8de
39 changed files with 168 additions and 221 deletions

View File

@@ -8,8 +8,8 @@ not migrating so as not to inconvenience users by logging them all out.
from functools import wraps
from urllib.parse import urlencode
import six
from django.core import cache
# If we can't find a 'general' CACHE defined in settings.py, we simply fall back
# to returning the default cache. This will happen with dev machines.
@@ -67,8 +67,8 @@ def cache_if_anonymous(*get_parameters):
if parameter_value is not None:
# urlencode expects data to be of type str, and doesn't deal well with Unicode data
# since it doesn't provide a way to specify an encoding.
cache_key = cache_key + '.' + six.moves.urllib.parse.urlencode({
get_parameter: six.text_type(parameter_value).encode('utf-8')
cache_key = cache_key + '.' + urlencode({
get_parameter: str(parameter_value).encode('utf-8')
})
response = cache.get(cache_key)

View File

@@ -5,8 +5,6 @@ Helper functions for configuration parsing
import collections
import six
def convert_tokens(tokens):
"""
@@ -19,7 +17,7 @@ def convert_tokens(tokens):
if tokens == 'None':
return None
elif isinstance(tokens, six.string_types) or (not isinstance(tokens, collections.Iterable)):
elif isinstance(tokens, str) or (not isinstance(tokens, collections.Iterable)):
return tokens
elif isinstance(tokens, dict):
return {

View File

@@ -4,8 +4,8 @@ Utility methods related to course
import logging
from urllib.parse import urlencode
import six
from django.conf import settings
from django.utils.timezone import now
@@ -32,8 +32,8 @@ def get_encoded_course_sharing_utm_params():
Returns encoded Course Sharing UTM Parameters.
"""
return {
utm_source: six.moves.urllib.parse.urlencode(utm_params)
for utm_source, utm_params in six.iteritems(COURSE_SHARING_UTM_PARAMETERS)
utm_source: urlencode(utm_params)
for utm_source, utm_params in COURSE_SHARING_UTM_PARAMETERS.items()
}
@@ -54,9 +54,9 @@ def get_link_for_about_page(course):
elif settings.FEATURES.get('ENABLE_MKTG_SITE') and getattr(course, 'marketing_url', None):
course_about_url = course.marketing_url
else:
course_about_url = u'{about_base_url}/courses/{course_key}/about'.format(
course_about_url = '{about_base_url}/courses/{course_key}/about'.format(
about_base_url=configuration_helpers.get_value('LMS_ROOT_URL', settings.LMS_ROOT_URL),
course_key=six.text_type(course.id),
course_key=str(course.id),
)
return course_about_url

View File

@@ -26,14 +26,14 @@ def get_default_time_display(dtime):
"""
if dtime is None:
return u""
return ""
if dtime.tzinfo is not None:
try:
timezone = u" " + dtime.tzinfo.tzname(dtime) # lint-amnesty, pylint: disable=redefined-outer-name
timezone = " " + dtime.tzinfo.tzname(dtime) # lint-amnesty, pylint: disable=redefined-outer-name
except NotImplementedError:
timezone = dtime.strftime('%z')
else:
timezone = u" UTC"
timezone = " UTC"
localized = strftime_localized(dtime, "DATE_TIME")
return (localized + timezone).strip()

View File

@@ -55,7 +55,7 @@ class OuterAtomic(transaction.Atomic):
def __init__(self, using, savepoint, read_committed=False, name=None):
self.read_committed = read_committed
self.name = name
super(OuterAtomic, self).__init__(using, savepoint) # lint-amnesty, pylint: disable=super-with-arguments
super().__init__(using, savepoint)
def __enter__(self):
@@ -88,7 +88,7 @@ class OuterAtomic(transaction.Atomic):
cursor = connection.cursor()
cursor.execute("SET TRANSACTION ISOLATION LEVEL READ COMMITTED")
super(OuterAtomic, self).__enter__() # lint-amnesty, pylint: disable=super-with-arguments
super().__enter__()
def outer_atomic(using=None, savepoint=True, read_committed=False, name=None):

View File

@@ -73,7 +73,7 @@ def can_disable_rate_limit(clz):
# No-op if the class isn't a Django Rest Framework view.
if not issubclass(clz, APIView):
msg = (
u"{clz} is not a Django Rest Framework APIView subclass."
"{clz} is not a Django Rest Framework APIView subclass."
).format(clz=clz)
LOGGER.warning(msg)
return clz

View File

@@ -6,7 +6,6 @@ Utility methods related to file handling.
import os
from datetime import datetime
import six
from django.core.exceptions import PermissionDenied
from django.core.files.storage import DefaultStorage, get_valid_filename
from django.utils.translation import ugettext as _
@@ -99,7 +98,7 @@ def course_filename_prefix_generator(course_id, separator='_'):
str: A unicode string which can safely be inserted into a
filename.
"""
return get_valid_filename(six.text_type(separator).join([course_id.org, course_id.course, course_id.run]))
return get_valid_filename(str(separator).join([course_id.org, course_id.course, course_id.run]))
def course_and_time_based_filename_generator(course_id, base_name):
@@ -118,14 +117,14 @@ def course_and_time_based_filename_generator(course_id, base_name):
and the current time. Note that there will be no extension.
"""
return u"{course_prefix}_{base_name}_{timestamp_str}".format(
return "{course_prefix}_{base_name}_{timestamp_str}".format(
course_prefix=course_filename_prefix_generator(course_id),
base_name=get_valid_filename(base_name),
timestamp_str=datetime.now(UTC).strftime("%Y-%m-%d-%H%M%S")
)
class UniversalNewlineIterator(object):
class UniversalNewlineIterator:
"""
This iterable class can be used as a wrapper around a file-like
object which does not inherently support being read in
@@ -143,8 +142,6 @@ class UniversalNewlineIterator(object):
"""
Replace CR and CRLF with LF within `string`.
"""
if six.PY2:
return string.replace('\r\n', '\n').replace('\r', '\n')
return string.replace('\r\n', '\n').replace('\r', '\n').encode('utf-8')
def generate_lines(self):
@@ -165,7 +162,7 @@ class UniversalNewlineIterator(object):
line = char
yield self.sanitize(last_line)
else:
line += six.text_type(char) if isinstance(char, int) else char
line += str(char) if isinstance(char, int) else char
buf = self.original_file.read(self.buffer_size)
if not buf and line:
yield self.sanitize(line)

View File

@@ -31,7 +31,7 @@ class EDXJSONEncoder(DjangoJSONEncoder):
return int(o)
return float(o)
else:
return super(EDXJSONEncoder, self).default(o) # lint-amnesty, pylint: disable=super-with-arguments
return super().default(o)
def expect_json(view_function):
@@ -73,7 +73,7 @@ class JsonResponse(HttpResponse):
kwargs.setdefault("content_type", "application/json")
if status:
kwargs["status"] = status
super(JsonResponse, self).__init__(content, *args, **kwargs) # lint-amnesty, pylint: disable=super-with-arguments
super().__init__(content, *args, **kwargs)
class JsonResponseBadRequest(HttpResponseBadRequest):
@@ -93,4 +93,4 @@ class JsonResponseBadRequest(HttpResponseBadRequest):
content = json.dumps(obj, cls=encoder, indent=2, ensure_ascii=False)
kwargs.setdefault("content_type", "application/json")
kwargs["status"] = status
super(JsonResponseBadRequest, self).__init__(content, *args, **kwargs) # lint-amnesty, pylint: disable=super-with-arguments
super().__init__(content, *args, **kwargs)

View File

@@ -5,7 +5,8 @@ so that we can cache any keys, not just ones that memcache would ordinarily acce
import hashlib
import six.moves.urllib.parse
from urllib.parse import quote_plus
from django.utils.encoding import smart_str
@@ -23,7 +24,7 @@ def cleaned_string(val):
Converts `val` to unicode and URL-encodes special characters
(including quotes and spaces)
"""
return six.moves.urllib.parse.quote_plus(smart_str(val))
return quote_plus(smart_str(val))
def safe_key(key, key_prefix, version):

View File

@@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models

View File

@@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from django.db import migrations, models
# Converted from the original South migration 0002_default_rate_limit_config.py

View File

@@ -1,9 +1,6 @@
"""
Utility library for working with the edx-milestones app
"""
import six
from django.conf import settings
from django.utils.translation import ugettext as _
from edx_toggles.toggles import SettingDictToggle
@@ -63,12 +60,12 @@ def add_prerequisite_course(course_key, prerequisite_course_key):
if not is_prerequisite_courses_enabled():
return None
milestone_name = _('Course {course_id} requires {prerequisite_course_id}').format(
course_id=six.text_type(course_key),
prerequisite_course_id=six.text_type(prerequisite_course_key)
course_id=str(course_key),
prerequisite_course_id=str(prerequisite_course_key)
)
milestone = milestones_api.add_milestone({
'name': milestone_name,
'namespace': six.text_type(prerequisite_course_key),
'namespace': str(prerequisite_course_key),
'description': _('System defined milestone'),
})
# add requirement course milestone
@@ -222,7 +219,7 @@ def get_required_content(course_key, user):
"""
required_content = []
if ENABLE_MILESTONES_APP.is_enabled():
course_run_id = six.text_type(course_key)
course_run_id = str(course_key)
if user.is_authenticated:
# Get all of the outstanding milestones for this course, for this user
@@ -287,7 +284,7 @@ def generate_milestone_namespace(namespace, course_key=None):
"""
if namespace in list(NAMESPACE_CHOICES.values()):
if namespace == 'entrance_exams':
return '{}.{}'.format(six.text_type(course_key), NAMESPACE_CHOICES['ENTRANCE_EXAM'])
return '{}.{}'.format(str(course_key), NAMESPACE_CHOICES['ENTRANCE_EXAM'])
def serialize_user(user):
@@ -382,7 +379,7 @@ def get_course_content_milestones(course_id, content_id=None, relationship='requ
if content_id is None:
return request_cache_dict[user_id][relationship]
return [m for m in request_cache_dict[user_id][relationship] if m['content_id'] == six.text_type(content_id)]
return [m for m in request_cache_dict[user_id][relationship] if m['content_id'] == str(content_id)]
def remove_course_content_user_milestones(course_key, content_key, user, relationship):

View File

@@ -4,14 +4,13 @@ Utilities for django models.
from typing import Dict, Any, Tuple
import six
from django.conf import settings
from django.dispatch import Signal
from django_countries.fields import Country
from eventtracking import tracker
# The setting name used for events when "settings" (account settings, preferences, profile information) change.
USER_SETTINGS_CHANGED_EVENT_NAME = u'edx.user.settings.changed'
USER_SETTINGS_CHANGED_EVENT_NAME = 'edx.user.settings.changed'
# Used to signal a field value change
USER_FIELD_CHANGED = Signal(providing_args=["user", "table", "setting", "old_value", "new_value"])
USER_FIELDS_CHANGED = Signal(providing_args=["user", "table", "changed_values"])
@@ -170,7 +169,7 @@ def _get_truncated_setting_value(value, max_length=None):
truncated_value (object): the possibly truncated version of the value.
was_truncated (bool): returns true if the serialized value was truncated.
"""
if isinstance(value, six.string_types) and max_length is not None and len(value) > max_length:
if isinstance(value, str) and max_length is not None and len(value) > max_length:
return value[0:max_length], True
else:
return value, False

View File

@@ -5,7 +5,6 @@ import gzip
import logging
from io import BytesIO
import six
from config_models.models import ConfigurationModel
from django.db import models
from django.utils.text import compress_string
@@ -58,7 +57,7 @@ class CompressedTextField(CreatorMixin, models.TextField):
Compress the text data.
"""
if value is not None:
if isinstance(value, six.text_type):
if isinstance(value, str):
value = value.encode('utf8')
value = compress_string(value)
value = value.encode('base64').decode('utf8')
@@ -68,7 +67,7 @@ class CompressedTextField(CreatorMixin, models.TextField):
"""
Decompresses the value from the database.
"""
if isinstance(value, six.text_type):
if isinstance(value, str):
value = decompress_string(value)
return value

View File

@@ -13,7 +13,6 @@ from django.contrib.auth.password_validation import validate_password as django_
from django.core.exceptions import ValidationError
from django.utils.translation import ugettext as _
from django.utils.translation import ungettext
from six import text_type
log = logging.getLogger(__name__)
@@ -71,7 +70,7 @@ def password_validators_instruction_texts():
complexity_instructions=' & '.join(complexity_instructions)
)
else:
return _('Your password must contain {length_instruction}.'.format(length_instruction=length_instruction)) # lint-amnesty, pylint: disable=translation-of-non-string
return _(f'Your password must contain {length_instruction}.') # lint-amnesty, pylint: disable=translation-of-non-string
def password_validators_restrictions():
@@ -93,10 +92,10 @@ def normalize_password(password):
Normalize all passwords to 'NFKC' across the platform to prevent mismatched hash strings when comparing entered
passwords on login. See LEARNER-4283 for more context.
"""
if not isinstance(password, text_type):
if not isinstance(password, str):
try:
# some checks rely on unicode semantics (e.g. length)
password = text_type(password, encoding='utf8')
password = str(password, encoding='utf8')
except UnicodeDecodeError:
# no reason to get into weeds
raise ValidationError([_('Invalid password.')]) # lint-amnesty, pylint: disable=raise-missing-from
@@ -159,7 +158,7 @@ class MinimumLengthValidator(DjangoMinimumLengthValidator): # lint-amnesty, pyl
return 'min_length', self.min_length
class MaximumLengthValidator(object):
class MaximumLengthValidator:
"""
Validate whether the password is shorter than a maximum length.
@@ -195,7 +194,7 @@ class MaximumLengthValidator(object):
return 'max_length', self.max_length
class AlphabeticValidator(object):
class AlphabeticValidator:
"""
Validate whether the password contains at least min_alphabetic letters.
@@ -243,7 +242,7 @@ class AlphabeticValidator(object):
return 'min_alphabetic', self.min_alphabetic
class NumericValidator(object):
class NumericValidator:
"""
Validate whether the password contains at least min_numeric numbers.
@@ -291,7 +290,7 @@ class NumericValidator(object):
return 'min_numeric', self.min_numeric
class UppercaseValidator(object):
class UppercaseValidator:
"""
Validate whether the password contains at least min_upper uppercase letters.
@@ -339,7 +338,7 @@ class UppercaseValidator(object):
return 'min_upper', self.min_upper
class LowercaseValidator(object):
class LowercaseValidator:
"""
Validate whether the password contains at least min_lower lowercase letters.
@@ -387,7 +386,7 @@ class LowercaseValidator(object):
return 'min_lower', self.min_lower
class PunctuationValidator(object):
class PunctuationValidator:
"""
Validate whether the password contains at least min_punctuation punctuation marks
as defined by unicode categories.
@@ -436,7 +435,7 @@ class PunctuationValidator(object):
return 'min_punctuation', self.min_punctuation
class SymbolValidator(object):
class SymbolValidator:
"""
Validate whether the password contains at least min_symbol symbols as defined by unicode categories.

View File

@@ -2,23 +2,19 @@
Utility Mixins for unit tests
"""
import json
import sys
from importlib import reload
from unittest.mock import patch
import six
from django.conf import settings
from django.test import TestCase
from django.urls import clear_url_caches, resolve
from mock import patch
from common.djangoapps.util.db import OuterAtomic
if six.PY3:
from importlib import reload
class UrlResetMixin(object):
class UrlResetMixin:
"""Mixin to reset urls.py before and after a test
Django memoizes the function that reads the urls module (whatever module
@@ -69,18 +65,18 @@ class UrlResetMixin(object):
URLCONF_MODULES = ['myapp.url', 'another_app.urls']
"""
super(UrlResetMixin, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
self.reset_urls()
self.addCleanup(self.reset_urls)
class EventTestMixin(object):
class EventTestMixin:
"""
Generic mixin for verifying that events were emitted during a test.
"""
def setUp(self, tracker):
super(EventTestMixin, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
patcher = patch(tracker)
self.mock_tracker = patcher.start()
self.addCleanup(patcher.stop)
@@ -124,7 +120,7 @@ class EventTestMixin(object):
return self.mock_tracker.emit.call_args[0]
class PatchMediaTypeMixin(object):
class PatchMediaTypeMixin:
"""
Generic mixin for verifying unsupported media type in PATCH
"""

View File

@@ -10,7 +10,7 @@ from django.conf import settings
from django.core.cache import cache
class CourseCatalogServiceMockMixin(object):
class CourseCatalogServiceMockMixin:
"""
Mocks for the Open edX service 'Course Catalog Service' responses.
"""
@@ -19,7 +19,7 @@ class CourseCatalogServiceMockMixin(object):
)
def setUp(self):
super(CourseCatalogServiceMockMixin, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
cache.clear()
def mock_course_discovery_api_for_catalog_contains(self, catalog_id=1, course_run_ids=None):

View File

@@ -1,10 +1,9 @@
"""
Tests for course utils.
"""
from unittest import mock
import ddt
import mock
from django.conf import settings
from openedx.core.djangoapps.content.course_overviews.models import CourseOverview
@@ -20,7 +19,7 @@ class TestCourseSharingLinks(ModuleStoreTestCase):
Tests for course sharing links.
"""
def setUp(self):
super(TestCourseSharingLinks, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
# create test mongo course
self.course = CourseFactory.create(
@@ -70,7 +69,7 @@ class TestCourseSharingLinks(ModuleStoreTestCase):
(True, True, 'test_social_sharing_url'),
(False, True, 'test_marketing_url'),
(True, False, 'test_social_sharing_url'),
(False, False, '{}/courses/course-v1:test_org+test_number+test_run/about'.format(settings.LMS_ROOT_URL)),
(False, False, f'{settings.LMS_ROOT_URL}/courses/course-v1:test_org+test_number+test_run/about'),
)
@ddt.unpack
def test_sharing_link_with_settings(self, enable_social_sharing, enable_mktg_site, expected_course_sharing_link):
@@ -88,7 +87,7 @@ class TestCourseSharingLinks(ModuleStoreTestCase):
(['marketing_url'], 'test_social_sharing_url'),
(
['social_sharing_url', 'marketing_url'],
'{}/courses/course-v1:test_org+test_number+test_run/about'.format(settings.LMS_ROOT_URL)
f'{settings.LMS_ROOT_URL}/courses/course-v1:test_org+test_number+test_run/about'
),
)
@ddt.unpack
@@ -112,7 +111,7 @@ class TestCourseSharingLinks(ModuleStoreTestCase):
(True, 'test_social_sharing_url'),
(
False,
'{}/courses/course-v1:test_org+test_number+test_run/about'.format(settings.LMS_ROOT_URL)
f'{settings.LMS_ROOT_URL}/courses/course-v1:test_org+test_number+test_run/about'
),
)
@ddt.unpack

View File

@@ -1,15 +1,14 @@
# -*- coding: utf-8 -*-
"""
Tests for util.date_utils
"""
import unittest
from datetime import datetime, timedelta, tzinfo
import pytest
from unittest.mock import patch
import ddt
import pytest
from markupsafe import Markup
from mock import patch
from pytz import utc
from common.djangoapps.util.date_utils import (
@@ -127,7 +126,7 @@ class StrftimeLocalizedTest(unittest.TestCase):
("%Y", "2013"),
("%m/%d/%y", "02/14/13"),
("hello", "hello"),
(u'%Y년 %m월 %d', u"2013년 02월 14일"),
('%Y년 %m월 %d', "2013년 02월 14일"),
("%a, %b %d, %Y", "Thu, Feb 14, 2013"),
("%I:%M:%S %p", "04:41:17 PM"),
("%A at %-I%P", "Thursday at 4pm"),

View File

@@ -4,6 +4,7 @@
import threading
import time
import unittest
from io import StringIO
import ddt
from django.contrib.auth.models import User # lint-amnesty, pylint: disable=imported-auth-user
@@ -12,8 +13,6 @@ from django.db import IntegrityError, connection
from django.db.transaction import TransactionManagementError, atomic
from django.test import TestCase, TransactionTestCase
from django.test.utils import override_settings
from django.utils.six import StringIO
from six.moves import range
from common.djangoapps.util.db import enable_named_outer_atomic, generate_int_id, outer_atomic
@@ -54,7 +53,7 @@ class TransactionManagersTestCase(TransactionTestCase):
class RequestThread(threading.Thread):
""" A thread which runs a dummy view."""
def __init__(self, delay, **kwargs):
super(RequestThread, self).__init__(**kwargs) # lint-amnesty, pylint: disable=super-with-arguments
super().__init__(**kwargs)
self.delay = delay
self.status = {}
@@ -189,7 +188,7 @@ class GenerateIntIdTestCase(TestCase):
used_ids = {2, 4, 6, 8}
for __ in range(times):
int_id = generate_int_id(minimum, maximum, used_ids)
assert int_id in list((set(range(minimum, (maximum + 1))) - used_ids))
assert int_id in list(set(range(minimum, (maximum + 1))) - used_ids)
class MigrationTests(TestCase):

View File

@@ -2,9 +2,9 @@
import unittest
from unittest import mock
import pytest
import mock
from django.conf import settings
from django.core.cache import cache
from django.test import TestCase
@@ -33,7 +33,7 @@ class DisableRateLimitTest(TestCase):
"""Check that we can disable rate limiting for perf testing. """
def setUp(self):
super(DisableRateLimitTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
cache.clear()
self.view = FakeApiView()

View File

@@ -13,7 +13,7 @@ from django.core.cache import caches
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase, SharedModuleStoreTestCase
class CacheCheckMixin(object):
class CacheCheckMixin:
"""Base mixin that does our cache check."""
def check_caches(self, key):

View File

@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
"""
Tests for file.py
"""
@@ -7,17 +6,17 @@ Tests for file.py
import os
from datetime import datetime
from io import StringIO
from unittest.mock import Mock, patch
import pytest
import ddt
from django.core import exceptions
from django.core.files.uploadedfile import SimpleUploadedFile
from django.http import HttpRequest
from django.test import TestCase
from mock import Mock, patch
from opaque_keys.edx.keys import CourseKey
from opaque_keys.edx.locations import CourseLocator
from pytz import UTC
from six import text_type
import common.djangoapps.util.file
from common.djangoapps.util.file import (
@@ -36,11 +35,11 @@ class FilenamePrefixGeneratorTestCase(TestCase):
"""
@ddt.data(CourseLocator(org='foo', course='bar', run='baz'), CourseKey.from_string('foo/bar/baz'))
def test_locators(self, course_key):
assert course_filename_prefix_generator(course_key) == u'foo_bar_baz'
assert course_filename_prefix_generator(course_key) == 'foo_bar_baz'
@ddt.data(CourseLocator(org='foo', course='bar', run='baz'), CourseKey.from_string('foo/bar/baz'))
def test_custom_separator(self, course_key):
assert course_filename_prefix_generator(course_key, separator='-') == u'foo-bar-baz'
assert course_filename_prefix_generator(course_key, separator='-') == 'foo-bar-baz'
@ddt.ddt
@@ -51,7 +50,7 @@ class FilenameGeneratorTestCase(TestCase):
NOW = datetime.strptime('1974-06-22T01:02:03', '%Y-%m-%dT%H:%M:%S').replace(tzinfo=UTC)
def setUp(self):
super(FilenameGeneratorTestCase, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
datetime_patcher = patch.object(
common.djangoapps.util.file, 'datetime',
Mock(wraps=datetime)
@@ -65,9 +64,9 @@ class FilenameGeneratorTestCase(TestCase):
"""
Tests that the generator creates names based on course_id, base name, and date.
"""
assert u'foo_bar_baz_file_1974-06-22-010203' == course_and_time_based_filename_generator(course_key, 'file')
assert 'foo_bar_baz_file_1974-06-22-010203' == course_and_time_based_filename_generator(course_key, 'file')
assert u'foo_bar_baz_base_name_ø_1974-06-22-010203' ==\
assert 'foo_bar_baz_base_name_ø_1974-06-22-010203' ==\
course_and_time_based_filename_generator(course_key, ' base` name ø ')
@@ -77,7 +76,7 @@ class StoreUploadedFileTestCase(TestCase):
"""
def setUp(self):
super(StoreUploadedFileTestCase, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
self.request = Mock(spec=HttpRequest)
self.file_content = b"test file content"
self.stored_file_name = None
@@ -85,7 +84,7 @@ class StoreUploadedFileTestCase(TestCase):
self.default_max_size = 2000000
def tearDown(self):
super(StoreUploadedFileTestCase, self).tearDown() # lint-amnesty, pylint: disable=super-with-arguments
super().tearDown()
if self.file_storage and self.stored_file_name:
self.file_storage.delete(self.stored_file_name)
@@ -93,7 +92,7 @@ class StoreUploadedFileTestCase(TestCase):
"""
Helper method to verify exception text.
"""
assert expected_message == text_type(error.value)
assert expected_message == str(error.value)
def test_error_conditions(self):
"""
@@ -226,39 +225,39 @@ class TestUniversalNewlineIterator(TestCase):
@ddt.data(1, 2, 999)
def test_line_feeds(self, buffer_size):
assert [thing.decode('utf-8') for thing
in UniversalNewlineIterator(StringIO(u'foo\nbar\n'), buffer_size=buffer_size)] == ['foo\n', 'bar\n']
in UniversalNewlineIterator(StringIO('foo\nbar\n'), buffer_size=buffer_size)] == ['foo\n', 'bar\n']
@ddt.data(1, 2, 999)
def test_carriage_returns(self, buffer_size):
assert [thing.decode('utf-8') for thing in
UniversalNewlineIterator(StringIO(u'foo\rbar\r'), buffer_size=buffer_size)] == ['foo\n', 'bar\n']
UniversalNewlineIterator(StringIO('foo\rbar\r'), buffer_size=buffer_size)] == ['foo\n', 'bar\n']
@ddt.data(1, 2, 999)
def test_carriage_returns_and_line_feeds(self, buffer_size):
assert [thing.decode('utf-8') for thing in
UniversalNewlineIterator(StringIO(u'foo\r\nbar\r\n'), buffer_size=buffer_size)] == ['foo\n', 'bar\n']
UniversalNewlineIterator(StringIO('foo\r\nbar\r\n'), buffer_size=buffer_size)] == ['foo\n', 'bar\n']
@ddt.data(1, 2, 999)
def test_no_trailing_newline(self, buffer_size):
assert [thing.decode('utf-8') for thing in
UniversalNewlineIterator(StringIO(u'foo\nbar'), buffer_size=buffer_size)] == ['foo\n', 'bar']
UniversalNewlineIterator(StringIO('foo\nbar'), buffer_size=buffer_size)] == ['foo\n', 'bar']
@ddt.data(1, 2, 999)
def test_only_one_line(self, buffer_size):
assert [thing.decode('utf-8') for thing in
UniversalNewlineIterator(StringIO(u'foo\n'), buffer_size=buffer_size)] == ['foo\n']
UniversalNewlineIterator(StringIO('foo\n'), buffer_size=buffer_size)] == ['foo\n']
@ddt.data(1, 2, 999)
def test_only_one_line_no_trailing_newline(self, buffer_size):
assert [thing.decode('utf-8') for thing in
UniversalNewlineIterator(StringIO(u'foo'), buffer_size=buffer_size)] == ['foo']
UniversalNewlineIterator(StringIO('foo'), buffer_size=buffer_size)] == ['foo']
@ddt.data(1, 2, 999)
def test_empty_file(self, buffer_size):
assert [thing.decode('utf-8') for thing in
UniversalNewlineIterator(StringIO(u''), buffer_size=buffer_size)] == []
UniversalNewlineIterator(StringIO(''), buffer_size=buffer_size)] == []
@ddt.data(1, 2, 999)
def test_unicode_data(self, buffer_size):
assert [thing.decode('utf-8') for thing
in UniversalNewlineIterator(StringIO(u'héllø wo®ld'), buffer_size=buffer_size)] == [u'héllø wo®ld']
in UniversalNewlineIterator(StringIO('héllø wo®ld'), buffer_size=buffer_size)] == ['héllø wo®ld']

View File

@@ -6,7 +6,7 @@ Test for JsonResponse and JsonResponseBadRequest util classes.
import json
import unittest
import mock
from unittest import mock
from django.http import HttpResponse, HttpResponseBadRequest
from common.djangoapps.util.json_request import JsonResponse, JsonResponseBadRequest

View File

@@ -1,11 +1,9 @@
"""
Tests for keyword_substitution.py
"""
from unittest.mock import patch
import six
from ddt import ddt, file_data
from mock import patch
from common.djangoapps.student.tests.factories import UserFactory
from common.djangoapps.util import keyword_substitution as Ks
@@ -21,7 +19,7 @@ class KeywordSubTest(ModuleStoreTestCase):
CREATE_USER = False
def setUp(self):
super(KeywordSubTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
self.user = UserFactory.create(
email="testuser@edx.org",
username="testuser",
@@ -115,14 +113,14 @@ class KeywordSubTest(ModuleStoreTestCase):
"""
test_string = 'This string should not be subbed here %%USER_ID%%'
no_course_context = dict(
(key, value) for key, value in six.iteritems(self.context) if key != 'course_title'
)
no_course_context = {
key: value for key, value in self.context.items() if key != 'course_title'
}
result = Ks.substitute_keywords_with_data(test_string, no_course_context)
assert test_string == result
no_user_id_context = dict(
(key, value) for key, value in six.iteritems(self.context) if key != 'user_id'
)
no_user_id_context = {
key: value for key, value in self.context.items() if key != 'user_id'
}
result = Ks.substitute_keywords_with_data(test_string, no_user_id_context)
assert test_string == result

View File

@@ -5,8 +5,6 @@ Tests for memcache in util app
from django.core.cache import caches
from django.test import TestCase
from six import unichr
from six.moves import range
from common.djangoapps.util.memcache import safe_key
@@ -21,7 +19,7 @@ class MemcacheTest(TestCase):
[129, 500, 2 ** 8 - 1, 2 ** 8 + 1, 2 ** 16 - 1])
def setUp(self):
super(MemcacheTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
self.cache = caches['default']
def test_safe_key(self):
@@ -51,7 +49,7 @@ class MemcacheTest(TestCase):
key = safe_key(key, '', '')
# The key should now be valid
assert self._is_valid_key(key), 'Failed for key length {0}'.format(length)
assert self._is_valid_key(key), f'Failed for key length {length}'
def test_long_key_prefix_version(self):
@@ -72,39 +70,39 @@ class MemcacheTest(TestCase):
for unicode_char in self.UNICODE_CHAR_CODES:
# Generate a key with that character
key = unichr(unicode_char)
key = chr(unicode_char)
# Make the key safe
key = safe_key(key, '', '')
# The key should now be valid
assert self._is_valid_key(key), 'Failed for unicode character {0}'.format(unicode_char)
assert self._is_valid_key(key), f'Failed for unicode character {unicode_char}'
def test_safe_key_prefix_unicode(self):
for unicode_char in self.UNICODE_CHAR_CODES:
# Generate a prefix with that character
prefix = unichr(unicode_char)
prefix = chr(unicode_char)
# Make the key safe
key = safe_key('test', prefix, '')
# The key should now be valid
assert self._is_valid_key(key), 'Failed for unicode character {0}'.format(unicode_char)
assert self._is_valid_key(key), f'Failed for unicode character {unicode_char}'
def test_safe_key_version_unicode(self):
for unicode_char in self.UNICODE_CHAR_CODES:
# Generate a version with that character
version = unichr(unicode_char)
version = chr(unicode_char)
# Make the key safe
key = safe_key('test', '', version)
# The key should now be valid
assert self._is_valid_key(key), 'Failed for unicode character {0}'.format(unicode_char)
assert self._is_valid_key(key), f'Failed for unicode character {unicode_char}'
def _is_valid_key(self, key):
"""

View File

@@ -1,17 +1,15 @@
"""
Tests for the milestones helpers library, which is the integration point for the edx_milestones API
"""
from unittest.mock import patch
import ddt
import pytest
import six
from django.conf import settings
from django.contrib.auth.models import AnonymousUser
from milestones import api as milestones_api
from milestones.exceptions import InvalidCourseKeyException, InvalidUserException
from milestones.models import MilestoneRelationshipType
from mock import patch
from common.djangoapps.util import milestones_helpers
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
@@ -31,7 +29,7 @@ class MilestonesHelpersTestCase(ModuleStoreTestCase):
"""
Test case scaffolding
"""
super(MilestonesHelpersTestCase, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
self.course = CourseFactory.create(
metadata={
'entrance_exam_enabled': True,
@@ -80,16 +78,16 @@ class MilestonesHelpersTestCase(ModuleStoreTestCase):
assert len(response) == 0
def test_add_course_milestone_returns_none_when_app_disabled(self):
response = milestones_helpers.add_course_milestone(six.text_type(self.course.id), 'requires', self.milestone)
response = milestones_helpers.add_course_milestone(str(self.course.id), 'requires', self.milestone)
assert response is None
def test_get_course_milestones_returns_none_when_app_disabled(self):
response = milestones_helpers.get_course_milestones(six.text_type(self.course.id))
response = milestones_helpers.get_course_milestones(str(self.course.id))
assert len(response) == 0
def test_add_course_content_milestone_returns_none_when_app_disabled(self):
response = milestones_helpers.add_course_content_milestone(
six.text_type(self.course.id),
str(self.course.id),
'i4x://any/content/id',
'requires',
self.milestone
@@ -98,7 +96,7 @@ class MilestonesHelpersTestCase(ModuleStoreTestCase):
def test_get_course_content_milestones_returns_none_when_app_disabled(self):
response = milestones_helpers.get_course_content_milestones(
six.text_type(self.course.id),
str(self.course.id),
'i4x://doesnt/matter/for/this/test',
'requires'
)
@@ -113,7 +111,7 @@ class MilestonesHelpersTestCase(ModuleStoreTestCase):
assert 'ENTRANCE_EXAM' in response
def test_get_course_milestones_fulfillment_paths_returns_none_when_app_disabled(self):
response = milestones_helpers.get_course_milestones_fulfillment_paths(six.text_type(self.course.id), self.user)
response = milestones_helpers.get_course_milestones_fulfillment_paths(str(self.course.id), self.user)
assert response is None
def test_add_user_milestone_returns_none_when_app_disabled(self):

View File

@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
"""Tests for util.password_policy_validators module."""
@@ -48,7 +47,7 @@ class PasswordPolicyValidatorsTestCase(unittest.TestCase):
def test_unicode_password(self):
""" Tests that validate_password enforces unicode """
unicode_str = u'𤭮'
unicode_str = '𤭮'
byte_str = unicode_str.encode('utf-8')
# Sanity checks and demonstration of why this test is useful
@@ -65,7 +64,7 @@ class PasswordPolicyValidatorsTestCase(unittest.TestCase):
def test_password_unicode_normalization(self):
""" Tests that validate_password normalizes passwords """
# s ̣ ̇ (s with combining dot below and combining dot above)
not_normalized_password = u'\u0073\u0323\u0307'
not_normalized_password = '\u0073\u0323\u0307'
assert len(not_normalized_password) == 3
# When we normalize we expect the not_normalized password to fail
@@ -102,10 +101,10 @@ class PasswordPolicyValidatorsTestCase(unittest.TestCase):
assert msg in password_validators_instruction_texts()
@data(
(u'userna', u'username', 'test@example.com', 'The password is too similar to the username.'),
(u'password', u'username', 'password@example.com', 'The password is too similar to the email address.'),
(u'password', u'username', 'test@password.com', 'The password is too similar to the email address.'),
(u'password', u'username', 'test@example.com', None),
('userna', 'username', 'test@example.com', 'The password is too similar to the username.'),
('password', 'username', 'password@example.com', 'The password is too similar to the email address.'),
('password', 'username', 'test@password.com', 'The password is too similar to the email address.'),
('password', 'username', 'test@example.com', None),
)
@unpack
@override_settings(AUTH_PASSWORD_VALIDATORS=[
@@ -118,13 +117,13 @@ class PasswordPolicyValidatorsTestCase(unittest.TestCase):
@data(
([create_validator_config('common.djangoapps.util.password_policy_validators.MinimumLengthValidator', {'min_length': 1})], # lint-amnesty, pylint: disable=line-too-long
u'', 'This password is too short. It must contain at least 1 character.'),
'', 'This password is too short. It must contain at least 1 character.'),
([create_validator_config('common.djangoapps.util.password_policy_validators.MinimumLengthValidator', {'min_length': 8})], # lint-amnesty, pylint: disable=line-too-long
u'd', 'This password is too short. It must contain at least 8 characters.'),
'd', 'This password is too short. It must contain at least 8 characters.'),
([create_validator_config('common.djangoapps.util.password_policy_validators.MinimumLengthValidator', {'min_length': 8})], # lint-amnesty, pylint: disable=line-too-long
u'longpassword', None),
'longpassword', None),
)
@unpack
def test_minimum_length_validation_errors(self, config, password, msg):
@@ -134,13 +133,13 @@ class PasswordPolicyValidatorsTestCase(unittest.TestCase):
@data(
([create_validator_config('common.djangoapps.util.password_policy_validators.MaximumLengthValidator', {'max_length': 1})], # lint-amnesty, pylint: disable=line-too-long
u'longpassword', 'This password is too long. It must contain no more than 1 character.'),
'longpassword', 'This password is too long. It must contain no more than 1 character.'),
([create_validator_config('common.djangoapps.util.password_policy_validators.MaximumLengthValidator', {'max_length': 10})], # lint-amnesty, pylint: disable=line-too-long
u'longpassword', 'This password is too long. It must contain no more than 10 characters.'),
'longpassword', 'This password is too long. It must contain no more than 10 characters.'),
([create_validator_config('common.djangoapps.util.password_policy_validators.MaximumLengthValidator', {'max_length': 20})], # lint-amnesty, pylint: disable=line-too-long
u'shortpassword', None),
'shortpassword', None),
)
@unpack
def test_maximum_length_validation_errors(self, config, password, msg):
@@ -149,8 +148,8 @@ class PasswordPolicyValidatorsTestCase(unittest.TestCase):
self.validation_errors_checker(password, msg)
@data(
(u'password', 'This password is too common.'),
(u'good_password', None),
('password', 'This password is too common.'),
('good_password', None),
)
@unpack
@override_settings(AUTH_PASSWORD_VALIDATORS=[
@@ -162,13 +161,13 @@ class PasswordPolicyValidatorsTestCase(unittest.TestCase):
@data(
([create_validator_config('common.djangoapps.util.password_policy_validators.AlphabeticValidator', {'min_alphabetic': 1})], # lint-amnesty, pylint: disable=line-too-long
u'12345', 'This password must contain at least 1 letter.'),
'12345', 'This password must contain at least 1 letter.'),
([create_validator_config('common.djangoapps.util.password_policy_validators.AlphabeticValidator', {'min_alphabetic': 5})], # lint-amnesty, pylint: disable=line-too-long
u'test123', 'This password must contain at least 5 letters.'),
'test123', 'This password must contain at least 5 letters.'),
([create_validator_config('common.djangoapps.util.password_policy_validators.AlphabeticValidator', {'min_alphabetic': 2})], # lint-amnesty, pylint: disable=line-too-long
u'password', None),
'password', None),
)
@unpack
def test_alphabetic_validation_errors(self, config, password, msg):
@@ -178,13 +177,13 @@ class PasswordPolicyValidatorsTestCase(unittest.TestCase):
@data(
([create_validator_config('common.djangoapps.util.password_policy_validators.NumericValidator', {'min_numeric': 1})], # lint-amnesty, pylint: disable=line-too-long
u'test', 'This password must contain at least 1 number.'),
'test', 'This password must contain at least 1 number.'),
([create_validator_config('common.djangoapps.util.password_policy_validators.NumericValidator', {'min_numeric': 4})], # lint-amnesty, pylint: disable=line-too-long
u'test123', 'This password must contain at least 4 numbers.'),
'test123', 'This password must contain at least 4 numbers.'),
([create_validator_config('common.djangoapps.util.password_policy_validators.NumericValidator', {'min_numeric': 2})], # lint-amnesty, pylint: disable=line-too-long
u'password123', None),
'password123', None),
)
@unpack
def test_numeric_validation_errors(self, config, password, msg):
@@ -194,13 +193,13 @@ class PasswordPolicyValidatorsTestCase(unittest.TestCase):
@data(
([create_validator_config('common.djangoapps.util.password_policy_validators.UppercaseValidator', {'min_upper': 1})], # lint-amnesty, pylint: disable=line-too-long
u'lowercase', 'This password must contain at least 1 uppercase letter.'),
'lowercase', 'This password must contain at least 1 uppercase letter.'),
([create_validator_config('common.djangoapps.util.password_policy_validators.UppercaseValidator', {'min_upper': 6})], # lint-amnesty, pylint: disable=line-too-long
u'NOTenough', 'This password must contain at least 6 uppercase letters.'),
'NOTenough', 'This password must contain at least 6 uppercase letters.'),
([create_validator_config('common.djangoapps.util.password_policy_validators.UppercaseValidator', {'min_upper': 1})], # lint-amnesty, pylint: disable=line-too-long
u'camelCase', None),
'camelCase', None),
)
@unpack
def test_upper_case_validation_errors(self, config, password, msg):
@@ -210,13 +209,13 @@ class PasswordPolicyValidatorsTestCase(unittest.TestCase):
@data(
([create_validator_config('common.djangoapps.util.password_policy_validators.LowercaseValidator', {'min_lower': 1})], # lint-amnesty, pylint: disable=line-too-long
u'UPPERCASE', 'This password must contain at least 1 lowercase letter.'),
'UPPERCASE', 'This password must contain at least 1 lowercase letter.'),
([create_validator_config('common.djangoapps.util.password_policy_validators.LowercaseValidator', {'min_lower': 4})], # lint-amnesty, pylint: disable=line-too-long
u'notENOUGH', 'This password must contain at least 4 lowercase letters.'),
'notENOUGH', 'This password must contain at least 4 lowercase letters.'),
([create_validator_config('common.djangoapps.util.password_policy_validators.LowercaseValidator', {'min_lower': 1})], # lint-amnesty, pylint: disable=line-too-long
u'goodPassword', None),
'goodPassword', None),
)
@unpack
def test_lower_case_validation_errors(self, config, password, msg):
@@ -226,13 +225,13 @@ class PasswordPolicyValidatorsTestCase(unittest.TestCase):
@data(
([create_validator_config('common.djangoapps.util.password_policy_validators.PunctuationValidator', {'min_punctuation': 1})], # lint-amnesty, pylint: disable=line-too-long
u'no punctuation', 'This password must contain at least 1 punctuation mark.'),
'no punctuation', 'This password must contain at least 1 punctuation mark.'),
([create_validator_config('common.djangoapps.util.password_policy_validators.PunctuationValidator', {'min_punctuation': 7})], # lint-amnesty, pylint: disable=line-too-long
u'p@$$w0rd$!', 'This password must contain at least 7 punctuation marks.'),
'p@$$w0rd$!', 'This password must contain at least 7 punctuation marks.'),
([create_validator_config('common.djangoapps.util.password_policy_validators.PunctuationValidator', {'min_punctuation': 3})], # lint-amnesty, pylint: disable=line-too-long
u'excl@m@t!on', None),
'excl@m@t!on', None),
)
@unpack
def test_punctuation_validation_errors(self, config, password, msg):
@@ -242,13 +241,13 @@ class PasswordPolicyValidatorsTestCase(unittest.TestCase):
@data(
([create_validator_config('common.djangoapps.util.password_policy_validators.SymbolValidator', {'min_symbol': 1})], # lint-amnesty, pylint: disable=line-too-long
u'no symbol', 'This password must contain at least 1 symbol.'),
'no symbol', 'This password must contain at least 1 symbol.'),
([create_validator_config('common.djangoapps.util.password_policy_validators.SymbolValidator', {'min_symbol': 3})], # lint-amnesty, pylint: disable=line-too-long
u'boo☹', 'This password must contain at least 3 symbols.'),
'boo☹', 'This password must contain at least 3 symbols.'),
([create_validator_config('common.djangoapps.util.password_policy_validators.SymbolValidator', {'min_symbol': 2})], # lint-amnesty, pylint: disable=line-too-long
u'☪symbols!☹️', None),
'☪symbols!☹️', None),
)
@unpack
def test_symbol_validation_errors(self, config, password, msg):

View File

@@ -4,15 +4,11 @@ Utility functions related to urls.
import sys
from importlib import import_module
from importlib import import_module, reload
import six
from django.conf import settings
from django.urls import set_urlconf
if six.PY3:
from importlib import reload
def reload_django_url_config():
"""

View File

@@ -1,7 +1,7 @@
""" Utility mixin; forces models to validate *before* saving to db """
class ValidateOnSaveMixin(object):
class ValidateOnSaveMixin:
"""
Forces models to call their full_clean method prior to saving
"""
@@ -11,4 +11,4 @@ class ValidateOnSaveMixin(object):
"""
if not (force_insert or force_update):
self.full_clean()
super(ValidateOnSaveMixin, self).save(force_insert, force_update, **kwargs) # lint-amnesty, pylint: disable=super-with-arguments
super().save(force_insert, force_update, **kwargs)

View File

@@ -14,7 +14,6 @@ from django.views.defaults import server_error
from django.shortcuts import redirect
from opaque_keys import InvalidKeyError
from opaque_keys.edx.keys import CourseKey, UsageKey
from six.moves import map
from lms.djangoapps.courseware.access import has_access
from lms.djangoapps.courseware.masquerade import setup_masquerade
@@ -75,7 +74,7 @@ def require_global_staff(func):
return func(request, *args, **kwargs)
else:
return HttpResponseForbidden(
u"Must be {platform_name} staff to perform this action.".format(
"Must be {platform_name} staff to perform this action.".format(
platform_name=settings.PLATFORM_NAME
)
)

View File

@@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models
@@ -19,7 +16,7 @@ class Migration(migrations.Migration):
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('change_date', models.DateTimeField(auto_now_add=True, verbose_name='Change date')),
('enabled', models.BooleanField(default=False, verbose_name='Enabled')),
('disabled_blocks', models.TextField(default=u'', help_text='Space-separated list of XBlocks which should not render.', blank=True)),
('disabled_blocks', models.TextField(default='', help_text='Space-separated list of XBlocks which should not render.', blank=True)),
('changed_by', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, editable=False, to=settings.AUTH_USER_MODEL, null=True, verbose_name='Changed by')),
],
options={

View File

@@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from django.db import migrations, models
@@ -14,6 +11,6 @@ class Migration(migrations.Migration):
migrations.AddField(
model_name='xblockdisableconfig',
name='disabled_create_blocks',
field=models.TextField(default=u'', help_text='Space-separated list of XBlock types whose creation to disable in Studio.', blank=True),
field=models.TextField(default='', help_text='Space-separated list of XBlock types whose creation to disable in Studio.', blank=True),
),
]

View File

@@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models
@@ -36,8 +33,8 @@ class Migration(migrations.Migration):
('change_date', models.DateTimeField(auto_now_add=True, verbose_name='Change date')),
('enabled', models.BooleanField(default=False, verbose_name='Enabled')),
('name', models.CharField(max_length=255, db_index=True)),
('template', models.CharField(default=u'', max_length=255, blank=True)),
('support_level', models.CharField(default=u'us', max_length=2, choices=[(u'fs', 'Fully Supported'), (u'ps', 'Provisionally Supported'), (u'us', 'Unsupported')])),
('template', models.CharField(default='', max_length=255, blank=True)),
('support_level', models.CharField(default='us', max_length=2, choices=[('fs', 'Fully Supported'), ('ps', 'Provisionally Supported'), ('us', 'Unsupported')])),
('changed_by', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, editable=False, to=settings.AUTH_USER_MODEL, null=True, verbose_name='Changed by')),
],
),

View File

@@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from django.db import migrations, models

View File

@@ -40,13 +40,13 @@ class XBlockStudioConfigurationFlag(ConfigurationModel):
.. no_pii:
"""
class Meta(object):
class Meta:
app_label = "xblock_django"
# boolean field 'enabled' inherited from parent ConfigurationModel
def __str__(self):
return "XBlockStudioConfigurationFlag(enabled={})".format(self.enabled)
return f"XBlockStudioConfigurationFlag(enabled={self.enabled})"
class XBlockStudioConfiguration(ConfigurationModel):
@@ -57,9 +57,9 @@ class XBlockStudioConfiguration(ConfigurationModel):
"""
KEY_FIELDS = ('name', 'template') # xblock name/template combination is unique
FULL_SUPPORT = u'fs'
PROVISIONAL_SUPPORT = u'ps'
UNSUPPORTED = u'us'
FULL_SUPPORT = 'fs'
PROVISIONAL_SUPPORT = 'ps'
UNSUPPORTED = 'us'
SUPPORT_CHOICES = (
(FULL_SUPPORT, _('Fully Supported')),
@@ -69,10 +69,10 @@ class XBlockStudioConfiguration(ConfigurationModel):
# boolean field 'enabled' inherited from parent ConfigurationModel
name = models.CharField(max_length=255, null=False, db_index=True)
template = models.CharField(max_length=255, blank=True, default=u'')
template = models.CharField(max_length=255, blank=True, default='')
support_level = models.CharField(max_length=2, choices=SUPPORT_CHOICES, default=UNSUPPORTED)
class Meta(object):
class Meta:
app_label = "xblock_django"
def __str__(self):

View File

@@ -1,10 +1,6 @@
"""
Tests related to XBlock support API.
"""
import six
from openedx.core.djangolib.testing.utils import CacheIsolationTestCase
from common.djangoapps.xblock_django.api import authorable_xblocks, deprecated_xblocks, disabled_xblocks
from common.djangoapps.xblock_django.models import XBlockConfiguration, XBlockStudioConfiguration, XBlockStudioConfigurationFlag # lint-amnesty, pylint: disable=line-too-long
@@ -15,7 +11,7 @@ class XBlockSupportTestCase(CacheIsolationTestCase):
Tests for XBlock Support methods.
"""
def setUp(self):
super(XBlockSupportTestCase, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
# Set up XBlockConfigurations for disabled and deprecated states
block_config = [
@@ -47,23 +43,23 @@ class XBlockSupportTestCase(CacheIsolationTestCase):
""" Tests the deprecated_xblocks method """
deprecated_xblock_names = [block.name for block in deprecated_xblocks()]
six.assertCountEqual(self, ["poll", "survey"], deprecated_xblock_names)
self.assertCountEqual(["poll", "survey"], deprecated_xblock_names)
XBlockConfiguration(name="poll", enabled=True, deprecated=False).save()
deprecated_xblock_names = [block.name for block in deprecated_xblocks()]
six.assertCountEqual(self, ["survey"], deprecated_xblock_names)
self.assertCountEqual(["survey"], deprecated_xblock_names)
def test_disabled_blocks(self):
""" Tests the disabled_xblocks method """
disabled_xblock_names = [block.name for block in disabled_xblocks()]
six.assertCountEqual(self, ["survey"], disabled_xblock_names)
self.assertCountEqual(["survey"], disabled_xblock_names)
XBlockConfiguration(name="poll", enabled=False, deprecated=True).save()
disabled_xblock_names = [block.name for block in disabled_xblocks()]
six.assertCountEqual(self, ["survey", "poll"], disabled_xblock_names)
self.assertCountEqual(["survey", "poll"], disabled_xblock_names)
def test_authorable_blocks_empty_model(self):
"""
@@ -81,7 +77,7 @@ class XBlockSupportTestCase(CacheIsolationTestCase):
Tests authorable_xblocks when name is not specified.
"""
authorable_xblock_names = [block.name for block in authorable_xblocks()]
six.assertCountEqual(self, ["done", "problem", "problem", "html"], authorable_xblock_names)
self.assertCountEqual(["done", "problem", "problem", "html"], authorable_xblock_names)
# Note that "survey" is disabled in XBlockConfiguration, but it is still returned by
# authorable_xblocks because it is marked as enabled and unsupported in XBlockStudioConfiguration.
@@ -89,8 +85,7 @@ class XBlockSupportTestCase(CacheIsolationTestCase):
# is a whitelist and uses a combination of xblock type and template (and in addition has a global feature flag),
# it is expected that Studio code will need to filter by both disabled_xblocks and authorable_xblocks.
authorable_xblock_names = [block.name for block in authorable_xblocks(allow_unsupported=True)]
six.assertCountEqual(
self,
self.assertCountEqual(
["survey", "done", "problem", "problem", "problem", "html", "split_module"],
authorable_xblock_names
)

View File

@@ -26,7 +26,7 @@ class UserServiceTestCase(TestCase):
Tests for the DjangoXBlockUserService.
"""
def setUp(self):
super(UserServiceTestCase, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
self.user = UserFactory(username="tester", email="test@tester.com")
self.user.profile.name = "Test Tester"
set_user_preference(self.user, 'pref-lang', 'en')
@@ -52,7 +52,7 @@ class UserServiceTestCase(TestCase):
assert xb_user.opt_attrs[ATTR_KEY_USERNAME] == dj_user.username
assert xb_user.opt_attrs[ATTR_KEY_USER_ID] == dj_user.id
assert not xb_user.opt_attrs[ATTR_KEY_USER_IS_STAFF]
assert all(((pref in USER_PREFERENCES_WHITE_LIST) for pref in xb_user.opt_attrs[ATTR_KEY_USER_PREFERENCES]))
assert all((pref in USER_PREFERENCES_WHITE_LIST) for pref in xb_user.opt_attrs[ATTR_KEY_USER_PREFERENCES])
def test_convert_anon_user(self):
"""

View File

@@ -24,7 +24,7 @@ class DjangoXBlockUserService(UserService):
A user service that converts Django users to XBlockUser
"""
def __init__(self, django_user, **kwargs):
super(DjangoXBlockUserService, self).__init__(**kwargs) # lint-amnesty, pylint: disable=super-with-arguments
super().__init__(**kwargs)
self._django_user = django_user
if self._django_user:
self._django_user.user_is_staff = kwargs.get('user_is_staff', False)