Skip to content

Commit

Permalink
PDM, Nox and Meson (#51)
Browse files Browse the repository at this point in the history
* Use PDM

* Simple Nox file

* No Python 3.8

* Tiny Makefile for dev + pdm lock

* Meson!

* Make Ruff happier

* docs/dev-install.md

* style: double quotes in pyproject.toml

* build: use nox in github actions

* nox --force-python for micromamba

* CI build doc

* CI: install gdal with mamba-org/setup-micromamba

---------

Co-authored-by: Martí Bosch <[email protected]>
  • Loading branch information
paugier and martibosch authored Aug 1, 2024
1 parent e754588 commit 4c3955a
Show file tree
Hide file tree
Showing 21 changed files with 3,280 additions and 96 deletions.
23 changes: 23 additions & 0 deletions .github/workflows/doc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
name: Documentation

on:
- push
- pull_request

jobs:
build:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Install PDM and Nox
run: |
pip install pdm nox
- name: Build doc
run: |
nox -s doc
16 changes: 10 additions & 6 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
strategy:
matrix:
os: [ubuntu-latest]
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
python-version: ["3.9", "3.10", "3.11", "3.12"]
include:
- os: macos-latest
python-version: "3.12"
Expand All @@ -33,14 +33,18 @@ jobs:
create-args: >-
python=${{ matrix.python-version }}
pip
gdal>=3.3
- name: install dependencies
run: pip install tox tox-gh-actions
run: pip install pdm nox

- name: test with tox
run: tox
env:
CONDA_EXE: mamba
- name: Build wheel
run: |
nox -s wheel
- name: test with nox
run: |
nox --force-python ${{ matrix.python-version }} -s test
- name: upload coverage reports to Codecov
uses: codecov/codecov-action@v3
Expand Down
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -113,3 +113,8 @@ output/
# Transonic
__pythran__
__numba__
__python__

# PDM
.pdm-python
.nox
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,4 @@ Before you submit a pull request, check that it meets these guidelines:

1. The pull request should include tests.
1. If the pull request adds functionality, the docs should be updated. Put your new functionality into a function with a docstring, and add the feature to the list in README.md.
1. The pull request should work for Python 2.7 and 3.6, as well as for PyPy. Check https://travis-ci.org/martibosch/pylandstats/pull_requests and make sure that the tests pass for all supported Python versions.
1. The pull request should work for Python >=3.9, as well as for PyPy. Check https://travis-ci.org/martibosch/pylandstats/pull_requests and make sure that the tests pass for all supported Python versions.
15 changes: 15 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@

install:
pdm sync

lock:
pdm lock

test:
pdm test

build_doc:
nox -s doc -R

test_in_nox_env:
nox -s test
1 change: 1 addition & 0 deletions docs/changelog.md
1 change: 0 additions & 1 deletion docs/changelog.rst

This file was deleted.

3 changes: 2 additions & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
"m2r2",
"sphinx.ext.napoleon",
"sphinx.ext.autodoc",
"sphinx.ext.viewcode",
"sphinx.ext.imgmath",
"myst_nb",
]

# List of patterns, relative to source directory, that match files and
Expand Down Expand Up @@ -56,6 +56,7 @@
"github_url": "https://github.com/martibosch/pylandstats",
"twitter_url": "https://twitter.com/mortybosch",
"pygment_light_style": "tango",
"navigation_with_keys": False,
}

# exclude patterns from sphinx-build
Expand Down
1 change: 1 addition & 0 deletions docs/contributing.md
1 change: 0 additions & 1 deletion docs/contributing.rst

This file was deleted.

29 changes: 29 additions & 0 deletions docs/dev-install.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Setup a development environment

Once [PDM] and [Nox] are installed, it is very easy to setup a development environment for
PyLandStats. On most systems, one can install PDM and Nox with [Pipx], with something like:

```sh
python3 -m pip install pipx
python3 -m pipx ensurepath
```

and then in a new terminal:

```sh
pipx install pdm
pipx install nox
```

Once PDM is installed, clone the PyLandStats repo and run `make` from the root
directory. This should install a dedicated local virtual environment `.venv`.
You can then activate it and run the tests.

Note that there are few other targets in the `Makefile` useful for developers. In
particular, it is good to periodically recompute the dependencies written in
the `pdm.lock` file (with `make lock`) to check if new packages uploaded on PyPI
do not break PyLandStats. It is reasonable to do this in a dedicated PR.

[nox]: https://nox.thea.codes
[pdm]: https://pdm-project.org
[pipx]: https://github.com/pypa/pipx
4 changes: 3 additions & 1 deletion docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ Open-source library to compute landscape metrics in the Python ecosystem (NumPy,
:maxdepth: 1
:caption: Development:

dev-install
changelog
contributing

Expand All @@ -41,14 +42,15 @@ which will install PyLandStats and all of its dependencies. Alternatively, you c

$ pip install pylandstats


Nevertheless, note that the `BufferAnalysis` and `SpatioTemporalBufferAnalysis` classes make use of `geopandas <https://github.com/geopandas/geopandas>`_, which cannot be installed with pip. If you already have `the dependencies for geopandas <https://geopandas.readthedocs.io/en/latest/install.html#dependencies>`_ installed in your system, you might then install PyLandStats with the `geo` extras as in:

$ pip install pylandstats[geo]

and you will be able to use the `BufferAnalysis` and `SpatioTemporalBufferAnalysis` classes (without having to use conda).




Indices and tables
==================
* :ref:`genindex`
Expand Down
67 changes: 67 additions & 0 deletions meson.build
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
project(
'pylandstats',
'cpp',
license: 'GPL-3.0-or-later',
meson_version: '>= 1.1.0',
default_options: [
'buildtype=release',
'cpp_std=c++11',
],
)

# https://mesonbuild.com/Python-module.html
py_mod = import('python')
py = py_mod.find_installation('python3', pure: false)
py_dep = py.dependency()

backend = get_option('transonic-backend')

if backend.contains(',')
backends = backend.split(',')
else
backends = [backend]
endif

use_pythran = backend.contains('pythran')
if use_pythran
incdir_numpy = run_command('transonic-get-include', 'numpy', check: true).stdout().strip()
inc_np = include_directories(incdir_numpy)
np_dep = declare_dependency(include_directories: inc_np)

incdir_pythran = run_command('transonic-get-include', 'pythran', check: true).stdout().strip()
pythran = find_program('pythran', native: true)

cpp_args_pythran = [
'-DENABLE_PYTHON_MODULE',
'-D__PYTHRAN__=3',
'-DPYTHRAN_BLAS_NONE'
]

if get_option('use-xsimd') == true
# xsimd is unvendored from pythran by conda-forge, and due to a compiler
# activation bug the default <prefix>/include/ may not be visible (see
# gh-15698). Hence look for xsimd explicitly.
xsimd_dep = dependency('xsimd', required: false)
pythran_dep = declare_dependency(
include_directories: incdir_pythran,
dependencies: xsimd_dep,
)
cpp_args_pythran += ['-DUSE_XSIMD']
else
pythran_dep = declare_dependency(
include_directories: incdir_pythran,
)
endif

pythran_complex_hook = get_option('pythran-complex-hook')
if pythran_complex_hook == 'os-dependent'
pythran_complex_hook = host_machine.system() == 'linux'
endif

if get_option('native')
cpp_args_pythran += ['-march=native', '-Ofast']
endif

endif

subdir('pylandstats')
27 changes: 27 additions & 0 deletions meson.options
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
option(
'transonic-backend',
type: 'string',
value: 'pythran,python,numba',
description:
'pythran,python,numba (default), cython, numpy, numba; ' +
'or comma separated value representing multi-backends',
)
option(
'native',
type: 'boolean',
value: false,
description: 'Performance oriented and not portable build',
)
option(
'use-xsimd',
type: 'boolean',
value: true,
description: 'Turns on xsimd vectorization',
)
option(
'pythran-complex-hook',
type: 'combo',
choices: ['os-dependent', 'true', 'false'],
value: 'os-dependent',
description: 'Pythran complex_hook option',
)
62 changes: 62 additions & 0 deletions noxfile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
"""Task runner for the developer.
# Usage
```
nox -l # list of sessions.
nox -s <session> # execute a session
nox -k <keyword> # execute some session
```
"""

import os

import nox

os.environ.update({"PDM_IGNORE_SAVED_PYTHON": "1"})
nox.options.reuse_existing_virtualenvs = 1


@nox.session
def doc(session):
"""Build the documentation in a Nox environment."""
command = "pdm sync --clean -G doc --no-self"
session.run_install(*command.split(), external=True)

# for documentation, we don't need the other backends
command = "pip install . -C setup-args=-Dtransonic-backend=python"
session.run_install(*command.split(), external=True)

session.run("sphinx-build", "docs", "docs/_build")
print(f"file://{os.getcwd()}/docs/_build/index.html")


@nox.session
def wheel(session):
"""Build the wheel."""
session.install("build", "twine")
session.run("python", "-m", "build")
session.run("twine", "check", "dist/*")


@nox.session(venv_backend="mamba|micromamba|conda")
def test(session):
"""Run the test in a Nox environment."""
command = "pdm sync --clean --prod -G test --no-self"
session.run_install(*command.split(), external=True)

# session.conda_install("gdal>=3.3", channel=["conda-forge"])
session.install(".", "--no-deps", external=True)

session.run(
"pytest",
"-v",
"-s",
"--cov=pylandstats",
"--cov-append",
"--cov-report=xml",
"--cov-report",
"term-missing",
"tests",
)
Loading

0 comments on commit 4c3955a

Please sign in to comment.