refactor: Remove PyContracts usage. (#27887)
* refactor: Remove PyContracts usage. We have not used PyContracts in a while and it is overhead we don't need in edx-platform. https://openedx.atlassian.net/browse/DEPR-147 * chore: Updating Python Requirements (#28018) Co-authored-by: edX requirements bot <49161187+edx-requirements-bot@users.noreply.github.com>
This commit is contained in:
@@ -11,7 +11,6 @@ import importlib
|
||||
import logging
|
||||
import os
|
||||
|
||||
import contracts
|
||||
import pytest
|
||||
|
||||
from openedx.core.pytest_hooks import DeferPlugin
|
||||
@@ -32,9 +31,6 @@ def pytest_configure(config):
|
||||
|
||||
if config.getoption('help'):
|
||||
return
|
||||
enable_contracts = os.environ.get('ENABLE_CONTRACTS', False)
|
||||
if not enable_contracts:
|
||||
contracts.disable_all()
|
||||
settings_module = os.environ.get('DJANGO_SETTINGS_MODULE')
|
||||
startup_module = 'cms.startup' if settings_module.startswith('cms') else 'lms.startup'
|
||||
startup = importlib.import_module(startup_module)
|
||||
|
||||
@@ -15,10 +15,6 @@ isort:skip_file
|
||||
from safe_lxml import defuse_xml_libs
|
||||
defuse_xml_libs()
|
||||
|
||||
# Disable PyContract contract checking when running as a webserver
|
||||
import contracts # lint-amnesty, pylint: disable=wrong-import-order, wrong-import-position
|
||||
contracts.disable_all()
|
||||
|
||||
import os # lint-amnesty, pylint: disable=wrong-import-order, wrong-import-position
|
||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "cms.envs.aws")
|
||||
|
||||
|
||||
@@ -8,18 +8,9 @@ from datetime import datetime
|
||||
|
||||
import dateutil.parser
|
||||
import pytz
|
||||
from contracts import contract, new_contract
|
||||
from lxml import etree
|
||||
from opaque_keys.edx.keys import AssetKey, CourseKey
|
||||
|
||||
new_contract('AssetKey', AssetKey)
|
||||
new_contract('CourseKey', CourseKey)
|
||||
new_contract('datetime', datetime)
|
||||
new_contract('basestring', (str,)[0])
|
||||
new_contract('long', int)
|
||||
new_contract('AssetElement', lambda x: isinstance(x, etree._Element) and x.tag == "asset") # pylint: disable=protected-access
|
||||
new_contract('AssetsElement', lambda x: isinstance(x, etree._Element) and x.tag == "assets") # pylint: disable=protected-access
|
||||
|
||||
|
||||
class AssetMetadata:
|
||||
"""
|
||||
@@ -51,13 +42,6 @@ class AssetMetadata:
|
||||
# Filename of all asset metadata exported as XML.
|
||||
EXPORTED_ASSET_FILENAME = 'assets.xml'
|
||||
|
||||
@contract(asset_id='AssetKey',
|
||||
pathname='str|None', internal_name='str|None',
|
||||
locked='bool|None', contenttype='str|None',
|
||||
thumbnail='str|None', fields='dict|None',
|
||||
curr_version='str|None', prev_version='str|None',
|
||||
created_by='int|long|None', created_by_email='str|None', created_on='datetime|None',
|
||||
edited_by='int|long|None', edited_by_email='str|None', edited_on='datetime|None')
|
||||
def __init__(self, asset_id,
|
||||
pathname=None, internal_name=None,
|
||||
locked=None, contenttype=None,
|
||||
@@ -155,7 +139,6 @@ class AssetMetadata:
|
||||
}
|
||||
}
|
||||
|
||||
@contract(asset_doc='dict|None')
|
||||
def from_storable(self, asset_doc):
|
||||
"""
|
||||
Fill in all metadata fields from a MongoDB document.
|
||||
@@ -179,7 +162,6 @@ class AssetMetadata:
|
||||
self.edited_by_email = asset_doc['edit_info']['edited_by_email']
|
||||
self.edited_on = asset_doc['edit_info']['edited_on']
|
||||
|
||||
@contract(node='AssetElement')
|
||||
def from_xml(self, node):
|
||||
"""
|
||||
Walk the etree XML node and fill in the asset metadata.
|
||||
@@ -210,7 +192,6 @@ class AssetMetadata:
|
||||
value = json.loads(value)
|
||||
setattr(self, tag, value)
|
||||
|
||||
@contract(node='AssetElement')
|
||||
def to_xml(self, node):
|
||||
"""
|
||||
Add the asset data as XML to the passed-in node.
|
||||
@@ -238,7 +219,6 @@ class AssetMetadata:
|
||||
child.text = value
|
||||
|
||||
@staticmethod
|
||||
@contract(node='AssetsElement', assets=list)
|
||||
def add_all_assets_as_xml(node, assets):
|
||||
"""
|
||||
Take a list of AssetMetadata objects. Add them all to the node.
|
||||
@@ -253,7 +233,6 @@ class CourseAssetsFromStorage:
|
||||
"""
|
||||
Wrapper class for asset metadata lists returned from modulestore storage.
|
||||
"""
|
||||
@contract(course_id='CourseKey', asset_md=dict)
|
||||
def __init__(self, course_id, doc_id, asset_md):
|
||||
"""
|
||||
Params:
|
||||
|
||||
@@ -13,14 +13,8 @@ Note: Hotfix (PLAT-734) No asset calls find_asset_metadata, and directly accesse
|
||||
|
||||
"""
|
||||
|
||||
|
||||
from contracts import contract, new_contract
|
||||
from opaque_keys.edx.keys import AssetKey
|
||||
|
||||
from xmodule.contentstore.django import contentstore
|
||||
|
||||
new_contract('AssetKey', AssetKey)
|
||||
|
||||
|
||||
class AssetException(Exception):
|
||||
"""
|
||||
@@ -48,7 +42,6 @@ class AssetManager:
|
||||
Manager for saving/loading course assets.
|
||||
"""
|
||||
@staticmethod
|
||||
@contract(asset_key='AssetKey', throw_on_not_found='bool', as_stream='bool')
|
||||
def find(asset_key, throw_on_not_found=True, as_stream=False):
|
||||
"""
|
||||
Finds course asset in the deprecated contentstore.
|
||||
|
||||
@@ -4,9 +4,7 @@ Test for asset XML generation / parsing.
|
||||
|
||||
|
||||
import unittest
|
||||
import pytest
|
||||
|
||||
from contracts import ContractNotRespected
|
||||
from lxml import etree
|
||||
from opaque_keys.edx.locator import CourseLocator
|
||||
from path import Path as path
|
||||
@@ -81,21 +79,3 @@ class TestAssetXml(unittest.TestCase):
|
||||
AssetMetadata.add_all_assets_as_xml(root, self.course_assets)
|
||||
# If this line does *not* raise, the XML is valid.
|
||||
etree.fromstring(etree.tostring(root), self.xmlparser)
|
||||
|
||||
def test_wrong_node_type_all(self):
|
||||
"""
|
||||
Ensure full asset sections with the wrong tag are detected.
|
||||
"""
|
||||
root = etree.Element("glassets")
|
||||
with pytest.raises(ContractNotRespected):
|
||||
AssetMetadata.add_all_assets_as_xml(root, self.course_assets)
|
||||
|
||||
def test_wrong_node_type_single(self):
|
||||
"""
|
||||
Ensure single asset blocks with the wrong tag are detected.
|
||||
"""
|
||||
asset_md = self.course_assets[0]
|
||||
root = etree.Element("assets")
|
||||
asset = etree.SubElement(root, "smashset")
|
||||
with pytest.raises(ContractNotRespected):
|
||||
asset_md.to_xml(asset)
|
||||
|
||||
@@ -11,7 +11,6 @@ import sys
|
||||
from collections import OrderedDict
|
||||
from datetime import datetime
|
||||
|
||||
from contracts import contract
|
||||
from pytz import UTC
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
@@ -26,7 +25,6 @@ class ScoreBase(metaclass=abc.ABCMeta): # pylint: disable=eq-without-hash
|
||||
Abstract base class for encapsulating fields of values scores.
|
||||
"""
|
||||
|
||||
@contract(graded="bool", first_attempted="datetime|None")
|
||||
def __init__(self, graded, first_attempted):
|
||||
"""
|
||||
Fields common to all scores include:
|
||||
@@ -56,7 +54,6 @@ class ProblemScore(ScoreBase):
|
||||
"""
|
||||
Encapsulates the fields of a Problem's score.
|
||||
"""
|
||||
@contract
|
||||
def __init__(self, raw_earned, raw_possible, weighted_earned, weighted_possible, weight, *args, **kwargs):
|
||||
"""
|
||||
In addition to the fields in ScoreBase, arguments include:
|
||||
@@ -88,7 +85,6 @@ class AggregatedScore(ScoreBase):
|
||||
"""
|
||||
Encapsulates the fields of a Subsection's score.
|
||||
"""
|
||||
@contract
|
||||
def __init__(self, tw_earned, tw_possible, *args, **kwargs):
|
||||
"""
|
||||
In addition to the fields in ScoreBase, also includes:
|
||||
|
||||
@@ -13,7 +13,6 @@ from collections import defaultdict
|
||||
from contextlib import contextmanager
|
||||
from operator import itemgetter
|
||||
|
||||
from contracts import contract, new_contract
|
||||
from opaque_keys.edx.keys import AssetKey, CourseKey
|
||||
from opaque_keys.edx.locations import Location # For import backwards compatibility
|
||||
from pytz import UTC
|
||||
@@ -32,11 +31,6 @@ from .exceptions import InsufficientSpecificationError, InvalidLocationError
|
||||
|
||||
log = logging.getLogger('edx.modulestore')
|
||||
|
||||
new_contract('CourseKey', CourseKey)
|
||||
new_contract('AssetKey', AssetKey)
|
||||
new_contract('AssetMetadata', AssetMetadata)
|
||||
new_contract('XBlock', XBlock)
|
||||
|
||||
LIBRARY_ROOT = 'library.xml'
|
||||
COURSE_ROOT = 'course.xml'
|
||||
|
||||
@@ -497,9 +491,6 @@ class BlockData: # pylint: disable=eq-without-hash
|
||||
return not self == block_data
|
||||
|
||||
|
||||
new_contract('BlockData', BlockData)
|
||||
|
||||
|
||||
class IncorrectlySortedList(Exception):
|
||||
"""
|
||||
Thrown when calling find() on a SortedAssetList not sorted by filename.
|
||||
@@ -519,7 +510,6 @@ class SortedAssetList(SortedKeyList): # lint-amnesty, pylint: disable=abstract-
|
||||
self.filename_sort = True
|
||||
super().__init__(**kwargs)
|
||||
|
||||
@contract(asset_id=AssetKey)
|
||||
def find(self, asset_id):
|
||||
"""
|
||||
Find the index of a particular asset in the list. This method is only functional for lists
|
||||
@@ -540,7 +530,6 @@ class SortedAssetList(SortedKeyList): # lint-amnesty, pylint: disable=abstract-
|
||||
idx = idx_left
|
||||
return idx
|
||||
|
||||
@contract(asset_md=AssetMetadata)
|
||||
def insert_or_update(self, asset_md):
|
||||
"""
|
||||
Insert asset metadata if asset is not present. Update asset metadata if asset is already present.
|
||||
@@ -577,7 +566,6 @@ class ModuleStoreAssetBase:
|
||||
|
||||
return course_assets, idx
|
||||
|
||||
@contract(asset_key='AssetKey')
|
||||
def find_asset_metadata(self, asset_key, **kwargs):
|
||||
"""
|
||||
Find the metadata for a particular course asset.
|
||||
@@ -597,10 +585,6 @@ class ModuleStoreAssetBase:
|
||||
mdata.from_storable(all_assets[asset_idx])
|
||||
return mdata
|
||||
|
||||
@contract(
|
||||
course_key='CourseKey', asset_type='None | str',
|
||||
start='int | None', maxresults='int | None', sort='tuple(str,int) | None'
|
||||
)
|
||||
def get_all_asset_metadata(self, course_key, asset_type, start=0, maxresults=-1, sort=None, **kwargs): # lint-amnesty, pylint: disable=unused-argument
|
||||
"""
|
||||
Returns a list of asset metadata for all assets of the given asset_type in the course.
|
||||
@@ -699,7 +683,6 @@ class ModuleStoreAssetWriteInterface(ModuleStoreAssetBase):
|
||||
all_assets.insert_or_update(asset_md)
|
||||
return assets_by_type
|
||||
|
||||
@contract(asset_metadata='AssetMetadata')
|
||||
def save_asset_metadata(self, asset_metadata, user_id, import_only):
|
||||
"""
|
||||
Saves the asset metadata for a particular course's asset.
|
||||
@@ -714,7 +697,6 @@ class ModuleStoreAssetWriteInterface(ModuleStoreAssetBase):
|
||||
"""
|
||||
raise NotImplementedError()
|
||||
|
||||
@contract(asset_metadata_list='list(AssetMetadata)')
|
||||
def save_asset_metadata_list(self, asset_metadata_list, user_id, import_only):
|
||||
"""
|
||||
Saves a list of asset metadata for a particular course's asset.
|
||||
@@ -741,7 +723,6 @@ class ModuleStoreAssetWriteInterface(ModuleStoreAssetBase):
|
||||
"""
|
||||
raise NotImplementedError()
|
||||
|
||||
@contract(asset_key='AssetKey', attr=str)
|
||||
def set_asset_metadata_attr(self, asset_key, attr, value, user_id):
|
||||
"""
|
||||
Add/set the given attr on the asset at the given location. Value can be any type which pymongo accepts.
|
||||
@@ -758,7 +739,6 @@ class ModuleStoreAssetWriteInterface(ModuleStoreAssetBase):
|
||||
"""
|
||||
return self.set_asset_metadata_attrs(asset_key, {attr: value}, user_id)
|
||||
|
||||
@contract(source_course_key='CourseKey', dest_course_key='CourseKey')
|
||||
def copy_all_asset_metadata(self, source_course_key, dest_course_key, user_id):
|
||||
"""
|
||||
Copy all the course assets from source_course_key to dest_course_key.
|
||||
@@ -832,7 +812,6 @@ class ModuleStoreRead(ModuleStoreAssetBase, metaclass=ABCMeta):
|
||||
"""
|
||||
pass # lint-amnesty, pylint: disable=unnecessary-pass
|
||||
|
||||
@contract(block='XBlock | BlockData | dict', qualifiers=dict)
|
||||
def _block_matches(self, block, qualifiers):
|
||||
"""
|
||||
Return True or False depending on whether the field value (block contents)
|
||||
|
||||
@@ -11,9 +11,8 @@ import itertools
|
||||
import logging
|
||||
from contextlib import contextmanager
|
||||
|
||||
from contracts import contract, new_contract
|
||||
from opaque_keys import InvalidKeyError
|
||||
from opaque_keys.edx.keys import AssetKey, CourseKey
|
||||
from opaque_keys.edx.keys import CourseKey
|
||||
from opaque_keys.edx.locator import LibraryLocator
|
||||
|
||||
from xmodule.assetstore import AssetMetadata
|
||||
@@ -23,12 +22,6 @@ from .draft_and_published import ModuleStoreDraftAndPublished
|
||||
from .exceptions import DuplicateCourseError, ItemNotFoundError
|
||||
from .split_migrator import SplitMigrator
|
||||
|
||||
new_contract('CourseKey', CourseKey)
|
||||
new_contract('AssetKey', AssetKey)
|
||||
new_contract('AssetMetadata', AssetMetadata)
|
||||
new_contract('LibraryLocator', LibraryLocator)
|
||||
new_contract('long', int)
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@@ -415,7 +408,6 @@ class MixedModuleStore(ModuleStoreDraftAndPublished, ModuleStoreWriteBase):
|
||||
return None
|
||||
|
||||
@strip_key
|
||||
@contract(library_key='LibraryLocator')
|
||||
def get_library(self, library_key, depth=0, **kwargs):
|
||||
"""
|
||||
returns the library block associated with the given key. If no such library exists,
|
||||
@@ -456,7 +448,6 @@ class MixedModuleStore(ModuleStoreDraftAndPublished, ModuleStoreWriteBase):
|
||||
store = self._get_modulestore_for_courselike(course_key)
|
||||
return store.delete_course(course_key, user_id)
|
||||
|
||||
@contract(asset_metadata='AssetMetadata', user_id='int|long', import_only=bool)
|
||||
def save_asset_metadata(self, asset_metadata, user_id, import_only=False):
|
||||
"""
|
||||
Saves the asset metadata for a particular course's asset.
|
||||
@@ -472,7 +463,6 @@ class MixedModuleStore(ModuleStoreDraftAndPublished, ModuleStoreWriteBase):
|
||||
store = self._get_modulestore_for_courselike(asset_metadata.asset_id.course_key)
|
||||
return store.save_asset_metadata(asset_metadata, user_id, import_only)
|
||||
|
||||
@contract(asset_metadata_list='list(AssetMetadata)', user_id='int|long', import_only=bool)
|
||||
def save_asset_metadata_list(self, asset_metadata_list, user_id, import_only=False):
|
||||
"""
|
||||
Saves the asset metadata for each asset in a list of asset metadata.
|
||||
@@ -492,7 +482,6 @@ class MixedModuleStore(ModuleStoreDraftAndPublished, ModuleStoreWriteBase):
|
||||
return store.save_asset_metadata_list(asset_metadata_list, user_id, import_only)
|
||||
|
||||
@strip_key
|
||||
@contract(asset_key='AssetKey')
|
||||
def find_asset_metadata(self, asset_key, **kwargs):
|
||||
"""
|
||||
Find the metadata for a particular course asset.
|
||||
@@ -507,7 +496,6 @@ class MixedModuleStore(ModuleStoreDraftAndPublished, ModuleStoreWriteBase):
|
||||
return store.find_asset_metadata(asset_key, **kwargs)
|
||||
|
||||
@strip_key
|
||||
@contract(course_key='CourseKey', asset_type='None | str', start=int, maxresults=int, sort='tuple|None')
|
||||
def get_all_asset_metadata(self, course_key, asset_type, start=0, maxresults=-1, sort=None, **kwargs):
|
||||
"""
|
||||
Returns a list of static assets for a course.
|
||||
@@ -529,7 +517,6 @@ class MixedModuleStore(ModuleStoreDraftAndPublished, ModuleStoreWriteBase):
|
||||
store = self._get_modulestore_for_courselike(course_key)
|
||||
return store.get_all_asset_metadata(course_key, asset_type, start, maxresults, sort, **kwargs)
|
||||
|
||||
@contract(asset_key='AssetKey', user_id='int|long')
|
||||
def delete_asset_metadata(self, asset_key, user_id):
|
||||
"""
|
||||
Deletes a single asset's metadata.
|
||||
@@ -544,7 +531,6 @@ class MixedModuleStore(ModuleStoreDraftAndPublished, ModuleStoreWriteBase):
|
||||
store = self._get_modulestore_for_courselike(asset_key.course_key)
|
||||
return store.delete_asset_metadata(asset_key, user_id)
|
||||
|
||||
@contract(source_course_key='CourseKey', dest_course_key='CourseKey', user_id='int|long')
|
||||
def copy_all_asset_metadata(self, source_course_key, dest_course_key, user_id):
|
||||
"""
|
||||
Copy all the course assets from source_course_key to dest_course_key.
|
||||
@@ -570,7 +556,6 @@ class MixedModuleStore(ModuleStoreDraftAndPublished, ModuleStoreWriteBase):
|
||||
# Courses in the same modulestore can be handled by the modulestore itself.
|
||||
source_store.copy_all_asset_metadata(source_course_key, dest_course_key, user_id)
|
||||
|
||||
@contract(asset_key='AssetKey', attr=str, user_id='int|long')
|
||||
def set_asset_metadata_attr(self, asset_key, attr, value, user_id):
|
||||
"""
|
||||
Add/set the given attr on the asset at the given location. Value can be any type which pymongo accepts.
|
||||
@@ -588,7 +573,6 @@ class MixedModuleStore(ModuleStoreDraftAndPublished, ModuleStoreWriteBase):
|
||||
store = self._get_modulestore_for_courselike(asset_key.course_key)
|
||||
return store.set_asset_metadata_attrs(asset_key, {attr: value}, user_id)
|
||||
|
||||
@contract(asset_key='AssetKey', attr_dict=dict, user_id='int|long')
|
||||
def set_asset_metadata_attrs(self, asset_key, attr_dict, user_id): # lint-amnesty, pylint: disable=arguments-differ
|
||||
"""
|
||||
Add/set the given dict of attrs on the asset at the given location. Value can be any type which pymongo accepts.
|
||||
|
||||
@@ -23,10 +23,9 @@ from uuid import uuid4
|
||||
|
||||
import pymongo
|
||||
from bson.son import SON
|
||||
from contracts import contract, new_contract
|
||||
from fs.osfs import OSFS
|
||||
from mongodb_proxy import autoretry_read
|
||||
from opaque_keys.edx.keys import AssetKey, CourseKey, UsageKey
|
||||
from opaque_keys.edx.keys import CourseKey, UsageKey
|
||||
from opaque_keys.edx.locator import BlockUsageLocator, CourseLocator, LibraryLocator
|
||||
from path import Path as path
|
||||
from pytz import UTC
|
||||
@@ -54,12 +53,6 @@ from xmodule.services import SettingsService
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
new_contract('CourseKey', CourseKey)
|
||||
new_contract('AssetKey', AssetKey)
|
||||
new_contract('AssetMetadata', AssetMetadata)
|
||||
new_contract('long', int)
|
||||
new_contract('BlockUsageLocator', BlockUsageLocator)
|
||||
|
||||
# sort order that returns DRAFT items first
|
||||
SORT_REVISION_FAVOR_DRAFT = ('_id.revision', pymongo.DESCENDING)
|
||||
|
||||
@@ -422,9 +415,6 @@ class CachingDescriptorSystem(MakoDescriptorSystem, EditInfoRuntimeMixin): # li
|
||||
return []
|
||||
|
||||
|
||||
new_contract('CachingDescriptorSystem', CachingDescriptorSystem)
|
||||
|
||||
|
||||
# The only thing using this w/ wildcards is contentstore.mongo for asset retrieval
|
||||
def location_to_query(location, wildcard=True, tag='i4x'):
|
||||
"""
|
||||
@@ -512,15 +502,12 @@ class ParentLocationCache(dict):
|
||||
Dict-based object augmented with a more cache-like interface, for internal use.
|
||||
"""
|
||||
|
||||
@contract(key=str)
|
||||
def has(self, key):
|
||||
return key in self
|
||||
|
||||
@contract(key=str, value="BlockUsageLocator | None")
|
||||
def set(self, key, value):
|
||||
self[key] = value
|
||||
|
||||
@contract(value="BlockUsageLocator")
|
||||
def delete_by_value(self, value):
|
||||
keys_to_delete = [k for k, v in self.items() if v == value]
|
||||
for key in keys_to_delete:
|
||||
@@ -874,12 +861,6 @@ class MongoModuleStore(ModuleStoreDraftAndPublished, ModuleStoreWriteBase, Mongo
|
||||
|
||||
return data
|
||||
|
||||
@contract(
|
||||
course_key=CourseKey,
|
||||
item=dict,
|
||||
apply_cached_metadata=bool,
|
||||
using_descriptor_system="None|CachingDescriptorSystem"
|
||||
)
|
||||
def _load_item(self, course_key, item, data_cache,
|
||||
apply_cached_metadata=True, using_descriptor_system=None, for_parent=None):
|
||||
"""
|
||||
@@ -1831,7 +1812,6 @@ class MongoModuleStore(ModuleStoreDraftAndPublished, ModuleStoreWriteBase, Mongo
|
||||
"""
|
||||
return f'assets.{asset_type}'
|
||||
|
||||
@contract(asset_metadata_list='list(AssetMetadata)', user_id='int|long')
|
||||
def _save_asset_metadata_list(self, asset_metadata_list, user_id, import_only):
|
||||
"""
|
||||
Internal; saves the info for a particular course's asset.
|
||||
@@ -1857,7 +1837,6 @@ class MongoModuleStore(ModuleStoreDraftAndPublished, ModuleStoreWriteBase, Mongo
|
||||
)
|
||||
return True
|
||||
|
||||
@contract(asset_metadata='AssetMetadata', user_id='int|long')
|
||||
def save_asset_metadata(self, asset_metadata, user_id, import_only=False):
|
||||
"""
|
||||
Saves the info for a particular course's asset.
|
||||
@@ -1872,7 +1851,6 @@ class MongoModuleStore(ModuleStoreDraftAndPublished, ModuleStoreWriteBase, Mongo
|
||||
"""
|
||||
return self._save_asset_metadata_list([asset_metadata, ], user_id, import_only)
|
||||
|
||||
@contract(asset_metadata_list='list(AssetMetadata)', user_id='int|long')
|
||||
def save_asset_metadata_list(self, asset_metadata_list, user_id, import_only=False):
|
||||
"""
|
||||
Saves the asset metadata for each asset in a list of asset metadata.
|
||||
@@ -1888,7 +1866,6 @@ class MongoModuleStore(ModuleStoreDraftAndPublished, ModuleStoreWriteBase, Mongo
|
||||
"""
|
||||
return self._save_asset_metadata_list(asset_metadata_list, user_id, import_only)
|
||||
|
||||
@contract(source_course_key='CourseKey', dest_course_key='CourseKey', user_id='int|long')
|
||||
def copy_all_asset_metadata(self, source_course_key, dest_course_key, user_id):
|
||||
"""
|
||||
Copy all the course assets from source_course_key to dest_course_key.
|
||||
@@ -1905,7 +1882,6 @@ class MongoModuleStore(ModuleStoreDraftAndPublished, ModuleStoreWriteBase, Mongo
|
||||
# Update the document.
|
||||
self.asset_collection.insert_one(dest_assets)
|
||||
|
||||
@contract(asset_key='AssetKey', attr_dict=dict, user_id='int|long')
|
||||
def set_asset_metadata_attrs(self, asset_key, attr_dict, user_id): # lint-amnesty, pylint: disable=arguments-differ
|
||||
"""
|
||||
Add/set the given dict of attrs on the asset at the given location. Value can be any type which pymongo accepts.
|
||||
@@ -1936,7 +1912,6 @@ class MongoModuleStore(ModuleStoreDraftAndPublished, ModuleStoreWriteBase, Mongo
|
||||
{"$set": {self._make_mongo_asset_key(asset_key.asset_type): all_assets}}
|
||||
)
|
||||
|
||||
@contract(asset_key='AssetKey', user_id='int|long')
|
||||
def delete_asset_metadata(self, asset_key, user_id):
|
||||
"""
|
||||
Internal; deletes a single asset's metadata.
|
||||
@@ -1961,7 +1936,6 @@ class MongoModuleStore(ModuleStoreDraftAndPublished, ModuleStoreWriteBase, Mongo
|
||||
)
|
||||
return 1
|
||||
|
||||
@contract(course_key='CourseKey', user_id='int|long')
|
||||
def delete_all_asset_metadata(self, course_key, user_id): # lint-amnesty, pylint: disable=unused-argument
|
||||
"""
|
||||
Delete all of the assets which use this course_key as an identifier.
|
||||
|
||||
@@ -5,19 +5,16 @@ General utilities
|
||||
|
||||
from collections import namedtuple
|
||||
|
||||
from contracts import check, contract
|
||||
from opaque_keys.edx.locator import BlockUsageLocator
|
||||
|
||||
|
||||
class BlockKey(namedtuple('BlockKey', 'type id')): # lint-amnesty, pylint: disable=missing-class-docstring
|
||||
__slots__ = ()
|
||||
|
||||
@contract(type="string[>0]")
|
||||
def __new__(cls, type, id): # lint-amnesty, pylint: disable=redefined-builtin
|
||||
return super().__new__(cls, type, id)
|
||||
|
||||
@classmethod
|
||||
@contract(usage_key=BlockUsageLocator)
|
||||
def from_usage_key(cls, usage_key):
|
||||
return cls(usage_key.block_type, usage_key.block_id)
|
||||
|
||||
|
||||
@@ -3,11 +3,9 @@
|
||||
import logging
|
||||
import sys
|
||||
|
||||
from contracts import contract, new_contract
|
||||
from fs.osfs import OSFS
|
||||
from lazy import lazy
|
||||
from opaque_keys.edx.locator import BlockUsageLocator, CourseLocator, DefinitionLocator, LibraryLocator, LocalId
|
||||
from xblock.core import XBlock
|
||||
from opaque_keys.edx.locator import BlockUsageLocator, DefinitionLocator, LocalId
|
||||
from xblock.fields import ScopeIds
|
||||
from xblock.runtime import KeyValueStore, KvsFieldData
|
||||
|
||||
@@ -15,7 +13,6 @@ from xmodule.error_module import ErrorBlock
|
||||
from xmodule.errortracker import exc_info_to_str
|
||||
from xmodule.library_tools import LibraryToolsService
|
||||
from xmodule.mako_module import MakoDescriptorSystem
|
||||
from xmodule.modulestore import BlockData
|
||||
from xmodule.modulestore.edit_info import EditInfoRuntimeMixin
|
||||
from xmodule.modulestore.exceptions import ItemNotFoundError
|
||||
from xmodule.modulestore.inheritance import InheritanceMixin, inheriting_field_data
|
||||
@@ -27,14 +24,6 @@ from xmodule.x_module import XModuleMixin
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
new_contract('BlockUsageLocator', BlockUsageLocator)
|
||||
new_contract('CourseLocator', CourseLocator)
|
||||
new_contract('LibraryLocator', LibraryLocator)
|
||||
new_contract('BlockKey', BlockKey)
|
||||
new_contract('BlockData', BlockData)
|
||||
new_contract('CourseEnvelope', CourseEnvelope)
|
||||
new_contract('XBlock', XBlock)
|
||||
|
||||
|
||||
class CachingDescriptorSystem(MakoDescriptorSystem, EditInfoRuntimeMixin): # lint-amnesty, pylint: disable=abstract-method
|
||||
"""
|
||||
@@ -43,7 +32,6 @@ class CachingDescriptorSystem(MakoDescriptorSystem, EditInfoRuntimeMixin): # li
|
||||
|
||||
Computes the settings (nee 'metadata') inheritance upon creation.
|
||||
"""
|
||||
@contract(course_entry=CourseEnvelope)
|
||||
def __init__(self, modulestore, course_entry, default_class, module_data, lazy, **kwargs): # lint-amnesty, pylint: disable=redefined-outer-name
|
||||
"""
|
||||
Computes the settings inheritance and sets up the cache.
|
||||
@@ -87,7 +75,6 @@ class CachingDescriptorSystem(MakoDescriptorSystem, EditInfoRuntimeMixin): # li
|
||||
self._services['library_tools'] = LibraryToolsService(modulestore, user_id=None)
|
||||
|
||||
@lazy
|
||||
@contract(returns="dict(BlockKey: BlockKey)")
|
||||
def _parent_map(self): # lint-amnesty, pylint: disable=missing-function-docstring
|
||||
parent_map = {}
|
||||
for block_key, block in self.course_entry.structure['blocks'].items():
|
||||
@@ -95,7 +82,6 @@ class CachingDescriptorSystem(MakoDescriptorSystem, EditInfoRuntimeMixin): # li
|
||||
parent_map[child] = block_key
|
||||
return parent_map
|
||||
|
||||
@contract(usage_key="BlockUsageLocator | BlockKey", course_entry_override="CourseEnvelope | None")
|
||||
def _load_item(self, usage_key, course_entry_override=None, **kwargs):
|
||||
"""
|
||||
Instantiate the xblock fetching it either from the cache or from the structure
|
||||
@@ -143,7 +129,6 @@ class CachingDescriptorSystem(MakoDescriptorSystem, EditInfoRuntimeMixin): # li
|
||||
self.modulestore.cache_block(course_key, version_guid, block_key, block)
|
||||
return block
|
||||
|
||||
@contract(block_key=BlockKey, course_key="CourseLocator | LibraryLocator")
|
||||
def get_module_data(self, block_key, course_key):
|
||||
"""
|
||||
Get block from module_data adding it to module_data if it's not already there but is in the structure
|
||||
@@ -172,7 +157,6 @@ class CachingDescriptorSystem(MakoDescriptorSystem, EditInfoRuntimeMixin): # li
|
||||
# low; thus, the course_entry is most likely correct. If the thread is looking at > 1 named container
|
||||
# pointing to the same structure, the access is likely to be chunky enough that the last known container
|
||||
# is the intended one when not given a course_entry_override; thus, the caching of the last branch/course id.
|
||||
@contract(block_key="BlockKey | None")
|
||||
def xblock_from_json(self, class_, course_key, block_key, block_data, course_entry_override=None, **kwargs):
|
||||
"""
|
||||
Load and return block info.
|
||||
@@ -299,7 +283,6 @@ class CachingDescriptorSystem(MakoDescriptorSystem, EditInfoRuntimeMixin): # li
|
||||
"""
|
||||
return xblock._edited_on # lint-amnesty, pylint: disable=protected-access
|
||||
|
||||
@contract(xblock='XBlock')
|
||||
def get_subtree_edited_by(self, xblock):
|
||||
"""
|
||||
See :class: cms.lib.xblock.runtime.EditInfoRuntimeMixin
|
||||
@@ -315,7 +298,6 @@ class CachingDescriptorSystem(MakoDescriptorSystem, EditInfoRuntimeMixin): # li
|
||||
|
||||
return xblock._subtree_edited_by
|
||||
|
||||
@contract(xblock='XBlock')
|
||||
def get_subtree_edited_on(self, xblock):
|
||||
"""
|
||||
See :class: cms.lib.xblock.runtime.EditInfoRuntimeMixin
|
||||
@@ -349,7 +331,6 @@ class CachingDescriptorSystem(MakoDescriptorSystem, EditInfoRuntimeMixin): # li
|
||||
|
||||
return getattr(xblock, '_published_on', None)
|
||||
|
||||
@contract(block_data='BlockData')
|
||||
def _compute_subtree_edited_internal(self, block_data, course_key):
|
||||
"""
|
||||
Recurse the subtree finding the max edited_on date and its corresponding edited_by. Cache it.
|
||||
|
||||
@@ -14,7 +14,6 @@ from time import time
|
||||
|
||||
import pymongo
|
||||
import pytz
|
||||
from contracts import check, new_contract
|
||||
from mongodb_proxy import autoretry_read
|
||||
# Import this just to export it
|
||||
from pymongo.errors import DuplicateKeyError # pylint: disable=unused-import
|
||||
@@ -29,7 +28,6 @@ try:
|
||||
except ImportError:
|
||||
DJANGO_AVAILABLE = False
|
||||
|
||||
new_contract('BlockData', BlockData)
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@@ -156,12 +154,6 @@ def structure_from_mongo(structure, course_context=None):
|
||||
with TIMER.timer('structure_from_mongo', course_context) as tagger:
|
||||
tagger.measure('blocks', len(structure['blocks']))
|
||||
|
||||
check('seq[2]', structure['root'])
|
||||
check('list(dict)', structure['blocks'])
|
||||
for block in structure['blocks']:
|
||||
if 'children' in block['fields']:
|
||||
check('list(list[2])', block['fields']['children'])
|
||||
|
||||
structure['root'] = BlockKey(*structure['root'])
|
||||
new_blocks = {}
|
||||
for block in structure['blocks']:
|
||||
@@ -184,12 +176,6 @@ def structure_to_mongo(structure, course_context=None):
|
||||
with TIMER.timer('structure_to_mongo', course_context) as tagger:
|
||||
tagger.measure('blocks', len(structure['blocks']))
|
||||
|
||||
check('BlockKey', structure['root'])
|
||||
check('dict(BlockKey: BlockData)', structure['blocks'])
|
||||
for block in structure['blocks'].values():
|
||||
if 'children' in block.fields:
|
||||
check('list(BlockKey)', block.fields['children'])
|
||||
|
||||
new_structure = dict(structure)
|
||||
new_structure['blocks'] = []
|
||||
|
||||
|
||||
@@ -64,7 +64,6 @@ from importlib import import_module
|
||||
|
||||
from bson.objectid import ObjectId
|
||||
from ccx_keys.locator import CCXBlockUsageLocator, CCXLocator
|
||||
from contracts import contract, new_contract
|
||||
from mongodb_proxy import autoretry_read
|
||||
from opaque_keys.edx.keys import CourseKey
|
||||
from opaque_keys.edx.locator import (
|
||||
@@ -134,11 +133,6 @@ log = logging.getLogger(__name__)
|
||||
EXCLUDE_ALL = '*'
|
||||
|
||||
|
||||
new_contract('BlockUsageLocator', BlockUsageLocator)
|
||||
new_contract('BlockKey', BlockKey)
|
||||
new_contract('XBlock', XBlock)
|
||||
|
||||
|
||||
class SplitBulkWriteRecord(BulkOpsRecord): # lint-amnesty, pylint: disable=missing-class-docstring
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
@@ -815,7 +809,6 @@ class SplitMongoModuleStore(SplitBulkWriteMixin, ModuleStoreWriteBase):
|
||||
system.module_data.update(new_module_data)
|
||||
return system.module_data
|
||||
|
||||
@contract(course_entry=CourseEnvelope, block_keys="list(BlockKey)", depth="int | None")
|
||||
def _load_items(self, course_entry, block_keys, depth=0, **kwargs):
|
||||
"""
|
||||
Load & cache the given blocks from the course. May return the blocks in any order.
|
||||
@@ -1224,7 +1217,6 @@ class SplitMongoModuleStore(SplitBulkWriteMixin, ModuleStoreWriteBase):
|
||||
|
||||
return self._get_block_from_structure(course_structure, BlockKey.from_usage_key(usage_key)) is not None
|
||||
|
||||
@contract(returns='XBlock')
|
||||
def get_item(self, usage_key, depth=0, **kwargs): # lint-amnesty, pylint: disable=arguments-differ
|
||||
"""
|
||||
depth (int): An argument that some module stores may use to prefetch
|
||||
@@ -1724,7 +1716,6 @@ class SplitMongoModuleStore(SplitBulkWriteMixin, ModuleStoreWriteBase):
|
||||
return potential_key
|
||||
serial += 1
|
||||
|
||||
@contract(returns='XBlock')
|
||||
def create_item(self, user_id, course_key, block_type, block_id=None, definition_locator=None, fields=None, # lint-amnesty, pylint: disable=arguments-differ
|
||||
asides=None, force=False, **kwargs):
|
||||
"""
|
||||
@@ -2491,7 +2482,6 @@ class SplitMongoModuleStore(SplitBulkWriteMixin, ModuleStoreWriteBase):
|
||||
self.update_structure(destination_course, destination_structure)
|
||||
self._update_head(destination_course, index_entry, destination_course.branch, destination_structure['_id'])
|
||||
|
||||
@contract(source_keys="list(BlockUsageLocator)", dest_usage=BlockUsageLocator)
|
||||
def copy_from_template(self, source_keys, dest_usage, user_id, head_validation=True):
|
||||
"""
|
||||
Flexible mechanism for inheriting content from an external course/library/etc.
|
||||
@@ -2723,7 +2713,6 @@ class SplitMongoModuleStore(SplitBulkWriteMixin, ModuleStoreWriteBase):
|
||||
|
||||
return result
|
||||
|
||||
@contract(root_block_key=BlockKey, blocks='dict(BlockKey: BlockData)')
|
||||
def _remove_subtree(self, root_block_key, blocks):
|
||||
"""
|
||||
Remove the subtree rooted at root_block_key
|
||||
@@ -2772,7 +2761,6 @@ class SplitMongoModuleStore(SplitBulkWriteMixin, ModuleStoreWriteBase):
|
||||
|
||||
self._emit_course_deleted_signal(course_key)
|
||||
|
||||
@contract(block_map="dict(BlockKey: dict)", block_key=BlockKey)
|
||||
def inherit_settings(
|
||||
self, block_map, block_key, inherited_settings_map, inheriting_settings=None, inherited_from=None
|
||||
):
|
||||
@@ -2927,7 +2915,6 @@ class SplitMongoModuleStore(SplitBulkWriteMixin, ModuleStoreWriteBase):
|
||||
"""
|
||||
return self.save_asset_metadata_list([asset_metadata, ], user_id, import_only)
|
||||
|
||||
@contract(asset_key='AssetKey', attr_dict=dict)
|
||||
def set_asset_metadata_attrs(self, asset_key, attr_dict, user_id): # lint-amnesty, pylint: disable=arguments-differ
|
||||
"""
|
||||
Add/set the given dict of attrs on the asset at the given location. Value can be any type which pymongo accepts.
|
||||
@@ -2958,7 +2945,6 @@ class SplitMongoModuleStore(SplitBulkWriteMixin, ModuleStoreWriteBase):
|
||||
|
||||
self._update_course_assets(user_id, asset_key, _internal_method)
|
||||
|
||||
@contract(asset_key='AssetKey')
|
||||
def delete_asset_metadata(self, asset_key, user_id):
|
||||
"""
|
||||
Internal; deletes a single asset's metadata.
|
||||
@@ -2985,7 +2971,6 @@ class SplitMongoModuleStore(SplitBulkWriteMixin, ModuleStoreWriteBase):
|
||||
except ItemNotFoundError:
|
||||
return 0
|
||||
|
||||
@contract(source_course_key='CourseKey', dest_course_key='CourseKey')
|
||||
def copy_all_asset_metadata(self, source_course_key, dest_course_key, user_id):
|
||||
"""
|
||||
Copy all the course assets from source_course_key to dest_course_key.
|
||||
@@ -3037,7 +3022,6 @@ class SplitMongoModuleStore(SplitBulkWriteMixin, ModuleStoreWriteBase):
|
||||
and converting them.
|
||||
:param jsonfields: the serialized copy of the xblock's fields
|
||||
"""
|
||||
@contract(block_key="BlockUsageLocator | seq[2]")
|
||||
def robust_usage_key(block_key):
|
||||
"""
|
||||
create a course_key relative usage key for the block_key. If the block_key is in blocks,
|
||||
@@ -3220,7 +3204,6 @@ class SplitMongoModuleStore(SplitBulkWriteMixin, ModuleStoreWriteBase):
|
||||
'schema_version': self.SCHEMA_VERSION,
|
||||
}
|
||||
|
||||
@contract(block_key=BlockKey)
|
||||
def _get_parents_from_structure(self, block_key, structure):
|
||||
"""
|
||||
Given a structure, find block_key's parent in that structure. Note returns
|
||||
@@ -3247,12 +3230,6 @@ class SplitMongoModuleStore(SplitBulkWriteMixin, ModuleStoreWriteBase):
|
||||
destination_parent.fields['children'] = destination_reordered
|
||||
return orphans
|
||||
|
||||
@contract(
|
||||
block_key=BlockKey,
|
||||
source_blocks="dict(BlockKey: *)",
|
||||
destination_blocks="dict(BlockKey: *)",
|
||||
blacklist="list(BlockKey) | str",
|
||||
)
|
||||
def _copy_subdag(self, user_id, destination_version, block_key, source_blocks, destination_blocks, blacklist):
|
||||
"""
|
||||
Update destination_blocks for the sub-dag rooted at block_key to be like the one in
|
||||
@@ -3321,7 +3298,6 @@ class SplitMongoModuleStore(SplitBulkWriteMixin, ModuleStoreWriteBase):
|
||||
destination_blocks[block_key] = destination_block
|
||||
return orphans
|
||||
|
||||
@contract(blacklist='list(BlockKey) | str')
|
||||
def _filter_blacklist(self, fields, blacklist):
|
||||
"""
|
||||
Filter out blacklist from the children field in fields. Will construct a new list for children;
|
||||
@@ -3333,7 +3309,6 @@ class SplitMongoModuleStore(SplitBulkWriteMixin, ModuleStoreWriteBase):
|
||||
fields['children'] = [child for child in fields.get('children', []) if BlockKey(*child) not in blacklist]
|
||||
return fields
|
||||
|
||||
@contract(orphan=BlockKey)
|
||||
def _delete_if_true_orphan(self, orphan, structure):
|
||||
"""
|
||||
Delete the orphan and any of its descendants which no longer have parents.
|
||||
@@ -3343,7 +3318,6 @@ class SplitMongoModuleStore(SplitBulkWriteMixin, ModuleStoreWriteBase):
|
||||
for child in orphan_data.fields.get('children', []):
|
||||
self._delete_if_true_orphan(BlockKey(*child), structure)
|
||||
|
||||
@contract(returns=BlockData)
|
||||
def _new_block(self, user_id, category, block_fields, definition_id, new_id, raw=False,
|
||||
asides=None, block_defaults=None):
|
||||
"""
|
||||
@@ -3375,7 +3349,6 @@ class SplitMongoModuleStore(SplitBulkWriteMixin, ModuleStoreWriteBase):
|
||||
document['defaults'] = block_defaults
|
||||
return BlockData(**document)
|
||||
|
||||
@contract(block_key=BlockKey, returns='BlockData | None')
|
||||
def _get_block_from_structure(self, structure, block_key):
|
||||
"""
|
||||
Encodes the block key before retrieving it from the structure to ensure it can
|
||||
@@ -3383,7 +3356,6 @@ class SplitMongoModuleStore(SplitBulkWriteMixin, ModuleStoreWriteBase):
|
||||
"""
|
||||
return structure['blocks'].get(block_key)
|
||||
|
||||
@contract(block_key=BlockKey)
|
||||
def _get_asides_to_update_from_structure(self, structure, block_key, asides):
|
||||
"""
|
||||
Get list of aside fields that should be updated/inserted
|
||||
@@ -3415,7 +3387,6 @@ class SplitMongoModuleStore(SplitBulkWriteMixin, ModuleStoreWriteBase):
|
||||
else:
|
||||
return block.asides, False
|
||||
|
||||
@contract(block_key=BlockKey, content=BlockData)
|
||||
def _update_block_in_structure(self, structure, block_key, content):
|
||||
"""
|
||||
Encodes the block key before accessing it in the structure to ensure it can
|
||||
|
||||
@@ -3,7 +3,6 @@ Module for the dual-branch fall-back Draft->Published Versioning ModuleStore
|
||||
"""
|
||||
|
||||
|
||||
from contracts import contract
|
||||
from opaque_keys.edx.locator import CourseLocator, LibraryLocator, LibraryUsageLocator
|
||||
|
||||
from xmodule.exceptions import InvalidVersionError
|
||||
@@ -612,7 +611,6 @@ class DraftVersioningModuleStore(SplitMongoModuleStore, ModuleStoreDraftAndPubli
|
||||
xblock._published_by = published_block.edit_info.edited_by
|
||||
xblock._published_on = published_block.edit_info.edited_on
|
||||
|
||||
@contract(asset_key='AssetKey')
|
||||
def find_asset_metadata(self, asset_key, **kwargs):
|
||||
return super().find_asset_metadata(
|
||||
self._map_revision_to_branch(asset_key), **kwargs
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
import copy
|
||||
from collections import namedtuple
|
||||
|
||||
from contracts import contract, new_contract
|
||||
from opaque_keys.edx.locator import BlockUsageLocator
|
||||
from xblock.core import XBlockAside
|
||||
from xblock.exceptions import InvalidScopeError
|
||||
from xblock.fields import Scope
|
||||
@@ -15,7 +13,6 @@ from .definition_lazy_loader import DefinitionLazyLoader
|
||||
|
||||
# id is a BlockUsageLocator, def_id is the definition's guid
|
||||
SplitMongoKVSid = namedtuple('SplitMongoKVSid', 'id, def_id')
|
||||
new_contract('BlockUsageLocator', BlockUsageLocator)
|
||||
|
||||
|
||||
class SplitMongoKVS(InheritanceKeyValueStore):
|
||||
@@ -26,7 +23,6 @@ class SplitMongoKVS(InheritanceKeyValueStore):
|
||||
|
||||
VALID_SCOPES = (Scope.parent, Scope.children, Scope.settings, Scope.content)
|
||||
|
||||
@contract(parent="BlockUsageLocator | None")
|
||||
def __init__(self, definition, initial_values, default_values, parent, aside_fields=None, field_decorator=None):
|
||||
"""
|
||||
|
||||
|
||||
@@ -14,7 +14,6 @@ from unittest.mock import patch
|
||||
import pytest
|
||||
import ddt
|
||||
from ccx_keys.locator import CCXBlockUsageLocator
|
||||
from contracts import contract
|
||||
from django.core.cache import InvalidCacheBackendError, caches
|
||||
from opaque_keys.edx.locator import BlockUsageLocator, CourseKey, CourseLocator, LocalId, VersionTree
|
||||
from path import Path as path
|
||||
@@ -2125,7 +2124,6 @@ class TestPublish(SplitModuleTest):
|
||||
]
|
||||
self._check_course(source_course, dest_course, expected, [BlockKey("chapter", "chapter2"), BlockKey("problem", "problem3_2")]) # lint-amnesty, pylint: disable=line-too-long
|
||||
|
||||
@contract(expected_blocks="list(BlockKey)", unexpected_blocks="list(BlockKey)")
|
||||
def _check_course(self, source_course_loc, dest_course_loc, expected_blocks, unexpected_blocks):
|
||||
"""
|
||||
Check that the course has the expected blocks and does not have the unexpected blocks
|
||||
@@ -2164,11 +2162,6 @@ class TestPublish(SplitModuleTest):
|
||||
actual = {key: BlockKey.from_usage_key(val) for (key, val) in actual}
|
||||
assert expected == actual
|
||||
|
||||
@contract(
|
||||
source_children="list(BlockUsageLocator)",
|
||||
dest_children="list(BlockUsageLocator)",
|
||||
unexpected="list(BlockKey)"
|
||||
)
|
||||
def _compare_children(self, source_children, dest_children, unexpected):
|
||||
"""
|
||||
Ensure dest_children == source_children minus unexpected
|
||||
|
||||
@@ -8,7 +8,6 @@ from collections import namedtuple
|
||||
from functools import partial
|
||||
|
||||
import yaml
|
||||
from contracts import contract, new_contract
|
||||
from django.utils.encoding import python_2_unicode_compatible
|
||||
from lazy import lazy
|
||||
from lxml import etree
|
||||
@@ -1618,9 +1617,6 @@ class DescriptorSystem(MetricsMixin, ConfigurableFragmentWrapper, Runtime):
|
||||
return service
|
||||
|
||||
|
||||
new_contract('DescriptorSystem', DescriptorSystem)
|
||||
|
||||
|
||||
class XMLParsingSystem(DescriptorSystem): # lint-amnesty, pylint: disable=abstract-method, missing-class-docstring
|
||||
def __init__(self, process_xml, **kwargs):
|
||||
"""
|
||||
@@ -1750,7 +1746,6 @@ class ModuleSystem(MetricsMixin, ConfigurableFragmentWrapper, Runtime):
|
||||
and user, or other environment-specific info.
|
||||
"""
|
||||
|
||||
@contract(descriptor_runtime='DescriptorSystem')
|
||||
def __init__(
|
||||
self, static_url, track_function, get_module, render_template,
|
||||
replace_urls, descriptor_runtime, user=None, filestore=None,
|
||||
|
||||
@@ -214,7 +214,6 @@ intersphinx_mapping = {
|
||||
# Mock out these external modules during code import to avoid errors
|
||||
autodoc_mock_imports = [
|
||||
'MySQLdb',
|
||||
'contracts',
|
||||
'django_mysql',
|
||||
'pymongo',
|
||||
]
|
||||
|
||||
@@ -27,7 +27,6 @@ import logging
|
||||
from abc import ABCMeta, abstractmethod
|
||||
from collections import defaultdict, namedtuple
|
||||
|
||||
from contracts import contract, new_contract
|
||||
from django.db import DatabaseError, IntegrityError, transaction
|
||||
from opaque_keys.edx.asides import AsideUsageKeyV1, AsideUsageKeyV2
|
||||
from opaque_keys.edx.block_types import BlockTypeKeyV1
|
||||
@@ -149,10 +148,6 @@ class DjangoKeyValueStore(KeyValueStore):
|
||||
raise InvalidScopeError(key, self._allowed_scopes)
|
||||
|
||||
|
||||
new_contract("DjangoKeyValueStore", DjangoKeyValueStore)
|
||||
new_contract("DjangoKeyValueStore_Key", DjangoKeyValueStore.Key)
|
||||
|
||||
|
||||
class DjangoOrmFieldCache(metaclass=ABCMeta):
|
||||
"""
|
||||
Baseclass for Scope-specific field cache objects that are based on
|
||||
@@ -175,7 +170,6 @@ class DjangoOrmFieldCache(metaclass=ABCMeta):
|
||||
for field_object in self._read_objects(fields, xblocks, aside_types):
|
||||
self._cache[self._cache_key_for_field_object(field_object)] = field_object
|
||||
|
||||
@contract(kvs_key=DjangoKeyValueStore.Key)
|
||||
def get(self, kvs_key):
|
||||
"""
|
||||
Return the django model object specified by `kvs_key` from
|
||||
@@ -194,7 +188,6 @@ class DjangoOrmFieldCache(metaclass=ABCMeta):
|
||||
|
||||
return json.loads(field_object.value)
|
||||
|
||||
@contract(kvs_key=DjangoKeyValueStore.Key)
|
||||
def set(self, kvs_key, value):
|
||||
"""
|
||||
Set the specified `kvs_key` to the field value `value`.
|
||||
@@ -205,7 +198,6 @@ class DjangoOrmFieldCache(metaclass=ABCMeta):
|
||||
"""
|
||||
self.set_many({kvs_key: value})
|
||||
|
||||
@contract(kv_dict="dict(DjangoKeyValueStore_Key: *)")
|
||||
def set_many(self, kv_dict):
|
||||
"""
|
||||
Set the specified fields to the supplied values.
|
||||
@@ -241,7 +233,6 @@ class DjangoOrmFieldCache(metaclass=ABCMeta):
|
||||
finally:
|
||||
saved_fields.append(kvs_key.field_name)
|
||||
|
||||
@contract(kvs_key=DjangoKeyValueStore.Key)
|
||||
def delete(self, kvs_key):
|
||||
"""
|
||||
Delete the value specified by `kvs_key`.
|
||||
@@ -260,7 +251,6 @@ class DjangoOrmFieldCache(metaclass=ABCMeta):
|
||||
field_object.delete()
|
||||
del self._cache[cache_key]
|
||||
|
||||
@contract(kvs_key=DjangoKeyValueStore.Key, returns=bool)
|
||||
def has(self, kvs_key):
|
||||
"""
|
||||
Return whether the specified `kvs_key` is set.
|
||||
@@ -272,7 +262,6 @@ class DjangoOrmFieldCache(metaclass=ABCMeta):
|
||||
"""
|
||||
return self._cache_key_for_kvs_key(kvs_key) in self._cache
|
||||
|
||||
@contract(kvs_key=DjangoKeyValueStore.Key, returns="datetime|None")
|
||||
def last_modified(self, kvs_key):
|
||||
"""
|
||||
Return when the supplied field was changed.
|
||||
@@ -368,7 +357,6 @@ class UserStateCache:
|
||||
for user_state in block_field_state:
|
||||
self._cache[user_state.block_key] = user_state.state
|
||||
|
||||
@contract(kvs_key=DjangoKeyValueStore.Key)
|
||||
def set(self, kvs_key, value):
|
||||
"""
|
||||
Set the specified `kvs_key` to the field value `value`.
|
||||
@@ -379,7 +367,6 @@ class UserStateCache:
|
||||
"""
|
||||
self.set_many({kvs_key: value})
|
||||
|
||||
@contract(kvs_key=DjangoKeyValueStore.Key, returns="datetime|None")
|
||||
def last_modified(self, kvs_key):
|
||||
"""
|
||||
Return when the supplied field was changed.
|
||||
@@ -398,7 +385,6 @@ class UserStateCache:
|
||||
except self._client.DoesNotExist:
|
||||
return None
|
||||
|
||||
@contract(kv_dict="dict(DjangoKeyValueStore_Key: *)")
|
||||
def set_many(self, kv_dict):
|
||||
"""
|
||||
Set the specified fields to the supplied values.
|
||||
@@ -424,7 +410,6 @@ class UserStateCache:
|
||||
finally:
|
||||
self._cache.update(pending_updates)
|
||||
|
||||
@contract(kvs_key=DjangoKeyValueStore.Key)
|
||||
def get(self, kvs_key):
|
||||
"""
|
||||
Return the django model object specified by `kvs_key` from
|
||||
@@ -441,7 +426,6 @@ class UserStateCache:
|
||||
|
||||
return self._cache[cache_key][kvs_key.field_name]
|
||||
|
||||
@contract(kvs_key=DjangoKeyValueStore.Key)
|
||||
def delete(self, kvs_key):
|
||||
"""
|
||||
Delete the value specified by `kvs_key`.
|
||||
@@ -463,7 +447,6 @@ class UserStateCache:
|
||||
self._client.delete(self.user.username, cache_key, fields=[kvs_key.field_name])
|
||||
del field_state[kvs_key.field_name]
|
||||
|
||||
@contract(kvs_key=DjangoKeyValueStore.Key, returns=bool)
|
||||
def has(self, kvs_key):
|
||||
"""
|
||||
Return whether the specified `kvs_key` is set.
|
||||
@@ -803,7 +786,6 @@ class FieldDataCache:
|
||||
scope_map[field.scope].add(field)
|
||||
return scope_map
|
||||
|
||||
@contract(key=DjangoKeyValueStore.Key)
|
||||
def get(self, key):
|
||||
"""
|
||||
Load the field value specified by `key`.
|
||||
@@ -825,7 +807,6 @@ class FieldDataCache:
|
||||
|
||||
return self.cache[key.scope].get(key)
|
||||
|
||||
@contract(kv_dict="dict(DjangoKeyValueStore_Key: *)")
|
||||
def set_many(self, kv_dict):
|
||||
"""
|
||||
Set all of the fields specified by the keys of `kv_dict` to the values
|
||||
@@ -862,7 +843,6 @@ class FieldDataCache:
|
||||
log.exception('Error saving fields %r', [key.field_name for key in set_many_data])
|
||||
raise KeyValueMultiSaveError(saved_fields + exc.saved_field_names) # lint-amnesty, pylint: disable=raise-missing-from
|
||||
|
||||
@contract(key=DjangoKeyValueStore.Key)
|
||||
def delete(self, key):
|
||||
"""
|
||||
Delete the value specified by `key`.
|
||||
@@ -885,7 +865,6 @@ class FieldDataCache:
|
||||
|
||||
self.cache[key.scope].delete(key)
|
||||
|
||||
@contract(key=DjangoKeyValueStore.Key, returns=bool)
|
||||
def has(self, key):
|
||||
"""
|
||||
Return whether the specified `key` is set.
|
||||
@@ -906,7 +885,6 @@ class FieldDataCache:
|
||||
|
||||
return self.cache[key.scope].has(key)
|
||||
|
||||
@contract(key=DjangoKeyValueStore.Key, returns="datetime|None")
|
||||
def last_modified(self, key):
|
||||
"""
|
||||
Return when the supplied field was changed.
|
||||
@@ -989,7 +967,6 @@ class ScoresClient:
|
||||
return client
|
||||
|
||||
|
||||
# @contract(user_id=int, usage_key=UsageKey, score="number|None", max_score="number|None")
|
||||
def set_score(user_id, usage_key, score, max_score):
|
||||
"""
|
||||
Set the score and max_score for the specified user and xblock usage.
|
||||
|
||||
@@ -12,10 +12,6 @@ It exposes a module-level variable named ``application``. Django's
|
||||
from safe_lxml import defuse_xml_libs
|
||||
defuse_xml_libs()
|
||||
|
||||
# Disable PyContract contract checking when running as a webserver
|
||||
import contracts # lint-amnesty, pylint: disable=wrong-import-order, wrong-import-position
|
||||
contracts.disable_all()
|
||||
|
||||
import os # lint-amnesty, pylint: disable=wrong-import-order, wrong-import-position
|
||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "lms.envs.aws")
|
||||
|
||||
|
||||
17
manage.py
17
manage.py
@@ -25,8 +25,6 @@ import os
|
||||
import sys
|
||||
from argparse import ArgumentParser
|
||||
|
||||
import contracts
|
||||
|
||||
|
||||
def parse_args():
|
||||
"""Parse edx specific arguments to manage.py"""
|
||||
@@ -49,11 +47,6 @@ def parse_args():
|
||||
choices=['lms', 'lms-xml', 'lms-preview'],
|
||||
default='lms',
|
||||
help='Which service variant to run, when using the production environment')
|
||||
lms.add_argument(
|
||||
'--contracts',
|
||||
action='store_true',
|
||||
default=False,
|
||||
help='Turn on pycontracts for local development')
|
||||
lms.set_defaults(
|
||||
help_string=lms.format_help(),
|
||||
settings_base='lms/envs',
|
||||
@@ -72,11 +65,6 @@ def parse_args():
|
||||
help="Which django settings module to use under cms.envs. If not provided, the DJANGO_SETTINGS_MODULE "
|
||||
"environment variable will be used if it is set, otherwise it will default to cms.envs.devstack_docker")
|
||||
cms.add_argument('-h', '--help', action='store_true', help='show this help message and exit')
|
||||
cms.add_argument(
|
||||
'--contracts',
|
||||
action='store_true',
|
||||
default=False,
|
||||
help='Turn on pycontracts for local development')
|
||||
cms.set_defaults(
|
||||
help_string=cms.format_help(),
|
||||
settings_base='cms/envs',
|
||||
@@ -106,11 +94,6 @@ if __name__ == "__main__":
|
||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", edx_args.default_settings)
|
||||
os.environ.setdefault("SERVICE_VARIANT", edx_args.service_variant)
|
||||
|
||||
enable_contracts = os.environ.get('ENABLE_CONTRACTS', False)
|
||||
# can override with '--contracts' argument
|
||||
if not enable_contracts and not edx_args.contracts:
|
||||
contracts.disable_all()
|
||||
|
||||
if edx_args.help:
|
||||
print("Django:")
|
||||
# This will trigger django-admin.py to print out its help
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
|
||||
import pytest
|
||||
from contracts import new_contract
|
||||
from django.test import TestCase
|
||||
from opaque_keys.edx.locator import CourseLocator
|
||||
|
||||
@@ -14,8 +13,6 @@ from xmodule.modulestore.django import modulestore
|
||||
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
|
||||
from xmodule.modulestore.tests.factories import CourseFactory
|
||||
|
||||
new_contract('basestring', str)
|
||||
|
||||
|
||||
class RoleAssignmentTest(TestCase):
|
||||
"""
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
"""
|
||||
Common comment client utility functions.
|
||||
"""
|
||||
from contracts import new_contract
|
||||
|
||||
from openedx.core.djangoapps.django_comment_common.models import (
|
||||
FORUM_ROLE_ADMINISTRATOR,
|
||||
FORUM_ROLE_COMMUNITY_TA,
|
||||
@@ -13,8 +11,6 @@ from openedx.core.djangoapps.django_comment_common.models import (
|
||||
Role
|
||||
)
|
||||
|
||||
new_contract('basestring', str)
|
||||
|
||||
|
||||
class ThreadContext:
|
||||
""" An enumeration that represents the context of a thread. Used primarily by the comments service. """
|
||||
|
||||
@@ -12,7 +12,6 @@ import uuid
|
||||
|
||||
import markupsafe
|
||||
import webpack_loader.utils
|
||||
from contracts import contract
|
||||
from django.conf import settings
|
||||
from django.contrib.auth.models import User # lint-amnesty, pylint: disable=imported-auth-user
|
||||
from django.contrib.staticfiles.storage import staticfiles_storage
|
||||
@@ -309,7 +308,6 @@ def sanitize_html_id(html_id):
|
||||
return sanitized_html_id
|
||||
|
||||
|
||||
@contract(user=User, block=XBlock, view=(str,)[0], frag=Fragment, context="dict|None")
|
||||
def add_staff_markup(user, disable_staff_debug_info, block, view, frag, context): # pylint: disable=unused-argument
|
||||
"""
|
||||
Updates the supplied module with a new get_html function that wraps
|
||||
|
||||
@@ -100,7 +100,6 @@ class TestPaverServerTasks(PaverTestCase):
|
||||
[{"fast": True}],
|
||||
[{"optimized": True}],
|
||||
[{"optimized": True, "fast": True}],
|
||||
[{"no-contracts": True}],
|
||||
)
|
||||
@ddt.unpack
|
||||
def test_devstack(self, server_options):
|
||||
@@ -119,7 +118,7 @@ class TestPaverServerTasks(PaverTestCase):
|
||||
settings=expected_settings,
|
||||
)
|
||||
]
|
||||
self.verify_server_task("devstack", options, contracts_default=True)
|
||||
self.verify_server_task("devstack", options)
|
||||
|
||||
# Then test with Studio
|
||||
options["system"] = "cms"
|
||||
@@ -129,7 +128,7 @@ class TestPaverServerTasks(PaverTestCase):
|
||||
settings=expected_settings,
|
||||
)
|
||||
]
|
||||
self.verify_server_task("devstack", options, contracts_default=True)
|
||||
self.verify_server_task("devstack", options)
|
||||
|
||||
@ddt.data(
|
||||
[{}],
|
||||
@@ -193,7 +192,7 @@ class TestPaverServerTasks(PaverTestCase):
|
||||
["echo 'import {system}.envs.{settings}' | python manage.py {system} "
|
||||
"--settings={settings} shell --plain --pythonpath=.".format(system=system, settings=settings)]
|
||||
|
||||
def verify_server_task(self, task_name, options, contracts_default=False):
|
||||
def verify_server_task(self, task_name, options):
|
||||
"""
|
||||
Verify the output of a server task.
|
||||
"""
|
||||
@@ -202,7 +201,6 @@ class TestPaverServerTasks(PaverTestCase):
|
||||
asset_settings = options.get("asset-settings", None)
|
||||
is_optimized = options.get("optimized", False)
|
||||
is_fast = options.get("fast", False)
|
||||
no_contracts = options.get("no-contracts", not contracts_default)
|
||||
if task_name == "devstack":
|
||||
system = options.get("system")
|
||||
elif task_name == "studio":
|
||||
@@ -221,8 +219,6 @@ class TestPaverServerTasks(PaverTestCase):
|
||||
args.append("--optimized")
|
||||
if is_fast:
|
||||
args.append("--fast")
|
||||
if no_contracts:
|
||||
args.append("--no-contracts")
|
||||
call_task("pavelib.servers.devstack", args=args)
|
||||
else:
|
||||
call_task(f"pavelib.servers.{task_name}", options=options)
|
||||
@@ -257,8 +253,6 @@ class TestPaverServerTasks(PaverTestCase):
|
||||
settings=expected_settings,
|
||||
port=port,
|
||||
)
|
||||
if not no_contracts:
|
||||
expected_run_server_command += " --contracts"
|
||||
expected_messages.append(expected_run_server_command)
|
||||
assert self.task_messages == expected_messages
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ ASSET_SETTINGS_HELP = (
|
||||
|
||||
|
||||
def run_server(
|
||||
system, fast=False, settings=None, asset_settings=None, port=None, contracts=False
|
||||
system, fast=False, settings=None, asset_settings=None, port=None
|
||||
):
|
||||
"""Start the server for LMS or Studio.
|
||||
|
||||
@@ -35,7 +35,6 @@ def run_server(
|
||||
settings (str): The Django settings module to use; if not provided, use the default.
|
||||
asset_settings (str) The settings to use when generating assets. If not provided, assets are not generated.
|
||||
port (str): The port number to run the server on. If not provided, uses the default port for the system.
|
||||
contracts (bool) If true then PyContracts is enabled (defaults to False).
|
||||
"""
|
||||
if system not in ['lms', 'studio']:
|
||||
print("System must be either lms or studio", file=sys.stderr)
|
||||
@@ -58,9 +57,6 @@ def run_server(
|
||||
|
||||
args = [settings, 'runserver', '--traceback', '--pythonpath=.', f'0.0.0.0:{port}']
|
||||
|
||||
if contracts:
|
||||
args.append("--contracts")
|
||||
|
||||
run_process(django_cmd(system, *args))
|
||||
|
||||
|
||||
@@ -127,12 +123,6 @@ def devstack(args):
|
||||
parser.add_argument('--optimized', action='store_true', default=False, help="Run with optimized assets")
|
||||
parser.add_argument('--settings', type=str, default=DEFAULT_SETTINGS, help="Settings file")
|
||||
parser.add_argument('--asset-settings', type=str, default=None, help=ASSET_SETTINGS_HELP)
|
||||
parser.add_argument(
|
||||
'--no-contracts',
|
||||
action='store_true',
|
||||
default=False,
|
||||
help="Disable contracts. By default, they're enabled in devstack."
|
||||
)
|
||||
args = parser.parse_args(args)
|
||||
settings = args.settings
|
||||
asset_settings = args.asset_settings if args.asset_settings else settings
|
||||
@@ -145,7 +135,6 @@ def devstack(args):
|
||||
fast=args.fast,
|
||||
settings=settings,
|
||||
asset_settings=asset_settings,
|
||||
contracts=not args.no_contracts,
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ nltk==3.6.2
|
||||
# via
|
||||
# -r requirements/edx-sandbox/py38.in
|
||||
# chem
|
||||
numpy==1.20.3
|
||||
numpy==1.21.0
|
||||
# via
|
||||
# -r requirements/edx-sandbox/py38.in
|
||||
# chem
|
||||
|
||||
@@ -123,7 +123,6 @@ openedx-calc # Library supporting mathematical calculatio
|
||||
ora2
|
||||
piexif # Exif image metadata manipulation, used in the profile_images app
|
||||
Pillow # Image manipulation library; used for course assets, profile images, invoice PDFs, etc.
|
||||
PyContracts
|
||||
pycountry
|
||||
pycryptodomex
|
||||
pygments # Used to support colors in paver command output
|
||||
|
||||
@@ -143,8 +143,6 @@ ddt==1.4.2
|
||||
# via
|
||||
# xblock-drag-and-drop-v2
|
||||
# xblock-poll
|
||||
decorator==5.0.9
|
||||
# via pycontracts
|
||||
defusedxml==0.7.1
|
||||
# via
|
||||
# -r requirements/edx/base.in
|
||||
@@ -390,7 +388,7 @@ edx-analytics-data-api-client==0.17.0
|
||||
# via -r requirements/edx/base.in
|
||||
edx-api-doc-tools==1.4.0
|
||||
# via -r requirements/edx/base.in
|
||||
edx-bulk-grades==0.8.11
|
||||
edx-bulk-grades==0.8.12
|
||||
# via
|
||||
# -r requirements/edx/base.in
|
||||
# staff-graded-xblock
|
||||
@@ -486,7 +484,7 @@ edx-toggles==4.1.0
|
||||
# edx-event-routing-backends
|
||||
# edxval
|
||||
# ora2
|
||||
edx-user-state-client==1.3.1
|
||||
edx-user-state-client==1.3.2
|
||||
# via -r requirements/edx/base.in
|
||||
edx-when==2.0.0
|
||||
# via
|
||||
@@ -494,7 +492,7 @@ edx-when==2.0.0
|
||||
# edx-proctoring
|
||||
edxval==2.0.3
|
||||
# via -r requirements/edx/base.in
|
||||
elasticsearch==7.13.2
|
||||
elasticsearch==7.13.1
|
||||
# via edx-search
|
||||
enmerkar-underscore==2.0.0
|
||||
# via -r requirements/edx/base.in
|
||||
@@ -521,7 +519,6 @@ future==0.18.2
|
||||
# django-ses
|
||||
# edx-celeryutils
|
||||
# edx-enterprise
|
||||
# pycontracts
|
||||
# pyjwkest
|
||||
geoip2==3.0.0
|
||||
# via
|
||||
@@ -595,7 +592,9 @@ libsass==0.10.0
|
||||
loremipsum==1.0.5
|
||||
# via ora2
|
||||
lti-consumer-xblock==2.10.1
|
||||
# via -r requirements/edx/base.in
|
||||
# via
|
||||
# -c requirements/edx/../constraints.txt
|
||||
# -r requirements/edx/base.in
|
||||
lxml==4.5.0
|
||||
# via
|
||||
# -c requirements/edx/../constraints.txt
|
||||
@@ -651,7 +650,7 @@ mpmath==1.2.1
|
||||
# via sympy
|
||||
mysqlclient==2.0.3
|
||||
# via -r requirements/edx/base.in
|
||||
newrelic==6.4.1.158
|
||||
newrelic==6.4.2.159
|
||||
# via
|
||||
# -r requirements/edx/base.in
|
||||
# edx-django-utils
|
||||
@@ -661,7 +660,7 @@ nltk==3.6.2
|
||||
# chem
|
||||
nodeenv==1.6.0
|
||||
# via -r requirements/edx/base.in
|
||||
numpy==1.20.3
|
||||
numpy==1.21.0
|
||||
# via
|
||||
# chem
|
||||
# openedx-calc
|
||||
@@ -676,7 +675,7 @@ oauthlib==3.0.1
|
||||
# social-auth-core
|
||||
openedx-calc==2.0.1
|
||||
# via -r requirements/edx/base.in
|
||||
ora2==3.6.6
|
||||
ora2==3.6.7
|
||||
# via -r requirements/edx/base.in
|
||||
packaging==20.9
|
||||
# via
|
||||
@@ -713,10 +712,6 @@ psutil==5.8.0
|
||||
# via
|
||||
# -r requirements/edx/paver.txt
|
||||
# edx-django-utils
|
||||
pycontracts==1.8.12
|
||||
# via
|
||||
# -r requirements/edx/base.in
|
||||
# edx-user-state-client
|
||||
pycountry==20.7.3
|
||||
# via -r requirements/edx/base.in
|
||||
pycparser==2.20
|
||||
@@ -761,7 +756,6 @@ pyparsing==2.4.7
|
||||
# chem
|
||||
# openedx-calc
|
||||
# packaging
|
||||
# pycontracts
|
||||
pysrt==1.1.2
|
||||
# via
|
||||
# -r requirements/edx/base.in
|
||||
@@ -919,7 +913,6 @@ six==1.16.0
|
||||
# isodate
|
||||
# libsass
|
||||
# paver
|
||||
# pycontracts
|
||||
# pyjwkest
|
||||
# python-dateutil
|
||||
# python-memcached
|
||||
|
||||
@@ -195,10 +195,6 @@ ddt==1.4.2
|
||||
# -r requirements/edx/testing.txt
|
||||
# xblock-drag-and-drop-v2
|
||||
# xblock-poll
|
||||
decorator==5.0.9
|
||||
# via
|
||||
# -r requirements/edx/testing.txt
|
||||
# pycontracts
|
||||
defusedxml==0.7.1
|
||||
# via
|
||||
# -r requirements/edx/testing.txt
|
||||
@@ -476,7 +472,7 @@ edx-analytics-data-api-client==0.17.0
|
||||
# via -r requirements/edx/testing.txt
|
||||
edx-api-doc-tools==1.4.0
|
||||
# via -r requirements/edx/testing.txt
|
||||
edx-bulk-grades==0.8.11
|
||||
edx-bulk-grades==0.8.12
|
||||
# via
|
||||
# -r requirements/edx/testing.txt
|
||||
# staff-graded-xblock
|
||||
@@ -582,7 +578,7 @@ edx-toggles==4.1.0
|
||||
# edx-event-routing-backends
|
||||
# edxval
|
||||
# ora2
|
||||
edx-user-state-client==1.3.1
|
||||
edx-user-state-client==1.3.2
|
||||
# via -r requirements/edx/testing.txt
|
||||
edx-when==2.0.0
|
||||
# via
|
||||
@@ -590,7 +586,7 @@ edx-when==2.0.0
|
||||
# edx-proctoring
|
||||
edxval==2.0.3
|
||||
# via -r requirements/edx/testing.txt
|
||||
elasticsearch==7.13.2
|
||||
elasticsearch==7.13.1
|
||||
# via
|
||||
# -r requirements/edx/testing.txt
|
||||
# edx-search
|
||||
@@ -612,7 +608,7 @@ execnet==1.9.0
|
||||
# pytest-xdist
|
||||
factory-boy==3.2.0
|
||||
# via -r requirements/edx/testing.txt
|
||||
faker==8.8.1
|
||||
faker==8.8.2
|
||||
# via
|
||||
# -r requirements/edx/testing.txt
|
||||
# factory-boy
|
||||
@@ -641,7 +637,6 @@ future==0.18.2
|
||||
# django-ses
|
||||
# edx-celeryutils
|
||||
# edx-enterprise
|
||||
# pycontracts
|
||||
# pyjwkest
|
||||
geoip2==3.0.0
|
||||
# via
|
||||
@@ -776,7 +771,9 @@ loremipsum==1.0.5
|
||||
# -r requirements/edx/testing.txt
|
||||
# ora2
|
||||
lti-consumer-xblock==2.10.1
|
||||
# via -r requirements/edx/testing.txt
|
||||
# via
|
||||
# -c requirements/edx/../constraints.txt
|
||||
# -r requirements/edx/testing.txt
|
||||
lxml==4.5.0
|
||||
# via
|
||||
# -c requirements/edx/../constraints.txt
|
||||
@@ -852,11 +849,11 @@ mpmath==1.2.1
|
||||
# sympy
|
||||
mypy-extensions==0.4.3
|
||||
# via mypy
|
||||
mypy==0.902
|
||||
mypy==0.910
|
||||
# via -r requirements/edx/development.in
|
||||
mysqlclient==2.0.3
|
||||
# via -r requirements/edx/testing.txt
|
||||
newrelic==6.4.1.158
|
||||
newrelic==6.4.2.159
|
||||
# via
|
||||
# -r requirements/edx/testing.txt
|
||||
# edx-django-utils
|
||||
@@ -866,7 +863,7 @@ nltk==3.6.2
|
||||
# chem
|
||||
nodeenv==1.6.0
|
||||
# via -r requirements/edx/testing.txt
|
||||
numpy==1.20.3
|
||||
numpy==1.21.0
|
||||
# via
|
||||
# -r requirements/edx/testing.txt
|
||||
# chem
|
||||
@@ -882,7 +879,7 @@ oauthlib==3.0.1
|
||||
# social-auth-core
|
||||
openedx-calc==2.0.1
|
||||
# via -r requirements/edx/testing.txt
|
||||
ora2==3.6.6
|
||||
ora2==3.6.7
|
||||
# via -r requirements/edx/testing.txt
|
||||
packaging==20.9
|
||||
# via
|
||||
@@ -922,7 +919,7 @@ pillow==8.2.0
|
||||
# -r requirements/edx/testing.txt
|
||||
# edx-enterprise
|
||||
# edx-organizations
|
||||
pip-tools==6.1.0
|
||||
pip-tools==6.2.0
|
||||
# via -r requirements/edx/pip-tools.txt
|
||||
pluggy==0.13.1
|
||||
# via
|
||||
@@ -947,10 +944,6 @@ py==1.10.0
|
||||
# tox
|
||||
pycodestyle==2.7.0
|
||||
# via -r requirements/edx/testing.txt
|
||||
pycontracts==1.8.12
|
||||
# via
|
||||
# -r requirements/edx/testing.txt
|
||||
# edx-user-state-client
|
||||
pycountry==20.7.3
|
||||
# via -r requirements/edx/testing.txt
|
||||
pycparser==2.20
|
||||
@@ -1025,7 +1018,6 @@ pyparsing==2.4.7
|
||||
# chem
|
||||
# openedx-calc
|
||||
# packaging
|
||||
# pycontracts
|
||||
pyquery==1.4.3
|
||||
# via -r requirements/edx/testing.txt
|
||||
pyrsistent==0.17.3
|
||||
@@ -1254,7 +1246,6 @@ six==1.16.0
|
||||
# jsonschema
|
||||
# libsass
|
||||
# paver
|
||||
# pycontracts
|
||||
# pyjwkest
|
||||
# python-dateutil
|
||||
# python-memcached
|
||||
@@ -1441,6 +1432,10 @@ webob==1.8.7
|
||||
# -r requirements/edx/testing.txt
|
||||
# xblock
|
||||
# xmodule
|
||||
wheel==0.36.2
|
||||
# via
|
||||
# -r requirements/edx/pip-tools.txt
|
||||
# pip-tools
|
||||
wrapt==1.11.2
|
||||
# via
|
||||
# -c requirements/edx/../constraints.txt
|
||||
|
||||
@@ -10,10 +10,13 @@ click==7.1.2
|
||||
# pip-tools
|
||||
pep517==0.10.0
|
||||
# via pip-tools
|
||||
pip-tools==6.1.0
|
||||
pip-tools==6.2.0
|
||||
# via -r requirements/edx/pip-tools.in
|
||||
toml==0.10.2
|
||||
# via pep517
|
||||
wheel==0.36.2
|
||||
# via pip-tools
|
||||
|
||||
# The following packages are considered to be unsafe in a requirements file:
|
||||
# pip
|
||||
# setuptools
|
||||
|
||||
@@ -188,10 +188,6 @@ ddt==1.4.2
|
||||
# -r requirements/edx/testing.in
|
||||
# xblock-drag-and-drop-v2
|
||||
# xblock-poll
|
||||
decorator==5.0.9
|
||||
# via
|
||||
# -r requirements/edx/base.txt
|
||||
# pycontracts
|
||||
defusedxml==0.7.1
|
||||
# via
|
||||
# -r requirements/edx/base.txt
|
||||
@@ -461,7 +457,7 @@ edx-analytics-data-api-client==0.17.0
|
||||
# via -r requirements/edx/base.txt
|
||||
edx-api-doc-tools==1.4.0
|
||||
# via -r requirements/edx/base.txt
|
||||
edx-bulk-grades==0.8.11
|
||||
edx-bulk-grades==0.8.12
|
||||
# via
|
||||
# -r requirements/edx/base.txt
|
||||
# staff-graded-xblock
|
||||
@@ -566,7 +562,7 @@ edx-toggles==4.1.0
|
||||
# edx-event-routing-backends
|
||||
# edxval
|
||||
# ora2
|
||||
edx-user-state-client==1.3.1
|
||||
edx-user-state-client==1.3.2
|
||||
# via -r requirements/edx/base.txt
|
||||
edx-when==2.0.0
|
||||
# via
|
||||
@@ -574,7 +570,7 @@ edx-when==2.0.0
|
||||
# edx-proctoring
|
||||
edxval==2.0.3
|
||||
# via -r requirements/edx/base.txt
|
||||
elasticsearch==7.13.2
|
||||
elasticsearch==7.13.1
|
||||
# via
|
||||
# -r requirements/edx/base.txt
|
||||
# edx-search
|
||||
@@ -594,7 +590,7 @@ execnet==1.9.0
|
||||
# via pytest-xdist
|
||||
factory-boy==3.2.0
|
||||
# via -r requirements/edx/testing.in
|
||||
faker==8.8.1
|
||||
faker==8.8.2
|
||||
# via factory-boy
|
||||
filelock==3.0.12
|
||||
# via
|
||||
@@ -620,7 +616,6 @@ future==0.18.2
|
||||
# django-ses
|
||||
# edx-celeryutils
|
||||
# edx-enterprise
|
||||
# pycontracts
|
||||
# pyjwkest
|
||||
geoip2==3.0.0
|
||||
# via
|
||||
@@ -743,7 +738,9 @@ loremipsum==1.0.5
|
||||
# -r requirements/edx/base.txt
|
||||
# ora2
|
||||
lti-consumer-xblock==2.10.1
|
||||
# via -r requirements/edx/base.txt
|
||||
# via
|
||||
# -c requirements/edx/../constraints.txt
|
||||
# -r requirements/edx/base.txt
|
||||
lxml==4.5.0
|
||||
# via
|
||||
# -c requirements/edx/../constraints.txt
|
||||
@@ -814,7 +811,7 @@ mpmath==1.2.1
|
||||
# sympy
|
||||
mysqlclient==2.0.3
|
||||
# via -r requirements/edx/base.txt
|
||||
newrelic==6.4.1.158
|
||||
newrelic==6.4.2.159
|
||||
# via
|
||||
# -r requirements/edx/base.txt
|
||||
# edx-django-utils
|
||||
@@ -824,7 +821,7 @@ nltk==3.6.2
|
||||
# chem
|
||||
nodeenv==1.6.0
|
||||
# via -r requirements/edx/base.txt
|
||||
numpy==1.20.3
|
||||
numpy==1.21.0
|
||||
# via
|
||||
# -r requirements/edx/base.txt
|
||||
# chem
|
||||
@@ -840,7 +837,7 @@ oauthlib==3.0.1
|
||||
# social-auth-core
|
||||
openedx-calc==2.0.1
|
||||
# via -r requirements/edx/base.txt
|
||||
ora2==3.6.6
|
||||
ora2==3.6.7
|
||||
# via -r requirements/edx/base.txt
|
||||
packaging==20.9
|
||||
# via
|
||||
@@ -898,10 +895,6 @@ py==1.10.0
|
||||
# tox
|
||||
pycodestyle==2.7.0
|
||||
# via -r requirements/edx/testing.in
|
||||
pycontracts==1.8.12
|
||||
# via
|
||||
# -r requirements/edx/base.txt
|
||||
# edx-user-state-client
|
||||
pycountry==20.7.3
|
||||
# via -r requirements/edx/base.txt
|
||||
pycparser==2.20
|
||||
@@ -970,7 +963,6 @@ pyparsing==2.4.7
|
||||
# chem
|
||||
# openedx-calc
|
||||
# packaging
|
||||
# pycontracts
|
||||
pyquery==1.4.3
|
||||
# via -r requirements/edx/testing.in
|
||||
pysrt==1.1.2
|
||||
@@ -1189,7 +1181,6 @@ six==1.16.0
|
||||
# isodate
|
||||
# libsass
|
||||
# paver
|
||||
# pycontracts
|
||||
# pyjwkest
|
||||
# python-dateutil
|
||||
# python-memcached
|
||||
|
||||
Reference in New Issue
Block a user