Skip to content
Merged
Show file tree
Hide file tree
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
106 changes: 106 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
name: CI

on:
push:
branches: [ main, master ]
pull_request:
branches: [ main, master ]

jobs:
pre-commit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.11"
- uses: pre-commit/action@v3.0.1

test:
runs-on: ubuntu-latest
strategy:
fail-fast: true
matrix:
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"]

steps:
- uses: actions/checkout@v4

- name: Install uv
uses: astral-sh/setup-uv@v4
with:
version: "latest"

- name: Set up Python ${{ matrix.python-version }}
run: uv python install ${{ matrix.python-version }}

- name: Install dependencies
run: |
uv sync --dev
# Install additional system dependencies for documentation
sudo apt-get update
sudo apt-get install -y graphviz

# - name: Lint with flake8
# run: |
# # Replicate: flake8 --doctests --exclude=doc, also exclude .venv
# uv run flake8 --doctests --exclude=doc,.venv

- name: Test with pytest
run: |
# Set matplotlib backend for headless testing
export MPLBACKEND=agg
# Run tests with pytest and coverage
uv run pytest --cov=pyunlocbox --cov-report=term-missing --cov-report=html --cov-report=xml -v

- name: Upload coverage to Coveralls
if: matrix.python-version == '3.11' # Only upload once
uses: coverallsapp/github-action@v2
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
file: coverage.xml
continue-on-error: true

- name: Build documentation
if: matrix.python-version == '3.11' # Only build docs once
run: |
# Replicate: sphinx-build commands from Makefile
uv run sphinx-build -b html -d doc/_build/doctrees doc doc/_build/html
uv run sphinx-build -b linkcheck -d doc/_build/doctrees doc doc/_build/linkcheck

- name: Upload documentation artifacts
if: matrix.python-version == '3.11'
uses: actions/upload-artifact@v4
with:
name: documentation
path: doc/_build/html/

# Separate job for building and checking distribution
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Install uv
uses: astral-sh/setup-uv@v4

- name: Set up Python
run: uv python install 3.11

- name: Install dependencies
run: uv sync --dev

- name: Build package
run: |
uv build
ls -lh dist/*

- name: Check package
run: |
uv run twine check dist/*

- name: Upload build artifacts
uses: actions/upload-artifact@v4
with:
name: dist
path: dist/
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
uv.lock
.venv/
coverage.xml
__pycache__/

# Packages
Expand Down
64 changes: 64 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
repos:
# Standard pre-commit hooks
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v5.0.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
- id: check-toml
- id: check-added-large-files
- id: check-merge-conflict
- id: debug-statements
- id: check-docstring-first

# Python code formatting with black
- repo: https://github.com/psf/black
rev: 24.10.0
hooks:
- id: black
language_version: python3
args: [--line-length=88]

# Import sorting with isort
- repo: https://github.com/pycqa/isort
rev: 5.13.2
hooks:
- id: isort
args: [--profile=black]

# Linting with flake8
- repo: https://github.com/pycqa/flake8
rev: 7.1.1
hooks:
- id: flake8
args: [--max-line-length=88, --extend-ignore=E203]
exclude: ^(doc/|\.venv/)

# Modern Python upgrade suggestions
- repo: https://github.com/asottile/pyupgrade
rev: v3.19.0
hooks:
- id: pyupgrade
args: [--py38-plus]

# Check for common security issues
- repo: https://github.com/pycqa/bandit
rev: 1.7.10
hooks:
- id: bandit
args: [-c, pyproject.toml]
additional_dependencies: ["bandit[toml]"]
exclude: ^tests/

ci:
autofix_commit_msg: |
[pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci
autofix_prs: true
autoupdate_branch: ''
autoupdate_commit_msg: '[pre-commit.ci] pre-commit autoupdate'
autoupdate_schedule: weekly
skip: []
submodules: false
50 changes: 27 additions & 23 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,24 +1,28 @@
language: python
# DEPRECATED: This project has migrated to GitHub Actions
# See .github/workflows/ci.yml for the new CI configuration
# This file is kept for reference and can be removed once migration is complete

python:
- 3.6
- 3.7
- 3.8
- 3.9

addons:
apt:
packages:
- graphviz # sphinx inheritance diagrams

install:
- pip install --upgrade pip setuptools wheel # install with latest tools
- pip install --upgrade --upgrade-strategy eager .[dev] # get latest deps

script:
- make lint
- make test
- make doc

after_success:
- coveralls
# language: python
#
# python:
# - 3.6
# - 3.7
# - 3.8
# - 3.9
#
# addons:
# apt:
# packages:
# - graphviz # sphinx inheritance diagrams
#
# install:
# - pip install --upgrade pip setuptools wheel # install with latest tools
# - pip install --upgrade --upgrade-strategy eager .[dev] # get latest deps
#
# script:
# - make lint
# - make test
# - make doc
#
# after_success:
# - coveralls
18 changes: 10 additions & 8 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,16 @@ All notable changes to this project will be documented in this file.
The format is based on `Keep a Changelog <https://keepachangelog.com>`_
and this project adheres to `Semantic Versioning <https://semver.org>`_.

Unreleased
----------

* New function: proj_lineq.
* New function: proj_sdsp.
* New function: proj_positive.
* New function: structured_sparsity.
* Continuous integration with Python 3.6, 3.7, 3.8, 3.9. Dropped 2.7, 3.4, 3.5.
0.6.0 (2025-09-10)
------------------

* Update to use pytest instead of unittest.
* Update to use UV instead of conda.
* New function: `proj_lineq`.
* New function: `proj_sdsp`.
* New function: `proj_positive`.
* New function: `structured_sparsity`.
* Continuous integration with Python 3.8 to 3.13.
* Merged all the extra requirements in a single dev requirement.

0.5.2 (2017-12-15)
Expand Down
17 changes: 7 additions & 10 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -14,25 +14,22 @@ clean:
jupyter nbconvert --inplace --ClearOutputPreprocessor.enabled=True $(NB)

lint:
flake8 --doctests --exclude=doc
uv run flake8 --doctests --exclude=doc,.venv

# Matplotlib doesn't print to screen. Also faster.
export MPLBACKEND = agg

test:
coverage run --branch --source pyunlocbox setup.py test
coverage report
coverage html
uv run pytest --cov=pyunlocbox --cov-report=term-missing --cov-report=html --cov-report=xml -v

doc:
sphinx-build -b html -d doc/_build/doctrees doc doc/_build/html
sphinx-build -b linkcheck -d doc/_build/doctrees doc doc/_build/linkcheck
uv run sphinx-build -b html -d doc/_build/doctrees doc doc/_build/html
uv run sphinx-build -b linkcheck -d doc/_build/doctrees doc doc/_build/linkcheck

dist: clean
python setup.py sdist
python setup.py bdist_wheel --universal
uv build
ls -lh dist/*
twine check dist/*
uv run twine check dist/*

release: dist
twine upload dist/*
uv run twine upload dist/*
84 changes: 84 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -125,10 +125,33 @@ for an exhaustive documentation of the API. Enjoy!
Installation
------------

UV (Recommended)
~~~~~~~~~~~~~~~~

For the fastest installation and dependency management, use `UV <https://docs.astral.sh/uv/>`_::

$ uv add pyunlocbox

Or install directly::

$ uv pip install pyunlocbox

To set up a development environment with UV::

$ git clone https://github.com/epfl-lts2/pyunlocbox.git
$ cd pyunlocbox
$ uv sync --dev

Pip
~~~

The PyUNLocBoX is available on PyPI::

$ pip install pyunlocbox

Conda
~~~~~

The PyUNLocBoX is available on `conda-forge <https://github.com/conda-forge/pyunlocbox-feedstock>`_::

$ conda install -c conda-forge pyunlocbox
Expand All @@ -138,6 +161,67 @@ Contributing

See the guidelines for contributing in ``CONTRIBUTING.rst``.

For development, we recommend using UV for fast dependency management::

$ git clone https://github.com/epfl-lts2/pyunlocbox.git
$ cd pyunlocbox
$ uv sync --dev
$ source .venv/bin/activate # On Windows: .venv\Scripts\activate

**Quick setup with just** (modern command runner)::

$ just setup # Installs dependencies and sets up pre-commit hooks

Set up pre-commit hooks (recommended)::

$ uv run pre-commit install

This will automatically run code formatting and linting checks before each commit.

**Pre-commit hooks include:**

* **Code formatting**: ``black`` for consistent Python code style
* **Import sorting**: ``isort`` for organized imports
* **Linting**: ``flake8`` for code quality and style checks
* **Security scanning**: ``bandit`` for common security issues
* **Modern Python**: ``pyupgrade`` for upgrading syntax to newer Python versions
* **General checks**: trailing whitespace, file endings, YAML/TOML validation

Run tests with pytest::

$ uv run pytest

Run tests with coverage::

$ uv run pytest --cov=pyunlocbox --cov-report=html

Run specific test files::

$ uv run pytest pyunlocbox/tests/test_acceleration.py

**Note**: All tests have been successfully migrated from unittest to pytest! The complete test
suite now uses modern pytest conventions: `test_acceleration.py`, `test_functions.py`,
`test_operators.py`, `test_solvers.py`, and `test_docstrings.py`.

Run pre-commit checks manually::

$ uv run pre-commit run --all-files

Run linting::

$ uv run flake8 --doctests --exclude=doc,.venv

Format code::

$ uv run black .
$ uv run isort .

Build documentation::

$ uv run sphinx-build -b html doc/ doc/_build/

Note: This project has migrated from Travis CI to GitHub Actions. The ``.travis.yml`` file can be removed once the migration is complete.

Similar libraries
-----------------

Expand Down
Loading