Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Poetry setup for PyElastica (#101) #141

Merged
merged 18 commits into from
Jul 19, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .coveragerc
Original file line number Diff line number Diff line change
@@ -8,7 +8,7 @@ exclude_lines =
def __repr__
from
import
show_missing = true

[run]
branch = True
@@ -20,6 +20,7 @@ omit =
elastica/systems/analytical.py
# omit deprecation warning message
elastica/_elastica_numpy.py
elastica/_elastica_numba.py
# omit experimental modules
elastica/experimental/*
setup.py
18 changes: 7 additions & 11 deletions .github/workflows/ci-sphinx.yml
Original file line number Diff line number Diff line change
@@ -22,11 +22,13 @@ jobs:
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v3

- name: Set up Python
uses: actions/[email protected]
- name: Setup Poetry
uses: Gr1N/setup-poetry@v7
with:
python-version: "3.x"
poetry-preview: false
- name: Export requirements file for sphinx
run: |
poetry export -E docs --without-hashes -f requirements.txt --output docs/requirements.txt
- name: Sphinx Build
# You may pin to the exact commit or the version.
@@ -36,10 +38,4 @@ jobs:
# The folder containing your sphinx docs.
docs-folder: docs/
# The command used to build your documentation.
build-command: make html SPHINXOPTS+="-W --keep-going" # -n"
# Run before the build command, you can use this to install system level dependencies, for example with "apt-get update -y && apt-get install -y perl"
pre-build-command: |
pwd
python --version
pip install -r requirements.txt
pip install -r docs/requirements.txt
build-command: make html #"-W --keep-going" # -n"
144 changes: 73 additions & 71 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
@@ -1,110 +1,112 @@
# This is a basic workflow to help you get started with Actions

name: CI

# Controls when the action will run. Triggers the workflow on push request
# events for the master branch, and pull request events for all branches.
on:
push:
branches: [ master ]
pull_request:
branches: [ '**' ]
# Controls when the action will run.
on: [push, pull_request]
# Older settings:
# Triggers the workflow on push request events for the master branch,
# and pull request events for all branches.
#on:
# push:
# branches: [ master ]
# pull_request:
# branches: [ '**' ]

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
# This workflow contains a single job called "build"
build:
# The type of runner that the job will run on
runs-on: ${{ matrix.os }} #ubuntu-latest

runs-on: ${{ matrix.os }}
strategy:
matrix:
python-version: ["3.7", "3.8", "3.9", "3.10"]
os: [ubuntu-latest, macos-latest] #, windows-latest] # Run macos tests if really required, since they charge 10 times more for macos
python-version: [3.6, 3.7, 3.8]

include:
- os: ubuntu-latest
path: ~/.cache/pip
- os: macos-latest
path: ~/Library/Caches/pip
# - os: windows-latest
# path: ~\AppData\Local\pip\Cache
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v2

# Ref: https://docs.github.com/en/free-pro-team@latest/actions/guides/building-and-testing-python
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
uses: actions/setup-python@v2.2.2
with:
python-version: ${{ matrix.python-version }}

# You can test your matrix by printing the current Python version
- name: Display Python version
run: python -c "import sys; print(sys.version)"

# Cache the pip requirmenets for other tests. If requirements cached use them to speed up the build.
# Ref: https://github.com/actions/cache/blob/main/examples.md#python---pip
- name: Cache pip Linux
uses: actions/cache@v2
if: startsWith(runner.os, 'Linux')
# Install Poetry and dependencies
- name: Install Poetry
uses: snok/install-poetry@v1
- name: Set up cache
uses: actions/cache@v3
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
path: ${{ matrix.path }}
key: ${{ runner.os }}-pip-${{ matrix.python-version }}-${{ hashFiles('pyproject.toml') }}-${{ hashFiles('poetry.lock') }}
restore-keys: |
${{ runner.os }}-pip-
- name: Cache pip MacOS
uses: actions/cache@v2
if: startsWith(runner.os, 'macOS')
- name: Install dependencies
run: |
poetry config virtualenvs.in-project true
poetry install
# Runs a single command using the runners shell
- name: Welcome message
run: echo Hello, world! Welcome PyElastica Build, lets start testing!
# Run style checks (black and flake8)
- name: Run style checks
run: |
make check-codestyle
# Test PyElastica using pytest
- name: Run tests
run: |
make test
report-coverage: # Report coverage from python 3.8 and mac-os. May change later
runs-on: ${{ matrix.os }}
strategy:
matrix:
python-version: ["3.8"]
os: [macos-latest]
include:
- os: macos-latest
path: ~/Library/Caches/pip
steps:
- uses: actions/checkout@v2
- name: Set up Python ${{ matrix.python-version }}
uses: actions/[email protected]
with:
path: ~/Library/Caches/pip
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
restore-keys: |
${{ runner.os }}-pip-
- name: Cache pip Windows
uses: actions/cache@v2
if: startsWith(runner.os, 'Windows')
python-version: ${{ matrix.python-version }}
- name: Install Poetry
uses: snok/install-poetry@v1
- name: Set up cache
uses: actions/cache@v3
with:
path: ~\AppData\Local\pip\Cache
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
path: ${{ matrix.path }}
key: ${{ runner.os }}-pip-${{ matrix.python-version }}-${{ hashFiles('pyproject.toml') }}-${{ hashFiles('poetry.lock') }}
restore-keys: |
${{ runner.os }}-pip-
- name: Install dependencies
run: |
echo update pip
python -m pip install --upgrade pip
echo update requirments
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
echo update test requirements
if [ -f tests/requirements.txt ]; then pip install -r tests/requirements.txt; fi
# Runs a single command using the runners shell
- name: Welcome message
run: echo Hello, world! Welcome PyElastica Build, lets start testing!

# Formatting test with black and flake8
- name: Black and Flake8 formatting tests
poetry config virtualenvs.in-project true
poetry install
- name: Run style checks
run: |
if [[ "${{ matrix.python-version }}" == "3.6" ]]; then
black --version
black --check elastica tests
flake8 --version
flake8 elastica tests
fi
# Set environment variables for coverage test. Coverage test is done using python 3.6
make check-codestyle
# Set environment variables for coverage test.
# For the coverage test we disable numba jit compilation, since it prevents generating coverage data.
- name: Set environment variables for coverage test
run: |
if [[ "${{ matrix.python-version }}" == "3.6" ]]; then
echo "NUMBA_DISABLE_JIT=1" >> $GITHUB_ENV
fi
# Test Pyelastica using pytest
echo "NUMBA_DISABLE_JIT=1" >> $GITHUB_ENV
- name: Test PyElastica using pytest
if: startsWith(runner.os, 'macOS')
run: |
if [[ "${{ matrix.python-version }}" == "3.6" ]]; then
python3 -m pytest --cov=elastica --cov-report=xml
codecov
else
python3 -m pytest
fi
- name: Upload coverage reports to Codecov with GitHub Action
uses: codecov/codecov-action@v3
poetry run pytest -c pyproject.toml --cov=elastica --cov-report=xml
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v2
with:
token: ${{ secrets.CODECOV_TOKEN }}
token: ${{ secrets.CODECOV_TOKEN }}
7 changes: 4 additions & 3 deletions .github/workflows/publish-to-pypi.yml
Original file line number Diff line number Diff line change
@@ -13,12 +13,13 @@ jobs:
uses: actions/[email protected]
with:
python-version: "3.x"
- name: Install Poetry
uses: snok/[email protected]
- name: Build
run: |
python setup.py sdist
ls dist
poetry build
- name: Publish distribution 📦 to PyPI
if: startsWith(github.ref, 'refs/tags')
uses: pypa/gh-action-pypi-publish@master
with:
password: ${{ secrets.PYPI_API_TOKEN }}
password: ${{ secrets.PYPI_API_TOKEN }}
File renamed without changes.
42 changes: 28 additions & 14 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -33,15 +33,37 @@ The following is a set of guidelines for contributing to PyElastica. These are m

## Before I get started

### Installation and packages
### Setup development environment

Below are steps of how to setup development environment. We mainly use `poetry` to manage
the project, although most of the important commands will be provided in `Makefile`.

1. Clone!

First **create the fork repository and clone** to your local machine.
We provide [requirements.txt](requirements.txt) to include all the dependencies.

2. Virtual python workspace: `conda`, `pyenv`, or `venv`.

We recommend using python version above 3.8.0.

```bash
conda create --name pyelastica-dev
conda activate pyelastica-dev
conda install python==3.8
```

3. Setup [`poetry`](https://python-poetry.org) and `dependencies`!

```bash
$ pip install -r requirements.txt
make poetry-download
make install
```

> **Note:** Make sure that **PyElastica** is not installed using pip.
If you are planning to contribute on documentation, extra dependencies can be installed
using `poetry install -E docs`. The detail instruction is included
[here](https://github.com/GazzolaLab/PyElastica/blob/master/docs/README.md).

4. Now your working environment is set!

### Project workflow

@@ -116,7 +138,7 @@ Please follow these steps to have your contribution considered by the maintainer
In order to run pytest, run the following line from the top directory:

`
python3 -m pytest
make test
`

3. After you submit your pull request, verify that all status checks are passing <details><summary>What if the status checks are failing?</summary>If a status check is failing, and you believe that the failure is unrelated to your change, please leave a comment on the pull request explaining why you believe the failure is unrelated. A maintainer will re-run the status check for you. If we conclude that the failure was a false positive, then we will open an issue to track that problem with our status check suite.</details>
@@ -139,17 +161,9 @@ Ask any question about **how to use PyElastica and detail implementation** in th

We use [flake8](https://pypi.org/project/flake8/) and [Black](https://pypi.org/project/black/) for python style.

You can install flake8 using pip:

`pip install flake8==3.8.3`

You can install black using pip:

`pip install black`

In order to format the code:

`make all`
`make formatting`

> **Note:** Format/refactoring patches that are not anything substantial to the context or functionality will likely be rejected.
84 changes: 72 additions & 12 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,19 +1,79 @@
black:
@black --version
@black --required-version 21.12b0 elastica tests examples
#* Variables
PYTHON := python
PYTHONPATH := `pwd`

#* Poetry
.PHONY: poetry-download
poetry-download:
curl -sSL https://install.python-poetry.org/ | $(PYTHON) -

.PHONY: poetry-remove
poetry-remove:
curl -sSL https://install.python-poetry.org/ | $(PYTHON) - --uninstall

#* Installation
.PHONY: install
install:
poetry lock -n && poetry export --without-hashes > requirements.txt
poetry install -n

#* Formatters
.PHONY: black
black:
poetry run black --version
poetry run black --config pyproject.toml --required-version 21.12b0 elastica tests examples

black_check:
@black --version
@find . -maxdepth 3 -name '*.py'\
| while read -r src; do black --check "$$src"; done
.PHONY: black-check
black-check:
poetry run black --version
poetry run black --diff --check --config pyproject.toml elastica tests examples

.PHONY: flake8
flake8:
@flake8 --version
@flake8 elastica tests
poetry run flake8 --version
poetry run flake8 elastica tests

.PHONY: format-codestyle
format-codestyle: black flake8

.PHONY: test
test:
@python -m pytest
poetry run pytest --cov=elastica

.PHONY: check-codestyle
check-codestyle: black-check flake8

.PHONY: formatting
formatting: format-codestyle

.PHONY: update-dev-deps
update-dev-deps:
poetry add -D pytest@latest coverage@latest pytest-html@latest pytest-cov@latest black@latest

#* Cleaning
.PHONY: pycache-remove
pycache-remove:
find . | grep -E "(__pycache__|\.pyc|\.pyo$$)" | xargs rm -rf

.PHONY: dsstore-remove
dsstore-remove:
find . | grep -E ".DS_Store" | xargs rm -rf

.PHONY: ipynbcheckpoints-remove
ipynbcheckpoints-remove:
find . | grep -E ".ipynb_checkpoints" | xargs rm -rf

.PHONY: pytestcache-remove
pytestcache-remove:
find . | grep -E ".pytest_cache" | xargs rm -rf

.PHONY: build-remove
build-remove:
rm -rf build/

.PHONY: cleanup
cleanup: pycache-remove dsstore-remove ipynbcheckpoints-remove pytestcache-remove

all: format-codestyle cleanup test

all:black flake8
ci:black_check flake8
ci: check-codestyle
6 changes: 4 additions & 2 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -8,11 +8,13 @@ In addition, we utilize the following extensions to enhance the documentation :c

## Build documentation

The `sphinx` is already initialized in `docs` directory. In order to build the documentation, you will need additional packages listed in `docs/requirements.txt`.
The `sphinx` is already initialized in `docs` directory.
In order to build the documentation, you will need additional
packages listed in extra dependencies.

```bash
poetry install -E docs
cd docs
pip install -r requirements.txt
make clean
make html
```
10 changes: 0 additions & 10 deletions docs/requirements.txt

This file was deleted.

2 changes: 1 addition & 1 deletion elastica/boundary_conditions.py
Original file line number Diff line number Diff line change
@@ -476,7 +476,7 @@ def __init__(
twisting_time: float,
slack: float,
number_of_rotations: float,
**kwargs
**kwargs,
):
"""
4 changes: 2 additions & 2 deletions elastica/rod/cosserat_rod.py
Original file line number Diff line number Diff line change
@@ -228,7 +228,7 @@ def straight_rod(
nu: float,
youngs_modulus: float,
*args,
**kwargs
**kwargs,
):
"""
Cosserat rod constructor for straight-rod geometry.
@@ -320,7 +320,7 @@ def straight_rod(
nu,
youngs_modulus,
*args,
**kwargs
**kwargs,
)

return cls(
2 changes: 1 addition & 1 deletion elastica/timestepper/__init__.py
Original file line number Diff line number Diff line change
@@ -78,7 +78,7 @@ def integrate(
n_steps: int = 1000,
restart_time: float = 0.0,
progress_bar: bool = True,
**kwargs
**kwargs,
):
"""
Original file line number Diff line number Diff line change
@@ -144,7 +144,7 @@ def plot_video(
fps=60,
step=1,
*args,
**kwargs
**kwargs,
): # (time step, x/y/z, node)
import matplotlib.animation as manimation

Original file line number Diff line number Diff line change
@@ -98,7 +98,7 @@ def __init__(
twisting_time,
time_twis_start,
number_of_rotations,
**kwargs
**kwargs,
):
super().__init__(**kwargs)
self.twisting_time = twisting_time
Original file line number Diff line number Diff line change
@@ -95,7 +95,7 @@ def __init__(
twisting_time,
time_twis_start,
number_of_rotations,
**kwargs
**kwargs,
):
super().__init__(**kwargs)
self.twisting_time = twisting_time
3 changes: 0 additions & 3 deletions examples/optional-requirements.txt

This file was deleted.

1,367 changes: 1,367 additions & 0 deletions poetry.lock

Large diffs are not rendered by default.

109 changes: 109 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
# Poetry pyproject.toml: https://python-poetry.org/docs/pyproject/
[build-system]
requires = ["poetry_core>=1.0.0"]
build-backend = "poetry.core.masonry.api"

[tool.poetry]
name = "pyelastica"
version = "0.3.0"
description = "Elastica is a software to simulate the dynamics of filaments that, at every cross-section, can undergo all six possible modes of deformation, allowing the filament to bend, twist, stretch and shear, while interacting with complex environments via muscular activity, surface contact, friction and hydrodynamics."
readme = "README.md"
authors = ["GazzolaLab <armant2@illinois.edu>"]
license = "MIT"
repository = "https://github.com/GazzolaLab/PyElastica"
homepage = "https://www.cosseratrods.org/"
documentation = "https://docs.cosseratrods.org/en/latest/"
keywords = []

# Pypi classifiers: https://pypi.org/classifiers/
classifiers = [
# Trove classifiers
# Full list: https://pypi.python.org/pypi?%3Aaction=list_classifiers
"License :: OSI Approved :: MIT License",
"Development Status :: 3 - Alpha",
"Programming Language :: Python",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: Implementation :: CPython",
"Intended Audience :: Science/Research",
"Intended Audience :: Education",
]

# ...
packages = [
{ include = "elastica" }
]

[tool.poetry.dependencies]
python = ">=3.7,<3.11"
numba = "^0.55.0"
numpy = "^1.19.2"
scipy = "^1.5.2"
matplotlib = "^3.3.2"
tqdm = "^4.61.1"
# A list of all of the optional dependencies, some of which are included in the
# below `extras`. They can be opted into by apps.
Sphinx = {version = "^4.4.0", optional = true, extras = ["docs"]}
sphinx-book-theme = {version = "^0.3.2", optional = true, extras = ["docs"]}
readthedocs-sphinx-search = {version = "^0.1.1", optional = true, extras = ["docs"]}
sphinx-autodoc-typehints = {version = "^1.17.1", optional = true, extras = ["docs"]}
myst-parser = {version = "^0.17.2", optional = true, extras = ["docs"]}
numpydoc = {version = "^1.3.1", optional = true, extras = ["docs"]}
docutils = {version = "^0.17.1", optional = true, extras = ["docs"]}
cma = {version = "^3.2.2", optional = true, extras = ["examples"]}
ffmpeg = {version = "^1.4", optional = true, extras = ["examples"]}
moviepy = {version = "^1.0.3", optional = true, extras = ["examples"]}

[tool.poetry.dev-dependencies]
black = "21.12b0"
pytest = "^7.1.1"
coverage = "^6.3.3"
pytest-html = "^3.1.1"
pytest-cov = "^3.0.0"
flake8 = "3.8.3"
codecov = "^2.1"
click = "8.0.0"

[tool.poetry.extras]
docs = [
"sphinx",
"sphinx-book-theme",
"readthedocs-sphinx-search",
"sphinx-autodoc-typehints",
"myst-parser",
"numpydoc",
"docutils",
]
examples = [
"cma",
"ffmpeg",
"moviepy",
]

[tool.black]
# https://github.com/psf/black
target-version = ["py38"]
line-length = 88
color = true
exclude = '''
/(
\.git
| \.hg
| \.mypy_cache
| \.tox
| \.venv
| _build
| buck-out
| build
| dist
| env
| venv
)/
'''

[tool.pytest.ini_options]
# https://docs.pytest.org/en/6.2.x/customize.html#pyproject-toml
# Directories that are not visited by pytest collector:
norecursedirs =["hooks", "*.egg", ".eggs", "dist", "build", "docs", ".tox", ".git", "__pycache__"]
7 changes: 0 additions & 7 deletions requirements.txt

This file was deleted.

118 changes: 0 additions & 118 deletions setup.py

This file was deleted.

6 changes: 0 additions & 6 deletions tests/requirements.txt

This file was deleted.

4 changes: 2 additions & 2 deletions tests/test_rod_initialisation.py
Original file line number Diff line number Diff line change
@@ -103,7 +103,7 @@ def straight_rod(
youngs_modulus,
# poisson_ratio,
*args,
**kwargs
**kwargs,
):

(
@@ -155,7 +155,7 @@ def straight_rod(
youngs_modulus,
alpha_c=(27.0 / 28.0),
*args,
**kwargs
**kwargs,
)

return cls(