├── tests ├── __init__.py ├── notebooks │ ├── passing_notebooks │ │ ├── x.npy │ │ ├── y.npy │ │ ├── HelloWorld.ipynb │ │ └── notebook_that_loads_things.ipynb │ └── failing_notebooks │ │ ├── failing_notebook.ipynb │ │ └── failing_notebook2.ipynb └── test_nbtest.py ├── requirements.txt ├── MANIFEST.in ├── credentials.tar.gz.enc ├── .flake8 ├── requirements_dev.txt ├── .bumpversion.cfg ├── docs ├── api.rst ├── images │ └── testing_syntax_highlighting.png ├── index.rst ├── Makefile ├── make.bat └── conf.py ├── .coveragerc ├── testipynb ├── __init__.py └── testipynb.py ├── ci └── deploy-pypi.sh ├── .travis.yml ├── LICENSE ├── .gitignore ├── setup.py ├── Makefile ├── README.rst └── .pylintrc /tests/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | -e . 2 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include *.rst LICENSE 2 | -------------------------------------------------------------------------------- /credentials.tar.gz.enc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opengeophysics/testipynb/HEAD/credentials.tar.gz.enc -------------------------------------------------------------------------------- /.flake8: -------------------------------------------------------------------------------- 1 | [flake8] 2 | ignore = E203, E266, E501, W503, F401, E741 3 | max-line-length = 88 4 | max-complexity = 10 5 | -------------------------------------------------------------------------------- /requirements_dev.txt: -------------------------------------------------------------------------------- 1 | twine 2 | pytest>=3.6 3 | pytest-cov 4 | coverage 5 | codecov 6 | sphinx_rtd_theme 7 | sphinx 8 | -------------------------------------------------------------------------------- /.bumpversion.cfg: -------------------------------------------------------------------------------- 1 | [bumpversion] 2 | current_version = 0.0.3 3 | files = setup.py testipynb/__init__.py docs/conf.py 4 | 5 | -------------------------------------------------------------------------------- /docs/api.rst: -------------------------------------------------------------------------------- 1 | .. _api: 2 | 3 | API 4 | *** 5 | 6 | .. automodule:: testipynb.testipynb 7 | :members: 8 | :undoc-members: 9 | -------------------------------------------------------------------------------- /tests/notebooks/passing_notebooks/x.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opengeophysics/testipynb/HEAD/tests/notebooks/passing_notebooks/x.npy -------------------------------------------------------------------------------- /tests/notebooks/passing_notebooks/y.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opengeophysics/testipynb/HEAD/tests/notebooks/passing_notebooks/y.npy -------------------------------------------------------------------------------- /docs/images/testing_syntax_highlighting.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opengeophysics/testipynb/HEAD/docs/images/testing_syntax_highlighting.png -------------------------------------------------------------------------------- /docs/index.rst: -------------------------------------------------------------------------------- 1 | .. include:: ../README.rst 2 | 3 | 4 | API 5 | --- 6 | 7 | .. toctree:: 8 | :maxdepth: 3 9 | 10 | api 11 | 12 | 13 | -------------------------------------------------------------------------------- /.coveragerc: -------------------------------------------------------------------------------- 1 | [run] 2 | source = testipynb 3 | omit = 4 | */python?.?/* 5 | */lib-python/?.?/*.py 6 | */lib_pypy/_*.py 7 | */site-packages/ordereddict.py 8 | */site-packages/nose/* 9 | */unittest2/* 10 | */setup.py 11 | -------------------------------------------------------------------------------- /testipynb/__init__.py: -------------------------------------------------------------------------------- 1 | # pylint: disable=missing-docstring 2 | # Import functions/classes to make the public API 3 | 4 | from .testipynb import TestNotebooks 5 | 6 | __version__ = "0.0.3" 7 | __author__ = "Lindsey Heagy" 8 | __license__ = "MIT" 9 | __copyright__ = "Lindsey Heagy" 10 | -------------------------------------------------------------------------------- /ci/deploy-pypi.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Package and upload to PyPI using twine. The env variables TWINE_USERNAME and 4 | # TWINE_PASSWORD must exist with your pypi.org credentials. 5 | 6 | # To return a failure if any commands inside fail 7 | set -e 8 | 9 | echo "" 10 | echo "Building source package and wheels for ${TRAVIS_TAG}" 11 | echo "" 12 | # Build source distributions and wheels 13 | python setup.py sdist bdist_wheel 14 | 15 | echo "" 16 | echo "Packages built:" 17 | ls dist 18 | 19 | echo "" 20 | echo "Deploy to PyPI using twine." 21 | echo "" 22 | # Upload to PyPI. Credentials are set using the TWINE_PASSWORD and 23 | # TWINE_USERNAME env variables. 24 | twine upload --skip-existing dist/* 25 | 26 | # Workaround for https://github.com/travis-ci/travis-ci/issues/6522 27 | # Turn off exit on failure. 28 | set +e 29 | -------------------------------------------------------------------------------- /tests/notebooks/passing_notebooks/HelloWorld.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 2, 6 | "metadata": {}, 7 | "outputs": [ 8 | { 9 | "name": "stdout", 10 | "output_type": "stream", 11 | "text": [ 12 | "Hello World\n" 13 | ] 14 | } 15 | ], 16 | "source": [ 17 | "print('Hello World')" 18 | ] 19 | } 20 | ], 21 | "metadata": { 22 | "anaconda-cloud": {}, 23 | "kernelspec": { 24 | "display_name": "Python 2", 25 | "language": "python", 26 | "name": "python2" 27 | }, 28 | "language_info": { 29 | "codemirror_mode": { 30 | "name": "ipython", 31 | "version": 2 32 | }, 33 | "file_extension": ".py", 34 | "mimetype": "text/x-python", 35 | "name": "python", 36 | "nbconvert_exporter": "python", 37 | "pygments_lexer": "ipython2", 38 | "version": "2.7.13" 39 | } 40 | }, 41 | "nbformat": 4, 42 | "nbformat_minor": 1 43 | } 44 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: python 2 | python: 3 | - 2.7 4 | - 3.5 5 | - 3.6 6 | - "nightly" 7 | matrix: 8 | allow_failures: 9 | - python: "nightly" 10 | 11 | sudo: false 12 | 13 | env: 14 | global: 15 | - MASTER_BRANCH=master 16 | - PYPI_PY=3.6 # deploy to pypi from python 3.6 17 | - TEST_DIR=tests 18 | 19 | install: 20 | - pip install --upgrade pip 21 | - pip install -r requirements_dev.txt 22 | - pip install -e . 23 | 24 | script: 25 | - cd $TEST_DIR; pytest . --cov=$TRAVIS_HOME --cov-config ../.coveragerc -v -s; cd ../ 26 | - if [ ${TRAVIS_PYTHON_VERSION} >= "3.6" ]; then 27 | pip install black flake8 pylint; 28 | make check; 29 | make lint; 30 | fi 31 | 32 | after_success: 33 | - if [ "$TEST" == "true" ]; then 34 | coverage xml; 35 | echo "Uploading coverage to Codecov"; 36 | codecov -e PYTHON ; 37 | fi 38 | 39 | deploy: 40 | - provider: script 41 | script: ci/deploy-pypi.sh 42 | on: 43 | tags: true 44 | 45 | notifications: 46 | slack: simpeg:1KZq5giMtlJJ58TijIPgqf7n 47 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Lindsey Heagy 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | env/ 12 | build/ 13 | develop-eggs/ 14 | dist/ 15 | downloads/ 16 | eggs/ 17 | .eggs/ 18 | lib/ 19 | lib64/ 20 | parts/ 21 | sdist/ 22 | var/ 23 | *.egg-info/ 24 | .installed.cfg 25 | *.egg 26 | 27 | # PyInstaller 28 | # Usually these files are written by a python script from a template 29 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 30 | *.manifest 31 | *.spec 32 | 33 | # Installer logs 34 | pip-log.txt 35 | pip-delete-this-directory.txt 36 | 37 | # Unit test / coverage reports 38 | htmlcov/ 39 | .tox/ 40 | .coverage 41 | .coverage.* 42 | .cache 43 | nosetests.xml 44 | coverage.xml 45 | *,cover 46 | .hypothesis/ 47 | 48 | # Translations 49 | *.mo 50 | *.pot 51 | 52 | # Django stuff: 53 | *.log 54 | local_settings.py 55 | 56 | # Flask stuff: 57 | instance/ 58 | .webassets-cache 59 | 60 | # Scrapy stuff: 61 | .scrapy 62 | 63 | # Sphinx documentation 64 | docs/_build/ 65 | 66 | # PyBuilder 67 | target/ 68 | 69 | # IPython Notebook 70 | .ipynb_checkpoints 71 | 72 | # pyenv 73 | .python-version 74 | 75 | # celery beat schedule file 76 | celerybeat-schedule 77 | 78 | # dotenv 79 | .env 80 | 81 | # virtualenv 82 | venv/ 83 | ENV/ 84 | 85 | # Spyder project settings 86 | .spyderproject 87 | 88 | # Rope project settings 89 | .ropeproject 90 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | """ 2 | Build and install the project: testipynb 3 | """ 4 | 5 | from setuptools import setup, find_packages 6 | 7 | 8 | CLASSIFIERS = [ 9 | "Development Status :: 4 - Beta", 10 | "Intended Audience :: Education", 11 | "Intended Audience :: Science/Research", 12 | "License :: OSI Approved :: MIT License", 13 | "Programming Language :: Python", 14 | "Topic :: Scientific/Engineering", 15 | "Topic :: Scientific/Engineering :: Mathematics", 16 | "Topic :: Scientific/Engineering :: Physics", 17 | "Operating System :: Microsoft :: Windows", 18 | "Operating System :: POSIX", 19 | "Operating System :: Unix", 20 | "Operating System :: MacOS", 21 | "Natural Language :: English", 22 | ] 23 | 24 | with open("README.rst") as f: 25 | LONG_DESCRIPTION = "".join(f.readlines()) 26 | 27 | setup( 28 | name="testipynb", 29 | version="0.0.3", 30 | packages=find_packages(), 31 | install_requires=[ 32 | "jupyter", 33 | "nbconvert", 34 | "nbformat", 35 | "properties", 36 | ], 37 | author="Lindsey Heagy", 38 | author_email="lindseyheagy@gmail.com", 39 | description="testipynb", 40 | long_description=LONG_DESCRIPTION, 41 | keywords="jupyter, testing", 42 | url="http://github.com/lheagy/testipynb", 43 | download_url="http://github.com/lheagy/testipynb", 44 | classifiers=CLASSIFIERS, 45 | platforms=["Windows", "Linux", "Solaris", "Mac OS-X", "Unix"], 46 | license="MIT License", 47 | use_2to3=False, 48 | ) 49 | -------------------------------------------------------------------------------- /tests/notebooks/failing_notebooks/failing_notebook.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 2, 6 | "metadata": { 7 | "collapsed": true 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "from __future__ import print_function" 12 | ] 13 | }, 14 | { 15 | "cell_type": "code", 16 | "execution_count": 3, 17 | "metadata": {}, 18 | "outputs": [ 19 | { 20 | "ename": "SyntaxError", 21 | "evalue": "invalid syntax (, line 1)", 22 | "output_type": "error", 23 | "traceback": [ 24 | "\u001b[0;36m File \u001b[0;32m\"\"\u001b[0;36m, line \u001b[0;32m1\u001b[0m\n\u001b[0;31m print 'hello world'\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n" 25 | ] 26 | } 27 | ], 28 | "source": [ 29 | "print 'hello world'" 30 | ] 31 | }, 32 | { 33 | "cell_type": "code", 34 | "execution_count": null, 35 | "metadata": { 36 | "collapsed": true 37 | }, 38 | "outputs": [], 39 | "source": [] 40 | } 41 | ], 42 | "metadata": { 43 | "kernelspec": { 44 | "display_name": "Python 2", 45 | "language": "python", 46 | "name": "python2" 47 | }, 48 | "language_info": { 49 | "codemirror_mode": { 50 | "name": "ipython", 51 | "version": 2 52 | }, 53 | "file_extension": ".py", 54 | "mimetype": "text/x-python", 55 | "name": "python", 56 | "nbconvert_exporter": "python", 57 | "pygments_lexer": "ipython2", 58 | "version": "2.7.11" 59 | } 60 | }, 61 | "nbformat": 4, 62 | "nbformat_minor": 2 63 | } 64 | -------------------------------------------------------------------------------- /tests/notebooks/failing_notebooks/failing_notebook2.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": {}, 7 | "outputs": [ 8 | { 9 | "ename": "ImportError", 10 | "evalue": "No module named module_that_doesnt_exist", 11 | "output_type": "error", 12 | "traceback": [ 13 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", 14 | "\u001b[0;31mImportError\u001b[0m Traceback (most recent call last)", 15 | "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0;32mimport\u001b[0m \u001b[0mmodule_that_doesnt_exist\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", 16 | "\u001b[0;31mImportError\u001b[0m: No module named module_that_doesnt_exist" 17 | ] 18 | } 19 | ], 20 | "source": [ 21 | "import module_that_doesnt_exist" 22 | ] 23 | }, 24 | { 25 | "cell_type": "code", 26 | "execution_count": null, 27 | "metadata": { 28 | "collapsed": true 29 | }, 30 | "outputs": [], 31 | "source": [] 32 | } 33 | ], 34 | "metadata": { 35 | "kernelspec": { 36 | "display_name": "Python 2", 37 | "language": "python", 38 | "name": "python2" 39 | }, 40 | "language_info": { 41 | "codemirror_mode": { 42 | "name": "ipython", 43 | "version": 2 44 | }, 45 | "file_extension": ".py", 46 | "mimetype": "text/x-python", 47 | "name": "python", 48 | "nbconvert_exporter": "python", 49 | "pygments_lexer": "ipython2", 50 | "version": "2.7.11" 51 | } 52 | }, 53 | "nbformat": 4, 54 | "nbformat_minor": 2 55 | } 56 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # Build, package, test, and clean 2 | PROJECT=testipynb 3 | TESTDIR=tmp-test-dir 4 | PYTEST_ARGS=../tests --cov-config=../.coveragerc --cov-report=term-missing --cov=$(PROJECT) -v 5 | LINT_FILES=setup.py $(PROJECT) 6 | BLACK_FILES=setup.py $(PROJECT) 7 | FLAKE8_FILES=setup.py $(PROJECT) 8 | 9 | help: 10 | @echo "Commands:" 11 | @echo "" 12 | @echo " install install in editable mode" 13 | @echo " test run the test suite (including doctests) and report coverage" 14 | @echo " format run black to automatically format the code" 15 | @echo " check run code style and quality checks (black and flake8)" 16 | @echo " lint run pylint for a deeper (and slower) quality check" 17 | @echo " clean clean up build and generated files" 18 | @echo " docs build the docs" 19 | @echo " deploy deploy to pypi" 20 | @echo "" 21 | 22 | install: 23 | pip install --no-deps -e . 24 | 25 | test: 26 | # Run a tmp folder to make sure the tests are run on the installed version 27 | mkdir -p $(TESTDIR) 28 | cd $(TESTDIR); MPLBACKEND='agg' pytest $(PYTEST_ARGS) 29 | cp $(TESTDIR)/.coverage* . 30 | rm -rvf $(TESTDIR) 31 | cd .. 32 | 33 | format: 34 | black $(BLACK_FILES) 35 | 36 | check: 37 | black --check $(BLACK_FILES) 38 | flake8 $(FLAKE8_FILES) 39 | 40 | lint: 41 | pylint --jobs=0 $(LINT_FILES) 42 | 43 | 44 | graphs: 45 | pyreverse -my -A -o pdf -p testipynb testipynb/**.py testipynb/**/**.py 46 | 47 | docs: 48 | cd docs 49 | make html 50 | cd .. 51 | 52 | deploy: 53 | python setup.py sdist bdist_wheel upload 54 | 55 | clean: 56 | find . -name "*.pyc" -exec rm -v {} \; 57 | find . -name ".coverage.*" -exec rm -v {} \; 58 | rm -rvf build dist *.egg-info __pycache__ .coverage .cache .pytest_cache 59 | -------------------------------------------------------------------------------- /tests/notebooks/passing_notebooks/notebook_that_loads_things.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": { 7 | "collapsed": true 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "import numpy as np" 12 | ] 13 | }, 14 | { 15 | "cell_type": "code", 16 | "execution_count": 2, 17 | "metadata": { 18 | "collapsed": true 19 | }, 20 | "outputs": [], 21 | "source": [ 22 | "x = 2*np.pi*np.arange(1, 200)/200.\n", 23 | "y = np.sin(x)" 24 | ] 25 | }, 26 | { 27 | "cell_type": "code", 28 | "execution_count": 3, 29 | "metadata": { 30 | "collapsed": true 31 | }, 32 | "outputs": [], 33 | "source": [ 34 | "# np.save('x', x)\n", 35 | "# np.save('y', y)" 36 | ] 37 | }, 38 | { 39 | "cell_type": "code", 40 | "execution_count": 4, 41 | "metadata": { 42 | "collapsed": true 43 | }, 44 | "outputs": [], 45 | "source": [ 46 | "x1 = np.load('x.npy')\n", 47 | "y1 = np.load('y.npy')" 48 | ] 49 | }, 50 | { 51 | "cell_type": "code", 52 | "execution_count": 6, 53 | "metadata": { 54 | "collapsed": true 55 | }, 56 | "outputs": [], 57 | "source": [ 58 | "assert(np.allclose(x, x1))\n", 59 | "assert(np.allclose(y, y1))" 60 | ] 61 | }, 62 | { 63 | "cell_type": "code", 64 | "execution_count": null, 65 | "metadata": { 66 | "collapsed": true 67 | }, 68 | "outputs": [], 69 | "source": [] 70 | } 71 | ], 72 | "metadata": { 73 | "kernelspec": { 74 | "display_name": "Python 2", 75 | "language": "python", 76 | "name": "python2" 77 | }, 78 | "language_info": { 79 | "codemirror_mode": { 80 | "name": "ipython", 81 | "version": 2 82 | }, 83 | "file_extension": ".py", 84 | "mimetype": "text/x-python", 85 | "name": "python", 86 | "nbconvert_exporter": "python", 87 | "pygments_lexer": "ipython2", 88 | "version": "2.7.11" 89 | } 90 | }, 91 | "nbformat": 4, 92 | "nbformat_minor": 2 93 | } 94 | -------------------------------------------------------------------------------- /tests/test_nbtest.py: -------------------------------------------------------------------------------- 1 | import testipynb 2 | import os 3 | import unittest 4 | 5 | class TestClassAttributes(unittest.TestCase): 6 | 7 | def test_class_attributes(self): 8 | directory = os.path.sep.join( 9 | os.path.abspath(__file__).split(os.path.sep)[:-1] + 10 | ['notebooks', 'passing_notebooks'] 11 | ) 12 | Test = testipynb.TestNotebooks(directory=directory) 13 | 14 | nbnames = ['HelloWorld', 'notebook_that_loads_things'] 15 | self.assertTrue( 16 | sorted(Test._nbnames) == 17 | sorted(nbnames) 18 | ) 19 | 20 | self.assertTrue( 21 | sorted(Test._nbpaths) == 22 | sorted([ 23 | directory + os.path.sep + "{}.ipynb".format(nb) 24 | for nb in nbnames 25 | ]) 26 | ) 27 | 28 | class TestMyNotebooks(unittest.TestCase): 29 | 30 | def test_passing_notebooks(self): 31 | directory = os.path.sep.join( 32 | os.path.abspath(__file__).split(os.path.sep)[:-1] + 33 | ['notebooks', 'passing_notebooks'] 34 | ) 35 | Test = testipynb.TestNotebooks(directory=directory) 36 | self.assertTrue(Test.run_tests()) 37 | 38 | def test_skipping_notebooks(self): 39 | directory = os.path.sep.join( 40 | os.path.abspath(__file__).split(os.path.sep)[:-1] + 41 | ['notebooks'] 42 | ) 43 | Test = testipynb.TestNotebooks( 44 | directory=directory, 45 | ignore=["failing_notebook", "failing_notebook2"] 46 | ) 47 | self.assertTrue(Test.run_tests()) 48 | 49 | @unittest.expectedFailure 50 | def test_simple_fail(self): 51 | directory = os.path.sep.join( 52 | os.path.abspath(__file__).split(os.path.sep)[:-1] + 53 | ['notebooks', 'failing_notebooks'] 54 | ) 55 | 56 | Test = testipynb.TestNotebooks(directory=directory) 57 | self.assertTrue(Test.run_tests()) 58 | 59 | 60 | if __name__ == "__main__": 61 | unittest.main() 62 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | 2 | testipynb 3 | ========= 4 | 5 | .. image:: https://img.shields.io/pypi/v/testipynb.svg 6 | :target: https://pypi.python.org/pypi/testipynb 7 | :alt: Latest PyPI version 8 | 9 | .. image:: https://readthedocs.org/projects/nbtest/badge/?version=latest 10 | :target: http://nbtest.readthedocs.io/en/latest/?badge=latest 11 | :alt: Documentation Status 12 | 13 | .. image:: https://travis-ci.org/opengeophysics/testipynb.svg?branch=master 14 | :target: https://travis-ci.org/opengeophysics/testipynb 15 | :alt: Travis CI build status 16 | 17 | .. image:: https://codecov.io/gh/opengeophysics/testipynb/branch/master/graph/badge.svg 18 | :target: https://codecov.io/gh/opengeophysics/testipynb 19 | :alt: coverage 20 | 21 | .. image:: https://img.shields.io/github/license/opengeophysics/testipynb.svg 22 | :target: https://github.com/opengeophysics/testipynb/blob/master/LICENSE 23 | :alt: MIT license 24 | 25 | Unit-testing for a collection of jupyter notebooks. :code:`testipynb` relies on `nbconvert `_ to run the notebooks and catches errors so that they are output (with syntax highlighting!) when unit-tests are run. 26 | 27 | why? 28 | ---- 29 | 30 | - If you want to share your notebooks and be confident that they _should_ work on someone else's machine 31 | - If you are using notebooks to generate figures in a publication and want to ensure they are reproducible (powerful when connected with `cron jobs on travis-ci `_) 32 | 33 | .. image:: https://raw.githubusercontent.com/opengeophysics/testipynb/master/docs/images/testing_syntax_highlighting.png 34 | :width: 80% 35 | :align: center 36 | 37 | installation 38 | ------------ 39 | 40 | .. code:: 41 | 42 | pip install testipynb 43 | 44 | usage 45 | ----- 46 | 47 | .. code:: python 48 | 49 | import testipynb 50 | 51 | NBDIR = '../notebooks' 52 | 53 | Test = testipynb.TestNotebooks(directory=NBDIR) 54 | Test.assertTrue(Test.run_tests()) 55 | 56 | or in a unit-test file: 57 | 58 | 59 | .. code:: python 60 | 61 | import testipynb 62 | import unittest 63 | 64 | NBDIR = '../notebooks' 65 | 66 | Test = testipynb.TestNotebooks(directory=NBDIR, timeout=2100) 67 | TestNotebooks = Test.get_tests() 68 | 69 | if __name__ == "__main__": 70 | unittest.main() 71 | 72 | 73 | connections 74 | ----------- 75 | 76 | :code:`testipynb` is used in: 77 | 78 | - https://github.com/simpeg-research/heagy_2018_AEM 79 | 80 | If you use :code:`testipynb` in one of your repositories and would like it listed, please `edit this file `_ 81 | -------------------------------------------------------------------------------- /testipynb/testipynb.py: -------------------------------------------------------------------------------- 1 | """Module for testing a repository of Jupyter Notebooks""" 2 | 3 | import unittest 4 | import sys 5 | import os 6 | import nbformat 7 | from nbconvert.preprocessors import ClearOutputPreprocessor, ExecutePreprocessor 8 | import properties 9 | 10 | 11 | __all__ = ["TestNotebooks"] 12 | 13 | 14 | def get_test(nbname, nbpath, timeout=600): 15 | """ 16 | construct a test method based on on the notebook name, path, and 17 | nbconvert Preprocessor options 18 | 19 | ** Required Inputs ** 20 | :param str nbname: name of the notebook (without the file extension) 21 | :param str nbpath: full filepath to the notebook including the '.ipynb' 22 | file extension 23 | 24 | ** Optional Inputs ** 25 | :param int timeout: preprocessor timeout 26 | 27 | ** Returns ** 28 | :returns: test_func a function for testing the notebook using nbconvert 29 | """ 30 | 31 | # use nbconvert to execute the notebook 32 | def test_func(self): 33 | cwd = os.getcwd() 34 | passing = True 35 | print( 36 | "\n---------------------" 37 | " Testing {0}.ipynb " 38 | "---------------------".format(nbname) 39 | ) 40 | 41 | if (nbname in self.ignore) or ( 42 | nbname in self.py2_ignore and sys.version_info[0] == 2 43 | ): 44 | print(" Skipping {}".format(nbname)) 45 | return 46 | 47 | run_path = os.path.sep.join(nbpath.split(os.path.sep)[:-1]) 48 | os.chdir(run_path) 49 | clear_output = ClearOutputPreprocessor() 50 | 51 | with open(nbpath) as nbfile: 52 | notebook = nbformat.read(nbfile, as_version=4) 53 | 54 | clear_output.preprocess(notebook, {}) 55 | 56 | execute = ExecutePreprocessor( 57 | timeout=timeout, 58 | kernel_name="python{}".format(sys.version_info[0]), 59 | allow_errors=True, 60 | ) 61 | 62 | out = execute.preprocess(notebook, {}) 63 | os.chdir(cwd) 64 | 65 | for cell in out[0]["cells"]: 66 | if "outputs" in cell.keys(): 67 | for output in cell["outputs"]: 68 | if output["output_type"] == "error": 69 | passing = False 70 | 71 | err_msg = [] 72 | for traceback in output["traceback"]: 73 | err_msg += ["{}".format(traceback)] 74 | err_msg = "\n".join(err_msg) 75 | 76 | msg = """ 77 | \n ... {} FAILED \n 78 | {} in cell [{}] \n-----------\n{}\n-----------\n 79 | """.format( 80 | nbname, 81 | output["ename"], 82 | cell["execution_count"], 83 | cell["source"], 84 | ) 85 | 86 | traceback = """ 87 | ----------------- >> begin Traceback << ----------------- \n 88 | {}\n 89 | \n----------------- >> end Traceback << -----------------\n 90 | """.format( 91 | err_msg 92 | ) 93 | 94 | print(u"{}".format(msg + traceback)) 95 | 96 | assert passing, msg 97 | 98 | print(" ... {0} Passed \n".format(nbname)) 99 | 100 | return test_func 101 | 102 | 103 | class TestNotebooks(properties.HasProperties): 104 | """ 105 | Class that generates a suite of tests for a directory of notebooks. 106 | 107 | .. code:: python 108 | 109 | import testipynb 110 | Test = TestNotebooks(directory="notebooks") 111 | assertTrue(Test.run_tests()) 112 | 113 | or if you are using pytest, you can create a file called 114 | `test_notebooks.py` 115 | 116 | .. code:: python 117 | 118 | import testipynb 119 | Test = testipynb.TestNotebooks(directory="notebooks") 120 | TestNotebooks = Test.get_tests() 121 | 122 | and from a command line, run 123 | 124 | .. code:: shell 125 | 126 | pytest test_notebooks.py 127 | 128 | """ 129 | 130 | _name = properties.String("test name", default="NbTestCase") 131 | 132 | directory = properties.String( 133 | "directory where the notebooks are stored", required=True, default="." 134 | ) 135 | 136 | ignore = properties.List( 137 | "list of notebooks to ignore when testing", 138 | properties.String("file to ignore when testing"), 139 | default=[], 140 | ) 141 | 142 | py2_ignore = properties.List( 143 | "list of notebook names to ignore if testing on python 2", 144 | properties.String("file to ignore in python 2"), 145 | default=[], 146 | ) 147 | 148 | timeout = properties.Integer( 149 | "timeout length for the execution of the notebook", default=600, min=0 150 | ) 151 | 152 | _nbpaths = properties.List( 153 | "paths to all of the notebooks", properties.String("path to notebook") 154 | ) 155 | 156 | _nbnames = properties.List( 157 | "names of all of the notebooks without the '.ipynb' file extension", 158 | properties.String("name of notebook"), 159 | ) 160 | 161 | @properties.validator("directory") 162 | def _use_abspath(self, change): # pylint: disable=no-self-use 163 | change["value"] = os.path.abspath(change["value"]) 164 | 165 | def __init__(self, **kwargs): 166 | super(TestNotebooks, self).__init__(**kwargs) 167 | nbpaths = [] # list of notebooks, with file paths 168 | nbnames = [] # list of notebook names (for making the tests) 169 | 170 | # walk the test directory and find all notebooks 171 | for dirname, _, filenames in os.walk(self.directory): 172 | for filename in filenames: 173 | if filename.endswith(".ipynb") and not filename.endswith( 174 | "-checkpoint.ipynb" 175 | ): 176 | # get abspath of notebook 177 | nbpaths.append(dirname + os.path.sep + filename) 178 | # strip off the file extension 179 | nbnames.append("".join(filename[:-6])) 180 | self._nbpaths = nbpaths 181 | self._nbnames = nbnames 182 | 183 | @property 184 | def test_dict(self): 185 | """ 186 | dictionary of the name of the test (keys) and test functions (values) 187 | built based upon the directory provided 188 | """ 189 | if getattr(self, "_test_dict", None) is None: 190 | tests = dict() 191 | 192 | # build test for each notebook 193 | for notebook, nbpath in zip(self._nbnames, self._nbpaths): 194 | tests["test_" + notebook] = get_test( 195 | notebook, nbpath, timeout=self.timeout 196 | ) 197 | self._test_dict = tests 198 | return self._test_dict 199 | 200 | def get_tests(self, obj=None): 201 | """ 202 | Create a unittest.TestCase object to attach the unit tests to. 203 | """ 204 | # create class to unit test notebooks 205 | if obj is None: 206 | obj = "{}".format(self._name) 207 | obj = type(obj, (unittest.TestCase,), self.test_dict) 208 | else: 209 | for key, val in self.test_dict: 210 | setattr(obj, key, val) 211 | obj.ignore = self.ignore 212 | obj.py2_ignore = self.py2_ignore 213 | return obj 214 | 215 | def run_tests(self): 216 | """ 217 | Run the unit-tests. Returns :code:`True` if all tests were successful 218 | and code`False` if there was a failure. 219 | 220 | .. code:: python 221 | 222 | import nbtest 223 | test = nbtest.TestNotebooks(directory='./notebooks') 224 | passed = test.run_tests() 225 | assert(passed) 226 | 227 | """ 228 | nb_test_case = self.get_tests() 229 | tests = unittest.TestSuite(map(nb_test_case, self.test_dict.keys())) 230 | result = unittest.TestResult() 231 | test_runner = unittest.TextTestRunner(verbosity=0) 232 | result = test_runner.run(tests) 233 | return result.wasSuccessful() 234 | -------------------------------------------------------------------------------- /docs/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line. 5 | SPHINXOPTS = 6 | SPHINXBUILD = sphinx-build 7 | PAPER = 8 | BUILDDIR = _build 9 | 10 | # Internal variables. 11 | PAPEROPT_a4 = -D latex_paper_size=a4 12 | PAPEROPT_letter = -D latex_paper_size=letter 13 | ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . 14 | # the i18n builder cannot share the environment and doctrees with the others 15 | I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . 16 | 17 | .PHONY: help 18 | help: 19 | @echo "Please use \`make ' where is one of" 20 | @echo " html to make standalone HTML files" 21 | @echo " dirhtml to make HTML files named index.html in directories" 22 | @echo " singlehtml to make a single large HTML file" 23 | @echo " pickle to make pickle files" 24 | @echo " json to make JSON files" 25 | @echo " htmlhelp to make HTML files and a HTML help project" 26 | @echo " qthelp to make HTML files and a qthelp project" 27 | @echo " applehelp to make an Apple Help Book" 28 | @echo " devhelp to make HTML files and a Devhelp project" 29 | @echo " epub to make an epub" 30 | @echo " epub3 to make an epub3" 31 | @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" 32 | @echo " latexpdf to make LaTeX files and run them through pdflatex" 33 | @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" 34 | @echo " text to make text files" 35 | @echo " man to make manual pages" 36 | @echo " texinfo to make Texinfo files" 37 | @echo " info to make Texinfo files and run them through makeinfo" 38 | @echo " gettext to make PO message catalogs" 39 | @echo " changes to make an overview of all changed/added/deprecated items" 40 | @echo " xml to make Docutils-native XML files" 41 | @echo " pseudoxml to make pseudoxml-XML files for display purposes" 42 | @echo " linkcheck to check all external links for integrity" 43 | @echo " doctest to run all doctests embedded in the documentation (if enabled)" 44 | @echo " coverage to run coverage check of the documentation (if enabled)" 45 | @echo " dummy to check syntax errors of document sources" 46 | 47 | .PHONY: clean 48 | clean: 49 | rm -rf $(BUILDDIR)/* 50 | 51 | .PHONY: html 52 | html: 53 | $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html 54 | @echo 55 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." 56 | 57 | .PHONY: dirhtml 58 | dirhtml: 59 | $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml 60 | @echo 61 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." 62 | 63 | .PHONY: singlehtml 64 | singlehtml: 65 | $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml 66 | @echo 67 | @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." 68 | 69 | .PHONY: pickle 70 | pickle: 71 | $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle 72 | @echo 73 | @echo "Build finished; now you can process the pickle files." 74 | 75 | .PHONY: json 76 | json: 77 | $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json 78 | @echo 79 | @echo "Build finished; now you can process the JSON files." 80 | 81 | .PHONY: htmlhelp 82 | htmlhelp: 83 | $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp 84 | @echo 85 | @echo "Build finished; now you can run HTML Help Workshop with the" \ 86 | ".hhp project file in $(BUILDDIR)/htmlhelp." 87 | 88 | .PHONY: qthelp 89 | qthelp: 90 | $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp 91 | @echo 92 | @echo "Build finished; now you can run "qcollectiongenerator" with the" \ 93 | ".qhcp project file in $(BUILDDIR)/qthelp, like this:" 94 | @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/nbtest.qhcp" 95 | @echo "To view the help file:" 96 | @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/nbtest.qhc" 97 | 98 | .PHONY: applehelp 99 | applehelp: 100 | $(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp 101 | @echo 102 | @echo "Build finished. The help book is in $(BUILDDIR)/applehelp." 103 | @echo "N.B. You won't be able to view it unless you put it in" \ 104 | "~/Library/Documentation/Help or install it in your application" \ 105 | "bundle." 106 | 107 | .PHONY: devhelp 108 | devhelp: 109 | $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp 110 | @echo 111 | @echo "Build finished." 112 | @echo "To view the help file:" 113 | @echo "# mkdir -p $$HOME/.local/share/devhelp/nbtest" 114 | @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/nbtest" 115 | @echo "# devhelp" 116 | 117 | .PHONY: epub 118 | epub: 119 | $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub 120 | @echo 121 | @echo "Build finished. The epub file is in $(BUILDDIR)/epub." 122 | 123 | .PHONY: epub3 124 | epub3: 125 | $(SPHINXBUILD) -b epub3 $(ALLSPHINXOPTS) $(BUILDDIR)/epub3 126 | @echo 127 | @echo "Build finished. The epub3 file is in $(BUILDDIR)/epub3." 128 | 129 | .PHONY: latex 130 | latex: 131 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 132 | @echo 133 | @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." 134 | @echo "Run \`make' in that directory to run these through (pdf)latex" \ 135 | "(use \`make latexpdf' here to do that automatically)." 136 | 137 | .PHONY: latexpdf 138 | latexpdf: 139 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 140 | @echo "Running LaTeX files through pdflatex..." 141 | $(MAKE) -C $(BUILDDIR)/latex all-pdf 142 | @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." 143 | 144 | .PHONY: latexpdfja 145 | latexpdfja: 146 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 147 | @echo "Running LaTeX files through platex and dvipdfmx..." 148 | $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja 149 | @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." 150 | 151 | .PHONY: text 152 | text: 153 | $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text 154 | @echo 155 | @echo "Build finished. The text files are in $(BUILDDIR)/text." 156 | 157 | .PHONY: man 158 | man: 159 | $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man 160 | @echo 161 | @echo "Build finished. The manual pages are in $(BUILDDIR)/man." 162 | 163 | .PHONY: texinfo 164 | texinfo: 165 | $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo 166 | @echo 167 | @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." 168 | @echo "Run \`make' in that directory to run these through makeinfo" \ 169 | "(use \`make info' here to do that automatically)." 170 | 171 | .PHONY: info 172 | info: 173 | $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo 174 | @echo "Running Texinfo files through makeinfo..." 175 | make -C $(BUILDDIR)/texinfo info 176 | @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." 177 | 178 | .PHONY: gettext 179 | gettext: 180 | $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale 181 | @echo 182 | @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." 183 | 184 | .PHONY: changes 185 | changes: 186 | $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes 187 | @echo 188 | @echo "The overview file is in $(BUILDDIR)/changes." 189 | 190 | .PHONY: linkcheck 191 | linkcheck: 192 | $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck 193 | @echo 194 | @echo "Link check complete; look for any errors in the above output " \ 195 | "or in $(BUILDDIR)/linkcheck/output.txt." 196 | 197 | .PHONY: doctest 198 | doctest: 199 | $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest 200 | @echo "Testing of doctests in the sources finished, look at the " \ 201 | "results in $(BUILDDIR)/doctest/output.txt." 202 | 203 | .PHONY: coverage 204 | coverage: 205 | $(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage 206 | @echo "Testing of coverage in the sources finished, look at the " \ 207 | "results in $(BUILDDIR)/coverage/python.txt." 208 | 209 | .PHONY: xml 210 | xml: 211 | $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml 212 | @echo 213 | @echo "Build finished. The XML files are in $(BUILDDIR)/xml." 214 | 215 | .PHONY: pseudoxml 216 | pseudoxml: 217 | $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml 218 | @echo 219 | @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." 220 | 221 | .PHONY: dummy 222 | dummy: 223 | $(SPHINXBUILD) -b dummy $(ALLSPHINXOPTS) $(BUILDDIR)/dummy 224 | @echo 225 | @echo "Build finished. Dummy builder generates no files." 226 | -------------------------------------------------------------------------------- /docs/make.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | REM Command file for Sphinx documentation 4 | 5 | if "%SPHINXBUILD%" == "" ( 6 | set SPHINXBUILD=sphinx-build 7 | ) 8 | set BUILDDIR=_build 9 | set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% . 10 | set I18NSPHINXOPTS=%SPHINXOPTS% . 11 | if NOT "%PAPER%" == "" ( 12 | set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% 13 | set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS% 14 | ) 15 | 16 | if "%1" == "" goto help 17 | 18 | if "%1" == "help" ( 19 | :help 20 | echo.Please use `make ^` where ^ is one of 21 | echo. html to make standalone HTML files 22 | echo. dirhtml to make HTML files named index.html in directories 23 | echo. singlehtml to make a single large HTML file 24 | echo. pickle to make pickle files 25 | echo. json to make JSON files 26 | echo. htmlhelp to make HTML files and a HTML help project 27 | echo. qthelp to make HTML files and a qthelp project 28 | echo. devhelp to make HTML files and a Devhelp project 29 | echo. epub to make an epub 30 | echo. epub3 to make an epub3 31 | echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter 32 | echo. text to make text files 33 | echo. man to make manual pages 34 | echo. texinfo to make Texinfo files 35 | echo. gettext to make PO message catalogs 36 | echo. changes to make an overview over all changed/added/deprecated items 37 | echo. xml to make Docutils-native XML files 38 | echo. pseudoxml to make pseudoxml-XML files for display purposes 39 | echo. linkcheck to check all external links for integrity 40 | echo. doctest to run all doctests embedded in the documentation if enabled 41 | echo. coverage to run coverage check of the documentation if enabled 42 | echo. dummy to check syntax errors of document sources 43 | goto end 44 | ) 45 | 46 | if "%1" == "clean" ( 47 | for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i 48 | del /q /s %BUILDDIR%\* 49 | goto end 50 | ) 51 | 52 | 53 | REM Check if sphinx-build is available and fallback to Python version if any 54 | %SPHINXBUILD% 1>NUL 2>NUL 55 | if errorlevel 9009 goto sphinx_python 56 | goto sphinx_ok 57 | 58 | :sphinx_python 59 | 60 | set SPHINXBUILD=python -m sphinx.__init__ 61 | %SPHINXBUILD% 2> nul 62 | if errorlevel 9009 ( 63 | echo. 64 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx 65 | echo.installed, then set the SPHINXBUILD environment variable to point 66 | echo.to the full path of the 'sphinx-build' executable. Alternatively you 67 | echo.may add the Sphinx directory to PATH. 68 | echo. 69 | echo.If you don't have Sphinx installed, grab it from 70 | echo.http://sphinx-doc.org/ 71 | exit /b 1 72 | ) 73 | 74 | :sphinx_ok 75 | 76 | 77 | if "%1" == "html" ( 78 | %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html 79 | if errorlevel 1 exit /b 1 80 | echo. 81 | echo.Build finished. The HTML pages are in %BUILDDIR%/html. 82 | goto end 83 | ) 84 | 85 | if "%1" == "dirhtml" ( 86 | %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml 87 | if errorlevel 1 exit /b 1 88 | echo. 89 | echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. 90 | goto end 91 | ) 92 | 93 | if "%1" == "singlehtml" ( 94 | %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml 95 | if errorlevel 1 exit /b 1 96 | echo. 97 | echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. 98 | goto end 99 | ) 100 | 101 | if "%1" == "pickle" ( 102 | %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle 103 | if errorlevel 1 exit /b 1 104 | echo. 105 | echo.Build finished; now you can process the pickle files. 106 | goto end 107 | ) 108 | 109 | if "%1" == "json" ( 110 | %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json 111 | if errorlevel 1 exit /b 1 112 | echo. 113 | echo.Build finished; now you can process the JSON files. 114 | goto end 115 | ) 116 | 117 | if "%1" == "htmlhelp" ( 118 | %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp 119 | if errorlevel 1 exit /b 1 120 | echo. 121 | echo.Build finished; now you can run HTML Help Workshop with the ^ 122 | .hhp project file in %BUILDDIR%/htmlhelp. 123 | goto end 124 | ) 125 | 126 | if "%1" == "qthelp" ( 127 | %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp 128 | if errorlevel 1 exit /b 1 129 | echo. 130 | echo.Build finished; now you can run "qcollectiongenerator" with the ^ 131 | .qhcp project file in %BUILDDIR%/qthelp, like this: 132 | echo.^> qcollectiongenerator %BUILDDIR%\qthelp\nbtest.qhcp 133 | echo.To view the help file: 134 | echo.^> assistant -collectionFile %BUILDDIR%\qthelp\nbtest.ghc 135 | goto end 136 | ) 137 | 138 | if "%1" == "devhelp" ( 139 | %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp 140 | if errorlevel 1 exit /b 1 141 | echo. 142 | echo.Build finished. 143 | goto end 144 | ) 145 | 146 | if "%1" == "epub" ( 147 | %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub 148 | if errorlevel 1 exit /b 1 149 | echo. 150 | echo.Build finished. The epub file is in %BUILDDIR%/epub. 151 | goto end 152 | ) 153 | 154 | if "%1" == "epub3" ( 155 | %SPHINXBUILD% -b epub3 %ALLSPHINXOPTS% %BUILDDIR%/epub3 156 | if errorlevel 1 exit /b 1 157 | echo. 158 | echo.Build finished. The epub3 file is in %BUILDDIR%/epub3. 159 | goto end 160 | ) 161 | 162 | if "%1" == "latex" ( 163 | %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex 164 | if errorlevel 1 exit /b 1 165 | echo. 166 | echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. 167 | goto end 168 | ) 169 | 170 | if "%1" == "latexpdf" ( 171 | %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex 172 | cd %BUILDDIR%/latex 173 | make all-pdf 174 | cd %~dp0 175 | echo. 176 | echo.Build finished; the PDF files are in %BUILDDIR%/latex. 177 | goto end 178 | ) 179 | 180 | if "%1" == "latexpdfja" ( 181 | %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex 182 | cd %BUILDDIR%/latex 183 | make all-pdf-ja 184 | cd %~dp0 185 | echo. 186 | echo.Build finished; the PDF files are in %BUILDDIR%/latex. 187 | goto end 188 | ) 189 | 190 | if "%1" == "text" ( 191 | %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text 192 | if errorlevel 1 exit /b 1 193 | echo. 194 | echo.Build finished. The text files are in %BUILDDIR%/text. 195 | goto end 196 | ) 197 | 198 | if "%1" == "man" ( 199 | %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man 200 | if errorlevel 1 exit /b 1 201 | echo. 202 | echo.Build finished. The manual pages are in %BUILDDIR%/man. 203 | goto end 204 | ) 205 | 206 | if "%1" == "texinfo" ( 207 | %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo 208 | if errorlevel 1 exit /b 1 209 | echo. 210 | echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo. 211 | goto end 212 | ) 213 | 214 | if "%1" == "gettext" ( 215 | %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale 216 | if errorlevel 1 exit /b 1 217 | echo. 218 | echo.Build finished. The message catalogs are in %BUILDDIR%/locale. 219 | goto end 220 | ) 221 | 222 | if "%1" == "changes" ( 223 | %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes 224 | if errorlevel 1 exit /b 1 225 | echo. 226 | echo.The overview file is in %BUILDDIR%/changes. 227 | goto end 228 | ) 229 | 230 | if "%1" == "linkcheck" ( 231 | %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck 232 | if errorlevel 1 exit /b 1 233 | echo. 234 | echo.Link check complete; look for any errors in the above output ^ 235 | or in %BUILDDIR%/linkcheck/output.txt. 236 | goto end 237 | ) 238 | 239 | if "%1" == "doctest" ( 240 | %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest 241 | if errorlevel 1 exit /b 1 242 | echo. 243 | echo.Testing of doctests in the sources finished, look at the ^ 244 | results in %BUILDDIR%/doctest/output.txt. 245 | goto end 246 | ) 247 | 248 | if "%1" == "coverage" ( 249 | %SPHINXBUILD% -b coverage %ALLSPHINXOPTS% %BUILDDIR%/coverage 250 | if errorlevel 1 exit /b 1 251 | echo. 252 | echo.Testing of coverage in the sources finished, look at the ^ 253 | results in %BUILDDIR%/coverage/python.txt. 254 | goto end 255 | ) 256 | 257 | if "%1" == "xml" ( 258 | %SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml 259 | if errorlevel 1 exit /b 1 260 | echo. 261 | echo.Build finished. The XML files are in %BUILDDIR%/xml. 262 | goto end 263 | ) 264 | 265 | if "%1" == "pseudoxml" ( 266 | %SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml 267 | if errorlevel 1 exit /b 1 268 | echo. 269 | echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml. 270 | goto end 271 | ) 272 | 273 | if "%1" == "dummy" ( 274 | %SPHINXBUILD% -b dummy %ALLSPHINXOPTS% %BUILDDIR%/dummy 275 | if errorlevel 1 exit /b 1 276 | echo. 277 | echo.Build finished. Dummy builder generates no files. 278 | goto end 279 | ) 280 | 281 | :end 282 | -------------------------------------------------------------------------------- /docs/conf.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # testipynb documentation build configuration file, created by 4 | # sphinx-quickstart on Sat Jan 7 13:44:51 2017. 5 | # 6 | # This file is execfile()d with the current directory set to its 7 | # containing dir. 8 | # 9 | # Note that not all possible configuration values are present in this 10 | # autogenerated file. 11 | # 12 | # All configuration values have a default; values that are commented out 13 | # serve to show the default. 14 | 15 | # If extensions (or modules to document with autodoc) are in another directory, 16 | # add these directories to sys.path here. If the directory is relative to the 17 | # documentation root, use os.path.abspath to make it absolute, like shown here. 18 | # 19 | # import os 20 | # import sys 21 | # sys.path.insert(0, os.path.abspath('.')) 22 | 23 | # -- General configuration ------------------------------------------------ 24 | 25 | # If your documentation needs a minimal Sphinx version, state it here. 26 | # 27 | # needs_sphinx = '1.0' 28 | 29 | # Add any Sphinx extension module names here, as strings. They can be 30 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom 31 | # ones. 32 | extensions = [ 33 | 'sphinx.ext.autodoc', 34 | 'sphinx.ext.doctest', 35 | 'sphinx.ext.intersphinx', 36 | 'sphinx.ext.todo', 37 | 'sphinx.ext.coverage', 38 | 'sphinx.ext.mathjax', 39 | 'sphinx.ext.viewcode', 40 | ] 41 | 42 | # Add any paths that contain templates here, relative to this directory. 43 | templates_path = ['_templates'] 44 | 45 | # The suffix(es) of source filenames. 46 | # You can specify multiple suffix as a list of string: 47 | # 48 | # source_suffix = ['.rst', '.md'] 49 | source_suffix = '.rst' 50 | 51 | # The encoding of source files. 52 | # 53 | # source_encoding = 'utf-8-sig' 54 | 55 | # The master toctree document. 56 | master_doc = 'index' 57 | 58 | # General information about the project. 59 | project = u'testipynb' 60 | copyright = u'2019, Lindsey Heagy' 61 | author = u'Lindsey Heagy' 62 | 63 | # The version info for the project you're documenting, acts as replacement for 64 | # |version| and |release|, also used in various other places throughout the 65 | # built documents. 66 | # 67 | # The short X.Y version. 68 | version = u'0.0.3' 69 | # The full version, including alpha/beta/rc tags. 70 | release = u'0.0.3' 71 | 72 | # The language for content autogenerated by Sphinx. Refer to documentation 73 | # for a list of supported languages. 74 | # 75 | # This is also used if you do content translation via gettext catalogs. 76 | # Usually you set "language" from the command line for these cases. 77 | language = None 78 | 79 | # There are two options for replacing |today|: either, you set today to some 80 | # non-false value, then it is used: 81 | # 82 | # today = '' 83 | # 84 | # Else, today_fmt is used as the format for a strftime call. 85 | # 86 | # today_fmt = '%B %d, %Y' 87 | 88 | # List of patterns, relative to source directory, that match files and 89 | # directories to ignore when looking for source files. 90 | # This patterns also effect to html_static_path and html_extra_path 91 | exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] 92 | 93 | # The reST default role (used for this markup: `text`) to use for all 94 | # documents. 95 | # 96 | # default_role = None 97 | 98 | # If true, '()' will be appended to :func: etc. cross-reference text. 99 | # 100 | # add_function_parentheses = True 101 | 102 | # If true, the current module name will be prepended to all description 103 | # unit titles (such as .. function::). 104 | # 105 | # add_module_names = True 106 | 107 | # If true, sectionauthor and moduleauthor directives will be shown in the 108 | # output. They are ignored by default. 109 | # 110 | # show_authors = False 111 | 112 | # The name of the Pygments (syntax highlighting) style to use. 113 | pygments_style = 'sphinx' 114 | 115 | # A list of ignored prefixes for module index sorting. 116 | # modindex_common_prefix = [] 117 | 118 | # If true, keep warnings as "system message" paragraphs in the built documents. 119 | # keep_warnings = False 120 | 121 | # If true, `todo` and `todoList` produce output, else they produce nothing. 122 | todo_include_todos = True 123 | 124 | 125 | # -- Options for HTML output ---------------------------------------------- 126 | 127 | # The theme to use for HTML and HTML Help pages. See the documentation for 128 | # a list of builtin themes. 129 | # 130 | try: 131 | import sphinx_rtd_theme 132 | html_theme = 'sphinx_rtd_theme' 133 | html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] 134 | pass 135 | except Exception, e: 136 | html_theme = 'default' 137 | 138 | # Theme options are theme-specific and customize the look and feel of a theme 139 | # further. For a list of options available for each theme, see the 140 | # documentation. 141 | # 142 | # html_theme_options = {} 143 | 144 | # Add any paths that contain custom themes here, relative to this directory. 145 | # html_theme_path = [] 146 | 147 | # The name for this set of Sphinx documents. 148 | # " v documentation" by default. 149 | # 150 | # html_title = u'testipynb v0.0.3' 151 | 152 | # A shorter title for the navigation bar. Default is the same as html_title. 153 | # 154 | # html_short_title = None 155 | 156 | # The name of an image file (relative to this directory) to place at the top 157 | # of the sidebar. 158 | # 159 | # html_logo = None 160 | 161 | # The name of an image file (relative to this directory) to use as a favicon of 162 | # the docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 163 | # pixels large. 164 | # 165 | # html_favicon = None 166 | 167 | # Add any paths that contain custom static files (such as style sheets) here, 168 | # relative to this directory. They are copied after the builtin static files, 169 | # so a file named "default.css" will overwrite the builtin "default.css". 170 | html_static_path = ['_static'] 171 | 172 | # Add any extra paths that contain custom files (such as robots.txt or 173 | # .htaccess) here, relative to this directory. These files are copied 174 | # directly to the root of the documentation. 175 | # 176 | # html_extra_path = [] 177 | 178 | # If not None, a 'Last updated on:' timestamp is inserted at every page 179 | # bottom, using the given strftime format. 180 | # The empty string is equivalent to '%b %d, %Y'. 181 | # 182 | # html_last_updated_fmt = None 183 | 184 | # If true, SmartyPants will be used to convert quotes and dashes to 185 | # typographically correct entities. 186 | # 187 | # html_use_smartypants = True 188 | 189 | # Custom sidebar templates, maps document names to template names. 190 | # 191 | # html_sidebars = {} 192 | 193 | # Additional templates that should be rendered to pages, maps page names to 194 | # template names. 195 | # 196 | # html_additional_pages = {} 197 | 198 | # If false, no module index is generated. 199 | # 200 | # html_domain_indices = True 201 | 202 | # If false, no index is generated. 203 | # 204 | # html_use_index = True 205 | 206 | # If true, the index is split into individual pages for each letter. 207 | # 208 | # html_split_index = False 209 | 210 | # If true, links to the reST sources are added to the pages. 211 | # 212 | # html_show_sourcelink = True 213 | 214 | # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. 215 | # 216 | # html_show_sphinx = True 217 | 218 | # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. 219 | # 220 | # html_show_copyright = True 221 | 222 | # If true, an OpenSearch description file will be output, and all pages will 223 | # contain a tag referring to it. The value of this option must be the 224 | # base URL from which the finished HTML is served. 225 | # 226 | # html_use_opensearch = '' 227 | 228 | # This is the file name suffix for HTML files (e.g. ".xhtml"). 229 | # html_file_suffix = None 230 | 231 | # Language to be used for generating the HTML full-text search index. 232 | # Sphinx supports the following languages: 233 | # 'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja' 234 | # 'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr', 'zh' 235 | # 236 | # html_search_language = 'en' 237 | 238 | # A dictionary with options for the search language support, empty by default. 239 | # 'ja' uses this config value. 240 | # 'zh' user can custom change `jieba` dictionary path. 241 | # 242 | # html_search_options = {'type': 'default'} 243 | 244 | # The name of a javascript file (relative to the configuration directory) that 245 | # implements a search results scorer. If empty, the default will be used. 246 | # 247 | # html_search_scorer = 'scorer.js' 248 | 249 | # Output file base name for HTML help builder. 250 | htmlhelp_basename = 'testipynbdoc' 251 | 252 | # -- Options for LaTeX output --------------------------------------------- 253 | 254 | latex_elements = { 255 | # The paper size ('letterpaper' or 'a4paper'). 256 | # 257 | # 'papersize': 'letterpaper', 258 | 259 | # The font size ('10pt', '11pt' or '12pt'). 260 | # 261 | # 'pointsize': '10pt', 262 | 263 | # Additional stuff for the LaTeX preamble. 264 | # 265 | # 'preamble': '', 266 | 267 | # Latex figure (float) alignment 268 | # 269 | # 'figure_align': 'htbp', 270 | } 271 | 272 | # Grouping the document tree into LaTeX files. List of tuples 273 | # (source start file, target name, title, 274 | # author, documentclass [howto, manual, or own class]). 275 | latex_documents = [ 276 | (master_doc, 'testipynb.tex', u'testipynb Documentation', 277 | u'Lindsey Heagy', 'manual'), 278 | ] 279 | 280 | # The name of an image file (relative to this directory) to place at the top of 281 | # the title page. 282 | # 283 | # latex_logo = None 284 | 285 | # For "manual" documents, if this is true, then toplevel headings are parts, 286 | # not chapters. 287 | # 288 | # latex_use_parts = False 289 | 290 | # If true, show page references after internal links. 291 | # 292 | # latex_show_pagerefs = False 293 | 294 | # If true, show URL addresses after external links. 295 | # 296 | # latex_show_urls = False 297 | 298 | # Documents to append as an appendix to all manuals. 299 | # 300 | # latex_appendices = [] 301 | 302 | # It false, will not define \strong, \code, itleref, \crossref ... but only 303 | # \sphinxstrong, ..., \sphinxtitleref, ... To help avoid clash with user added 304 | # packages. 305 | # 306 | # latex_keep_old_macro_names = True 307 | 308 | # If false, no module index is generated. 309 | # 310 | # latex_domain_indices = True 311 | 312 | 313 | # -- Options for manual page output --------------------------------------- 314 | 315 | # One entry per manual page. List of tuples 316 | # (source start file, name, description, authors, manual section). 317 | man_pages = [ 318 | (master_doc, 'testipynb', u'testipynb Documentation', 319 | [author], 1) 320 | ] 321 | 322 | # If true, show URL addresses after external links. 323 | # 324 | # man_show_urls = False 325 | 326 | 327 | # -- Options for Texinfo output ------------------------------------------- 328 | 329 | # Grouping the document tree into Texinfo files. List of tuples 330 | # (source start file, target name, title, author, 331 | # dir menu entry, description, category) 332 | texinfo_documents = [ 333 | (master_doc, 'testipynb', u'testipynb Documentation', 334 | author, 'testipynb', 'One line description of project.', 335 | 'Miscellaneous'), 336 | ] 337 | 338 | # Documents to append as an appendix to all manuals. 339 | # 340 | # texinfo_appendices = [] 341 | 342 | # If false, no module index is generated. 343 | # 344 | # texinfo_domain_indices = True 345 | 346 | # How to display URL addresses: 'footnote', 'no', or 'inline'. 347 | # 348 | # texinfo_show_urls = 'footnote' 349 | 350 | # If true, do not generate a @detailmenu in the "Top" node's menu. 351 | # 352 | # texinfo_no_detailmenu = False 353 | 354 | 355 | # Example configuration for intersphinx: refer to the Python standard library. 356 | intersphinx_mapping = {'https://docs.python.org/3/': None} 357 | -------------------------------------------------------------------------------- /.pylintrc: -------------------------------------------------------------------------------- 1 | [MASTER] 2 | 3 | # A comma-separated list of package or module names from where C extensions may 4 | # be loaded. Extensions are loading into the active Python interpreter and may 5 | # run arbitrary code 6 | extension-pkg-whitelist= 7 | 8 | # Add files or directories to the blacklist. They should be base names, not 9 | # paths. 10 | ignore=CVS 11 | 12 | # Add files or directories matching the regex patterns to the blacklist. The 13 | # regex matches against base names, not paths. 14 | ignore-patterns= 15 | 16 | # Python code to execute, usually for sys.path manipulation such as 17 | # pygtk.require(). 18 | #init-hook= 19 | 20 | # Use multiple processes to speed up Pylint. 21 | jobs=1 22 | 23 | # List of plugins (as comma separated values of python modules names) to load, 24 | # usually to register additional checkers. 25 | load-plugins= 26 | 27 | # Pickle collected data for later comparisons. 28 | persistent=yes 29 | 30 | # Specify a configuration file. 31 | #rcfile= 32 | 33 | # Allow loading of arbitrary C extensions. Extensions are imported into the 34 | # active Python interpreter and may run arbitrary code. 35 | unsafe-load-any-extension=no 36 | 37 | 38 | [MESSAGES CONTROL] 39 | 40 | # Only show warnings with the listed confidence levels. Leave empty to show 41 | # all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED 42 | confidence= 43 | 44 | # Disable the message, report, category or checker with the given id(s). You 45 | # can either give multiple identifiers separated by comma (,) or put this 46 | # option multiple times (only on the command line, not in the configuration 47 | # file where it should appear only once).You can also use "--disable=all" to 48 | # disable everything first and then reenable specific checks. For example, if 49 | # you want to run only the similarities checker, you can use "--disable=all 50 | # --enable=similarities". If you want to run only the classes checker, but have 51 | # no Warning level messages displayed, use"--disable=all --enable=classes 52 | # --disable=W" 53 | disable=print-statement,parameter-unpacking,unpacking-in-except,old-raise-syntax,backtick,long-suffix,old-ne-operator,old-octal-literal,raw-checker-failed,bad-inline-option,locally-disabled,locally-enabled,file-ignored,suppressed-message,deprecated-pragma,apply-builtin,basestring-builtin,buffer-builtin,cmp-builtin,coerce-builtin,execfile-builtin,file-builtin,long-builtin,raw_input-builtin,reduce-builtin,standarderror-builtin,unicode-builtin,xrange-builtin,coerce-method,delslice-method,getslice-method,setslice-method,no-absolute-import,old-division,dict-iter-method,dict-view-method,next-method-called,metaclass-assignment,indexing-exception,raising-string,reload-builtin,oct-method,hex-method,nonzero-method,cmp-method,input-builtin,round-builtin,intern-builtin,unichr-builtin,map-builtin-not-iterating,zip-builtin-not-iterating,range-builtin-not-iterating,filter-builtin-not-iterating,using-cmp-argument,eq-without-hash,div-method,idiv-method,rdiv-method,exception-message-attribute,invalid-str-codec,sys-max-int,bad-python3-import,deprecated-string-function,deprecated-str-translate-call,attribute-defined-outside-init,similarities,bad-continuation,import-error 54 | 55 | # Enable the message, report, category or checker with the given id(s). You can 56 | # either give multiple identifier separated by comma (,) or put this option 57 | # multiple time (only on the command line, not in the configuration file where 58 | # it should appear only once). See also the "--disable" option for examples. 59 | enable= 60 | 61 | 62 | [REPORTS] 63 | 64 | # Python expression which should return a note less than 10 (10 is the highest 65 | # note). You have access to the variables errors warning, statement which 66 | # respectively contain the number of errors / warnings messages and the total 67 | # number of statements analyzed. This is used by the global evaluation report 68 | # (RP0004). 69 | evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10) 70 | 71 | # Template used to display messages. This is a python new-style format string 72 | # used to format the message information. See doc for all details 73 | #msg-template= 74 | 75 | # Set the output format. Available formats are text, parseable, colorized, json 76 | # and msvs (visual studio).You can also give a reporter class, eg 77 | # mypackage.mymodule.MyReporterClass. 78 | output-format=text 79 | 80 | # Tells whether to display a full report or only the messages 81 | reports=no 82 | 83 | # Activate the evaluation score. 84 | score=yes 85 | 86 | 87 | [REFACTORING] 88 | 89 | # Maximum number of nested blocks for function / method body 90 | max-nested-blocks=5 91 | 92 | 93 | [FORMAT] 94 | 95 | # Expected format of line ending, e.g. empty (any line ending), LF or CRLF. 96 | expected-line-ending-format= 97 | 98 | # Regexp for a line that is allowed to be longer than the limit. 99 | ignore-long-lines=^\s*(# )??$ 100 | 101 | # Number of spaces of indent required inside a hanging or continued line. 102 | indent-after-paren=4 103 | 104 | # String used as indentation unit. This is usually " " (4 spaces) or "\t" (1 105 | # tab). 106 | indent-string=' ' 107 | 108 | # Maximum number of characters on a single line. 109 | max-line-length=100 110 | 111 | # Maximum number of lines in a module 112 | max-module-lines=2000 113 | 114 | # List of optional constructs for which whitespace checking is disabled. `dict- 115 | # separator` is used to allow tabulation in dicts, etc.: {1 : 1,\n222: 2}. 116 | # `trailing-comma` allows a space between comma and closing bracket: (a, ). 117 | # `empty-line` allows space-only lines. 118 | no-space-check=trailing-comma,dict-separator 119 | 120 | # Allow the body of a class to be on the same line as the declaration if body 121 | # contains single statement. 122 | single-line-class-stmt=no 123 | 124 | # Allow the body of an if to be on the same line as the test if there is no 125 | # else. 126 | single-line-if-stmt=no 127 | 128 | 129 | [VARIABLES] 130 | 131 | # List of additional names supposed to be defined in builtins. Remember that 132 | # you should avoid to define new builtins when possible. 133 | additional-builtins= 134 | 135 | # Tells whether unused global variables should be treated as a violation. 136 | allow-global-unused-variables=yes 137 | 138 | # List of strings which can identify a callback function by name. A callback 139 | # name must start or end with one of those strings. 140 | callbacks=cb_,_cb 141 | 142 | # A regular expression matching the name of dummy variables (i.e. expectedly 143 | # not used). 144 | dummy-variables-rgx=_+$|(_[a-zA-Z0-9_]*[a-zA-Z0-9]+?$)|dummy|^ignored_|^unused_ 145 | 146 | # Argument names that match this expression will be ignored. Default to name 147 | # with leading underscore 148 | ignored-argument-names=_.*|^ignored_|^unused_ 149 | 150 | # Tells whether we should check for unused import in __init__ files. 151 | init-import=no 152 | 153 | # List of qualified module names which can have objects that can redefine 154 | # builtins. 155 | redefining-builtins-modules=six.moves,future.builtins 156 | 157 | 158 | [SIMILARITIES] 159 | 160 | # Ignore comments when computing similarities. 161 | ignore-comments=yes 162 | 163 | # Ignore docstrings when computing similarities. 164 | ignore-docstrings=yes 165 | 166 | # Ignore imports when computing similarities. 167 | ignore-imports=yes 168 | 169 | # Minimum lines number of a similarity. 170 | min-similarity-lines=3 171 | 172 | 173 | [LOGGING] 174 | 175 | # Logging modules to check that the string format arguments are in logging 176 | # function parameter format 177 | logging-modules=logging 178 | 179 | 180 | [SPELLING] 181 | 182 | # Spelling dictionary name. Available dictionaries: none. To make it working 183 | # install python-enchant package. 184 | spelling-dict= 185 | 186 | # List of comma separated words that should not be checked. 187 | spelling-ignore-words= 188 | 189 | # A path to a file that contains private dictionary; one word per line. 190 | spelling-private-dict-file= 191 | 192 | # Tells whether to store unknown words to indicated private dictionary in 193 | # --spelling-private-dict-file option instead of raising a message. 194 | spelling-store-unknown-words=no 195 | 196 | 197 | [BASIC] 198 | 199 | # Naming hint for argument names 200 | argument-name-hint=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$ 201 | 202 | # Regular expression matching correct argument names 203 | argument-rgx=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$ 204 | 205 | # Naming hint for attribute names 206 | attr-name-hint=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$ 207 | 208 | # Regular expression matching correct attribute names 209 | attr-rgx=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$ 210 | 211 | # Bad variable names which should always be refused, separated by a comma 212 | bad-names=foo,bar,baz,toto,tutu,tata 213 | 214 | # Naming hint for class attribute names 215 | class-attribute-name-hint=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$ 216 | 217 | # Regular expression matching correct class attribute names 218 | class-attribute-rgx=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$ 219 | 220 | # Naming hint for class names 221 | class-name-hint=[A-Z_][a-zA-Z0-9]+$ 222 | 223 | # Regular expression matching correct class names 224 | class-rgx=[A-Z_][a-zA-Z0-9]+$ 225 | 226 | # Naming hint for constant names 227 | const-name-hint=(([A-Z_][A-Z0-9_]*)|(__.*__))$ 228 | 229 | # Regular expression matching correct constant names 230 | const-rgx=(([A-Z_][A-Z0-9_]*)|(__.*__))$ 231 | 232 | # Minimum line length for functions/classes that require docstrings, shorter 233 | # ones are exempt. 234 | docstring-min-length=-1 235 | 236 | # Naming hint for function names 237 | function-name-hint=(([a-z][a-z0-9_]{2,50})|(_[a-z0-9_]*))$ 238 | 239 | # Regular expression matching correct function names 240 | function-rgx=(([a-z][a-z0-9_]{2,50})|(_[a-z0-9_]*))$ 241 | 242 | # Good variable names which should always be accepted, separated by a comma 243 | good-names=i,j,k,w,e,s,n,x,y,z,cv,ax 244 | 245 | # Include a hint for the correct naming format with invalid-name 246 | include-naming-hint=no 247 | 248 | # Naming hint for inline iteration names 249 | inlinevar-name-hint=[A-Za-z_][A-Za-z0-9_]*$ 250 | 251 | # Regular expression matching correct inline iteration names 252 | inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$ 253 | 254 | # Naming hint for method names 255 | method-name-hint=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$ 256 | 257 | # Regular expression matching correct method names 258 | method-rgx=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$ 259 | 260 | # Naming hint for module names 261 | module-name-hint=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$ 262 | 263 | # Regular expression matching correct module names 264 | module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$ 265 | 266 | # Colon-delimited sets of names that determine each other's naming style when 267 | # the name regexes allow several styles. 268 | name-group= 269 | 270 | # Regular expression which should only match function or class names that do 271 | # not require a docstring. 272 | no-docstring-rgx=^_ 273 | 274 | # List of decorators that produce properties, such as abc.abstractproperty. Add 275 | # to this list to register other decorators that produce valid properties. 276 | property-classes=abc.abstractproperty 277 | 278 | # Naming hint for variable names 279 | variable-name-hint=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$ 280 | 281 | # Regular expression matching correct variable names 282 | variable-rgx=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$ 283 | 284 | 285 | [TYPECHECK] 286 | 287 | # List of decorators that produce context managers, such as 288 | # contextlib.contextmanager. Add to this list to register other decorators that 289 | # produce valid context managers. 290 | contextmanager-decorators=contextlib.contextmanager 291 | 292 | # List of members which are set dynamically and missed by pylint inference 293 | # system, and so shouldn't trigger E1101 when accessed. Python regular 294 | # expressions are accepted. 295 | generated-members= 296 | 297 | # Tells whether missing members accessed in mixin class should be ignored. A 298 | # mixin class is detected if its name ends with "mixin" (case insensitive). 299 | ignore-mixin-members=yes 300 | 301 | # This flag controls whether pylint should warn about no-member and similar 302 | # checks whenever an opaque object is returned when inferring. The inference 303 | # can return multiple potential results while evaluating a Python object, but 304 | # some branches might not be evaluated, which results in partial inference. In 305 | # that case, it might be useful to still emit no-member and other checks for 306 | # the rest of the inferred objects. 307 | ignore-on-opaque-inference=yes 308 | 309 | # List of class names for which member attributes should not be checked (useful 310 | # for classes with dynamically set attributes). This supports the use of 311 | # qualified names. 312 | ignored-classes=optparse.Values,thread._local,_thread._local 313 | 314 | # List of module names for which member attributes should not be checked 315 | # (useful for modules/projects where namespaces are manipulated during runtime 316 | # and thus existing member attributes cannot be deduced by static analysis. It 317 | # supports qualified module names, as well as Unix pattern matching. 318 | ignored-modules= 319 | 320 | # Show a hint with possible names when a member name was not found. The aspect 321 | # of finding the hint is based on edit distance. 322 | missing-member-hint=yes 323 | 324 | # The minimum edit distance a name should have in order to be considered a 325 | # similar match for a missing member name. 326 | missing-member-hint-distance=1 327 | 328 | # The total number of similar names that should be taken in consideration when 329 | # showing a hint for a missing member. 330 | missing-member-max-choices=1 331 | 332 | 333 | [MISCELLANEOUS] 334 | 335 | # List of note tags to take in consideration, separated by a comma. 336 | notes=FIXME,XXX,TODO 337 | 338 | 339 | [DESIGN] 340 | 341 | # Maximum number of arguments for function / method 342 | max-args=10 343 | 344 | # Maximum number of attributes for a class (see R0902). 345 | max-attributes=10 346 | 347 | # Maximum number of boolean expressions in a if statement 348 | max-bool-expr=5 349 | 350 | # Maximum number of branch for function / method body 351 | max-branches=12 352 | 353 | # Maximum number of locals for function / method body 354 | max-locals=15 355 | 356 | # Maximum number of parents for a class (see R0901). 357 | max-parents=7 358 | 359 | # Maximum number of public methods for a class (see R0904). 360 | max-public-methods=20 361 | 362 | # Maximum number of return / yield for function / method body 363 | max-returns=6 364 | 365 | # Maximum number of statements in function / method body 366 | max-statements=50 367 | 368 | # Minimum number of public methods for a class (see R0903). 369 | min-public-methods=2 370 | 371 | 372 | [IMPORTS] 373 | 374 | # Allow wildcard imports from modules that define __all__. 375 | allow-wildcard-with-all=no 376 | 377 | # Analyse import fallback blocks. This can be used to support both Python 2 and 378 | # 3 compatible code, which means that the block might have code that exists 379 | # only in one or another interpreter, leading to false positives when analysed. 380 | analyse-fallback-blocks=no 381 | 382 | # Deprecated modules which should not be used, separated by a comma 383 | deprecated-modules=optparse,tkinter.tix 384 | 385 | # Create a graph of external dependencies in the given file (report RP0402 must 386 | # not be disabled) 387 | ext-import-graph= 388 | 389 | # Create a graph of every (i.e. internal and external) dependencies in the 390 | # given file (report RP0402 must not be disabled) 391 | import-graph= 392 | 393 | # Create a graph of internal dependencies in the given file (report RP0402 must 394 | # not be disabled) 395 | int-import-graph= 396 | 397 | # Force import order to recognize a module as part of the standard 398 | # compatibility libraries. 399 | known-standard-library= 400 | 401 | # Force import order to recognize a module as part of a third party library. 402 | known-third-party=enchant 403 | 404 | 405 | [CLASSES] 406 | 407 | # List of method names used to declare (i.e. assign) instance attributes. 408 | defining-attr-methods=__init__,__new__,setUp 409 | 410 | # List of member names, which should be excluded from the protected access 411 | # warning. 412 | exclude-protected=_asdict,_fields,_replace,_source,_make 413 | 414 | # List of valid names for the first argument in a class method. 415 | valid-classmethod-first-arg=cls 416 | 417 | # List of valid names for the first argument in a metaclass class method. 418 | valid-metaclass-classmethod-first-arg=mcs 419 | 420 | 421 | [EXCEPTIONS] 422 | 423 | # Exceptions that will emit a warning when being caught. Defaults to 424 | # "Exception" 425 | overgeneral-exceptions=Exception 426 | --------------------------------------------------------------------------------