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:
Diana Huang
2021-06-23 18:24:06 -04:00
committed by GitHub
parent a775d5cebc
commit 29548459fa
32 changed files with 47 additions and 343 deletions

View File

@@ -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)

View File

@@ -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")

View File

@@ -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:

View File

@@ -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.

View File

@@ -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)

View File

@@ -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:

View File

@@ -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)

View File

@@ -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.

View File

@@ -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.

View File

@@ -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)

View File

@@ -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.

View File

@@ -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'] = []

View File

@@ -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

View File

@@ -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

View File

@@ -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):
"""

View File

@@ -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

View File

@@ -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,

View File

@@ -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',
]

View File

@@ -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.

View File

@@ -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")

View File

@@ -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

View File

@@ -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):
"""

View File

@@ -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. """

View File

@@ -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

View File

@@ -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

View File

@@ -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,
)

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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