From a47618c8b35c3a13603adf9d1e040db1f09a1bcf Mon Sep 17 00:00:00 2001 From: Marc Weitz Date: Thu, 11 Aug 2022 12:08:07 +0200 Subject: [PATCH] Adds support for pypoetry (https://python-poetry.org) (#222) * introduces python poetry to maintain and build the package * allows building wheels for PyPI (fixes #212) * uses `pyproject.toml` instead of `setup.py` and thus fixes #143 and fixes #137 * sets up Github Actions for general testing (replaces Travis) * bumps version to 1.0.0-beta Co-authored-by: Konstantin (Tino) Sering --- .github/workflows/python-test.yml | 72 ++++++++++++ .gitignore | 6 +- .readthedocs.yml | 28 ++++- .travis.yml | 29 ----- MANIFEST.in | 16 --- Makefile | 28 ----- README.rst | 9 +- setup.py => build.py | 58 +++------- doc/requirements.txt | 7 ++ doc/source/about.rst | 5 +- doc/source/conf.py | 177 ++++++------------------------ doc/source/development.rst | 113 +++++++++---------- doc/source/examples.rst | 11 +- doc/source/index.rst | 6 +- doc/source/quickstart.rst | 11 ++ pyndl/__init__.py | 31 +----- pyproject.toml | 73 ++++++++++++ requirements.txt | 8 -- setup.cfg | 13 --- tests/test_activation.py | 2 + tox.ini | 71 ------------ 21 files changed, 317 insertions(+), 457 deletions(-) create mode 100644 .github/workflows/python-test.yml delete mode 100644 .travis.yml delete mode 100644 MANIFEST.in delete mode 100644 Makefile rename setup.py => build.py (51%) create mode 100644 doc/requirements.txt create mode 100644 pyproject.toml delete mode 100644 requirements.txt delete mode 100644 setup.cfg delete mode 100644 tox.ini diff --git a/.github/workflows/python-test.yml b/.github/workflows/python-test.yml new file mode 100644 index 0000000..67125bc --- /dev/null +++ b/.github/workflows/python-test.yml @@ -0,0 +1,72 @@ +name: Linux & OSX tests + +on: + push: + branches: + - master + pull_request: + branches: + - master + +jobs: + build: + name: ${{ matrix.os }} ${{ matrix.python-version }} + strategy: + matrix: + os: [ubuntu-latest, macOS-latest] + python-version: ['3.8', '3.10'] + poetry-version: [1.1.13] + fail-fast: false + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v2 + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + + - name: Get full Python version + id: full-python-version + run: echo ::set-output name=version::$(python -c "import sys; print('-'.join(str(v) for v in sys.version_info))") + + - name: Setup poetry + uses: abatilo/actions-poetry@v2.1.3 + with: + poetry-version: ${{ matrix.poetry-version }} + + - name: Update PATH + if: ${{ runner.os != 'Windows' }} + run: echo "$HOME/.local/bin" >> $GITHUB_PATH + + - name: Update Path for Windows + if: ${{ runner.os == 'Windows' }} + run: echo "$APPDATA\Python\Scripts" >> $GITHUB_PATH + + - name: Configure poetry + run: poetry config virtualenvs.in-project true + + - name: Set up cache + uses: actions/cache@v2 + id: cache + with: + path: .venv + key: venv-cache-${{ runner.os }}-${{ steps.full-python-version.outputs.version }}-${{ hashFiles('**/poetry.lock') }} + + - name: Install dependencies + run: poetry install + + - name: Run linux tests + if: ${{ runner.os == 'Linux' }} + run: poetry run pytest --cov=pyndl --cov-report=xml --disable-pytest-warnings + + - name: Run tests on other distributions (skip linux-only tests) + if: ${{ runner.os != 'Linux' }} + run: poetry run pytest --no-linux + + - name: Upload coverage to Codecov + uses: codecov/codecov-action@v2 + with: + file: ./coverage.xml + flags: unittests + env_vars: OS,PYTHON diff --git a/.gitignore b/.gitignore index ca3690e..6ed6ad4 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ pyndl/ndl_parallel.c pyndl/ndl_openmp.c pyndl/corr_parallel.c pyndl/wh_parallel.c +pyndl/correlation_openmp.c latex/ *.pyc __pycache__/ @@ -28,4 +29,7 @@ doc/data/levent.tab.filtered doc/data/weights.nc # copybutton js script -doc/source/_static/copybutton.js +copybutton.js + +# pypoetry +poetry.lock diff --git a/.readthedocs.yml b/.readthedocs.yml index 5445147..d1a4222 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -1,5 +1,25 @@ +# .readthedocs.yaml +# Read the Docs configuration file +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details + +# Required +version: 2 + +# Set the version of Python and other tools you might need +build: + os: ubuntu-20.04 + tools: + python: "3.9" + +# Build documentation in the docs/ directory with Sphinx +sphinx: + configuration: doc/source/conf.py + +# If using Sphinx, optionally build your docs in additional formats such as PDF +formats: all + +# Optionally declare the Python requirements required to build your docs python: - setup_py_install: true - pip_install: true - extra_requirements: - - docs + install: + - path: . + - requirements: doc/requirements.txt diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 7d88873..0000000 --- a/.travis.yml +++ /dev/null @@ -1,29 +0,0 @@ -language: python -group: travis_latest -dist: xenial - -git: - depth: 3 - quiet: true - -python: - - 3.9 - - 3.8 - -install: - - pip3 install --upgrade pip # all three OSes agree about 'pip3' - - pip3 install tox-travis - -script: tox -e travis - -# Macos Testing -matrix: - include: - - name: "MacOS" - os: osx - osx_image: xcode10.3 # default xcode9.4 is too old for some dependencies - language: sh - script: tox -e nolinux - -env: - OMP_NUM_THREADS: 4 diff --git a/MANIFEST.in b/MANIFEST.in deleted file mode 100644 index 233dfd0..0000000 --- a/MANIFEST.in +++ /dev/null @@ -1,16 +0,0 @@ -include MANIFEST.in -include README.rst -include LICENSE.txt -include requirements.txt -graft pyndl -graft doc -graft tests -graft stubs -global-exclude __pycache__ -global-exclude *.py[co] -global-exclude *.so -global-exclude *.sw[po] -global-exclude *.c -prune doc/build -prune tests/temp - diff --git a/Makefile b/Makefile deleted file mode 100644 index 9872e19..0000000 --- a/Makefile +++ /dev/null @@ -1,28 +0,0 @@ -PYTHON_MODULES := pyndl tests -PYTHON_VERSION := '' -PYTHONPATH := . -VENV := .venv -PYTEST := env PYTHONPATH=$(PYTHONPATH) PYTEST=1 $(VENV)/bin/py.test -PYCODESTYLE := env PYTHONPATH=$(PYTHONPATH) $(VENV)/bin/pycodestyle --repeat -PYTHON := env PYTHONPATH=$(PYTHONPATH) $(VENV)/bin/python$(PYTHON_VERSION) -PIP := $(VENV)/bin/pip - -DEFAULT_PYTHON := /usr/bin/python$(PYTHON_VERSION) -VIRTUALENV := /usr/bin/env virtualenv - - -default: - tox -install: install-venv - which tox > /dev/null || (echo "Please install tox (pip install tox)!" && exit 1) && echo "All right! Run with tox." -checkstyle: - tox -e checkstyle -documentation: - tox -e documentation -test: - tox -e test -test-versions: - tox -e $(tox -l | grep test | paste -d, -s) -test-slow: use-venv - tox -e test -- --runslow -.PHONY: default install test use-venv install-venv checkstyle test-slow diff --git a/README.rst b/README.rst index 9f89ab9..c932bb7 100644 --- a/README.rst +++ b/README.rst @@ -2,11 +2,11 @@ Pyndl - Naive Discriminative Learning in Python =============================================== -.. image:: https://travis-ci.com/quantling/pyndl.svg?branch=master - :target: https://travis-ci.com/quantling/pyndl +.. image:: https://github.com/quantling/pyndl/actions/workflows/python-test.yml/badge.svg?branch=master + :target: https://github.com/quantling/pyndl/actions/workflows/python-test.yml -.. image:: https://coveralls.io/repos/github/quantling/pyndl/badge.svg?branch=master - :target: https://coveralls.io/github/quantling/pyndl?branch=master +.. image:: https://codecov.io/gh/quantling/pyndl/branch/master/graph/badge.svg?token=2GWUXRA9PD + :target: https://codecov.io/gh/quantling/pyndl .. image:: https://img.shields.io/lgtm/grade/python/g/quantling/pyndl.svg?logo=lgtm&logoWidth=18 :target: https://lgtm.com/projects/g/quantling/pyndl/context:python @@ -87,4 +87,3 @@ Acknowledgments This research was supported by an ERC advanced Grant (no. 742545) and by the Alexander von Humboldt Professorship awarded to R. H. Baayen and by the University of Tübingen. - diff --git a/setup.py b/build.py similarity index 51% rename from setup.py rename to build.py index aabeaec..db63f5b 100644 --- a/setup.py +++ b/build.py @@ -1,4 +1,4 @@ -from setuptools import setup, Extension +from setuptools import Extension from setuptools.command.build_ext import build_ext as _build_ext import sys @@ -9,27 +9,11 @@ class build_ext(_build_ext): def finalize_options(self): _build_ext.finalize_options(self) # Prevent numpy from thinking it is still in its setup process: - __builtins__.__NUMPY_SETUP__ = False + #__builtins__.__NUMPY_SETUP__ = False import numpy self.include_dirs.append(numpy.get_include()) -pkg = __import__('pyndl') - -author = pkg.__author__ -email = pkg.__author_email__ - -version = pkg.__version__ -classifiers = pkg.__classifiers__ - -description = pkg.__description__ - -def load_requirements(fn): - """Read a requirements file and create a list that can be used in setup.""" - with open(fn, 'r') as f: - return [x.rstrip() for x in list(f) if x and not x.startswith('#')] - - ndl_parallel = Extension("pyndl.ndl_parallel", ["pyndl/ndl_parallel.pyx"]) ndl_openmp = Extension("pyndl.ndl_openmp", ["pyndl/ndl_openmp.pyx"], extra_compile_args=['-fopenmp'], extra_link_args=['-fopenmp']) @@ -46,30 +30,14 @@ def load_requirements(fn): elif sys.platform.startswith('darwin'): ext_modules = [ndl_parallel] # skip openmp installation on macos for now -setup( - name='pyndl', - version=version, - license='MIT', - description=description, - long_description=open('README.rst', encoding="utf-8").read(), - author=author, - author_email=email, - url='https://github.com/quantling/pyndl', - classifiers=classifiers, - platforms='Linux', - packages=['pyndl'], - setup_requires=['numpy', 'cython'], - install_requires=load_requirements('requirements.txt'), - extras_require={ - 'tests': [ - 'pylint', - 'pytest', - 'pycodestyle'], - 'docs': [ - 'sphinx >= 1.4', - 'sphinx_rtd_theme', - 'numpydoc', - 'easydev']}, - ext_modules=ext_modules, - cmdclass={'build_ext': build_ext} -) + +def build(setup_kwargs): + """ + This function is mandatory in order to build the extensions. + """ + setup_kwargs.update({ + 'ext_modules': ext_modules, + 'cmdclass': { + 'build_ext': build_ext + } + }) diff --git a/doc/requirements.txt b/doc/requirements.txt new file mode 100644 index 0000000..53218f3 --- /dev/null +++ b/doc/requirements.txt @@ -0,0 +1,7 @@ +sphinx>=1.4 +sphinx_rtd_theme>=1.0.0 +notebook>=6.4.10 +seaborn>=0.11.2 +numpydoc>=1.2 +easydev>=0.9.35 +nbsphinx>=0.8.8 diff --git a/doc/source/about.rst b/doc/source/about.rst index a2d67c1..f14b7c4 100644 --- a/doc/source/about.rst +++ b/doc/source/about.rst @@ -7,8 +7,9 @@ Authors *pyndl* was mainly developed by `Konstantin Sering `_, `Marc Weitz `_, -`David-Elias Künstle `_ -and `Lennart Schneider `_. For the full list of +`David-Elias Künstle `_, +`Lennart Schneider `_ and +`Elnaz Shafaei-Bajestan `_. For the full list of contributors have a look at `Github's Contributor summary `_. diff --git a/doc/source/conf.py b/doc/source/conf.py index 8e9927a..7f1d9c1 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -1,179 +1,72 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- +# Configuration file for the Sphinx documentation builder. # -# pyndl documentation build configuration file, created by -# sphinx-quickstart on Thu Jan 26 17:28:31 2017. -# -# This file is execfile()d with the current directory set to its -# containing dir. -# -# Note that not all possible configuration values are present in this -# autogenerated file. -# -# All configuration values have a default; values that are commented out -# serve to show the default. +# This file only contains a selection of the most common options. For a full +# list see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- Path setup -------------------------------------------------------------- # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. # import os -# import sys -import shutil +import sys import time +from importlib import metadata +sys.path.insert(0, os.path.abspath('.')) + -import easydev -# sys.path.insert(0, os.path.abspath('.')) +# -- Project information ----------------------------------------------------- +project = 'pyndl' +author = "Konstantin Sering, Marc Weitz, David-Elias Künstle, Lennart Schneider & Elnaz Shafaei-Bajestan" +copyright = time.strftime('2017 - %Y ') + author -# -- General configuration ------------------------------------------------ +# -- General configuration --------------------------------------------------- -# If your documentation needs a minimal Sphinx version, state it here. -# -# needs_sphinx = '1.0' +# Set master doc name +master_doc = 'index' # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = ['sphinx.ext.autodoc', - 'sphinx.ext.doctest', - 'sphinx.ext.intersphinx', - 'sphinx.ext.todo', - 'sphinx.ext.coverage', - 'sphinx.ext.mathjax', - 'sphinx.ext.ifconfig', - 'sphinx.ext.viewcode', - 'numpydoc', - 'easydev.copybutton', - ] - -if os.path.isdir('_static') == False: - os.mkdir('_static') - -# Add copy button -jscopybutton_path = easydev.copybutton.get_copybutton_path() -shutil.copy(jscopybutton_path, '_static') + 'sphinx.ext.doctest', + 'sphinx.ext.intersphinx', + 'sphinx.ext.todo', + 'sphinx.ext.coverage', + 'sphinx.ext.mathjax', + 'sphinx.ext.ifconfig', + 'sphinx.ext.viewcode', + 'numpydoc', + 'easydev.copybutton', + ] # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] -# The suffix(es) of source filenames. -# You can specify multiple suffix as a list of string: -# -# source_suffix = ['.rst', '.md'] -source_suffix = '.rst' - -# The master toctree document. -master_doc = 'index' - -# General information about the project. -pkg = __import__('pyndl') -project = 'pyndl' -author = pkg.__author__ -copyright = time.strftime('2017 - %Y ') + pkg.__author__ - -# The version info for the project you're documenting, acts as replacement for -# |version| and |release|, also used in various other places throughout the -# built documents. -# -# The short X.Y version. -version = "v" + pkg.__version__ -# The full version, including alpha/beta/rc tags. -release = "v" + pkg.__version__ - -# The language for content autogenerated by Sphinx. Refer to documentation -# for a list of supported languages. -# -# This is also used if you do content translation via gettext catalogs. -# Usually you set "language" from the command line for these cases. -language = None - # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. -# This patterns also effect to html_static_path and html_extra_path +# This pattern also affects html_static_path and html_extra_path. exclude_patterns = [] -# The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' -# If true, `todo` and `todoList` produce output, else they produce nothing. -todo_include_todos = False - - -# -- Options for HTML output ---------------------------------------------- +# -- Options for HTML output ------------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. # html_theme = 'sphinx_rtd_theme' - # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ['_static'] -html_context = { -"display_github": True, # Add 'Edit on Github' link instead of 'View page source' -"github_user": 'quantling', -"github_repo": 'pyndl', -"github_version": 'master', -"conf_py_path": '/doc/source/' -} - - -# -- Options for HTMLHelp output ------------------------------------------ - -# Output file base name for HTML help builder. -htmlhelp_basename = 'pyndldoc' - - -# -- Options for LaTeX output --------------------------------------------- - -latex_elements = { - # The paper size ('letterpaper' or 'a4paper'). - # - # 'papersize': 'letterpaper', - - # The font size ('10pt', '11pt' or '12pt'). - # - # 'pointsize': '10pt', - - # Additional stuff for the LaTeX preamble. - # - # 'preamble': '', - - # Latex figure (float) alignment - # - # 'figure_align': 'htbp', -} - -# Grouping the document tree into LaTeX files. List of tuples -# (source start file, target name, title, -# author, documentclass [howto, manual, or own class]). -latex_documents = [ - (master_doc, 'pyndl.tex', 'pyndl Documentation', - 'Künstle, Schneider, Sering, Weitz', 'manual'), -] - - -# -- Options for manual page output --------------------------------------- - -# One entry per manual page. List of tuples -# (source start file, name, description, authors, manual section). -man_pages = [ - (master_doc, 'pyndl', 'pyndl Documentation', - [author], 1) -] - - -# -- Options for Texinfo output ------------------------------------------- - -# Grouping the document tree into Texinfo files. List of tuples -# (source start file, target name, title, author, -# dir menu entry, description, category) -texinfo_documents = [ - (master_doc, 'pyndl', 'pyndl Documentation', - author, 'pyndl', 'One line description of project.', - 'Miscellaneous'), -] +html_context = {"display_github": True, # Add 'Edit on Github' link instead of 'View page source' + "github_user": 'quantling', + "github_repo": 'pyndl', + "github_version": 'master', + "conf_py_path": '/doc/source/' + } diff --git a/doc/source/development.rst b/doc/source/development.rst index 00de46c..c3ed752 100644 --- a/doc/source/development.rst +++ b/doc/source/development.rst @@ -1,10 +1,10 @@ Development =========== -.. image:: https://travis-ci.com/quantling/pyndl.svg?branch=master - :target: https://travis-ci.com/quantling/pyndl?branch=master +.. image:: https://github.com/quantling/pyndl/actions/workflows/python-test.yml/badge.svg?branch=master + :target: https://github.com/quantling/pyndl/actions/workflows/python-test.yml -.. image:: https://coveralls.io/repos/github/quantling/pyndl/badge.svg?branch=master - :target: https://coveralls.io/github/quantling/pyndl?branch=master +.. image:: https://codecov.io/gh/quantling/pyndl/branch/master/graph/badge.svg?token=2GWUXRA9PD + :target: https://codecov.io/gh/quantling/pyndl .. image:: https://img.shields.io/lgtm/grade/python/g/quantling/pyndl.svg?logo=lgtm&logoWidth=18 :target: https://lgtm.com/projects/g/quantling/pyndl/context:python @@ -39,14 +39,13 @@ Workflow 1. Fork this repository on Github. From here on we assume you successfully forked this repository to https://github.com/yourname/pyndl.git -2. Get a local copy of your fork and install the package in 'development' - mode, which will make changes in the source code active immediately, by running +2. Install all dependencies with poetry (https://python-poetry.org/) .. code:: bash git clone https://github.com/yourname/pyndl.git cd pyndl - python setup.py develop --user + poetry install 3. Add code, tests or documentation. @@ -54,8 +53,8 @@ Workflow .. code:: bash - make checkstyle - make test + poetry run pytest + poetry run pylint pyndl 5. Add and commit your changes after tests run through without complaints. @@ -78,46 +77,44 @@ Workflow click "New pull request" to submit your Pull Request to https://github.com/quantling/pyndl. -.. note:: - - If you want to develop *pyndl* you should have installed: - - .. code:: bash - - pip install --user tox pylint pytest pycodestyle sphinx - Running tests ------------- -We use ``make`` and ``tox`` to manage testing. You can run the tests by +We use ``poetry`` to manage testing. You can run the tests by executing the following within the repository's root folder (``pyndl/``): .. code:: bash - make test + poetry run pytest -For manually checking coding guidelines run: +For extensive, time and memory consuming tests run (at least 12 GB of free +memory should be available): .. code:: bash - make checkstyle + poetry run pytest --run-slow -There is an additional way to invoke ``pylint`` as a linter with tox by running +For manually checking coding guidelines run: .. code:: bash - tox -e lint + poetry run pylint pyndl The linting gives still a lot of complaints that need some decisions on how to fix them appropriately. +.. note:: + + Previous versions of *pyndl* used ``make`` and ``tox`` to manage testing. For + documentation on this, please check the respective version documentations + Local testing with conda ------------------------ Sometimes it might be useful to test if ``pyndl`` works in a clean python -environment. Besides ``tox`` this is possible with ``conda`` as well. The +environment. Besides ``poetry`` this is possible with ``conda`` as well. The commands are as follows: .. code:: bash @@ -201,26 +198,27 @@ Some sources with more explanation: Building documentation ---------------------- -Building the documentation requires some extra dependencies. Therefore, run +Building the documentation requires some extra dependencies. Usually, these are +installed when installing the dependencies with poetry. Some services like Readthedocs, +however, require the documentation dependencies extra. For that reason, they can +also be found in `doc/requirements.txt`. For normal usage, installing all dependencies +with poetry is sufficient. -.. code:: bash +The projects documentation is stored in the ``pyndl/doc/`` folder +and is created with ``sphinx``. However, it is not necessary to build the documentation +from there. - pip install -e .[docs] - -in the project root directory. This command will install all required -dependencies. The projects documentation is stored in the ``pyndl/doc/`` folder -and is created with ``sphinx``. You can rebuild the documentation by either -executing +You can rebuild the documentation by either executing .. code:: bash - make documentation + poetry run sphinx-build -b html doc/source doc/build/html in the repository's root folder (``pyndl``) or by executing .. code:: bash - make html + poetry run make html in the documentation folder (``pyndl/doc/``). @@ -230,24 +228,24 @@ Continuous Integration We use several services in order to continuously monitor our project: -=========== =========== ================= =========================== -Service Status Config file Description -=========== =========== ================= =========================== -Travis CI |travis| `.travis.yml`_ Automated testing -Coveralls |coveralls| Monitoring of test coverage -LGTM |lgtm| Monitoring code quality -=========== =========== ================= =========================== +=============== =========== ================== =========================== +Service Status Config file Description +=============== =========== ================== =========================== +Github Actions |actions| `python-test.yml`_ Automated testing +Codecov |codecov| Monitoring of test coverage +LGTM |lgtm| Monitoring code quality +=============== =========== ================== =========================== -.. |travis| image:: https://travis-ci.com/quantling/pyndl.svg?branch=master - :target: https://travis-ci.com/quantling/pyndl?branch=master +.. |actions| image:: https://github.com/quantling/pyndl/actions/workflows/python-test.yml/badge.svg?branch=master + :target: https://github.com/quantling/pyndl/actions/workflows/python-test.yml -.. |coveralls| image:: https://coveralls.io/repos/github/quantling/pyndl/badge.svg?branch=master - :target: https://coveralls.io/github/quantling/pyndl?branch=master +.. |codecov| image:: https://codecov.io/gh/quantling/pyndl/branch/master/graph/badge.svg?token=2GWUXRA9PD + :target: https://codecov.io/gh/quantling/pyndl .. |lgtm| image:: https://img.shields.io/lgtm/grade/python/g/quantling/pyndl.svg?logo=lgtm&logoWidth=18 :target: https://lgtm.com/projects/g/quantling/pyndl/context:python -.. _.travis.yml: https://github.com/quantling/pyndl/blob/master/.travis.yml +.. _python-test.yml: https://github.com/quantling/pyndl/blob/master/.github/workflows/python-test.yml Licensing @@ -262,8 +260,13 @@ request for another license is made and agreed on. Release Process --------------- -1. Ensure, that the version of the branch to be mered, is adequately increased - see Versioning_ below. +1. Update the version accordingly to Versioning_ below. This can be easily done + by poetry running + + .. code:: bash + + poetry version major|minor|patch|... + 2. Merge Pull Requests with new features or bugfixes into *pyndl*'s' ``master`` branch. @@ -280,20 +283,13 @@ Release Process git pull git checkout vX.Y.Z - python setup.py build # to compile *.pyx -> *.c - python setup.py sdist + poetry build -5. Create GPG signatures of the distribution files using: +5. (maintainers only) Publish the builds to PyPI. .. code:: bash - gpg --detach-sign -a dist/pyndl-X.Y.Z.tar.gz - -6. (maintainers only) Upload the distribution files to PyPI using twine. - -.. code:: bash - - twine upload -s dist/* + poetry publish 7. (maintainers only) Check if the new version is on pypi (https://pypi.python.org/pypi/pyndl/). @@ -330,4 +326,3 @@ pull request which only contains the following two changes: - the change of the version number from ``X.Y.Z`` to ``X+1.0.0`` - remove all the API with deprecation warning introduced in the current ``X.Y.Z`` release - diff --git a/doc/source/examples.rst b/doc/source/examples.rst index 3fcc755..3f06321 100644 --- a/doc/source/examples.rst +++ b/doc/source/examples.rst @@ -105,9 +105,10 @@ pyndl.ndl.ndl :py:mod:`pyndl.ndl.ndl` is a parallel Python implementation using numpy, multithreading and a binary format which is created automatically. It allows you to choose between the two methods ``openmp`` and ``threading``, with the -former one using `openMP `_ and therefore being expected -to be much faster when analyzing larger data. Besides, you can set three -technical arguments which we will not change here: +former one using `openMP `_ and therefore being +expected to be faster when analyzing larger data. Unfortunately, ``openmp`` is +only available on Linux right now, therefore all examples use ``threading``. +Besides, you can set three technical arguments which we will not change here: 1. ``n_jobs`` (int) giving the number of threads in which the job should be executed (default=2) @@ -123,7 +124,7 @@ Let's start: >>> from pyndl import ndl >>> weights = ndl.ndl(events='doc/data/lexample.tab.gz', alpha=0.1, - ... betas=(0.1, 0.1), method='openmp') + ... betas=(0.1, 0.1), method='threading') >>> weights # doctest: +ELLIPSIS ... @@ -165,7 +166,7 @@ weight matrix by specifying the ``weight`` argument: .. code-block:: python >>> weights2 = ndl.ndl(events='doc/data/lexample.tab.gz', alpha=0.1, - ... betas=(0.1, 0.1), method='openmp', weights=weights) + ... betas=(0.1, 0.1), method='threading', weights=weights) >>> weights2 # doctest: +ELLIPSIS array([[ 0.24... diff --git a/doc/source/index.rst b/doc/source/index.rst index 4d6f1b2..bd34908 100644 --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -1,7 +1,5 @@ -.. pyndl documentation master file, created by - sphinx-quickstart on Thu Jan 26 17:28:31 2017. - You can adapt this file completely to your liking, but it should at least - contain the root `toctree` directive. +.. automodule:: pyndl + :noindex: .. toctree:: :maxdepth: 2 diff --git a/doc/source/quickstart.rst b/doc/source/quickstart.rst index 182673c..781aac3 100644 --- a/doc/source/quickstart.rst +++ b/doc/source/quickstart.rst @@ -205,6 +205,17 @@ to load a in netCDF format saved matrix: > nc_close(nc = weights_nc) > rm(weights_nc) +Clean up +-------- + +In order to keep everything clean we might want to remove all the files we +created in this tutorial: + +.. code-block:: python + + >>> import os + >>> os.remove('doc/data/levent.tab.gz') + .. _lexample.tab.gz: https://github.com/quantling/pyndl/blob/master/doc/data/lexample.tab.gz diff --git a/pyndl/__init__.py b/pyndl/__init__.py index bbdd8d0..e2043c1 100644 --- a/pyndl/__init__.py +++ b/pyndl/__init__.py @@ -20,31 +20,12 @@ except ModuleNotFoundError: # this should only happend during setup phase Requirement = None - -__author__ = ('Konstantin Sering, Marc Weitz, ' - 'David-Elias Künstle, Lennard Schneider, ' - 'Elnaz Shafaei-Bajestan') -__author_email__ = 'konstantin.sering@uni-tuebingen.de' -__version__ = '0.8.2' -__license__ = 'MIT' -__description__ = ('Naive discriminative learning implements learning and ' - 'classification models based on the Rescorla-Wagner ' - 'equations.') -__classifiers__ = [ - 'Development Status :: 4 - Beta', - 'Environment :: Console', - 'Intended Audience :: Science/Research', - 'License :: OSI Approved :: MIT License', - 'Operating System :: POSIX :: Linux', - 'Operating System :: MacOS', - 'Programming Language :: Python', - 'Programming Language :: Python :: 3.8', - 'Programming Language :: Python :: 3.9', - 'Programming Language :: Python :: 3 :: Only', - 'Topic :: Scientific/Engineering', - 'Topic :: Scientific/Engineering :: Artificial Intelligence', - 'Topic :: Scientific/Engineering :: Information Analysis', - ] +try: + from importlib import metadata + __version__ = metadata.version(__package__) +except metadata.PackageNotFoundError: + import toml + __version__ = toml.load("pyproject.toml")["tool"]["poetry"]["version"] + "dev" def sysinfo(): diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..9d5647f --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,73 @@ +[tool.poetry] +name = "pyndl" +version = "1.0.0-beta" +description = "Naive discriminative learning implements learning and classification models based on the Rescorla-Wagner equations." + +license = "MIT" + +authors = ["Konstantin Sering ", + "Marc Weitz", + "David-Elias Künstle", + "Lennard Schneider", + "Elnaz Shafaei-Bajestan" + ] + +readme = "README.rst" # Markdown files are supported + +repository = "https://github.com/quantling/pyndl" +homepage = "https://pyndl.readthedocs.io/en/latest/" + +classifiers = ['Development Status :: 4 - Beta', + 'Environment :: Console', + 'Intended Audience :: Science/Research', + 'Operating System :: POSIX :: Linux', + 'Operating System :: MacOS', + 'Topic :: Scientific/Engineering', + 'Topic :: Scientific/Engineering :: Artificial Intelligence', + 'Topic :: Scientific/Engineering :: Information Analysis',] + +build = "build.py" + +[tool.poetry.dependencies] +python = ">=3.8,<3.12" # Compatible python versions must be declared here +numpy = "^1.23.1" +scipy = "^1.9.0" +pandas = "^1.4.3" +xarray = "^2022.6.0" +netCDF4 = "^1.6.0" +Cython = "^0.29.32" + +[tool.poetry.dev-dependencies] +pytest = "^7.0" +pytest-cov = "^2.4" +pydocstyle = "^6.1.1" +flake8 = "^4.0.1" +sphinx = "^1.4" +sphinx_rtd_theme = "1.0.0" +notebook = "^6.4.10" +seaborn = "^0.11.2" +numpydoc = "1.2" +easydev = "0.9.35" +pylint = "^2.0.0" +nbsphinx = "0.8.8" +vulture = "^2.3" +Jinja2 = "<3.1.0" + +[tool.pytest.ini_options] +addopts = '--doctest-glob "*.rst"' + +[tool.pylint] + [tool.pylint.basic] + good-names = ["nn", "ii", "_", "jj", "df"] + extension-pkg-whitelist = ["numpy", "pyndl.ndl_parallel", "pyndl/ndl_openmp"] + ignore = ["pyndl/ndl_parallel", "pyndl/ndl_openmp"] + + [tool.pylint.format] + max-line-length = 120 + + [tool.pylint.message_control] + disable = "E1101" + +[build-system] +requires = ["poetry>=1.0.0", "setuptools", "Cython", "numpy"] +build-backend = "poetry.masonry.api" diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index c5d1a52..0000000 --- a/requirements.txt +++ /dev/null @@ -1,8 +0,0 @@ -numpy>=1.8.2 -scipy>=1.5.4 -cython>=0.21.1 -pandas>=0.14.1 -xarray>=0.7.2 -netCDF4>=1.3.1 -pip>=9.0.1 -packaging>=20.0 diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index 3dcc50d..0000000 --- a/setup.cfg +++ /dev/null @@ -1,13 +0,0 @@ -[pycodestyle] -ignore = -max-line-length = 120 - -[pylint] -max-line-length = 120 -good-names = nn, ii, _, jj, df -extension-pkg-whitelist=numpy,pyndl.ndl_parallel,pyndl/ndl_openmp -ignore=pyndl/ndl_parallel,pyndl/ndl_openmp -disable=E1101 - -[aliases] -test=pytest diff --git a/tests/test_activation.py b/tests/test_activation.py index 2d6361b..0d3caca 100644 --- a/tests/test_activation.py +++ b/tests/test_activation.py @@ -36,6 +36,7 @@ def test_exceptions(): assert e_info == "Weights other than xarray.DataArray or dicts are not supported." +@pytest.mark.nolinux def test_activation_matrix(): weights = xr.DataArray(np.array([[0, 1, 0], [1, 0, 0]]), coords={ @@ -60,6 +61,7 @@ def test_activation_matrix(): assert np.allclose(reference_activations, activations_mp) +@pytest.mark.nolinux def test_ignore_missing_cues(): weights = xr.DataArray(np.array([[0, 1, 0], [1, 0, 0]]), coords={ diff --git a/tox.ini b/tox.ini deleted file mode 100644 index 40641f9..0000000 --- a/tox.ini +++ /dev/null @@ -1,71 +0,0 @@ -[tox] -envlist = py{38,39}-test, checkstyle, documentation - -[testenv] -usedevelop = True -whitelist_externals=rm -deps = - test: pytest - -rrequirements.txt -commands = - py.test --doctest-glob "*.rst" - rm doc/data/levent.tab.gz - -[testenv:nolinux] -usedevelop = True -deps = - pytest - -rrequirements.txt -commands = - py.test -m "not nolinux" - -[testenv:testdoc] -usedevelop = True -whitelist_externals=rm -deps = - pytest -commands = - py.test doc/ --doctest-glob "*.rst" - rm doc/data/levent.tab.gz - -[testenv:checkstyle] -deps = pycodestyle -commands = pycodestyle pyndl tests - -[testenv:travis] -usedevelop = True -passenv = TRAVIS TRAVIS_JOB_ID TRAVIS_BRANCH -whitelist_externals=rm -deps = - mock - pytest - pytest-runner - sh - coveralls -commands = - coverage run --source=pyndl setup.py test - coveralls - py.test doc/ --doctest-glob "*.rst" - rm doc/data/levent.tab.gz - -[testenv:lint] -deps = - pylint>=1.7.1 - pytest -commands = pylint [] --ignore-patterns='.*\.so' --rcfile=setup.cfg -j 2 pyndl tests -ignore_outcome = True - -[testenv:checktypes] -deps = mypy -setenv = - MYPYPATH=./stubs/ -commands = mypy --ignore-missing-imports pyndl -ignore_outcome = True - -[testenv:documentation] -usedevelop = True -changedir = doc -whitelist_externals=make -extras = docs -commands = - make html