BOM-2369 (B): Pyupgrade on contentstore/management (#26758)

* pyupgrade on contentstore/management
This commit is contained in:
M. Zulqarnain
2021-03-04 14:31:10 +05:00
committed by GitHub
parent 32fd2407e3
commit da970bf215
41 changed files with 206 additions and 255 deletions

View File

@@ -7,8 +7,6 @@ erroneous certificate names.
from collections import namedtuple
from django.core.management.base import BaseCommand
from six import text_type
from six.moves import input, range, zip
from xmodule.modulestore import ModuleStoreEnum
from xmodule.modulestore.django import modulestore
@@ -153,11 +151,11 @@ class Command(BaseCommand):
"""
headers = ["Course Key", "cert_name_short", "cert_name_short", "Should clean?"]
col_widths = [
max(len(text_type(result[col])) for result in results + [headers])
max(len(str(result[col])) for result in results + [headers])
for col in range(len(results[0]))
]
id_format = u"{{:>{}}} |".format(len(text_type(len(results))))
col_format = u"| {{:>{}}} |"
id_format = "{{:>{}}} |".format(len(str(len(results))))
col_format = "| {{:>{}}} |"
self.stdout.write(id_format.format(""), ending='')
for header, width in zip(headers, col_widths):
@@ -168,7 +166,7 @@ class Command(BaseCommand):
for idx, result in enumerate(results):
self.stdout.write(id_format.format(idx), ending='')
for col, width in zip(result, col_widths):
self.stdout.write(col_format.format(width).format(text_type(col)), ending='')
self.stdout.write(col_format.format(width).format(str(col)), ending='')
self.stdout.write("")
def _commit(self, results):

View File

@@ -33,10 +33,10 @@ class Command(BaseCommand):
assets_deleted = content_store.remove_redundant_content_for_courses()
success = True
except Exception as err: # lint-amnesty, pylint: disable=broad-except
log.info("=" * 30 + u"> failed to cleanup") # lint-amnesty, pylint: disable=logging-not-lazy
log.info("=" * 30 + "> failed to cleanup") # lint-amnesty, pylint: disable=logging-not-lazy
log.info("Error:")
log.info(err)
if success:
log.info("=" * 80)
log.info(u"Total number of assets deleted: {0}".format(assets_deleted))
log.info(f"Total number of assets deleted: {assets_deleted}")

View File

@@ -7,7 +7,6 @@ from datetime import datetime, timedelta
from django.contrib.auth.models import User # lint-amnesty, pylint: disable=imported-auth-user
from django.core.management.base import BaseCommand, CommandError
from six import text_type
from cms.djangoapps.contentstore.management.commands.utils import user_from_str
from cms.djangoapps.contentstore.views.course import create_new_course_in_store
@@ -23,12 +22,12 @@ class Command(BaseCommand):
"""
# can this query modulestore for the list of write accessible stores or does that violate command pattern?
help = u"Create a course in one of {}".format([ModuleStoreEnum.Type.mongo, ModuleStoreEnum.Type.split])
help = "Create a course in one of {}".format([ModuleStoreEnum.Type.mongo, ModuleStoreEnum.Type.split])
def add_arguments(self, parser):
parser.add_argument('modulestore',
choices=MODULESTORE_CHOICES,
help=u"Modulestore must be one of {}".format(MODULESTORE_CHOICES))
help=f"Modulestore must be one of {MODULESTORE_CHOICES}")
parser.add_argument('user',
help="The instructor's email address or integer ID.")
parser.add_argument('org',
@@ -53,7 +52,7 @@ class Command(BaseCommand):
try:
user_object = user_from_str(user)
except User.DoesNotExist:
raise CommandError(u"No user {user} found.".format(user=user)) # lint-amnesty, pylint: disable=raise-missing-from
raise CommandError(f"No user {user} found.") # lint-amnesty, pylint: disable=raise-missing-from
return user_object
def handle(self, *args, **options):
@@ -87,6 +86,6 @@ class Command(BaseCommand):
run,
fields
)
self.stdout.write(u"Created {}".format(text_type(new_course.id)))
self.stdout.write("Created {}".format(str(new_course.id)))
except DuplicateCourseError:
self.stdout.write(u"Course already exists")
self.stdout.write("Course already exists")

View File

@@ -6,7 +6,6 @@ Management Command to delete course.
from django.core.management.base import BaseCommand, CommandError
from opaque_keys import InvalidKeyError
from opaque_keys.edx.keys import CourseKey
from six import text_type
from cms.djangoapps.contentstore.utils import delete_course
from xmodule.contentstore.django import contentstore
@@ -62,25 +61,25 @@ class Command(BaseCommand):
try:
# a course key may have unicode chars in it
try:
course_key = text_type(options['course_key'], 'utf8')
course_key = str(options['course_key'], 'utf8')
# May already be decoded to unicode if coming in through tests, this is ok.
except TypeError:
course_key = text_type(options['course_key'])
course_key = str(options['course_key'])
course_key = CourseKey.from_string(course_key)
except InvalidKeyError:
raise CommandError(u'Invalid course_key: {}'.format(options['course_key'])) # lint-amnesty, pylint: disable=raise-missing-from
raise CommandError('Invalid course_key: {}'.format(options['course_key'])) # lint-amnesty, pylint: disable=raise-missing-from
if not modulestore().get_course(course_key):
raise CommandError(u'Course not found: {}'.format(options['course_key']))
raise CommandError('Course not found: {}'.format(options['course_key']))
print(u'Preparing to delete course %s from module store....' % options['course_key'])
print('Preparing to delete course %s from module store....' % options['course_key'])
if query_yes_no(u'Are you sure you want to delete course {}?'.format(course_key), default='no'):
if query_yes_no(u'Are you sure? This action cannot be undone!', default='no'):
if query_yes_no(f'Are you sure you want to delete course {course_key}?', default='no'):
if query_yes_no('Are you sure? This action cannot be undone!', default='no'):
delete_course(course_key, ModuleStoreEnum.UserID.mgmt_command, options['keep_instructors'])
if options['remove_assets']:
contentstore().delete_all_course_assets(course_key)
print(u'Deleted assets for course'.format(course_key)) # lint-amnesty, pylint: disable=too-many-format-args
print(f'Deleted assets for course {course_key}') # lint-amnesty, pylint: disable=too-many-format-args
print(u'Deleted course {}'.format(course_key))
print(f'Deleted course {course_key}')

View File

@@ -86,7 +86,7 @@ command again, adding --insert or --delete to edit the list.
if num < 3:
raise CommandError("Tabs 1 and 2 cannot be changed.")
if query_yes_no(u'Deleting tab {0} Confirm?'.format(num), default='no'):
if query_yes_no(f'Deleting tab {num} Confirm?', default='no'):
tabs.primitive_delete(course, num - 1) # -1 for 0-based indexing
elif options['insert']:
num, tab_type, name = options['insert']
@@ -94,7 +94,7 @@ command again, adding --insert or --delete to edit the list.
if num < 3:
raise CommandError("Tabs 1 and 2 cannot be changed.")
if query_yes_no(u'Inserting tab {0} "{1}" "{2}" Confirm?'.format(num, tab_type, name), default='no'):
if query_yes_no(f'Inserting tab {num} "{tab_type}" "{name}" Confirm?', default='no'):
tabs.primitive_insert(course, num - 1, tab_type, name) # -1 as above
except ValueError as e:
# Cute: translate to CommandError so the CLI error prints nicely.

View File

@@ -27,5 +27,5 @@ class Command(BaseCommand):
else:
course_ids = [course.id for course in modulestore().get_courses()]
if query_yes_no(u"Emptying {} trashcan(s). Confirm?".format(len(course_ids)), default="no"):
if query_yes_no("Emptying {} trashcan(s). Confirm?".format(len(course_ids)), default="no"):
empty_asset_trashcan(course_ids)

View File

@@ -32,14 +32,14 @@ class Command(BaseCommand):
try:
course_key = CourseKey.from_string(options['course_id'])
except InvalidKeyError:
raise CommandError(u"Invalid course_key: '%s'." % options['course_id']) # lint-amnesty, pylint: disable=raise-missing-from
raise CommandError("Invalid course_key: '%s'." % options['course_id']) # lint-amnesty, pylint: disable=raise-missing-from
if not modulestore().get_course(course_key):
raise CommandError(u"Course with %s key not found." % options['course_id'])
raise CommandError("Course with %s key not found." % options['course_id'])
output_path = options['output_path']
print(u"Exporting course id = {0} to {1}".format(course_key, output_path))
print(f"Exporting course id = {course_key} to {output_path}")
if not output_path.endswith('/'):
output_path += '/'

View File

@@ -4,7 +4,6 @@ Script for exporting all courseware from Mongo to a directory and listing the co
from django.core.management.base import BaseCommand
from six import text_type
from xmodule.contentstore.django import contentstore
from xmodule.modulestore.django import modulestore
@@ -28,8 +27,8 @@ class Command(BaseCommand):
print("=" * 80)
print("=" * 30 + "> Export summary")
print(u"Total number of courses to export: {0}".format(len(courses)))
print(u"Total number of courses which failed to export: {0}".format(len(failed_export_courses)))
print("Total number of courses to export: {}".format(len(courses)))
print("Total number of courses which failed to export: {}".format(len(failed_export_courses)))
print("List of export failed courses ids:")
print("\n".join(failed_export_courses))
print("=" * 80)
@@ -49,13 +48,13 @@ def export_courses_to_output_path(output_path):
for course_id in course_ids:
print("-" * 80)
print(u"Exporting course id = {0} to {1}".format(course_id, output_path))
print(f"Exporting course id = {course_id} to {output_path}")
try:
course_dir = text_type(course_id).replace('/', '...')
course_dir = str(course_id).replace('/', '...')
export_course_to_xml(module_store, content_store, course_id, root_dir, course_dir)
except Exception as err: # pylint: disable=broad-except
failed_export_courses.append(text_type(course_id))
print(u"=" * 30 + u"> Oops, failed to export {0}".format(course_id))
failed_export_courses.append(str(course_id))
print("=" * 30 + f"> Oops, failed to export {course_id}")
print("Error:")
print(err)

View File

@@ -34,33 +34,33 @@ class Command(BaseCommand):
try:
library_key = CourseKey.from_string(options['library_id'])
except InvalidKeyError:
raise CommandError(u'Invalid library ID: "{0}".'.format(options['library_id'])) # lint-amnesty, pylint: disable=raise-missing-from
raise CommandError('Invalid library ID: "{}".'.format(options['library_id'])) # lint-amnesty, pylint: disable=raise-missing-from
if not isinstance(library_key, LibraryLocator):
raise CommandError(u'Argument "{0}" is not a library key'.format(options['library_id']))
raise CommandError('Argument "{}" is not a library key'.format(options['library_id']))
library = module_store.get_library(library_key)
if library is None:
raise CommandError(u'Library "{0}" not found.'.format(options['library_id']))
raise CommandError('Library "{}" not found.'.format(options['library_id']))
dest_path = options['output_path'] or '.'
if not os.path.isdir(dest_path):
raise CommandError(u'Output path "{0}" not found.'.format(dest_path))
raise CommandError(f'Output path "{dest_path}" not found.')
try:
# Generate archive using the handy tasks implementation
tarball = tasks.create_export_tarball(library, library_key, {}, None)
except Exception as e:
raise CommandError(u'Failed to export "{0}" with "{1}"'.format(library_key, e)) # lint-amnesty, pylint: disable=raise-missing-from
raise CommandError(f'Failed to export "{library_key}" with "{e}"') # lint-amnesty, pylint: disable=raise-missing-from
else:
with tarball:
# Save generated archive with keyed filename
prefix, suffix, n = str(library_key).replace(':', '+'), '.tar.gz', 0
while os.path.exists(prefix + suffix):
n += 1
prefix = u'{0}_{1}'.format(prefix.rsplit('_', 1)[0], n) if n > 1 else u'{}_1'.format(prefix)
prefix = '{}_{}'.format(prefix.rsplit('_', 1)[0], n) if n > 1 else f'{prefix}_1'
filename = prefix + suffix
target = os.path.join(dest_path, filename)
tarball.file.seek(0)
with open(target, 'w') as f:
shutil.copyfileobj(tarball.file, f)
print(u'Library "{0}" exported to "{1}"'.format(library.location.library_key, target))
print(f'Library "{library.location.library_key}" exported to "{target}"')

View File

@@ -98,7 +98,7 @@ def export_course_to_directory(course_key, root_dir):
# The safest characters are A-Z, a-z, 0-9, <underscore>, <period> and <hyphen>.
# We represent the first four with \w.
# TODO: Once we support courses with unicode characters, we will need to revisit this.
replacement_char = u'-'
replacement_char = '-'
course_dir = replacement_char.join([course.id.org, course.id.course, course.id.run])
course_dir = re.sub(r'[^\w\.\-]', replacement_char, course_dir)

View File

@@ -45,10 +45,10 @@ class Command(BaseCommand):
owning_store = modulestore()._get_modulestore_for_courselike(course_key) # pylint: disable=protected-access
if hasattr(owning_store, 'force_publish_course'):
versions = get_course_versions(options['course_key'])
print(u"Course versions : {0}".format(versions))
print(f"Course versions : {versions}")
if options['commit']:
if query_yes_no(u"Are you sure to publish the {0} course forcefully?".format(course_key), default="no"):
if query_yes_no(f"Are you sure to publish the {course_key} course forcefully?", default="no"):
# publish course forcefully
updated_versions = owning_store.force_publish_course(
course_key, ModuleStoreEnum.UserID.mgmt_command, options['commit']
@@ -56,20 +56,20 @@ class Command(BaseCommand):
if updated_versions:
# if publish and draft were different
if versions['published-branch'] != versions['draft-branch']:
print(u"Success! Published the course '{0}' forcefully.".format(course_key))
print(u"Updated course versions : \n{0}".format(updated_versions))
print(f"Success! Published the course '{course_key}' forcefully.")
print(f"Updated course versions : \n{updated_versions}")
else:
print(u"Course '{0}' is already in published state.".format(course_key))
print(f"Course '{course_key}' is already in published state.")
else:
print(u"Error! Could not publish course {0}.".format(course_key))
print(f"Error! Could not publish course {course_key}.")
else:
# if publish and draft were different
if versions['published-branch'] != versions['draft-branch']:
print("Dry run. Following would have been changed : ")
print(u"Published branch version {0} changed to draft branch version {1}".format(
print("Published branch version {} changed to draft branch version {}".format(
versions['published-branch'], versions['draft-branch'])
)
else:
print(u"Dry run. Course '{0}' is already in published state.".format(course_key))
print(f"Dry run. Course '{course_key}' is already in published state.")
else:
raise CommandError("The owning modulestore does not support this command.")

View File

@@ -8,7 +8,6 @@ import logging
from django.contrib.auth.models import User # lint-amnesty, pylint: disable=imported-auth-user
from django.core.management.base import BaseCommand, CommandError
from six import text_type
from cms.djangoapps.contentstore.management.commands.utils import user_from_str
from cms.djangoapps.contentstore.views.course import create_new_course_in_store
@@ -60,9 +59,9 @@ class Command(BaseCommand):
# Create the course
try:
new_course = create_new_course_in_store("split", user, org, num, run, fields)
logger.info(u"Created {}".format(text_type(new_course.id)))
logger.info("Created {}".format(str(new_course.id)))
except DuplicateCourseError:
logger.warning(u"Course already exists for %s, %s, %s", org, num, run)
logger.warning("Course already exists for %s, %s, %s", org, num, run)
# Configure credit provider
if ("enrollment" in course_settings) and ("credit_provider" in course_settings["enrollment"]):

View File

@@ -20,7 +20,6 @@ from django.core.management.base import BaseCommand, CommandError
from django.utils.translation import ugettext as _
from opaque_keys import InvalidKeyError
from opaque_keys.edx.keys import CourseKey
from six import text_type
import cms.djangoapps.contentstore.git_export_utils as git_export_utils
@@ -51,7 +50,7 @@ class Command(BaseCommand):
try:
course_key = CourseKey.from_string(options['course_loc'])
except InvalidKeyError:
raise CommandError(text_type(git_export_utils.GitExportError.BAD_COURSE)) # lint-amnesty, pylint: disable=raise-missing-from
raise CommandError(str(git_export_utils.GitExportError.BAD_COURSE)) # lint-amnesty, pylint: disable=raise-missing-from
try:
git_export_utils.export_to_git(
@@ -61,4 +60,4 @@ class Command(BaseCommand):
options.get('rdir', None)
)
except git_export_utils.GitExportError as ex:
raise CommandError(text_type(ex)) # lint-amnesty, pylint: disable=raise-missing-from
raise CommandError(str(ex)) # lint-amnesty, pylint: disable=raise-missing-from

View File

@@ -50,10 +50,10 @@ class Command(BaseCommand):
python_lib_filename = options.get('python_lib_filename')
output = (
u"Importing...\n"
u" data_dir={data}, source_dirs={courses}\n"
u" Importing static content? {import_static}\n"
u" Importing python lib? {import_python_lib}"
"Importing...\n"
" data_dir={data}, source_dirs={courses}\n"
" Importing static content? {import_static}\n"
" Importing python lib? {import_python_lib}"
).format(
data=data_dir,
courses=source_dirs,
@@ -74,5 +74,5 @@ class Command(BaseCommand):
for course in course_items:
course_id = course.id
if not are_permissions_roles_seeded(course_id):
self.stdout.write(u'Seeding forum roles for course {0}\n'.format(course_id))
self.stdout.write(f'Seeding forum roles for course {course_id}\n')
seed_permissions_roles(course_id)

View File

@@ -14,7 +14,6 @@ from django.core.management.base import BaseCommand, CommandError
from lxml import etree
from opaque_keys.edx.locator import LibraryLocator
from path import Path
from six.moves import input
from cms.djangoapps.contentstore.utils import add_instructor
from openedx.core.lib.extract_tar import safetar_extractall
@@ -52,7 +51,7 @@ class Command(BaseCommand):
try:
safetar_extractall(tar_file, course_dir.encode('utf-8'))
except SuspiciousOperation as exc:
raise CommandError(u'\n=== Course import {0}: Unsafe tar file - {1}\n'.format(archive_path, exc.args[0])) # lint-amnesty, pylint: disable=raise-missing-from
raise CommandError('\n=== Course import {}: Unsafe tar file - {}\n'.format(archive_path, exc.args[0])) # lint-amnesty, pylint: disable=raise-missing-from
finally:
tar_file.close()
@@ -63,7 +62,7 @@ class Command(BaseCommand):
# Gather library metadata from XML file
xml_root = etree.parse(abs_xml_path / 'library.xml').getroot()
if xml_root.tag != 'library':
raise CommandError(u'Failed to import {0}: Not a library archive'.format(archive_path))
raise CommandError(f'Failed to import {archive_path}: Not a library archive')
metadata = xml_root.attrib
org = metadata['org']
@@ -77,10 +76,10 @@ class Command(BaseCommand):
# Check if data would be overwritten
ans = ''
while not created and ans not in ['y', 'yes', 'n', 'no']:
inp = input(u'Library "{0}" already exists, overwrite it? [y/n] '.format(courselike_key))
inp = input(f'Library "{courselike_key}" already exists, overwrite it? [y/n] ')
ans = inp.lower()
if ans.startswith('n'):
print(u'Aborting import of "{0}"'.format(courselike_key))
print(f'Aborting import of "{courselike_key}"')
return
# At last, import the library
@@ -93,10 +92,10 @@ class Command(BaseCommand):
target_id=courselike_key
)
except Exception:
print(u'\n=== Failed to import library-v1:{0}+{1}'.format(org, library))
print(f'\n=== Failed to import library-v1:{org}+{library}')
raise
print(u'Library "{0}" imported to "{1}"'.format(archive_path, courselike_key))
print(f'Library "{archive_path}" imported to "{courselike_key}"')
def _get_or_create_library(org, number, display_name, user):

View File

@@ -42,7 +42,7 @@ class Command(BaseCommand):
try:
user = user_from_str(options['email'])
except User.DoesNotExist:
raise CommandError(u"No user found identified by {}".format(options['email'])) # lint-amnesty, pylint: disable=raise-missing-from
raise CommandError("No user found identified by {}".format(options['email'])) # lint-amnesty, pylint: disable=raise-missing-from
return course_key, user.id, options['org'], options['course'], options['run']

View File

@@ -5,8 +5,6 @@ Takes user input.
import sys
from six.moves import input
def query_yes_no(question, default="yes"):
"""Ask a yes/no question via raw_input() and return their answer.
@@ -32,7 +30,7 @@ def query_yes_no(question, default="yes"):
elif default == "no":
prompt = " [y/N] "
else:
raise ValueError(u"invalid default answer: '%s'" % default)
raise ValueError("invalid default answer: '%s'" % default)
while True:
sys.stdout.write(question + prompt)

View File

@@ -10,9 +10,8 @@ from opaque_keys import InvalidKeyError
from opaque_keys.edx.keys import CourseKey
from opaque_keys.edx.locator import CourseLocator
from search.search_engine_base import SearchEngine
from six.moves import map
from cms.djangoapps.contentstore.courseware_index import CoursewareSearchIndexer, CourseAboutSearchIndexer
from cms.djangoapps.contentstore.courseware_index import CourseAboutSearchIndexer, CoursewareSearchIndexer
from xmodule.modulestore.django import modulestore
from .prompt import query_yes_no
@@ -29,7 +28,7 @@ class Command(BaseCommand):
./manage.py reindex_course --setup - reindexes all courses for devstack setup
"""
help = dedent(__doc__)
CONFIRMATION_PROMPT = u"Re-indexing all courses might be a time consuming operation. Do you want to continue?"
CONFIRMATION_PROMPT = "Re-indexing all courses might be a time consuming operation. Do you want to continue?"
def add_arguments(self, parser):
parser.add_argument('course_ids',
@@ -47,10 +46,10 @@ class Command(BaseCommand):
try:
result = CourseKey.from_string(raw_value)
except InvalidKeyError:
raise CommandError(u"Invalid course_key: '%s'." % raw_value) # lint-amnesty, pylint: disable=raise-missing-from
raise CommandError("Invalid course_key: '%s'." % raw_value) # lint-amnesty, pylint: disable=raise-missing-from
if not isinstance(result, CourseLocator):
raise CommandError(u"Argument {0} is not a course key".format(raw_value))
raise CommandError(f"Argument {raw_value} is not a course key")
return result
@@ -76,7 +75,7 @@ class Command(BaseCommand):
try:
searcher = SearchEngine.get_search_engine(index_name)
except exceptions.ElasticsearchException as exc:
logging.exception(u'Search Engine error - %s', exc)
logging.exception('Search Engine error - %s', exc)
return
index_exists = searcher._es.indices.exists(index=index_name) # pylint: disable=protected-access

View File

@@ -6,7 +6,6 @@ from textwrap import dedent
from django.core.management import BaseCommand, CommandError
from opaque_keys.edx.keys import CourseKey
from opaque_keys.edx.locator import LibraryLocator
from six.moves import map
from cms.djangoapps.contentstore.courseware_index import LibrarySearchIndexer
from xmodule.modulestore.django import modulestore
@@ -24,7 +23,7 @@ class Command(BaseCommand):
./manage.py reindex_library --all - reindexes all available libraries
"""
help = dedent(__doc__)
CONFIRMATION_PROMPT = u"Reindexing all libraries might be a time consuming operation. Do you want to continue?"
CONFIRMATION_PROMPT = "Reindexing all libraries might be a time consuming operation. Do you want to continue?"
def add_arguments(self, parser):
parser.add_argument('library_ids', nargs='*')
@@ -40,7 +39,7 @@ class Command(BaseCommand):
result = CourseKey.from_string(raw_value)
if not isinstance(result, LibraryLocator):
raise CommandError(u"Argument {0} is not a library key".format(raw_value))
raise CommandError(f"Argument {raw_value} is not a library key")
return result
@@ -50,7 +49,7 @@ class Command(BaseCommand):
So, there could be no better docstring than emphasize this once again.
"""
if (not options['library_ids'] and not options['all']) or (options['library_ids'] and options['all']):
raise CommandError(u"reindex_library requires one or more <library_id>s or the --all flag.")
raise CommandError("reindex_library requires one or more <library_id>s or the --all flag.")
store = modulestore()
@@ -63,5 +62,5 @@ class Command(BaseCommand):
library_keys = list(map(self._parse_library_key, options['library_ids']))
for library_key in library_keys:
print(u"Indexing library {}".format(library_key))
print(f"Indexing library {library_key}")
LibrarySearchIndexer.do_library_reindex(store, library_key)

View File

@@ -53,7 +53,7 @@ class Command(BaseCommand):
if unparseable_guid or len(version_guid) != 24:
raise CommandError("version_guid should be a 24-digit hexadecimal number")
print("Resetting '{}' to version '{}'...".format(course_key, version_guid))
print(f"Resetting '{course_key}' to version '{version_guid}'...")
modulestore().reset_course_to_version(
course_key,
version_guid,

View File

@@ -8,7 +8,6 @@ from textwrap import dedent
from django.contrib.auth.models import User # lint-amnesty, pylint: disable=imported-auth-user
from django.core.management.base import BaseCommand, CommandError
from opaque_keys.edx.keys import CourseKey
from six import text_type
from cms.djangoapps.contentstore.management.commands.utils import user_from_str
from cms.djangoapps.contentstore.views.course import create_new_course_in_store
@@ -37,7 +36,7 @@ class Command(BaseCommand):
try:
user_object = user_from_str(user)
except User.DoesNotExist:
raise CommandError(u"No user {user} found.".format(user=user)) # lint-amnesty, pylint: disable=raise-missing-from
raise CommandError(f"No user {user} found.") # lint-amnesty, pylint: disable=raise-missing-from
return user_object
def handle(self, *args, **options):
@@ -60,10 +59,10 @@ class Command(BaseCommand):
course_key.run,
fields,
)
logger.info(u"Created {}".format(text_type(new_course.id)))
logger.info("Created {}".format(str(new_course.id)))
except DuplicateCourseError:
logger.warning(
u"Course already exists for %s, %s, %s. Skipping",
"Course already exists for %s, %s, %s. Skipping",
course_key.org,
course_key.course,
course_key.run,

View File

@@ -78,9 +78,9 @@ class BackfillOrgsAndOrgCoursesTest(SharedModuleStoreTestCase):
# Confirm starting condition:
# Only orgs are org_A and org_B, and only linkage is org_a->course_a1.
assert set(
assert {
org["short_name"] for org in get_organizations()
) == {
} == {
"org_A", "org_B"
}
assert len(get_organization_courses(get_organization_by_short_name('org_A'))) == 1
@@ -91,9 +91,9 @@ class BackfillOrgsAndOrgCoursesTest(SharedModuleStoreTestCase):
if run_type == "--dry":
# Confirm ending conditions are the same as the starting conditions.
assert set(
assert {
org["short_name"] for org in get_organizations()
) == {
} == {
"org_A", "org_B"
}
assert len(get_organization_courses(get_organization_by_short_name('org_A'))) == 1
@@ -101,9 +101,9 @@ class BackfillOrgsAndOrgCoursesTest(SharedModuleStoreTestCase):
else:
# Confirm ending condition:
# All five orgs present. Each org a has expected number of org-course linkages.
assert set(
assert {
org["short_name"] for org in get_organizations()
) == {
} == {
"org_A", "org_B", "org_C", "org_D", "org_E"
}
assert len(get_organization_courses(get_organization_by_short_name('org_A'))) == 2

View File

@@ -28,7 +28,7 @@ class ExportAllCourses(ModuleStoreTestCase):
def setUp(self):
""" Common setup. """
super(ExportAllCourses, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
self.content_store = contentstore()
# pylint: disable=protected-access
self.module_store = modulestore()._get_modulestore_by_type(ModuleStoreEnum.Type.mongo)
@@ -56,27 +56,27 @@ class ExportAllCourses(ModuleStoreTestCase):
# check that there are two assets ['example.txt', '.example.txt'] in contentstore for imported course
all_assets, count = self.content_store.get_all_content_for_course(course.id)
self.assertEqual(count, 2)
self.assertEqual(set([asset['_id']['name'] for asset in all_assets]), set([u'.example.txt', u'example.txt'])) # lint-amnesty, pylint: disable=consider-using-set-comprehension
self.assertEqual({asset['_id']['name'] for asset in all_assets}, {'.example.txt', 'example.txt'})
# manually add redundant assets (file ".DS_Store" and filename starts with "._")
course_filter = course.id.make_asset_key("asset", None)
query = location_to_query(course_filter, wildcard=True, tag=XASSET_LOCATION_TAG)
query['_id.name'] = all_assets[0]['_id']['name']
asset_doc = self.content_store.fs_files.find_one(query)
asset_doc['_id']['name'] = u'._example_test.txt'
asset_doc['_id']['name'] = '._example_test.txt'
self.content_store.fs_files.insert_one(asset_doc)
asset_doc['_id']['name'] = u'.DS_Store'
asset_doc['_id']['name'] = '.DS_Store'
self.content_store.fs_files.insert_one(asset_doc)
# check that now course has four assets
all_assets, count = self.content_store.get_all_content_for_course(course.id)
self.assertEqual(count, 4)
self.assertEqual(
set([asset['_id']['name'] for asset in all_assets]), # lint-amnesty, pylint: disable=consider-using-set-comprehension
set([u'.example.txt', u'example.txt', u'._example_test.txt', u'.DS_Store'])
{asset['_id']['name'] for asset in all_assets},
{'.example.txt', 'example.txt', '._example_test.txt', '.DS_Store'}
)
# now call asset_cleanup command and check that there is only two proper assets in contentstore for the course
call_command('cleanup_assets')
all_assets, count = self.content_store.get_all_content_for_course(course.id)
self.assertEqual(count, 2)
self.assertEqual(set([asset['_id']['name'] for asset in all_assets]), set([u'.example.txt', u'example.txt'])) # lint-amnesty, pylint: disable=consider-using-set-comprehension
self.assertEqual({asset['_id']['name'] for asset in all_assets}, {'.example.txt', 'example.txt'})

View File

@@ -2,12 +2,11 @@
Unittests for creating a course in an chosen modulestore
"""
from io import StringIO
import ddt
import six
from django.core.management import CommandError, call_command
from django.test import TestCase
from six import StringIO
from xmodule.modulestore import ModuleStoreEnum
from xmodule.modulestore.django import modulestore
@@ -19,13 +18,10 @@ class TestArgParsing(TestCase):
Tests for parsing arguments for the `create_course` management command
"""
def setUp(self): # lint-amnesty, pylint: disable=useless-super-delegation
super(TestArgParsing, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
def test_no_args(self):
if six.PY2:
errstring = "Error: too few arguments"
else:
errstring = "Error: the following arguments are required: modulestore, user, org, number, run"
errstring = "Error: the following arguments are required: modulestore, user, org, number, run"
with self.assertRaisesRegex(CommandError, errstring):
call_command('create_course')
@@ -61,7 +57,7 @@ class TestCreateCourse(ModuleStoreTestCase):
new_key = modulestore().make_course_key("org", "course", "run")
self.assertTrue(
modulestore().has_course(new_key),
u"Could not find course in {}".format(store)
f"Could not find course in {store}"
)
# pylint: disable=protected-access
self.assertEqual(store, modulestore()._get_modulestore_for_courselike(new_key).get_modulestore_type())
@@ -86,7 +82,7 @@ class TestCreateCourse(ModuleStoreTestCase):
"org", "course", "run", "dummy-course-name",
stderr=out
)
expected = u"Course already exists"
expected = "Course already exists"
self.assertIn(out.getvalue().strip(), expected)
@ddt.data(ModuleStoreEnum.Type.split, ModuleStoreEnum.Type.mongo)
@@ -114,7 +110,7 @@ class TestCreateCourse(ModuleStoreTestCase):
)
course = self.store.get_course(lowercase_course_id)
self.assertIsNotNone(course, 'Course not found using lowercase course key.')
self.assertEqual(six.text_type(course.id), six.text_type(lowercase_course_id))
self.assertEqual(str(course.id), str(lowercase_course_id))
# Verify store does not return course with different case.
uppercase_course_id = self.store.make_course_key(org.upper(), number.upper(), run.upper())

View File

@@ -3,7 +3,8 @@ Delete course tests.
"""
import mock
from unittest import mock
from django.core.management import CommandError, call_command
from common.djangoapps.student.roles import CourseInstructorRole

View File

@@ -2,7 +2,6 @@
import ddt
import six
from django.core.management import CommandError, call_command
from cms.djangoapps.contentstore.tests.test_orphan import TestOrphanBase
@@ -20,10 +19,7 @@ class TestDeleteOrphan(TestOrphanBase):
"""
Test delete_orphans command with no arguments
"""
if six.PY2:
errstring = 'Error: too few arguments'
else:
errstring = 'Error: the following arguments are required: course_id'
errstring = 'Error: the following arguments are required: course_id'
with self.assertRaisesRegex(CommandError, errstring):
call_command('delete_orphans')
@@ -34,7 +30,7 @@ class TestDeleteOrphan(TestOrphanBase):
results in no orphans being deleted
"""
course = self.create_course_with_orphans(default_store)
call_command('delete_orphans', six.text_type(course.id))
call_command('delete_orphans', str(course.id))
self.assertTrue(self.store.has_item(course.id.make_usage_key('html', 'multi_parent_html')))
self.assertTrue(self.store.has_item(course.id.make_usage_key('vertical', 'OrphanVert')))
self.assertTrue(self.store.has_item(course.id.make_usage_key('chapter', 'OrphanChapter')))
@@ -48,7 +44,7 @@ class TestDeleteOrphan(TestOrphanBase):
"""
course = self.create_course_with_orphans(default_store)
call_command('delete_orphans', six.text_type(course.id), '--commit')
call_command('delete_orphans', str(course.id), '--commit')
# make sure this module wasn't deleted
self.assertTrue(self.store.has_item(course.id.make_usage_key('html', 'multi_parent_html')))
@@ -72,7 +68,7 @@ class TestDeleteOrphan(TestOrphanBase):
# call delete orphans, specifying the published branch
# of the course
call_command('delete_orphans', six.text_type(published_branch), '--commit')
call_command('delete_orphans', str(published_branch), '--commit')
# now all orphans should be deleted
self.assertOrphanCount(course.id, 0)

View File

@@ -8,7 +8,6 @@ import unittest
from tempfile import mkdtemp
import ddt
import six
from django.core.management import CommandError, call_command
from xmodule.modulestore import ModuleStoreEnum
@@ -25,10 +24,7 @@ class TestArgParsingCourseExport(unittest.TestCase):
"""
Test export command with no arguments
"""
if six.PY2:
errstring = "Error: too few arguments"
else:
errstring = "Error: the following arguments are required: course_id, output_path"
errstring = "Error: the following arguments are required: course_id, output_path"
with self.assertRaisesRegex(CommandError, errstring):
call_command('export')
@@ -39,7 +35,7 @@ class TestCourseExport(ModuleStoreTestCase):
Test exporting a course
"""
def setUp(self):
super(TestCourseExport, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
# Temp directories (temp_dir_1: relative path, temp_dir_2: absolute path)
self.temp_dir_1 = mkdtemp()
@@ -55,10 +51,10 @@ class TestCourseExport(ModuleStoreTestCase):
Create a new course try exporting in a path specified
"""
course = CourseFactory.create(default_store=store)
course_id = six.text_type(course.id)
course_id = str(course.id)
self.assertTrue(
modulestore().has_course(course.id),
u"Could not find course in {}".format(store)
f"Could not find course in {store}"
)
# Test `export` management command with invalid course_id
errstring = "Invalid course_key: 'InvalidCourseID'."

View File

@@ -6,8 +6,6 @@ Test for export all courses.
import shutil
from tempfile import mkdtemp
import six
from cms.djangoapps.contentstore.management.commands.export_all_courses import export_courses_to_output_path
from xmodule.modulestore import ModuleStoreEnum
from xmodule.modulestore.django import modulestore
@@ -21,7 +19,7 @@ class ExportAllCourses(ModuleStoreTestCase):
"""
def setUp(self):
""" Common setup. """
super(ExportAllCourses, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
self.store = modulestore()._get_modulestore_by_type(ModuleStoreEnum.Type.mongo) # lint-amnesty, pylint: disable=protected-access
self.temp_dir = mkdtemp()
self.addCleanup(shutil.rmtree, self.temp_dir)
@@ -50,4 +48,4 @@ class ExportAllCourses(ModuleStoreTestCase):
courses, failed_export_courses = export_courses_to_output_path(self.temp_dir)
self.assertEqual(len(courses), 2)
self.assertEqual(len(failed_export_courses), 1)
self.assertEqual(failed_export_courses[0], six.text_type(second_course_id))
self.assertEqual(failed_export_courses[0], str(second_course_id))

View File

@@ -6,13 +6,12 @@ Tests for exporting OLX content.
import shutil
import tarfile
import unittest
from io import StringIO
from tempfile import mkdtemp
import ddt
import six
from django.core.management import CommandError, call_command
from path import Path as path
from six import StringIO
from xmodule.modulestore import ModuleStoreEnum
from xmodule.modulestore.django import modulestore
@@ -28,10 +27,7 @@ class TestArgParsingCourseExportOlx(unittest.TestCase):
"""
Test export command with no arguments
"""
if six.PY2:
errstring = "Error: too few arguments"
else:
errstring = "Error: the following arguments are required: course_id"
errstring = "Error: the following arguments are required: course_id"
with self.assertRaisesRegex(CommandError, errstring):
call_command('export_olx')
@@ -63,7 +59,7 @@ class TestCourseExportOlx(ModuleStoreTestCase):
course = CourseFactory.create(default_store=store_type)
self.assertTrue(
modulestore().has_course(course.id),
u"Could not find course in {}".format(store_type)
f"Could not find course in {store_type}"
)
return course.id
@@ -73,10 +69,10 @@ class TestCourseExportOlx(ModuleStoreTestCase):
dirname = "{0.org}-{0.course}-{0.run}".format(course_key)
self.assertIn(dirname, names)
# Check if some of the files are present, without being exhaustive.
self.assertIn("{}/about".format(dirname), names)
self.assertIn("{}/about/overview.html".format(dirname), names)
self.assertIn("{}/assets/assets.xml".format(dirname), names)
self.assertIn("{}/policies".format(dirname), names)
self.assertIn(f"{dirname}/about", names)
self.assertIn(f"{dirname}/about/overview.html", names)
self.assertIn(f"{dirname}/assets/assets.xml", names)
self.assertIn(f"{dirname}/policies", names)
@ddt.data(ModuleStoreEnum.Type.mongo, ModuleStoreEnum.Type.split)
def test_export_course(self, store_type):
@@ -84,7 +80,7 @@ class TestCourseExportOlx(ModuleStoreTestCase):
tmp_dir = path(mkdtemp())
self.addCleanup(shutil.rmtree, tmp_dir)
filename = tmp_dir / 'test.tar.gz'
call_command('export_olx', '--output', filename, six.text_type(test_course_key))
call_command('export_olx', '--output', filename, str(test_course_key))
with tarfile.open(filename) as tar_file:
self.check_export_file(tar_file, test_course_key)
@@ -99,7 +95,7 @@ class TestCourseExportOlx(ModuleStoreTestCase):
def test_export_course_stdout(self, store_type):
test_course_key = self.create_dummy_course(store_type)
out = StringIO()
call_command('export_olx', six.text_type(test_course_key), stdout=out)
call_command('export_olx', str(test_course_key), stdout=out)
out.seek(0)
output = out.read()
with tarfile.open(fileobj=StringIO(output)) as tar_file:

View File

@@ -3,7 +3,6 @@ Tests for the fix_not_found management command
"""
import six
from django.core.management import CommandError, call_command
from xmodule.modulestore import ModuleStoreEnum
@@ -19,10 +18,7 @@ class TestFixNotFound(ModuleStoreTestCase):
"""
Test fix_not_found command with no arguments
"""
if six.PY2:
msg = "Error: too few arguments"
else:
msg = "Error: the following arguments are required: course_id"
msg = "Error: the following arguments are required: course_id"
with self.assertRaisesRegex(CommandError, msg):
call_command('fix_not_found')
@@ -33,7 +29,7 @@ class TestFixNotFound(ModuleStoreTestCase):
"""
course = CourseFactory.create(default_store=ModuleStoreEnum.Type.mongo)
with self.assertRaisesRegex(CommandError, "The owning modulestore does not support this command."):
call_command("fix_not_found", six.text_type(course.id))
call_command("fix_not_found", str(course.id))
def test_fix_not_found(self):
course = CourseFactory.create(default_store=ModuleStoreEnum.Type.split)
@@ -53,7 +49,7 @@ class TestFixNotFound(ModuleStoreTestCase):
self.assertEqual(len(course.children), 2)
self.assertIn(dangling_pointer, course.children)
call_command("fix_not_found", six.text_type(course.id))
call_command("fix_not_found", str(course.id))
# make sure the dangling pointer was removed from
# the course block's children

View File

@@ -3,8 +3,8 @@ Tests for the force_publish management command
"""
import mock
import six
from unittest import mock
from django.core.management import CommandError, call_command
from cms.djangoapps.contentstore.management.commands.force_publish import Command
@@ -20,7 +20,7 @@ class TestForcePublish(SharedModuleStoreTestCase):
"""
@classmethod
def setUpClass(cls):
super(TestForcePublish, cls).setUpClass()
super().setUpClass()
cls.course = CourseFactory.create(default_store=ModuleStoreEnum.Type.split)
cls.test_user_id = ModuleStoreEnum.UserID.test
cls.command = Command()
@@ -29,10 +29,7 @@ class TestForcePublish(SharedModuleStoreTestCase):
"""
Test 'force_publish' command with no arguments
"""
if six.PY2:
errstring = "Error: too few arguments"
else:
errstring = "Error: the following arguments are required: course_key"
errstring = "Error: the following arguments are required: course_key"
with self.assertRaisesRegex(CommandError, errstring):
call_command('force_publish')
@@ -51,7 +48,7 @@ class TestForcePublish(SharedModuleStoreTestCase):
"""
errstring = "Error: unrecognized arguments: invalid-arg"
with self.assertRaisesRegex(CommandError, errstring):
call_command('force_publish', six.text_type(self.course.id), '--commit', 'invalid-arg')
call_command('force_publish', str(self.course.id), '--commit', 'invalid-arg')
def test_course_key_not_found(self):
"""
@@ -59,7 +56,7 @@ class TestForcePublish(SharedModuleStoreTestCase):
"""
errstring = "Course not found."
with self.assertRaisesRegex(CommandError, errstring):
call_command('force_publish', six.text_type('course-v1:org+course+run'))
call_command('force_publish', 'course-v1:org+course+run')
def test_force_publish_non_split(self):
"""
@@ -68,7 +65,7 @@ class TestForcePublish(SharedModuleStoreTestCase):
course = CourseFactory.create(default_store=ModuleStoreEnum.Type.mongo)
errstring = 'The owning modulestore does not support this command.'
with self.assertRaisesRegex(CommandError, errstring):
call_command('force_publish', six.text_type(course.id))
call_command('force_publish', str(course.id))
class TestForcePublishModifications(ModuleStoreTestCase):
@@ -78,7 +75,7 @@ class TestForcePublishModifications(ModuleStoreTestCase):
"""
def setUp(self):
super(TestForcePublishModifications, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
self.course = CourseFactory.create(default_store=ModuleStoreEnum.Type.split)
self.test_user_id = ModuleStoreEnum.UserID.test
self.command = Command()
@@ -100,7 +97,7 @@ class TestForcePublishModifications(ModuleStoreTestCase):
self.assertTrue(self.store.has_changes(self.store.get_item(self.course.location)))
# get draft and publish branch versions
versions = get_course_versions(six.text_type(self.course.id))
versions = get_course_versions(str(self.course.id))
draft_version = versions['draft-branch']
published_version = versions['published-branch']
@@ -111,13 +108,13 @@ class TestForcePublishModifications(ModuleStoreTestCase):
patched_yes_no.return_value = True
# force publish course
call_command('force_publish', six.text_type(self.course.id), '--commit')
call_command('force_publish', str(self.course.id), '--commit')
# verify that course has no changes
self.assertFalse(self.store.has_changes(self.store.get_item(self.course.location)))
# get new draft and publish branch versions
versions = get_course_versions(six.text_type(self.course.id))
versions = get_course_versions(str(self.course.id))
new_draft_version = versions['draft-branch']
new_published_version = versions['published-branch']

View File

@@ -4,9 +4,9 @@ Unittest for generate a test course in an given modulestore
import json
from unittest import mock
import ddt
import mock
from django.core.management import CommandError, call_command
from xmodule.modulestore.django import modulestore
@@ -120,7 +120,7 @@ class TestGenerateCourses(ModuleStoreTestCase):
}]}
arg = json.dumps(settings)
call_command("generate_courses", arg)
mock_logger.info.assert_any_call((u'invalid_field') + "is not a valid CourseField")
mock_logger.info.assert_any_call(('invalid_field') + "is not a valid CourseField")
@mock.patch('cms.djangoapps.contentstore.management.commands.generate_courses.logger')
def test_invalid_date_setting(self, mock_logger):

View File

@@ -8,15 +8,14 @@ import os
import shutil
import subprocess
import unittest
from io import StringIO
from uuid import uuid4
import six
from django.conf import settings
from django.core.management import call_command
from django.core.management.base import CommandError
from django.test.utils import override_settings
from opaque_keys.edx.locator import CourseLocator
from six import StringIO
import cms.djangoapps.contentstore.git_export_utils as git_export_utils
from cms.djangoapps.contentstore.git_export_utils import GitExportError
@@ -39,13 +38,13 @@ class TestGitExport(CourseTestCase):
"""
Create/reinitialize bare repo and folders needed
"""
super(TestGitExport, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
if not os.path.isdir(git_export_utils.GIT_REPO_EXPORT_DIR):
os.mkdir(git_export_utils.GIT_REPO_EXPORT_DIR)
self.addCleanup(shutil.rmtree, git_export_utils.GIT_REPO_EXPORT_DIR)
self.bare_repo_dir = '{0}/data/test_bare.git'.format(
self.bare_repo_dir = '{}/data/test_bare.git'.format(
os.path.abspath(settings.TEST_ROOT))
if not os.path.isdir(self.bare_repo_dir):
os.mkdir(self.bare_repo_dir)
@@ -61,34 +60,30 @@ class TestGitExport(CourseTestCase):
with self.assertRaisesRegex(CommandError, 'Error: unrecognized arguments:*'):
call_command('git_export', 'blah', 'blah', 'blah', stderr=StringIO())
if six.PY2:
with self.assertRaisesMessage(CommandError, 'Error: too few arguments'):
call_command('git_export', stderr=StringIO())
else:
with self.assertRaisesMessage(
CommandError,
'Error: the following arguments are required: course_loc, git_url'
):
call_command('git_export', stderr=StringIO())
with self.assertRaisesMessage(
CommandError,
'Error: the following arguments are required: course_loc, git_url'
):
call_command('git_export', stderr=StringIO())
# Send bad url to get course not exported
with self.assertRaisesRegex(CommandError, six.text_type(GitExportError.URL_BAD)):
with self.assertRaisesRegex(CommandError, str(GitExportError.URL_BAD)):
call_command('git_export', 'foo/bar/baz', 'silly', stderr=StringIO())
# Send bad course_id to get course not exported
with self.assertRaisesRegex(CommandError, six.text_type(GitExportError.BAD_COURSE)):
with self.assertRaisesRegex(CommandError, str(GitExportError.BAD_COURSE)):
call_command('git_export', 'foo/bar:baz', 'silly', stderr=StringIO())
def test_error_output(self):
"""
Verify that error output is actually resolved as the correct string
"""
with self.assertRaisesRegex(CommandError, six.text_type(GitExportError.BAD_COURSE)):
with self.assertRaisesRegex(CommandError, str(GitExportError.BAD_COURSE)):
call_command(
'git_export', 'foo/bar:baz', 'silly'
)
with self.assertRaisesRegex(CommandError, six.text_type(GitExportError.URL_BAD)):
with self.assertRaisesRegex(CommandError, str(GitExportError.URL_BAD)):
call_command(
'git_export', 'foo/bar/baz', 'silly'
)
@@ -98,37 +93,37 @@ class TestGitExport(CourseTestCase):
Test several bad URLs for validation
"""
course_key = CourseLocator('org', 'course', 'run')
with self.assertRaisesRegex(GitExportError, six.text_type(GitExportError.URL_BAD)):
with self.assertRaisesRegex(GitExportError, str(GitExportError.URL_BAD)):
git_export_utils.export_to_git(course_key, 'Sillyness')
with self.assertRaisesRegex(GitExportError, six.text_type(GitExportError.URL_BAD)):
with self.assertRaisesRegex(GitExportError, str(GitExportError.URL_BAD)):
git_export_utils.export_to_git(course_key, 'example.com:edx/notreal')
with self.assertRaisesRegex(GitExportError, six.text_type(GitExportError.URL_NO_AUTH)):
with self.assertRaisesRegex(GitExportError, str(GitExportError.URL_NO_AUTH)):
git_export_utils.export_to_git(course_key, 'http://blah')
def test_bad_git_repos(self):
"""
Test invalid git repos
"""
test_repo_path = '{}/test_repo'.format(git_export_utils.GIT_REPO_EXPORT_DIR)
test_repo_path = f'{git_export_utils.GIT_REPO_EXPORT_DIR}/test_repo'
self.assertFalse(os.path.isdir(test_repo_path))
course_key = CourseLocator('foo', 'blah', '100-')
# Test bad clones
with self.assertRaisesRegex(GitExportError, six.text_type(GitExportError.CANNOT_PULL)):
with self.assertRaisesRegex(GitExportError, str(GitExportError.CANNOT_PULL)):
git_export_utils.export_to_git(
course_key,
'https://user:blah@example.com/test_repo.git')
self.assertFalse(os.path.isdir(test_repo_path))
# Setup good repo with bad course to test xml export
with self.assertRaisesRegex(GitExportError, six.text_type(GitExportError.XML_EXPORT_FAIL)):
with self.assertRaisesRegex(GitExportError, str(GitExportError.XML_EXPORT_FAIL)):
git_export_utils.export_to_git(
course_key,
'file://{0}'.format(self.bare_repo_dir))
f'file://{self.bare_repo_dir}')
# Test bad git remote after successful clone
with self.assertRaisesRegex(GitExportError, six.text_type(GitExportError.CANNOT_PULL)):
with self.assertRaisesRegex(GitExportError, str(GitExportError.CANNOT_PULL)):
git_export_utils.export_to_git(
course_key,
'https://user:blah@example.com/r.git')
@@ -148,10 +143,10 @@ class TestGitExport(CourseTestCase):
"""
git_export_utils.export_to_git(
self.course.id,
'file://{0}'.format(self.bare_repo_dir),
f'file://{self.bare_repo_dir}',
'enigma'
)
expect_string = '{0}|{1}\n'.format(
expect_string = '{}|{}\n'.format(
git_export_utils.GIT_EXPORT_DEFAULT_IDENT['name'],
git_export_utils.GIT_EXPORT_DEFAULT_IDENT['email']
)
@@ -164,10 +159,10 @@ class TestGitExport(CourseTestCase):
self.populate_course()
git_export_utils.export_to_git(
self.course.id,
'file://{0}'.format(self.bare_repo_dir),
f'file://{self.bare_repo_dir}',
self.user.username
)
expect_string = '{0}|{1}\n'.format(
expect_string = '{}|{}\n'.format(
self.user.username,
self.user.email,
)
@@ -181,9 +176,9 @@ class TestGitExport(CourseTestCase):
"""
git_export_utils.export_to_git(
self.course.id,
'file://{0}'.format(self.bare_repo_dir)
f'file://{self.bare_repo_dir}'
)
with self.assertRaisesRegex(GitExportError, six.text_type(GitExportError.CANNOT_COMMIT)):
with self.assertRaisesRegex(GitExportError, str(GitExportError.CANNOT_COMMIT)):
git_export_utils.export_to_git(
self.course.id, 'file://{0}'.format(self.bare_repo_dir))
self.course.id, f'file://{self.bare_repo_dir}')

View File

@@ -7,7 +7,6 @@ import os
import shutil
import tempfile
import six
from django.core.management import call_command
from path import Path as path
@@ -26,9 +25,9 @@ class TestImport(ModuleStoreTestCase):
directory = tempfile.mkdtemp(dir=content_dir)
os.makedirs(os.path.join(directory, "course"))
with open(os.path.join(directory, "course.xml"), "w+") as f:
f.write(u'<course url_name="{0.run}" org="{0.org}" course="{0.course}"/>'.format(course_id))
f.write('<course url_name="{0.run}" org="{0.org}" course="{0.course}"/>'.format(course_id))
with open(os.path.join(directory, "course", "{0.run}.xml".format(course_id)), "w+") as f:
with open(os.path.join(directory, "course", f"{course_id.run}.xml"), "w+") as f:
f.write('<course><chapter name="Test Chapter"></chapter></course>')
return directory
@@ -37,12 +36,12 @@ class TestImport(ModuleStoreTestCase):
"""
Build course XML for importing
"""
super(TestImport, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
self.content_dir = path(tempfile.mkdtemp())
self.addCleanup(shutil.rmtree, self.content_dir)
self.base_course_key = self.store.make_course_key(u'edX', u'test_import_course', u'2013_Spring')
self.truncated_key = self.store.make_course_key(u'edX', u'test_import', u'2014_Spring')
self.base_course_key = self.store.make_course_key('edX', 'test_import_course', '2013_Spring')
self.truncated_key = self.store.make_course_key('edX', 'test_import', '2014_Spring')
# Create good course xml
self.good_dir = self.create_course_xml(self.content_dir, self.base_course_key)
@@ -93,4 +92,4 @@ class TestImport(ModuleStoreTestCase):
course = modulestore().get_course(self.base_course_key)
# With the bug, this fails because the chapter's course_key is the split mongo form,
# while the course's course_key is the old mongo form.
self.assertEqual(six.text_type(course.location.course_key), six.text_type(course.children[0].course_key))
self.assertEqual(str(course.location.course_key), str(course.children[0].course_key))

View File

@@ -3,7 +3,6 @@ Unittests for migrating a course to split mongo
"""
import six
from django.core.management import CommandError, call_command
from django.test import TestCase
@@ -19,16 +18,13 @@ class TestArgParsing(TestCase):
Tests for parsing arguments for the `migrate_to_split` management command
"""
def setUp(self): # lint-amnesty, pylint: disable=useless-super-delegation
super(TestArgParsing, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
def test_no_args(self):
"""
Test the arg length error
"""
if six.PY2:
errstring = "Error: too few arguments"
else:
errstring = "Error: the following arguments are required: course_key, email"
errstring = "Error: the following arguments are required: course_key, email"
with self.assertRaisesRegex(CommandError, errstring):
call_command("migrate_to_split")
@@ -64,7 +60,7 @@ class TestMigrateToSplit(ModuleStoreTestCase):
"""
def setUp(self):
super(TestMigrateToSplit, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
self.course = CourseFactory(default_store=ModuleStoreEnum.Type.mongo)
def test_user_email(self):

View File

@@ -1,13 +1,11 @@
""" Tests for course reindex command """
import ddt
import mock
import six
from django.core.management import CommandError, call_command
from six import text_type
from unittest import mock
import ddt
from django.core.management import CommandError, call_command
from cms.djangoapps.contentstore.courseware_index import SearchIndexingError # lint-amnesty, pylint: disable=unused-import
from cms.djangoapps.contentstore.management.commands.reindex_course import Command as ReindexCommand
from xmodule.modulestore import ModuleStoreEnum
from xmodule.modulestore.django import modulestore
@@ -20,7 +18,7 @@ class TestReindexCourse(ModuleStoreTestCase):
""" Tests for course reindex command """
def setUp(self):
""" Setup method - create courses """
super(TestReindexCourse, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
self.store = modulestore()
self.first_lib = LibraryFactory.create(
org="test", library="lib1", display_name="run1", default_store=ModuleStoreEnum.Type.split
@@ -58,41 +56,41 @@ class TestReindexCourse(ModuleStoreTestCase):
@ddt.data('qwerty', 'invalid_key', 'xblockv1:qwerty')
def test_given_invalid_course_key_raises_not_found(self, invalid_key):
""" Test that raises InvalidKeyError for invalid keys """
err_string = u"Invalid course_key: '{0}'".format(invalid_key)
err_string = f"Invalid course_key: '{invalid_key}'"
with self.assertRaisesRegex(CommandError, err_string):
call_command('reindex_course', invalid_key)
def test_given_library_key_raises_command_error(self):
""" Test that raises CommandError if library key is passed """
with self.assertRaisesRegex(CommandError, ".* is not a course key"):
call_command('reindex_course', text_type(self._get_lib_key(self.first_lib)))
call_command('reindex_course', str(self._get_lib_key(self.first_lib)))
with self.assertRaisesRegex(CommandError, ".* is not a course key"):
call_command('reindex_course', text_type(self._get_lib_key(self.second_lib)))
call_command('reindex_course', str(self._get_lib_key(self.second_lib)))
with self.assertRaisesRegex(CommandError, ".* is not a course key"):
call_command(
'reindex_course',
text_type(self.second_course.id),
text_type(self._get_lib_key(self.first_lib))
str(self.second_course.id),
str(self._get_lib_key(self.first_lib))
)
def test_given_id_list_indexes_courses(self):
""" Test that reindexes courses when given single course key or a list of course keys """
with mock.patch(self.REINDEX_PATH_LOCATION) as patched_index, \
mock.patch(self.MODULESTORE_PATCH_LOCATION, mock.Mock(return_value=self.store)):
call_command('reindex_course', text_type(self.first_course.id))
call_command('reindex_course', str(self.first_course.id))
self.assertEqual(patched_index.mock_calls, self._build_calls(self.first_course))
patched_index.reset_mock()
call_command('reindex_course', text_type(self.second_course.id))
call_command('reindex_course', str(self.second_course.id))
self.assertEqual(patched_index.mock_calls, self._build_calls(self.second_course))
patched_index.reset_mock()
call_command(
'reindex_course',
text_type(self.first_course.id),
text_type(self.second_course.id)
str(self.first_course.id),
str(self.second_course.id)
)
expected_calls = self._build_calls(self.first_course, self.second_course)
self.assertEqual(patched_index.mock_calls, expected_calls)
@@ -107,7 +105,7 @@ class TestReindexCourse(ModuleStoreTestCase):
patched_yes_no.assert_called_once_with(ReindexCommand.CONFIRMATION_PROMPT, default='no')
expected_calls = self._build_calls(self.first_course, self.second_course)
six.assertCountEqual(self, patched_index.mock_calls, expected_calls)
self.assertCountEqual(patched_index.mock_calls, expected_calls)
def test_given_all_key_prompts_and_reindexes_all_courses_cancelled(self):
""" Test that does not reindex anything when --all key is given and cancelled """

View File

@@ -1,9 +1,9 @@
""" Tests for library reindex command """
from unittest import mock
import ddt
import mock
import six
from django.core.management import CommandError, call_command
from opaque_keys import InvalidKeyError
@@ -20,7 +20,7 @@ class TestReindexLibrary(ModuleStoreTestCase):
""" Tests for library reindex command """
def setUp(self):
""" Setup method - create libraries and courses """
super(TestReindexLibrary, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
self.store = modulestore()
self.first_lib = LibraryFactory.create(
org="test", library="lib1", display_name="run1", default_store=ModuleStoreEnum.Type.split
@@ -64,34 +64,34 @@ class TestReindexLibrary(ModuleStoreTestCase):
def test_given_course_key_raises_command_error(self):
""" Test that raises CommandError if course key is passed """
with self.assertRaisesRegex(CommandError, ".* is not a library key"):
call_command('reindex_library', six.text_type(self.first_course.id))
call_command('reindex_library', str(self.first_course.id))
with self.assertRaisesRegex(CommandError, ".* is not a library key"):
call_command('reindex_library', six.text_type(self.second_course.id))
call_command('reindex_library', str(self.second_course.id))
with self.assertRaisesRegex(CommandError, ".* is not a library key"):
call_command(
'reindex_library',
six.text_type(self.second_course.id),
six.text_type(self._get_lib_key(self.first_lib))
str(self.second_course.id),
str(self._get_lib_key(self.first_lib))
)
def test_given_id_list_indexes_libraries(self):
""" Test that reindexes libraries when given single library key or a list of library keys """
with mock.patch(self.REINDEX_PATH_LOCATION) as patched_index, \
mock.patch(self.MODULESTORE_PATCH_LOCATION, mock.Mock(return_value=self.store)):
call_command('reindex_library', six.text_type(self._get_lib_key(self.first_lib)))
call_command('reindex_library', str(self._get_lib_key(self.first_lib)))
self.assertEqual(patched_index.mock_calls, self._build_calls(self.first_lib))
patched_index.reset_mock()
call_command('reindex_library', six.text_type(self._get_lib_key(self.second_lib)))
call_command('reindex_library', str(self._get_lib_key(self.second_lib)))
self.assertEqual(patched_index.mock_calls, self._build_calls(self.second_lib))
patched_index.reset_mock()
call_command(
'reindex_library',
six.text_type(self._get_lib_key(self.first_lib)),
six.text_type(self._get_lib_key(self.second_lib))
str(self._get_lib_key(self.first_lib)),
str(self._get_lib_key(self.second_lib))
)
expected_calls = self._build_calls(self.first_lib, self.second_lib)
self.assertEqual(patched_index.mock_calls, expected_calls)
@@ -106,7 +106,7 @@ class TestReindexLibrary(ModuleStoreTestCase):
patched_yes_no.assert_called_once_with(ReindexCommand.CONFIRMATION_PROMPT, default='no')
expected_calls = self._build_calls(self.first_lib, self.second_lib)
six.assertCountEqual(self, patched_index.mock_calls, expected_calls)
self.assertCountEqual(patched_index.mock_calls, expected_calls)
def test_given_all_key_prompts_and_reindexes_all_libraries_cancelled(self):
""" Test that does not reindex anything when --all key is given and cancelled """
@@ -125,4 +125,4 @@ class TestReindexLibrary(ModuleStoreTestCase):
patched_index.side_effect = SearchIndexingError("message", [])
with self.assertRaises(SearchIndexingError):
call_command('reindex_library', six.text_type(self._get_lib_key(self.second_lib)))
call_command('reindex_library', str(self._get_lib_key(self.second_lib)))

View File

@@ -1,10 +1,10 @@
"""
Shallow tests for `./manage.py cms reset_course_content COURSE_KEY VERSION_GUID`
"""
import mock
from unittest import mock
from django.test import TestCase
from django.core.management import CommandError, call_command
from django.test import TestCase
from opaque_keys import InvalidKeyError
from opaque_keys.edx.keys import CourseKey

View File

@@ -1,15 +1,16 @@
"""
Tests for sync courses management command
"""
import mock
from unittest import mock
from django.core.management import call_command
from opaque_keys.edx.keys import CourseKey
from testfixtures import LogCapture
from cms.djangoapps.contentstore.views.course import create_new_course_in_store
from common.djangoapps.student.tests.factories import UserFactory
from openedx.core.djangoapps.catalog.tests.factories import CourseRunFactory
from openedx.core.djangoapps.content.course_overviews.models import CourseOverview
from common.djangoapps.student.tests.factories import UserFactory
from xmodule.modulestore import ModuleStoreEnum
from xmodule.modulestore.django import modulestore
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
@@ -22,7 +23,7 @@ class TestSyncCoursesCommand(ModuleStoreTestCase):
""" Test sync_courses command """
def setUp(self):
super(TestSyncCoursesCommand, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
self.user = UserFactory(username='test', email='test@example.com')
self.catalog_course_runs = [
@@ -62,7 +63,7 @@ class TestSyncCoursesCommand(ModuleStoreTestCase):
with LogCapture() as capture:
call_command('sync_courses', self.user.email)
expected_message = u"Course already exists for {}, {}, {}. Skipping".format(
expected_message = "Course already exists for {}, {}, {}. Skipping".format(
course_key.org,
course_key.course,
course_key.run,

View File

@@ -6,7 +6,6 @@ do it manually for debugging, error recovery, or backfilling purposes.
Should be invoked from the Studio process.
"""
from django.core.management.base import BaseCommand
from opaque_keys.edx.keys import CourseKey
from ...tasks import update_outline_from_modulestore

View File

@@ -27,7 +27,7 @@ class Command(BaseCommand):
data_dir = options['data_dir']
source_dirs = options['source_dirs']
print(u"Importing. Data_dir={data}, source_dirs={courses}".format(
print("Importing. Data_dir={data}, source_dirs={courses}".format(
data=data_dir,
courses=source_dirs))