diff --git a/.travis.yml b/.travis.yml index 3b959345e..9b6d5d414 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,29 +1,18 @@ language: python sudo: false python: - - 2.7 - 3.5 + - 3.8 cache: pip install: - pip install -r requirements/travis.txt env: - - TOX_ENV=django111 - - TOX_ENV=django20 - - TOX_ENV=django21 - TOX_ENV=django22 + - TOX_ENV=docs + - TOX_ENV=quality matrix: - exclude: - - python: 2.7 - env: TOX_ENV=django20 - - python: 2.7 - env: TOX_ENV=django21 - - python: 2.7 - env: TOX_ENV=django22 - include: - - python: 3.5 - env: TOX_ENV=docs - - python: 3.5 - env: TOX_ENV=quality + allow_failures: + - python: 3.8 script: - tox -e $TOX_ENV after_success: diff --git a/Makefile b/Makefile index 361560964..dffb7955e 100644 --- a/Makefile +++ b/Makefile @@ -22,7 +22,7 @@ help: ## display this help message quality: ## check coding style with pycodestyle and pylint pycodestyle script/max_pylint_violations - pylint --py3k xblock + pylint xblock test: ## run tests on every supported Python/Django combination tox diff --git a/pylintrc b/pylintrc index aa471e9b5..dd2f45735 100644 --- a/pylintrc +++ b/pylintrc @@ -19,7 +19,6 @@ persistent=yes # List of plugins (as comma separated values of python modules names) to load, # usually to register additional checkers. -load-plugins=caniusepython3.pylint_checker [MESSAGES CONTROL] @@ -62,6 +61,7 @@ disable= too-many-locals, duplicate-code, len-as-condition, + fixme, [REPORTS] diff --git a/requirements/base.txt b/requirements/base.txt index d9125e409..e60c7a160 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -5,10 +5,7 @@ # make upgrade # appdirs==1.4.3 # via fs -backports.os==0.1.1 # via fs -enum34==1.1.10 # via fs fs==2.4.11 # via -r requirements/base.in -future==0.18.2 # via backports.os lxml==4.5.0 # via -r requirements/base.in markupsafe==1.1.1 # via -r requirements/base.in python-dateutil==2.8.0 # via -c requirements/constraints.txt, -r requirements/base.in diff --git a/requirements/constraints.txt b/requirements/constraints.txt index b5e9feb8a..9f6b5dae0 100644 --- a/requirements/constraints.txt +++ b/requirements/constraints.txt @@ -9,10 +9,6 @@ # linking to it here is good. -# futures is part of the builtin python in python3 -futures ; python_version == "2.7" - - # latest botocore release cap upper version of python-dateutil<2.8.1, this conflicts # with our dependencies due to the order in which the dependecies are pip-compiled. # Adding this constraint till botocore can figure out a fix around this, keep a look at diff --git a/requirements/dev.txt b/requirements/dev.txt index 1630813da..abfd94e31 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -5,38 +5,27 @@ # make upgrade # appdirs==1.4.3 # via -r requirements/test.txt, -r requirements/travis.txt, fs, virtualenv -argparse==1.4.0 # via -r requirements/test.txt, caniusepython3 -astroid==1.6.6 # via -r requirements/test.txt, pylint -atomicwrites==1.3.0 # via -r requirements/test.txt, pytest +astroid==2.3.3 # via -r requirements/test.txt, pylint attrs==19.3.0 # via -r requirements/test.txt, hypothesis, pytest -backports.functools-lru-cache==1.6.1 # via -r requirements/test.txt, astroid, caniusepython3, isort, pylint -backports.os==0.1.1 # via -r requirements/test.txt, fs, path.py -boto3==1.12.45 # via -r requirements/test.txt, fs-s3fs -botocore==1.15.45 # via -r requirements/test.txt, boto3, s3transfer -caniusepython3==7.2.0 # via -r requirements/test.txt -certifi==2020.4.5.1 # via -r requirements/test.txt, -r requirements/travis.txt, requests -chardet==3.0.4 # via -r requirements/test.txt, -r requirements/travis.txt, requests +boto3==1.12.46 # via -r requirements/test.txt, fs-s3fs +botocore==1.15.46 # via -r requirements/test.txt, boto3, s3transfer +certifi==2020.4.5.1 # via -r requirements/travis.txt, requests +chardet==3.0.4 # via -r requirements/travis.txt, requests click==7.1.1 # via -r requirements/pip-tools.txt, pip-tools codecov==2.0.22 # via -r requirements/travis.txt -configparser==4.0.2 # via -r requirements/test.txt, -r requirements/travis.txt, importlib-metadata, pylint -contextlib2==0.6.0.post1 # via -r requirements/test.txt, -r requirements/travis.txt, importlib-metadata, importlib-resources, virtualenv, zipp coverage==5.1 # via -r requirements/test.txt, -r requirements/travis.txt, codecov, pytest-cov ddt==1.3.1 # via -r requirements/test.txt diff-cover==2.6.1 # via -r requirements/test.txt -distlib==0.3.0 # via -r requirements/test.txt, -r requirements/travis.txt, caniusepython3, virtualenv +distlib==0.3.0 # via -r requirements/test.txt, -r requirements/travis.txt, virtualenv django-pyfs==2.1 # via -r requirements/test.txt -django==1.11.29 # via -r requirements/test.txt, django-pyfs +django==2.2.12 # via -r requirements/test.txt, django-pyfs docutils==0.15.2 # via -r requirements/test.txt, botocore -enum34==1.1.10 # via -r requirements/test.txt, astroid, fs, hypothesis filelock==3.0.12 # via -r requirements/test.txt, -r requirements/travis.txt, tox, virtualenv fs-s3fs==1.1.1 # via -r requirements/test.txt, django-pyfs fs==2.4.11 # via -r requirements/test.txt, django-pyfs, fs-s3fs -funcsigs==1.0.2 # via -r requirements/test.txt, mock, pytest -future==0.18.2 # via -r requirements/test.txt, backports.os -futures==3.3.0 ; python_version == "2.7" # via -c requirements/constraints.txt, -r requirements/test.txt, caniusepython3, isort, s3transfer -hypothesis==4.57.1 # via -r requirements/test.txt -idna==2.9 # via -r requirements/test.txt, -r requirements/travis.txt, requests -importlib-metadata==1.6.0 # via -r requirements/test.txt, -r requirements/travis.txt, importlib-resources, inflect, path.py, pluggy, pytest, tox, virtualenv +hypothesis==5.10.4 # via -r requirements/test.txt +idna==2.9 # via -r requirements/travis.txt, requests +importlib-metadata==1.6.0 # via -r requirements/test.txt, -r requirements/travis.txt, importlib-resources, inflect, path, pluggy, pytest, tox, virtualenv importlib-resources==1.4.0 # via -r requirements/test.txt, -r requirements/travis.txt, virtualenv inflect==3.0.2 # via -r requirements/test.txt, jinja2-pluralize isort==4.3.21 # via -r requirements/test.txt, pylint @@ -49,41 +38,42 @@ lxml==4.5.0 # via -r requirements/test.txt markupsafe==1.1.1 # via -r requirements/test.txt, jinja2 mccabe==0.6.1 # via -r requirements/test.txt, pylint mock==3.0.5 # via -r requirements/test.txt -more-itertools==5.0.0 # via -r requirements/test.txt, pytest +more-itertools==8.2.0 # via -r requirements/test.txt, pytest nose==1.3.7 # via -r requirements/test.txt -packaging==20.3 # via -r requirements/test.txt, -r requirements/travis.txt, caniusepython3, pytest, tox -path.py==11.5.2 # via -r requirements/test.txt -pathlib2==2.3.5 # via -r requirements/test.txt, -r requirements/travis.txt, importlib-metadata, importlib-resources, pytest, pytest-django, virtualenv +packaging==20.3 # via -r requirements/test.txt, -r requirements/travis.txt, pytest, tox +path.py==12.4.0 # via -r requirements/test.txt +path==13.1.0 # via -r requirements/test.txt, path.py +pathlib2==2.3.5 # via -r requirements/test.txt, pytest pip-tools==5.0.0 # via -r requirements/pip-tools.txt pluggy==0.13.1 # via -r requirements/test.txt, -r requirements/travis.txt, diff-cover, pytest, tox py==1.8.1 # via -r requirements/test.txt, -r requirements/travis.txt, pytest, tox pycodestyle==2.5.0 # via -r requirements/test.txt -pygments==2.5.2 # via -r requirements/test.txt, diff-cover -pylint==1.9.5 # via -r requirements/test.txt +pygments==2.6.1 # via -r requirements/test.txt, diff-cover +pylint==2.4.4 # via -r requirements/test.txt pyparsing==2.4.7 # via -r requirements/test.txt, -r requirements/travis.txt, packaging pytest-cov==2.8.1 # via -r requirements/test.txt pytest-django==3.9.0 # via -r requirements/test.txt -pytest==4.6.9 # via -r requirements/test.txt, pytest-cov, pytest-django +pytest==5.4.1 # via -r requirements/test.txt, pytest-cov, pytest-django python-dateutil==2.8.0 # via -c requirements/constraints.txt, -r requirements/test.txt, botocore pytz==2019.3 # via -r requirements/test.txt, django, fs pyyaml==5.3.1 # via -r requirements/test.txt -requests==2.23.0 # via -r requirements/test.txt, -r requirements/travis.txt, caniusepython3, codecov +requests==2.23.0 # via -r requirements/travis.txt, codecov s3transfer==0.3.3 # via -r requirements/test.txt, boto3 -scandir==1.10.0 # via -r requirements/test.txt, -r requirements/travis.txt, pathlib2 simplejson==3.17.0 # via -r requirements/test.txt -singledispatch==3.4.0.3 # via -r requirements/test.txt, -r requirements/travis.txt, astroid, importlib-resources, pylint -six==1.14.0 # via -r requirements/pip-tools.txt, -r requirements/test.txt, -r requirements/travis.txt, astroid, diff-cover, django-pyfs, fs, fs-s3fs, mock, more-itertools, packaging, pathlib2, pip-tools, pylint, pytest, python-dateutil, singledispatch, tox, virtualenv +six==1.14.0 # via -r requirements/pip-tools.txt, -r requirements/test.txt, -r requirements/travis.txt, astroid, diff-cover, django-pyfs, fs, fs-s3fs, mock, packaging, pathlib2, pip-tools, python-dateutil, tox, virtualenv sortedcontainers==2.1.0 # via -r requirements/test.txt, hypothesis +sqlparse==0.3.1 # via -r requirements/test.txt, django toml==0.10.0 # via -r requirements/test.txt, -r requirements/travis.txt, tox tox-battery==0.5.2 # via -r requirements/travis.txt tox==3.14.6 # via -r requirements/test.txt, -r requirements/travis.txt, tox-battery -typing==3.7.4.1 # via -r requirements/test.txt, -r requirements/travis.txt, fs, importlib-resources +typed-ast==1.4.1 # via -r requirements/test.txt, astroid +typing==3.7.4.1 # via -r requirements/test.txt, fs urllib3==1.25.9 # via -r requirements/test.txt, -r requirements/travis.txt, botocore, requests virtualenv==20.0.18 # via -r requirements/test.txt, -r requirements/travis.txt, tox wcwidth==0.1.9 # via -r requirements/test.txt, pytest web-fragments==0.3.1 # via -r requirements/test.txt webob==1.8.6 # via -r requirements/test.txt -wrapt==1.12.1 # via -r requirements/test.txt, astroid +wrapt==1.11.2 # via -r requirements/test.txt, astroid zipp==1.2.0 # via -r requirements/test.txt, -r requirements/travis.txt, importlib-metadata, importlib-resources # The following packages are considered to be unsafe in a requirements file: diff --git a/requirements/django.in b/requirements/django.in index c0d0b0420..d8615f6b1 100644 --- a/requirements/django.in +++ b/requirements/django.in @@ -5,6 +5,6 @@ -r base.txt # Core XBlock dependencies -Django>=1.11 +Django>=2.2,<3.0 django-pyfs>=1.0.5 lazy diff --git a/requirements/django.txt b/requirements/django.txt index 01ecc5032..0e3489076 100644 --- a/requirements/django.txt +++ b/requirements/django.txt @@ -5,17 +5,13 @@ # make upgrade # appdirs==1.4.3 # via -r requirements/base.txt, fs -backports.os==0.1.1 # via -r requirements/base.txt, fs -boto3==1.12.45 # via fs-s3fs -botocore==1.15.45 # via boto3, s3transfer +boto3==1.12.46 # via fs-s3fs +botocore==1.15.46 # via boto3, s3transfer django-pyfs==2.1 # via -r requirements/django.in -django==1.11.29 # via -r requirements/django.in, django-pyfs +django==2.2.12 # via -r requirements/django.in, django-pyfs docutils==0.15.2 # via botocore -enum34==1.1.10 # via -r requirements/base.txt, fs fs-s3fs==1.1.1 # via django-pyfs fs==2.4.11 # via -r requirements/base.txt, django-pyfs, fs-s3fs -future==0.18.2 # via -r requirements/base.txt, backports.os -futures==3.3.0 ; python_version == "2.7" # via -c requirements/constraints.txt, s3transfer jmespath==0.9.5 # via boto3, botocore lazy==1.4 # via -r requirements/django.in lxml==4.5.0 # via -r requirements/base.txt @@ -26,6 +22,7 @@ pyyaml==5.3.1 # via -r requirements/base.txt s3transfer==0.3.3 # via boto3 simplejson==3.17.0 # via -r requirements/base.txt six==1.14.0 # via -r requirements/base.txt, django-pyfs, fs, fs-s3fs, python-dateutil +sqlparse==0.3.1 # via django typing==3.7.4.1 # via -r requirements/base.txt, fs urllib3==1.25.9 # via botocore web-fragments==0.3.1 # via -r requirements/base.txt diff --git a/requirements/doc.txt b/requirements/doc.txt index 85243fe21..0ee463a9f 100644 --- a/requirements/doc.txt +++ b/requirements/doc.txt @@ -7,21 +7,16 @@ alabaster==0.7.12 # via sphinx appdirs==1.4.3 # via -r requirements/django.txt, fs babel==2.8.0 # via sphinx -backports.os==0.1.1 # via -r requirements/django.txt, fs -boto3==1.12.45 # via -r requirements/django.txt, fs-s3fs -botocore==1.15.45 # via -r requirements/django.txt, boto3, s3transfer +boto3==1.12.46 # via -r requirements/django.txt, fs-s3fs +botocore==1.15.46 # via -r requirements/django.txt, boto3, s3transfer certifi==2020.4.5.1 # via requests chardet==3.0.4 # via requests django-pyfs==2.1 # via -r requirements/django.txt -django==1.11.29 # via -r requirements/django.txt, django-pyfs +django==2.2.12 # via -r requirements/django.txt, django-pyfs docutils==0.15.2 # via -r requirements/django.txt, botocore, sphinx edx-sphinx-theme==1.5.0 # via -r requirements/doc.in -enum34==1.1.10 # via -r requirements/django.txt, fs fs-s3fs==1.1.1 # via -r requirements/django.txt, django-pyfs fs==2.4.11 # via -r requirements/django.txt, django-pyfs, fs-s3fs -funcsigs==1.0.2 # via mock -future==0.18.2 # via -r requirements/django.txt, backports.os -futures==3.3.0 ; python_version == "2.7" # via -c requirements/constraints.txt, -r requirements/django.txt, s3transfer idna==2.9 # via requests imagesize==1.2.0 # via sphinx jinja2==2.11.2 # via sphinx @@ -31,7 +26,7 @@ lxml==4.5.0 # via -r requirements/django.txt markupsafe==1.1.1 # via -r requirements/django.txt, jinja2 mock==3.0.5 # via -r requirements/doc.in packaging==20.3 # via sphinx -pygments==2.5.2 # via sphinx +pygments==2.6.1 # via sphinx pyparsing==2.4.7 # via packaging python-dateutil==2.8.0 # via -c requirements/constraints.txt, -r requirements/django.txt, botocore pytz==2019.3 # via -r requirements/django.txt, babel, django, fs @@ -39,11 +34,17 @@ pyyaml==5.3.1 # via -r requirements/django.txt requests==2.23.0 # via sphinx s3transfer==0.3.3 # via -r requirements/django.txt, boto3 simplejson==3.17.0 # via -r requirements/django.txt -six==1.14.0 # via -r requirements/django.txt, django-pyfs, edx-sphinx-theme, fs, fs-s3fs, mock, packaging, python-dateutil, sphinx +six==1.14.0 # via -r requirements/django.txt, django-pyfs, edx-sphinx-theme, fs, fs-s3fs, mock, packaging, python-dateutil snowballstemmer==2.0.0 # via sphinx -sphinx==1.8.5 # via -r requirements/doc.in, edx-sphinx-theme -sphinxcontrib-websupport==1.1.2 # via sphinx -typing==3.7.4.1 # via -r requirements/django.txt, fs, sphinx +sphinx==3.0.2 # via -r requirements/doc.in, edx-sphinx-theme +sphinxcontrib-applehelp==1.0.2 # via sphinx +sphinxcontrib-devhelp==1.0.2 # via sphinx +sphinxcontrib-htmlhelp==1.0.3 # via sphinx +sphinxcontrib-jsmath==1.0.1 # via sphinx +sphinxcontrib-qthelp==1.0.3 # via sphinx +sphinxcontrib-serializinghtml==1.1.4 # via sphinx +sqlparse==0.3.1 # via -r requirements/django.txt, django +typing==3.7.4.1 # via -r requirements/django.txt, fs urllib3==1.25.9 # via -r requirements/django.txt, botocore, requests web-fragments==0.3.1 # via -r requirements/django.txt webob==1.8.6 # via -r requirements/django.txt diff --git a/requirements/test.in b/requirements/test.in index b25ac852d..183163103 100644 --- a/requirements/test.in +++ b/requirements/test.in @@ -5,7 +5,6 @@ -r django.txt # Package dependencies, including optional Django support astroid -caniusepython3 coverage ddt diff-cover >= 0.2.1 diff --git a/requirements/test.txt b/requirements/test.txt index 051f5ec67..1f6cdcf1e 100644 --- a/requirements/test.txt +++ b/requirements/test.txt @@ -5,35 +5,21 @@ # make upgrade # appdirs==1.4.3 # via -r requirements/django.txt, fs, virtualenv -argparse==1.4.0 # via caniusepython3 -astroid==1.6.6 # via -r requirements/test.in, pylint -atomicwrites==1.3.0 # via pytest +astroid==2.3.3 # via -r requirements/test.in, pylint attrs==19.3.0 # via hypothesis, pytest -backports.functools-lru-cache==1.6.1 # via astroid, caniusepython3, isort, pylint -backports.os==0.1.1 # via -r requirements/django.txt, fs, path.py -boto3==1.12.45 # via -r requirements/django.txt, fs-s3fs -botocore==1.15.45 # via -r requirements/django.txt, boto3, s3transfer -caniusepython3==7.2.0 # via -r requirements/test.in -certifi==2020.4.5.1 # via requests -chardet==3.0.4 # via requests -configparser==4.0.2 # via importlib-metadata, pylint -contextlib2==0.6.0.post1 # via importlib-metadata, importlib-resources, virtualenv, zipp +boto3==1.12.46 # via -r requirements/django.txt, fs-s3fs +botocore==1.15.46 # via -r requirements/django.txt, boto3, s3transfer coverage==5.1 # via -r requirements/test.in, pytest-cov ddt==1.3.1 # via -r requirements/test.in diff-cover==2.6.1 # via -r requirements/test.in -distlib==0.3.0 # via caniusepython3, virtualenv +distlib==0.3.0 # via virtualenv django-pyfs==2.1 # via -r requirements/django.txt docutils==0.15.2 # via -r requirements/django.txt, botocore -enum34==1.1.10 # via -r requirements/django.txt, astroid, fs, hypothesis filelock==3.0.12 # via tox, virtualenv fs-s3fs==1.1.1 # via -r requirements/django.txt, django-pyfs fs==2.4.11 # via -r requirements/django.txt, django-pyfs, fs-s3fs -funcsigs==1.0.2 # via mock, pytest -future==0.18.2 # via -r requirements/django.txt, backports.os -futures==3.3.0 ; python_version == "2.7" # via -c requirements/constraints.txt, -r requirements/django.txt, caniusepython3, isort, s3transfer -hypothesis==4.57.1 # via -r requirements/test.in -idna==2.9 # via requests -importlib-metadata==1.6.0 # via importlib-resources, inflect, path.py, pluggy, pytest, tox, virtualenv +hypothesis==5.10.4 # via -r requirements/test.in +importlib-metadata==1.6.0 # via importlib-resources, inflect, path, pluggy, pytest, tox, virtualenv importlib-resources==1.4.0 # via virtualenv inflect==3.0.2 # via jinja2-pluralize isort==4.3.21 # via pylint @@ -46,39 +32,39 @@ lxml==4.5.0 # via -r requirements/django.txt markupsafe==1.1.1 # via -r requirements/django.txt, jinja2 mccabe==0.6.1 # via pylint mock==3.0.5 # via -r requirements/test.in -more-itertools==5.0.0 # via pytest +more-itertools==8.2.0 # via pytest nose==1.3.7 # via -r requirements/test.in -packaging==20.3 # via caniusepython3, pytest, tox -path.py==11.5.2 # via -r requirements/test.in -pathlib2==2.3.5 # via importlib-metadata, importlib-resources, pytest, pytest-django, virtualenv +packaging==20.3 # via pytest, tox +path.py==12.4.0 # via -r requirements/test.in +path==13.1.0 # via path.py +pathlib2==2.3.5 # via pytest pluggy==0.13.1 # via diff-cover, pytest, tox py==1.8.1 # via pytest, tox pycodestyle==2.5.0 # via -r requirements/test.in -pygments==2.5.2 # via diff-cover -pylint==1.9.5 # via -r requirements/test.in +pygments==2.6.1 # via diff-cover +pylint==2.4.4 # via -r requirements/test.in pyparsing==2.4.7 # via packaging pytest-cov==2.8.1 # via -r requirements/test.in pytest-django==3.9.0 # via -r requirements/test.in -pytest==4.6.9 # via -r requirements/test.in, pytest-cov, pytest-django +pytest==5.4.1 # via -r requirements/test.in, pytest-cov, pytest-django python-dateutil==2.8.0 # via -c requirements/constraints.txt, -r requirements/django.txt, botocore pytz==2019.3 # via -r requirements/django.txt, django, fs pyyaml==5.3.1 # via -r requirements/django.txt -requests==2.23.0 # via caniusepython3 s3transfer==0.3.3 # via -r requirements/django.txt, boto3 -scandir==1.10.0 # via pathlib2 simplejson==3.17.0 # via -r requirements/django.txt -singledispatch==3.4.0.3 # via astroid, importlib-resources, pylint -six==1.14.0 # via -r requirements/django.txt, astroid, diff-cover, django-pyfs, fs, fs-s3fs, mock, more-itertools, packaging, pathlib2, pylint, pytest, python-dateutil, singledispatch, tox, virtualenv +six==1.14.0 # via -r requirements/django.txt, astroid, diff-cover, django-pyfs, fs, fs-s3fs, mock, packaging, pathlib2, python-dateutil, tox, virtualenv sortedcontainers==2.1.0 # via hypothesis +sqlparse==0.3.1 # via -r requirements/django.txt, django toml==0.10.0 # via tox tox==3.14.6 # via -r requirements/test.in -typing==3.7.4.1 # via -r requirements/django.txt, fs, importlib-resources -urllib3==1.25.9 # via -r requirements/django.txt, botocore, requests +typed-ast==1.4.1 # via astroid +typing==3.7.4.1 # via -r requirements/django.txt, fs +urllib3==1.25.9 # via -r requirements/django.txt, botocore virtualenv==20.0.18 # via tox wcwidth==0.1.9 # via pytest web-fragments==0.3.1 # via -r requirements/django.txt webob==1.8.6 # via -r requirements/django.txt -wrapt==1.12.1 # via astroid +wrapt==1.11.2 # via astroid zipp==1.2.0 # via importlib-metadata, importlib-resources # The following packages are considered to be unsafe in a requirements file: diff --git a/requirements/travis.txt b/requirements/travis.txt index 3e576a166..3199459f5 100644 --- a/requirements/travis.txt +++ b/requirements/travis.txt @@ -8,8 +8,6 @@ appdirs==1.4.3 # via virtualenv certifi==2020.4.5.1 # via requests chardet==3.0.4 # via requests codecov==2.0.22 # via -r requirements/travis.in -configparser==4.0.2 # via importlib-metadata -contextlib2==0.6.0.post1 # via importlib-metadata, importlib-resources, virtualenv, zipp coverage==5.1 # via codecov distlib==0.3.0 # via virtualenv filelock==3.0.12 # via tox, virtualenv @@ -17,18 +15,14 @@ idna==2.9 # via requests importlib-metadata==1.6.0 # via importlib-resources, pluggy, tox, virtualenv importlib-resources==1.4.0 # via virtualenv packaging==20.3 # via tox -pathlib2==2.3.5 # via importlib-metadata, importlib-resources, virtualenv pluggy==0.13.1 # via tox py==1.8.1 # via tox pyparsing==2.4.7 # via packaging requests==2.23.0 # via codecov -scandir==1.10.0 # via pathlib2 -singledispatch==3.4.0.3 # via importlib-resources -six==1.14.0 # via packaging, pathlib2, tox, virtualenv +six==1.14.0 # via packaging, tox, virtualenv toml==0.10.0 # via tox tox-battery==0.5.2 # via -r requirements/travis.in tox==3.14.6 # via -r requirements/travis.in, tox-battery -typing==3.7.4.1 # via importlib-resources urllib3==1.25.9 # via requests virtualenv==20.0.18 # via tox zipp==1.2.0 # via importlib-metadata, importlib-resources diff --git a/setup.py b/setup.py index ea05ca1de..2422883ae 100755 --- a/setup.py +++ b/setup.py @@ -47,15 +47,10 @@ classifiers=[ 'Development Status :: 5 - Production/Stable', 'Framework :: Django', - 'Framework :: Django :: 1.11', - 'Framework :: Django :: 2.0', - 'Framework :: Django :: 2.1', 'Framework :: Django :: 2.2', 'Intended Audience :: Developers', 'License :: OSI Approved :: Apache Software License', 'Natural Language :: English', - 'Programming Language :: Python :: 2', - 'Programming Language :: Python :: 2.7', "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.5", ] diff --git a/tox.ini b/tox.ini index 1304d3b2e..024934087 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = py{27,35}-django111,py{35}-django{20,21,22} +envlist = py35-django22,py38-django{22,30} [pytest] DJANGO_SETTINGS_MODULE = xblock.test.settings @@ -10,10 +10,8 @@ norecursedirs = .* doc requirements [testenv] passenv = CI TRAVIS TRAVIS_* deps = - django111: Django>=1.11,<2.0 - django20: Django>=2.0,<2.1 - django21: Django>=2.1,<2.2 django22: Django>=2.2,<2.3 + django30: Django>=3.0,<3.1 -r requirements/test.txt changedir = {envsitepackagesdir} commands = @@ -25,7 +23,7 @@ whitelist_externals = [testenv:docs] basepython = - python2.7 + python3.5 changedir = {toxinidir}/doc deps= @@ -35,7 +33,7 @@ commands = [testenv:quality] deps = - django111: Django>=1.11,<2.0 + django22: Django>=2.2,<2.3 -r requirements/test.txt changedir = {toxinidir} commands = diff --git a/xblock/completable.py b/xblock/completable.py index 1126b978d..b6f55b42e 100644 --- a/xblock/completable.py +++ b/xblock/completable.py @@ -4,7 +4,7 @@ from __future__ import absolute_import, unicode_literals -class XBlockCompletionMode(object): +class XBlockCompletionMode: """ Enumeration for completion modes. """ @@ -22,7 +22,7 @@ def get_mode(cls, block_class): return getattr(block_class, 'completion_mode', cls.COMPLETABLE) -class CompletableXBlockMixin(object): +class CompletableXBlockMixin: """ This mixin sets attributes and provides helper method to integrate XBlock with Completion API. """ diff --git a/xblock/core.py b/xblock/core.py index fbb97b8d0..18dfa6bbc 100644 --- a/xblock/core.py +++ b/xblock/core.py @@ -50,7 +50,6 @@ class XBlockMixin(ScopedStorageMixin): created by a particular runtime. """ - pass class SharedBlockBase(Plugin): diff --git a/xblock/django/request.py b/xblock/django/request.py index 87e7e3be1..f0d6000bd 100644 --- a/xblock/django/request.py +++ b/xblock/django/request.py @@ -8,12 +8,12 @@ import six import webob +from django.http import HttpResponse from webob.multidict import MultiDict, NestedMultiDict, NoVars def webob_to_django_response(webob_response): """Returns a django response to the `webob_response`""" - from django.http import HttpResponse django_response = HttpResponse( webob_response.app_iter, content_type=webob_response.content_type, @@ -87,7 +87,7 @@ def querydict_to_multidict(query_dict, wrap=None): )) -class DjangoUploadedFile(object): +class DjangoUploadedFile: """ Looks like a cgi.FieldStorage, but wraps a Django UploadedFile. """ @@ -146,15 +146,15 @@ def POST(self): querydict_to_multidict(self._request.FILES, wrap=DjangoUploadedFile), ) - @lazy - def body(self): # pylint: disable=method-hidden + @property + def body(self): """ Return the content of the request body. """ return self._request.body - @lazy - def body_file(self): # pylint: disable=method-hidden + @property + def body_file(self): """ Input stream of the request """ diff --git a/xblock/exceptions.py b/xblock/exceptions.py index 1d1971354..eb719143c 100644 --- a/xblock/exceptions.py +++ b/xblock/exceptions.py @@ -93,24 +93,20 @@ class NoSuchHandlerError(Exception): """ Raised to indicate that the requested handler was not found. """ - pass class NoSuchServiceError(Exception): """ Raised to indicate that a requested service was not found. """ - pass class NoSuchUsage(Exception): """Raised by :meth:`.IdReader.get_definition_id` if the usage doesn't exist.""" - pass class NoSuchDefinition(Exception): """Raised by :meth:`.IdReader.get_block_type` if the definition doesn't exist.""" - pass class JsonHandlerError(Exception): @@ -141,9 +137,7 @@ def get_response(self, **kwargs): class DisallowedFileError(Exception): """Raised by :meth:`open_local_resource` if the requested file is not allowed.""" - pass class FieldDataDeprecationWarning(DeprecationWarning): """Warning for use of deprecated _field_data accessor""" - pass diff --git a/xblock/fields.py b/xblock/fields.py index 9ac115cef..77d098add 100644 --- a/xblock/fields.py +++ b/xblock/fields.py @@ -39,17 +39,15 @@ class FailingEnforceTypeWarning(DeprecationWarning): """ A warning triggered when enforce_type would cause a exception if enabled """ - pass class ModifyingEnforceTypeWarning(DeprecationWarning): """ A warning triggered when enforce_type would change a value if enabled """ - pass -class Sentinel(object): +class Sentinel: """ Class for implementing sentinel objects (only equal to themselves). """ @@ -81,7 +79,7 @@ def __hash__(self): return hash(self.name) -class BlockScope(object): +class BlockScope: """ Enumeration of block scopes. @@ -117,7 +115,7 @@ def scopes(cls): return [cls.USAGE, cls.DEFINITION, cls.TYPE, cls.ALL] -class UserScope(object): +class UserScope: """ Enumeration of user scopes. @@ -695,7 +693,7 @@ class JSONField(Field): """ Field type which has a convenient JSON representation. """ - pass # for now; we'll bubble functions down when we finish deprecation in Field + # for now; we'll bubble functions down when we finish deprecation in Field class Integer(JSONField): @@ -1020,7 +1018,6 @@ class Any(JSONField): THIS SHOULD BE DEPRECATED. THIS SHOULD EITHER BE ANY JSON DATA, OR IT MAKES NO SENSE """ - pass class Reference(JSONField): @@ -1030,7 +1027,6 @@ class Reference(JSONField): It's up to the runtime to know how to dereference this field type, but the field type enables the runtime to know that it must do the interpretation. """ - pass class ReferenceList(List): @@ -1042,7 +1038,6 @@ class ReferenceList(List): """ # this could define from_json and to_json as list comprehensions calling from/to_json on the list eles, # but since Reference doesn't stipulate a definition for from/to, that seems unnecessary at this time. - pass class ReferenceValueDict(Dict): @@ -1054,7 +1049,6 @@ class ReferenceValueDict(Dict): """ # this could define from_json and to_json as list comprehensions calling from/to_json on the list eles, # but since Reference doesn't stipulate a definition for from/to, that seems unnecessary at this time. - pass def scope_key(instance, xblock): diff --git a/xblock/internal.py b/xblock/internal.py index ba88dc310..f75dbe9e3 100644 --- a/xblock/internal.py +++ b/xblock/internal.py @@ -10,7 +10,7 @@ import six -class LazyClassProperty(object): +class LazyClassProperty: """ A descriptor that acts as a class-level @lazy. @@ -57,14 +57,12 @@ def __new__(mcs, name, bases, attrs): return super(NamedAttributesMetaclass, mcs).__new__(mcs, name, bases, attrs) -class Nameable(object): +class Nameable: """ A base class for class attributes which, when used in concert with :class:`.NamedAttributesMetaclass`, will be assigned a `__name__` attribute based on what class attribute they are bound to. """ - if six.PY2: - __slots__ = ('__name__',) __name__ = None @staticmethod diff --git a/xblock/mixins.py b/xblock/mixins.py index 65bcfee80..16b86ffa8 100644 --- a/xblock/mixins.py +++ b/xblock/mixins.py @@ -31,7 +31,7 @@ ]) -class HandlersMixin(object): +class HandlersMixin: """ A mixin provides all of the machinery needed for working with XBlock-style handlers. """ @@ -89,7 +89,7 @@ def handle(self, handler_name, request, suffix=''): return self.runtime.handle(self, handler_name, request, suffix) -class RuntimeServicesMixin(object): +class RuntimeServicesMixin: """ This mixin provides all of the machinery needed for an XBlock-style object to declare dependencies on particular runtime services. @@ -550,7 +550,7 @@ def _add_field(self, node, field_name, field): node.set(field_name, text_value) -class IndexInfoMixin(object): +class IndexInfoMixin: """ This mixin provides interface for classes that wish to provide index information which might be used within a search index @@ -565,7 +565,7 @@ def index_dictionary(self): return {} -class ViewsMixin(object): +class ViewsMixin: """ This mixin provides decorators that can be used on xBlock view methods. """ diff --git a/xblock/plugin.py b/xblock/plugin.py index 12c6b1c62..710189772 100644 --- a/xblock/plugin.py +++ b/xblock/plugin.py @@ -10,6 +10,8 @@ import itertools import logging import pkg_resources +from mock import Mock + from xblock.internal import class_lazy log = logging.getLogger(__name__) @@ -19,7 +21,6 @@ class PluginMissingError(Exception): """Raised when trying to load a plugin from an entry_point that cannot be found.""" - pass class AmbiguousPluginError(Exception): @@ -38,15 +39,13 @@ def default_select(identifier, all_entry_points): # pylint: disable=inconsisten if len(all_entry_points) == 0: raise PluginMissingError(identifier) - - elif len(all_entry_points) == 1: + if len(all_entry_points) == 1: return all_entry_points[0] - elif len(all_entry_points) > 1: raise AmbiguousPluginError(all_entry_points) -class Plugin(object): +class Plugin: """Base class for a system that uses entry_points to load plugins. Implementing classes are expected to have the following attributes: @@ -106,7 +105,7 @@ def select(identifier, all_entry_points): select = default_select all_entry_points = list(pkg_resources.iter_entry_points(cls.entry_point, name=identifier)) - for extra_identifier, extra_entry_point in cls.extra_entry_points: + for extra_identifier, extra_entry_point in iter(cls.extra_entry_points): if identifier == extra_identifier: all_entry_points.append(extra_entry_point) @@ -139,7 +138,7 @@ def load_classes(cls, fail_silently=True): """ all_classes = itertools.chain( pkg_resources.iter_entry_points(cls.entry_point), - (entry_point for identifier, entry_point in cls.extra_entry_points), + (entry_point for identifier, entry_point in iter(cls.extra_entry_points)), ) for class_ in all_classes: try: @@ -161,7 +160,6 @@ def test_the_thing(): # Here I can load MyXBlockClass by name. """ - from mock import Mock if identifier is None: identifier = class_.__name__.lower() @@ -180,7 +178,7 @@ def _inner(*args, **kwargs): # pylint: disable=C0111 old = list(cls.extra_entry_points) old_cache = PLUGIN_CACHE - cls.extra_entry_points.append((identifier, entry_point)) + cls.extra_entry_points.append((identifier, entry_point)) # pylint: disable=no-member PLUGIN_CACHE = {} try: diff --git a/xblock/reference/plugins.py b/xblock/reference/plugins.py index 3499da931..f3354682a 100644 --- a/xblock/reference/plugins.py +++ b/xblock/reference/plugins.py @@ -20,7 +20,6 @@ class ImproperlyConfigured(Exception): either in a proper Django app, or don't have Django installed at all. ''' - pass try: from djpyfs import djpyfs # pylint: disable=import-error @@ -66,7 +65,7 @@ def wrapper(function): return wrapper -class Service(object): +class Service: """ Top-level definition for an XBlocks service. diff --git a/xblock/reference/user_service.py b/xblock/reference/user_service.py index 039342cd2..d272f441e 100644 --- a/xblock/reference/user_service.py +++ b/xblock/reference/user_service.py @@ -23,7 +23,7 @@ def get_current_user(self): raise NotImplementedError() -class XBlockUser(object): +class XBlockUser: """ A model representation of user data returned by the `UserService`. diff --git a/xblock/runtime.py b/xblock/runtime.py index f93cd3249..6d3e83b6d 100644 --- a/xblock/runtime.py +++ b/xblock/runtime.py @@ -54,22 +54,18 @@ def __new__(cls, scope, user_id, block_scope_id, field_name, block_family='xbloc @abstractmethod def get(self, key): """Reads the value of the given `key` from storage.""" - pass @abstractmethod def set(self, key, value): """Sets `key` equal to `value` in storage.""" - pass @abstractmethod def delete(self, key): """Deletes `key` from storage.""" - pass @abstractmethod def has(self, key): """Returns whether or not `key` is present in storage.""" - pass def default(self, key): """ @@ -1126,7 +1122,6 @@ def querypath(self, block, path): """An XPath-like interface to `query`.""" class BadPath(Exception): """Bad path exception thrown when path cannot be found.""" - pass results = self.query(block) ROOT, SEP, WORD, FINAL = six.moves.range(4) # pylint: disable=C0103 state = ROOT @@ -1176,7 +1171,7 @@ class BadPath(Exception): results = results.attr(toktext[1:]) state = FINAL elif tokname == "word": - # xxx (tag selection) + # xxx (tag selection) # pylint: disable=fixme if state != SEP: raise BadPath() results = results.children().tagged(toktext) @@ -1195,7 +1190,7 @@ def _family_id_to_superclass(self, family_id): raise ValueError('No such family: {}'.format(family_id)) -class ObjectAggregator(object): +class ObjectAggregator: """ Provides a single object interface that combines many smaller objects. @@ -1235,7 +1230,7 @@ def __delattr__(self, name): _CLASS_CACHE_LOCK = threading.RLock() -class Mixologist(object): +class Mixologist: """ Provides a facility to dynamically generate classes with additional mixins. """ @@ -1299,7 +1294,7 @@ def mix(self, cls): return _CLASS_CACHE[mixin_key] -class RegexLexer(object): +class RegexLexer: """Split text into lexical tokens based on regexes.""" def __init__(self, *toks): parts = [] @@ -1314,7 +1309,7 @@ def lex(self, text): yield (name, match.group(name)) -class NullI18nService(object): +class NullI18nService: """ A simple implementation of the runtime "i18n" service. """ diff --git a/xblock/scorable.py b/xblock/scorable.py index 2815fab11..2e9417683 100644 --- a/xblock/scorable.py +++ b/xblock/scorable.py @@ -14,7 +14,7 @@ Score = namedtuple('Score', ['raw_earned', 'raw_possible']) -class ScorableXBlockMixin(object): +class ScorableXBlockMixin: """ Mixin to handle functionality related to scoring. diff --git a/xblock/test/test_core.py b/xblock/test/test_core.py index c366efae8..86da159f9 100644 --- a/xblock/test/test_core.py +++ b/xblock/test/test_core.py @@ -506,11 +506,10 @@ class FieldTester(XBlock): def test_class_tags(): xblock = XBlock(None, None, None) - assert xblock._class_tags == set() + assert xblock._class_tags == set() # pylint: disable=comparison-with-callable class Sub1Block(XBlock): """Toy XBlock""" - pass sub1block = Sub1Block(None, None, None) assert sub1block._class_tags == set() @@ -518,14 +517,12 @@ class Sub1Block(XBlock): @XBlock.tag("cat dog") class Sub2Block(Sub1Block): """Toy XBlock""" - pass sub2block = Sub2Block(None, None, None) assert sub2block._class_tags == set(["cat", "dog"]) class Sub3Block(Sub2Block): """Toy XBlock""" - pass sub3block = Sub3Block(None, None, None) assert sub3block._class_tags == set(["cat", "dog"]) @@ -533,11 +530,9 @@ class Sub3Block(Sub2Block): @XBlock.tag("mixin") class MixinBlock(XBlock): """Toy XBlock""" - pass class Sub4Block(MixinBlock, Sub3Block): """Toy XBlock""" - pass sub4block = Sub4Block(None, None, None) assert sub4block._class_tags == set(["cat", "dog", "mixin"]) @@ -548,15 +543,12 @@ def test_loading_tagged_classes(): @XBlock.tag("thetag") class HasTag1(XBlock): """Toy XBlock""" - pass class HasTag2(HasTag1): """Toy XBlock""" - pass class HasntTag(XBlock): """Toy XBlock""" - pass the_classes = [('hastag1', HasTag1), ('hastag2', HasTag2), ('hasnttag', HasntTag)] tagged_classes = [('hastag1', HasTag1), ('hastag2', HasTag2)] @@ -757,13 +749,12 @@ def test_services_decorators(): # A default XBlock has requested no services xblock = XBlock(None, None, None) assert XBlock._services_requested == {} - assert xblock._services_requested == {} + assert xblock._services_requested == {} # pylint: disable=comparison-with-callable @XBlock.needs("n") @XBlock.wants("w") class ServiceUsingBlock(XBlock): """XBlock using some services.""" - pass service_using_block = ServiceUsingBlock(None, scope_ids=None) assert ServiceUsingBlock._services_requested == {'n': 'need', 'w': 'want'} @@ -775,13 +766,11 @@ def test_services_decorators_with_inheritance(): @XBlock.wants("w1") class ServiceUsingBlock(XBlock): """XBlock using some services.""" - pass @XBlock.needs("n2") @XBlock.wants("w2") class SubServiceUsingBlock(ServiceUsingBlock): """Does this class properly inherit services from ServiceUsingBlock?""" - pass sub_service_using_block = SubServiceUsingBlock(None, scope_ids=None) assert sub_service_using_block.service_declaration("n1") == "need" @@ -796,7 +785,6 @@ class HasParent(XBlock): """ Dummy empty class """ - pass runtime = TestRuntime(services={'field-data': DictFieldData({})}) runtime.get_block = Mock() @@ -930,7 +918,6 @@ class OpenLocalResourceTest(unittest.TestCase): class LoadableXBlock(XBlock): """Just something to load resources from.""" - pass class UnloadableXBlock(XBlock): """Just something to load resources from.""" @@ -1031,7 +1018,6 @@ class TestXBlockDeprecation(WarningTestMixin, unittest.TestCase): class TestBlock(XBlock): """An empty XBlock for testing""" - pass def test_field_data_paramater(self): field_data = Mock(spec=FieldData) @@ -1056,7 +1042,6 @@ class TestXBlock(XBlock): """ Class to test default Xblock provides a dictionary """ - pass class TestIndexedXBlock(XBlock): """ diff --git a/xblock/test/test_field_data.py b/xblock/test/test_field_data.py index 260e34bd6..1c0309148 100644 --- a/xblock/test/test_field_data.py +++ b/xblock/test/test_field_data.py @@ -28,7 +28,7 @@ class TestingBlock(XBlock): user_state = String(scope=Scope.user_state) -class TestSplitFieldData(object): +class TestSplitFieldData: """ Tests of :ref:`SplitFieldData`. """ @@ -85,7 +85,7 @@ def test_default(self): assert not self.settings.default.called -class TestReadOnlyFieldData(object): +class TestReadOnlyFieldData: """ Tests of :ref:`ReadOnlyFieldData`. """ diff --git a/xblock/test/test_fields_api.py b/xblock/test/test_fields_api.py index 7de9a98f1..1afd86775 100644 --- a/xblock/test/test_fields_api.py +++ b/xblock/test/test_fields_api.py @@ -46,7 +46,7 @@ # without pylint complaining # pylint: disable=no-member # ~~~~~~~~~~~~~ Classes defining test operations ~~~~~~~~~~~~~~~~~~~~~~ -class BlockFirstOperations(object): +class BlockFirstOperations: """ Defines operations using the block-first implementations @@ -71,7 +71,7 @@ def is_default(self): return not self.block.__class__.field.is_set_on(self.block) -class FieldFirstOperations(object): +class FieldFirstOperations: """ Defines operations using the field-first implementations @@ -97,7 +97,7 @@ def is_default(self): # ~~~~~~~~~~~~~ Classes defining test properties ~~~~~~~~~~~~~~~~~~~~~~ -class UniversalProperties(object): +class UniversalProperties: """ Properties that can be tested without knowing whether a field has an initial value or a default value @@ -181,7 +181,7 @@ def test_set_after_get_doesnt_save(self): assert patched_set_many.called -class MutationProperties(object): +class MutationProperties: """ Properties of mutable fields that can be tested without knowing whether the field has an initial value or a default value @@ -238,7 +238,7 @@ def test_set_save_mutate_save(self): assert pointer == self.field_data.get(self.block, 'field') -class InitialValueProperties(object): +class InitialValueProperties: """ Properties dependent on the field having an initial value @@ -271,7 +271,7 @@ def test_set_with_save_writes(self): assert self.new_value == self.field_data.get(self.block, 'field') -class DefaultValueProperties(object): +class DefaultValueProperties: """ Properties dependent on the field not having an initial value @@ -305,7 +305,7 @@ def test_delete_with_save_succeeds(self): assert not self.field_data.has(self.block, 'field') -class DefaultValueMutationProperties(object): +class DefaultValueMutationProperties: """ Properties testing mutation of default field values @@ -339,7 +339,7 @@ def test_mutation_with_save_writes(self): assert reference_copy == final_value -class InitialValueMutationProperties(object): +class InitialValueMutationProperties: """ Properties testing mutation of set field value @@ -502,7 +502,7 @@ class TestImmutableWithInitialValueAndUniqueIdDefault(UniqueIdTestCases, Initial # Allow base classes to leave out class attributes and that they access # without pylint complaining # pylint: disable=no-member -class GetNoopPrefix(object): +class GetNoopPrefix: """ Mixin that prefixes existing field tests with a call to `self.block.field`. @@ -516,7 +516,7 @@ def setup_method(self): self.get() -class GetSaveNoopPrefix(object): +class GetSaveNoopPrefix: """ Mixin that prefixes existing field tests with a call to `self.block.field` and then `self.block.save()` @@ -531,7 +531,7 @@ def setup_method(self): self.block.save() -class SaveNoopPrefix(object): +class SaveNoopPrefix: """ Mixin that prefixes existing field tests with a call to `self.block.save()` diff --git a/xblock/test/test_internal.py b/xblock/test/test_internal.py index 0a18976cc..726220fe0 100644 --- a/xblock/test/test_internal.py +++ b/xblock/test/test_internal.py @@ -13,7 +13,7 @@ class TestLazyClassProperty(TestCase): """ Tests of @class_lazy. """ - class Base(object): + class Base: """Test class that uses @class_lazy.""" @class_lazy def isolated_dict(cls): # pylint: disable=no-self-argument @@ -22,7 +22,6 @@ def isolated_dict(cls): # pylint: disable=no-self-argument class Derived(Base): """Test class that inherits a @class_lazy definition.""" - pass def test_isolation(self): self.assertEqual({}, self.Base.isolated_dict) @@ -54,12 +53,10 @@ class NamingTester(six.with_metaclass(NamedAttributesMetaclass, object)): def meth(self): "An empty method." - pass @property def prop(self): "An empty property." - pass class InheritedNamingTester(NamingTester): diff --git a/xblock/test/test_json_conversion.py b/xblock/test/test_json_conversion.py index 0dfe0d8be..1976a9290 100644 --- a/xblock/test/test_json_conversion.py +++ b/xblock/test/test_json_conversion.py @@ -47,7 +47,7 @@ def default(self, block, name): return {'$type': 'set', '$vals': [0, 1]} -class TestJsonConversion(object): +class TestJsonConversion: """ Verify that all ModelType operations correctly convert the json that comes out of the ModelData to python objects diff --git a/xblock/test/test_mixins.py b/xblock/test/test_mixins.py index 09e6b9fec..b22583a45 100644 --- a/xblock/test/test_mixins.py +++ b/xblock/test/test_mixins.py @@ -7,11 +7,11 @@ from datetime import datetime from unittest import TestCase -import ddt as ddt -from lxml import etree +import ddt import mock import pytz import six +from lxml import etree from xblock.core import XBlock, XBlockAside from xblock.fields import List, Scope, Integer, String, ScopeIds, UNIQUE_ID, DateTime @@ -45,19 +45,16 @@ class ScopedStorageMixinTester(ScopedStorageMixin): class ChildClass(ScopedStorageMixinTester): """Toy class for ModelMetaclass testing""" - pass - class FieldsMixin(object): + class FieldsMixin: """Toy mixin for field testing""" field_c = Integer(scope=Scope.settings) class MixinChildClass(FieldsMixin, ScopedStorageMixinTester): """Toy class for ScopedStorageMixin testing with mixed-in fields""" - pass class MixinGrandchildClass(MixinChildClass): """Toy class for ScopedStorageMixin testing with inherited mixed-in fields""" - pass def test_scoped_storage_mixin(self): @@ -124,11 +121,9 @@ class HasChildren(HierarchyMixin): class WithoutChildren(HierarchyMixin): """Toy class for ChildrenModelMetaclass testing""" - pass class InheritedChildren(HasChildren): """Toy class for ChildrenModelMetaclass testing""" - pass def test_children_metaclass(self): # `HasChildren` and `WithoutChildren` both obtain the `children` attribute and @@ -156,7 +151,6 @@ class TestIndexInfoMixin(AttrAssertionMixin): """ class IndexInfoMixinTester(IndexInfoMixin): """Test class for index mixin""" - pass def test_index_info(self): self.assertHasAttr(self.IndexInfoMixinTester, 'index_dictionary') @@ -182,20 +176,20 @@ def functionality_supported_view(self): """ A view that supports a functionality """ - pass # pragma: no cover + # pragma: no cover @ViewsMixin.supports("functionality1", "functionality2") def multi_featured_view(self): """ A view that supports multiple functionalities """ - pass # pragma: no cover + # pragma: no cover def an_unsupported_view(self): """ A view that does not support any functionality """ - pass # pragma: no cover + # pragma: no cover test_xblock = SupportsDecoratorTester() @@ -309,7 +303,7 @@ def _assert_node_elements(self, node, expected_elements): Checks XML node elements to match expected elements. """ node_elements = list(node) - self.assertEqual(set([elem.tag for elem in node_elements]), set(expected_elements.keys())) + self.assertEqual({elem.tag for elem in node_elements}, set(expected_elements.keys())) # All elements on the node are expected to have a "none"="true" attribute. for elem in node: self.assertEqual(elem.get('none'), 'true') @@ -486,7 +480,7 @@ def test_datetime_serialization(self, value, expected_attributes): """ node = etree.Element(self.test_xblock_datetime_tag) - self.test_xblock_datetime.datetime = value + self.test_xblock_datetime.datetime = value # pylint: disable=attribute-defined-outside-init self.test_xblock_datetime.add_xml_to_node(node) diff --git a/xblock/test/test_parsing.py b/xblock/test/test_parsing.py index 146f5807f..e4da20c32 100644 --- a/xblock/test/test_parsing.py +++ b/xblock/test/test_parsing.py @@ -96,7 +96,7 @@ def add_xml_to_node(self, node): # Helpers -class XmlTestMixin(object): +class XmlTestMixin: """ Wraps parsing and exporting and other things to return more useful values. Does not define a runtime (thus calling it a mixin) diff --git a/xblock/test/test_plugin.py b/xblock/test/test_plugin.py index 127ed3dd2..00f1a2d86 100644 --- a/xblock/test/test_plugin.py +++ b/xblock/test/test_plugin.py @@ -14,17 +14,14 @@ class AmbiguousBlock1(XBlock): """A dummy class to find as a plugin.""" - pass class AmbiguousBlock2(XBlock): """A dummy class to find as a plugin.""" - pass class UnambiguousBlock(XBlock): """A dummy class to find as a plugin.""" - pass @XBlock.register_temp_plugin(AmbiguousBlock1, "bad_block") @@ -47,7 +44,6 @@ def test_ambiguous_plugins(): # We can use our own function as the select function. class MyOwnException(Exception): """We'll raise this from `boom`.""" - pass def boom(identifier, entry_points): """A select function to prove user-defined functions are called.""" diff --git a/xblock/test/test_runtime.py b/xblock/test/test_runtime.py index eed874378..433bba3e3 100644 --- a/xblock/test/test_runtime.py +++ b/xblock/test/test_runtime.py @@ -37,7 +37,7 @@ from xblock.test.tools import unabc, WarningTestMixin, TestRuntime -class TestMixin(object): +class TestMixin: """ Set up namespaces for each scope to use. """ @@ -75,7 +75,6 @@ class TestXBlockNoFallback(XBlock): def handler_without_correct_decoration(self, request, suffix=''): """a handler which is missing the @XBlock.handler decoration.""" - pass class TestXBlock(TestXBlockNoFallback): @@ -316,7 +315,7 @@ def test_default_fn(): assert second_call == 2 -class TestSimpleMixin(object): +class TestSimpleMixin: """Toy class for mixin testing""" field_x = List(scope=Scope.content) field_y = String(scope=Scope.user_state, default="default_value") @@ -370,7 +369,7 @@ def test_mixin_field_access(): assert not field_tester._field_data.has(field_tester, 'field_z') -class Dynamic(object): +class Dynamic: """ Object for testing that sets attrs based on __init__ kwargs """ @@ -379,7 +378,7 @@ def __init__(self, **kwargs): setattr(self, name, value) -class TestObjectAggregator(object): +class TestObjectAggregator: """ Test that the ObjectAggregator behaves correctly """ @@ -440,7 +439,7 @@ class ThirdMixin(XBlockMixin): field = Integer(default=3) -class TestMixologist(object): +class TestMixologist: """Test that the Mixologist class behaves correctly.""" def setup_method(self): """ @@ -492,7 +491,7 @@ def test_multiply_mixed(self): assert len(post_mixed.__bases__) == 4 -class TestMixologistErrors(object): +class TestMixologistErrors: """ Test failures in Mixologist initialization. """ def test_bad_class_name(self): bad_class_name = 'xblock.test.test_runtime.NonExistentMixin' diff --git a/xblock/test/test_scorable.py b/xblock/test/test_scorable.py index 449d972eb..5131f3d84 100644 --- a/xblock/test/test_scorable.py +++ b/xblock/test/test_scorable.py @@ -45,8 +45,8 @@ def set_score(self, score): def calculate_score(self): if self._scoring_error: raise RuntimeError('Whoops') # Any error will do - else: - return scorable.Score(raw_earned=1.6, raw_possible=2.0) + + return scorable.Score(raw_earned=1.6, raw_possible=2.0) @ddt.ddt diff --git a/xblock/test/test_test_tools.py b/xblock/test/test_test_tools.py index 4e7749f4d..d96ef53ea 100644 --- a/xblock/test/test_test_tools.py +++ b/xblock/test/test_test_tools.py @@ -36,13 +36,11 @@ def absmeth2(self): @unabc # pylint: disable=abstract-method class ForceConcrete(Abstract): """Ha-ha! Can't make me implement what I don't want to!""" - pass @unabc("Sorry, no {}") # pylint: disable=abstract-method class ForceConcreteMessage(Abstract): """I'll implement what I want to implement.""" - pass class TestUnAbc(unittest.TestCase): diff --git a/xblock/test/tools.py b/xblock/test/tools.py index fb66d931e..3b6909bc7 100644 --- a/xblock/test/tools.py +++ b/xblock/test/tools.py @@ -92,7 +92,7 @@ class NotAbstract(SomeAbstractClass): return partial(_unabc, msg=msg) -class WarningTestMixin(object): +class WarningTestMixin: """ Add the ability to assert on warnings raised by a chunk of code. """ diff --git a/xblock/validation.py b/xblock/validation.py index ca371832f..5dabc7b57 100644 --- a/xblock/validation.py +++ b/xblock/validation.py @@ -7,7 +7,7 @@ import six -class ValidationMessage(object): +class ValidationMessage: """ A message containing validation information about an xblock. """ @@ -45,7 +45,7 @@ def to_json(self): } -class Validation(object): +class Validation: """ An object containing validation information for an xblock instance.