diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml new file mode 100644 index 00000000..1bb27061 --- /dev/null +++ b/.github/workflows/check.yml @@ -0,0 +1,34 @@ +name: Checks + +on: + pull_request: + branches: + - master + push: + branches: + - master + +env: + PIP_DISABLE_PIP_VERSION_CHECK: '1' + PY_COLORS: '1' + +jobs: + check: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + env: + #- ruff + #- black + - package + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-python@v4 + with: + python-version: '3.10' + - name: Install build tools + run: | + python -m pip install tox wheel + - name: Run ${{ matrix.env }} + run: tox -e ${{ matrix.env }} diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 00000000..9dd37a93 --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,29 @@ +name: Publish + +on: + push: + tags: + - '*' + +env: + PIP_DISABLE_PIP_VERSION_CHECK: '1' + PY_COLORS: '1' + +jobs: + publish: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-python@v4 + with: + python-version: '3.10' + - name: Install build tools + run: | + python -m pip install build twine wheel + - name: Build package + run: python -m build + - name: Upload to PyPI + env: + TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }} + TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }} + run: twine upload dist/* diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 00000000..da420163 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,56 @@ +name: Tests + +on: + pull_request: + branches: + - master + push: + branches: + - master + +env: + PIP_DISABLE_PIP_VERSION_CHECK: '1' + PY_COLORS: '1' + +jobs: + test: + runs-on: ${{ matrix.platform }} + strategy: + fail-fast: false + matrix: + platform: + - ubuntu-20.04 + - macos-latest + - windows-latest + python-version: + - '2.7' + - '3.5' + - '3.6' + - '3.7' + - '3.8' + - '3.9' + - '3.10' + - '3.11' + - pypy-2.7 + - pypy-3.8 + - pypy-3.9 + dependencies: + - none + - scipy + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python-version }} + - name: Install build tools + run: python -m pip install tox-gh-actions wheel + - name: Install optional dependencies + run: python -m pip install ${{ matrix.dependencies }} + if: ${{ matrix.dependencies != 'none' }} + - name: Run tests + run: tox + - name: Upload coverage report + uses: codacy/codacy-coverage-reporter-action@v1 + with: + project-token: ${{ secrets.CODACY_PROJECT_TOKEN }} + coverage-reports: coverage.xml diff --git a/.gitignore b/.gitignore index 3d04dc2a..cb7301dc 100644 --- a/.gitignore +++ b/.gitignore @@ -1,15 +1,69 @@ -*.pyc -scratch/ -examples/data -.idea/ -.DS_Store +__pycache__/ +*.py[cod] +*$py.class + +# Distribution / packaging +.Python build/ -data/ +develop-eggs/ dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +*.egg-info/ +.installed.cfg +*.egg MANIFEST + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.coverage.* +.cache +coverage.* +*.cover +.hypothesis/ +nosetests.xml +.pytest_cache/ +junit-report.xml + +# pyenv +.python-version + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# mypy +.mypy_cache/ + +# OS and IDE config files +.DS_Store +.idea/ + +# project-specific +data/ *.so *.c +scratch/ +examples/data + .asv/ -autograd.egg-info/ asv.conf.json benchmarks/asv.conf.js diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index a360e8fa..00000000 --- a/.travis.yml +++ /dev/null @@ -1,26 +0,0 @@ -sudo: false -notifications: - email: false -language: python -python: - - "2.7" - - "3.6" -env: - - DEPS="pip pytest future numpy scipy" - - DEPS="pip pytest future numpy" -before_install: - - if [[ "$TRAVIS_PYTHON_VERSION" == "2.7" ]]; then - wget https://repo.continuum.io/miniconda/Miniconda2-latest-Linux-x86_64.sh -O miniconda.sh; - else - wget https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh -O miniconda.sh; - fi - - bash miniconda.sh -b -p $HOME/miniconda - - export PATH="$HOME/miniconda/bin:$PATH" - - conda update --yes conda - - conda config --add channels conda-forge -install: - - conda install --yes python=$TRAVIS_PYTHON_VERSION $DEPS - - pip install -v . -script: - - (cd tests; python -mpytest .) # Run from inside tests directory to make sure - - # Autograd has fully installed. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..d20ca31e --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,43 @@ +# Contributing + +Use Tox to run tests and linting, e.g. + +```shell +pip install tox +``` + +## Run tests, linting, packaging checks + +```shell +tox list # list all Tox environments +tox run -e black,ruff # run code style checks +tox run -e py # run tests with your default Python +tox run -e package # verify packaging +tox # run all Tox environments +``` + +Make sure all tests pass before you push your changes to GitHub. +GH Actions will run the tests across all supported Python versions. + +## Using arguments (reformat, upload package, help) + +You can use additional arguments for the tools called by Tox by +separating them from the Tox arguments by a double-dash `--`, e.g. + +```shell +tox run -e black -- autograd/core.py --check --diff +tox run -e black -- autograd/core.py +``` + +```shell +tox run -e ruff -- autograd/core.py --show-source +tox run -e ruff -- autograd/core.py --fix +``` + +```shell +tox run -e package -- upload +``` + +```shell +tox run -e py -- --help +``` diff --git a/MANIFEST.in b/MANIFEST.in index f0fd68f8..a3e17ed3 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1 +1,2 @@ recursive-include autograd *.c *.h *.pyx +prune tests diff --git a/README.md b/README.md index 140896ad..9bfeb520 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,15 @@ Townsend) are now working on [JAX](https://github.com/google/jax), with Dougal a working on it full-time. JAX combines a new version of Autograd with extra features such as jit compilation.__ -# Autograd [![Test status](https://travis-ci.org/HIPS/autograd.svg?branch=master)](https://travis-ci.org/HIPS/autograd) [![asv](http://img.shields.io/badge/benchmarked%20by-asv-green.svg?style=flat)](#) +# Autograd [![Checks status][checks-badge]][checks-url] [![Tests status][tests-badge]][tests-url] [![Publish status][publish-badge]][publish-url] [![asv][asv-badge]](#) + +[publish-badge]: https://github.com/HIPS/autograd/actions/workflows/publish.yml/badge.svg +[checks-badge]: https://github.com/HIPS/autograd/actions/workflows/check.yml/badge.svg +[tests-badge]: https://github.com/HIPS/autograd/actions/workflows/test.yml/badge.svg +[asv-badge]: http://img.shields.io/badge/benchmarked%20by-asv-green.svg?style=flat +[publish-url]: https://github.com/HIPS/autograd/actions/workflows/publish.yml +[checks-url]: https://github.com/HIPS/autograd/actions/workflows/check.yml +[tests-url]: https://github.com/HIPS/autograd/actions/workflows/test.yml Autograd can automatically differentiate native Python and Numpy code. It can handle a large subset of Python's features, including loops, ifs, recursion and @@ -75,7 +83,18 @@ You can find a tutorial [here.](docs/tutorial.md) ## How to install -Just run `pip install autograd` +Install _autograd_ using Pip, e.g. + +```shell +pip install autograd +``` + +Some features require _scipy_, which you can install separately or as an +optional dependency along with _autograd_ , e.g. + +```shell +pip install "autograd[scipy]" +``` ## Authors diff --git a/autograd/builtins.py b/autograd/builtins.py index 8db7c238..39880fd5 100644 --- a/autograd/builtins.py +++ b/autograd/builtins.py @@ -1,5 +1,4 @@ -import itertools -from future.utils import with_metaclass +from six import with_metaclass from .util import subvals from .extend import (Box, primitive, notrace_primitive, VSpace, vspace, SparseObject, defvjp, defvjp_argnum, defjvp, defjvp_argnum) diff --git a/autograd/numpy/numpy_vjps.py b/autograd/numpy/numpy_vjps.py index aab566f8..774afa92 100644 --- a/autograd/numpy/numpy_vjps.py +++ b/autograd/numpy/numpy_vjps.py @@ -1,5 +1,5 @@ from __future__ import absolute_import -from future.utils import string_types +from six import string_types from functools import partial import numpy as onp from ..util import func diff --git a/autograd/scipy/signal.py b/autograd/scipy/signal.py index 44bed02c..e1f0d650 100644 --- a/autograd/scipy/signal.py +++ b/autograd/scipy/signal.py @@ -6,7 +6,7 @@ from autograd.extend import primitive, defvjp from numpy.lib.stride_tricks import as_strided -from future.utils import iteritems +from six import iteritems @primitive def convolve(A, B, axes=None, dot_axes=[(),()], mode='full'): diff --git a/examples/data_mnist.py b/examples/data_mnist.py index 6dcff1d2..21df35d8 100644 --- a/examples/data_mnist.py +++ b/examples/data_mnist.py @@ -1,7 +1,9 @@ from __future__ import absolute_import from __future__ import print_function -from future.standard_library import install_aliases -install_aliases() +import sys +if sys.version < "3": + from future.standard_library import install_aliases + install_aliases() import os import gzip diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 00000000..02f71ec9 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,73 @@ +[build-system] +requires = ["setuptools>=63"] +build-backend = "setuptools.build_meta" + +[project] +name = "autograd" +version = "1.6.3" +description = "Efficiently computes derivatives of numpy code." +readme = "README.md" +license = {file = "license.txt"} +authors = [ + {name = "Dougal Maclaurin", email = "maclaurin@physics.harvard.edu"}, + {name = "David Duvenaud", email = "duvenaud@cs.toronto.edu"}, + {name = "Matthew Johnson", email = "mattjj@csail.mit.edu"}, +] +maintainers = [ + {name = "Jamie Townsend", email = "jamiehntownsend@gmail.com"}, +] +classifiers = [ + "Development Status :: 4 - Beta", + "Intended Audience :: Information Technology", + "Intended Audience :: Science/Research", + "License :: OSI Approved :: MIT License", + "Programming Language :: Python :: 2", + "Programming Language :: Python :: 2.7", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.5", + "Programming Language :: Python :: 3.6", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", +] +keywords = [ + "Automatic differentiation", + "backpropagation", + "gradients", + "machine learning", + "optimization", + "neural networks", + "Python", + "Numpy", + "Scipy", +] +dependencies = [ + "numpy>=1.12", + "six", + "future>=0.15.2; python_version < '3'", +] + +[project.optional-dependencies] +scipy = [ + "scipy", +] + +[tool.coverage.run] +source = ["autograd"] + +[tool.coverage.report] +show_missing = true + +[tool.pytest.ini_options] +addopts = "--color=yes --junitxml=junit-report.xml" + +[tool.setuptools] +packages=[ + "autograd", + "autograd.numpy", + "autograd.scipy", + "autograd.scipy.stats", + "autograd.misc", +] diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index b88034e4..00000000 --- a/setup.cfg +++ /dev/null @@ -1,2 +0,0 @@ -[metadata] -description-file = README.md diff --git a/setup.py b/setup.py deleted file mode 100644 index d352318e..00000000 --- a/setup.py +++ /dev/null @@ -1,20 +0,0 @@ -from setuptools import setup - -setup( - name='autograd', - version='1.6.2', - description='Efficiently computes derivatives of numpy code.', - author='Dougal Maclaurin and David Duvenaud and Matthew Johnson', - author_email="maclaurin@physics.harvard.edu, duvenaud@cs.toronto.edu, mattjj@csail.mit.edu", - packages=['autograd', 'autograd.numpy', 'autograd.scipy', 'autograd.scipy.stats', 'autograd.misc'], - install_requires=['numpy>=1.12', 'future>=0.15.2'], - keywords=['Automatic differentiation', 'backpropagation', 'gradients', - 'machine learning', 'optimization', 'neural networks', - 'Python', 'Numpy', 'Scipy'], - url='https://github.com/HIPS/autograd', - license='MIT', - classifiers=['Development Status :: 4 - Beta', - 'License :: OSI Approved :: MIT License', - 'Programming Language :: Python :: 2.7', - 'Programming Language :: Python :: 3.5'], -) diff --git a/tox.ini b/tox.ini new file mode 100644 index 00000000..8ad433f8 --- /dev/null +++ b/tox.ini @@ -0,0 +1,76 @@ +# Tox (https://tox.wiki/) - run tests in isolation using virtualenv. +# Also contains config settings for tools that don't look into pyproject.toml. + +[tox] +envlist = + ruff + black + py2{7} + pypy2{7} + py3{5,6,7,8,9,10,11} + pypy3{8,9} + package + clean + +[gh-actions] +python = + 2.7: py27 + 3.5: py35 + 3.6: py36 + 3.7: py37 + 3.8: py38 + 3.9: py39 + 3.10: py310 + 3.11: py311 + pypy-2.7: pypy27 + pypy-3.8: pypy38 + pypy-3.9: pypy39 + +[testenv] +description = Unit tests and test coverage +deps = + py27: mock + pypy27: mock + coverage[toml] + pytest +commands = + coverage run -m pytest {posargs} + coverage xml + coverage report + +[testenv:black] +description = Ensure consistent code style +skip_install = true +deps = black +commands = black {posargs:. --check} + +[testenv:clean] +description = Clean up bytecode and build artifacts +skip_install = true +deps = pyclean +commands = pyclean {posargs:. --debris --erase junit-report.xml --yes} + +[testenv:ruff] +description = Lightening-fast linting for Python +skip_install = true +deps = ruff +commands = ruff {posargs:.} + +[testenv:package] +description = Build package and check metadata (or upload package) +skip_install = true +deps = + build + twine +commands = + python -m build + twine {posargs:check --strict} dist/* +passenv = + TWINE_USERNAME + TWINE_PASSWORD + TWINE_REPOSITORY_URL + +[pytest] +addopts = + --color=yes + --junitxml=junit-report.xml