Skip to content

Commit 19a1042

Browse files
jdebackerclaude
andcommitted
Switch to uv and ruff; remove setup.py and pytest.ini
- Replace setup.py with full [project] metadata in pyproject.toml - Move pytest.ini config into [tool.pytest.ini_options] in pyproject.toml - Replace [tool.black] with [tool.ruff] (line-length = 79) in pyproject.toml - Add [project.optional-dependencies] dev and docs groups - Rename check_black.yml -> check_ruff.yml; use uvx ruff format/check - Update build_and_test.yml to use astral-sh/setup-uv instead of conda - Update deploy_docs.yml and docs_check.yml to use uv - Update publish_to_pypi.yml to use uv build - Update Makefile format target (ruff) and pip-package target (uv build) - Update environment.yml: replace black/pylint with ruff, drop setuptools - Update README.md: replace black badge with ruff, update install instructions Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent dbe0b9f commit 19a1042

12 files changed

Lines changed: 135 additions & 149 deletions

.github/workflows/build_and_test.yml

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ on:
44
paths:
55
- '**.yml'
66
- '**.toml'
7-
- '**.ini'
87
- '**.py'
98
- '**.json'
109
- '**.csv'
@@ -14,7 +13,6 @@ on:
1413
paths:
1514
- '**.yml'
1615
- '**.toml'
17-
- '**.ini'
1816
- '**.py'
1917
- '**.json'
2018
- '**.csv'
@@ -33,24 +31,14 @@ jobs:
3331
uses: actions/checkout@v4
3432
with:
3533
persist-credentials: false
36-
- name: Setup Miniconda using Python ${{ matrix.python-version }}
37-
uses: conda-incubator/setup-miniconda@v3
34+
- name: Install uv
35+
uses: astral-sh/setup-uv@v4
3836
with:
39-
miniconda-version: "latest"
40-
auto-update-conda: true
41-
activate-environment: ogcore-dev
42-
environment-file: environment.yml
4337
python-version: ${{ matrix.python-version }}
44-
auto-activate-base: false
45-
- name: Build
46-
shell: bash -l {0}
47-
run: |
48-
pip install -e .
38+
- name: Install package and dependencies
39+
run: uv pip install -e ".[dev]" --system
4940
- name: Test
50-
shell: bash -l {0}
51-
working-directory: ./
52-
run: |
53-
python -m pytest -m "not local and not benchmark" --cov=./ --cov-report=xml
41+
run: python -m pytest -m "not local and not benchmark" --cov=./ --cov-report=xml
5442
- name: Upload coverage to Codecov
5543
if: matrix.os == 'ubuntu-latest' && contains(github.repository, 'PSLmodels/OG-Core')
5644
uses: codecov/codecov-action@v4

.github/workflows/check_black.yml

Lines changed: 0 additions & 15 deletions
This file was deleted.

.github/workflows/check_ruff.yml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
name: Check Ruff formatting and linting
2+
3+
on: [push, pull_request]
4+
5+
jobs:
6+
lint:
7+
runs-on: ubuntu-latest
8+
steps:
9+
- uses: actions/checkout@v4
10+
- uses: astral-sh/setup-uv@v4
11+
- name: Check formatting with Ruff
12+
run: uvx ruff format --check .
13+
- name: Check linting with Ruff
14+
run: uvx ruff check .

.github/workflows/deploy_docs.yml

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,19 +21,16 @@ jobs:
2121
with:
2222
persist-credentials: false
2323

24-
- name: Setup Miniconda
25-
uses: conda-incubator/setup-miniconda@v3
24+
- name: Install uv
25+
uses: astral-sh/setup-uv@v4
2626
with:
27-
miniconda-version: "latest"
28-
activate-environment: ogcore-dev
29-
environment-file: environment.yml
3027
python-version: "3.13"
31-
auto-activate-base: false
28+
29+
- name: Install package and dependencies
30+
run: uv pip install -e ".[dev,docs]" --system
3231

3332
- name: Build # Build Jupyter Book
34-
shell: bash -l {0}
3533
run: |
36-
pip install -e .
3734
python -m ipykernel install --user --name=ogcore-dev
3835
make build-docs
3936

.github/workflows/docs_check.yml

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,18 +19,15 @@ jobs:
1919
with:
2020
persist-credentials: false
2121

22-
- name: Setup Miniconda
23-
uses: conda-incubator/setup-miniconda@v3
22+
- name: Install uv
23+
uses: astral-sh/setup-uv@v4
2424
with:
25-
miniconda-version: "latest"
26-
activate-environment: ogcore-dev
27-
environment-file: environment.yml
2825
python-version: "3.13"
29-
auto-activate-base: false
26+
27+
- name: Install package and dependencies
28+
run: uv pip install -e ".[dev,docs]" --system
3029

3130
- name: Build # Build Jupyter Book
32-
shell: bash -l {0}
3331
run: |
34-
pip install -e .
3532
python -m ipykernel install --user --name=ogcore-dev
3633
make build-docs

.github/workflows/publish_to_pypi.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,12 @@ jobs:
1313
steps:
1414
- name: Checkout repo
1515
uses: actions/checkout@v4
16-
- name: Setup Python
17-
uses: actions/setup-python@v5
16+
- name: Install uv
17+
uses: astral-sh/setup-uv@v4
1818
with:
1919
python-version: "3.13"
2020
- name: Build package
21-
run: make pip-package
21+
run: uv build
2222
- name: Publish a Python distribution to PyPI
2323
uses: pypa/gh-action-pypi-publish@release/v1
2424
with:

Makefile

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,9 @@ build-docs:
7171
@cd ./docs ; python make_params.py; python make_vars.py; jb build ./book
7272

7373
format:
74-
black . -l 79
74+
ruff format .
75+
ruff check . --fix
7576
linecheck . --fix
7677

7778
pip-package:
78-
pip install wheel
79-
pip install setuptools
80-
python setup.py sdist bdist_wheel
79+
uv build

README.md

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
| | |
44
| --- | --- |
55
| Org | [![PSL cataloged](https://img.shields.io/badge/PSL-cataloged-a0a0a0.svg)](https://www.PSLmodels.org) [![OS License: CCO-1.0](https://img.shields.io/badge/OS%20License-CCO%201.0-yellow)](https://github.com/PSLmodels/OG-Core/blob/master/LICENSE) [![Jupyter Book Badge](https://raw.githubusercontent.com/jupyter-book/jupyter-book/next/docs/media/images/badge.svg)](https://pslmodels.github.io/OG-Core/) |
6-
| Package | [![Python 3.12](https://img.shields.io/badge/python-3.12-blue.svg)](https://www.python.org/downloads/release/python-3129/) [![Python 3.13](https://img.shields.io/badge/python-3.13-blue.svg)](https://www.python.org/downloads/release/python-3137/) [![PyPI Latest Release](https://img.shields.io/pypi/v/ogcore.svg)](https://pypi.org/project/ogcore/) [![PyPI Downloads](https://img.shields.io/pypi/dm/ogcore.svg?label=PyPI%20downloads)](https://pypi.org/project/ogcore/) [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black) |
7-
| Testing | ![example event parameter](https://github.com/PSLmodels/OG-Core/actions/workflows/build_and_test.yml/badge.svg?branch=master) ![example event parameter](https://github.com/PSLmodels/OG-Core/actions/workflows/deploy_docs.yml/badge.svg?branch=master) ![example event parameter](https://github.com/PSLmodels/OG-Core/actions/workflows/check_black.yml/badge.svg?branch=master) [![Codecov](https://codecov.io/gh/PSLmodels/OG-Core/branch/master/graph/badge.svg)](https://codecov.io/gh/PSLmodels/OG-Core) |
6+
| Package | [![Python 3.12](https://img.shields.io/badge/python-3.12-blue.svg)](https://www.python.org/downloads/release/python-3129/) [![Python 3.13](https://img.shields.io/badge/python-3.13-blue.svg)](https://www.python.org/downloads/release/python-3137/) [![PyPI Latest Release](https://img.shields.io/pypi/v/ogcore.svg)](https://pypi.org/project/ogcore/) [![PyPI Downloads](https://img.shields.io/pypi/dm/ogcore.svg?label=PyPI%20downloads)](https://pypi.org/project/ogcore/) [![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff) |
7+
| Testing | ![example event parameter](https://github.com/PSLmodels/OG-Core/actions/workflows/build_and_test.yml/badge.svg?branch=master) ![example event parameter](https://github.com/PSLmodels/OG-Core/actions/workflows/deploy_docs.yml/badge.svg?branch=master) ![example event parameter](https://github.com/PSLmodels/OG-Core/actions/workflows/check_ruff.yml/badge.svg?branch=master) [![Codecov](https://codecov.io/gh/PSLmodels/OG-Core/branch/master/graph/badge.svg)](https://codecov.io/gh/PSLmodels/OG-Core) |
88

99

1010
OG-Core is an overlapping-generations (OG) model core theory, logic, and solution method algorithms that allow for dynamic general equilibrium analysis of fiscal policy. OG-Core provides a general framework and is a dependency of several country-specific OG model caliibrations, as listed in the table belowsuch as [OG-USA](https://github.com/PSLmodels/OG-USA) and [OG-UK](https://github.com/PSLmodels/OG-UK). The model output includes changes in macroeconomic aggregates (GDP, investment, consumption), wages, interest rates, and the stream of tax revenues over time. Regularly updated documentation of the model theory--its output, and solution method--and the Python API is available [here](https://pslmodels.github.io/OG-Core).
@@ -24,13 +24,12 @@ The model is constantly under development, and model components could change sig
2424

2525
## Using/contributing to OG-Core
2626

27-
There are two primary methods for installing and running OG-Core on your computer locally. The first and simplest method is to download the most recent `ogcore` Python package from the Python Package Index ([PyPI.org]()). A second option is to fork and clone the most recent version of OG-Core from its GitHub repository and create the conda environment for the `ogcore` package. We detail both of these methods below.
27+
There are two primary methods for installing and running OG-Core on your computer locally. The first and simplest method is to download the most recent `ogcore` Python package from the Python Package Index ([PyPI.org](https://pypi.org/project/ogcore/)). A second option is to fork and clone the most recent version of OG-Core from its GitHub repository and install the `ogcore` package with its development dependencies using `uv`. We detail both of these methods below.
2828

2929

3030
### Installing and Running OG-Core from Python Package Index (PyPI.org)
3131

32-
* Open your terminal (or Conda command prompt), and make sure you have the most recent version of `pip` (the Python Index Package manager) by typing on a Unix/macOS machine `python3 -m pip install --upgrade pip` or on a Windows machine `py -m pip install --upgrade pip`.
33-
* Install the [`ogcore`](https://pypi.org/project/ogcore/) package from the Python Package Index by typing `pip install ogcore`.
32+
* Open your terminal and install the [`ogcore`](https://pypi.org/project/ogcore/) package from the Python Package Index by typing `pip install ogcore`.
3433
* Navigate to a folder `./YourFolderName/` where you want to save scripts to run OG-Core and output from the simulations in those scripts.
3534
* Save the python script [`run_ogcore_example.py`](https://github.com/PSLmodels/OG-Core/blob/master/run_examples/run_ogcore_example.py) from the OG-Core GitHub repository in the folder where you are working on your local machine `./YourFolderName/run_ogcore_example.py`.
3635
* Run the model with an example reform from terminal/command prompt by typing `python run_ogcore_example.py`
@@ -60,11 +59,9 @@ The CSV output file `./ogcore_example_output.csv` can be compared to the [`./run
6059

6160
### Installing and Running OG-Core from GitHub repository
6261

63-
* Install the [Anaconda distribution](https://www.anaconda.com/distribution/) of Python
62+
* Install [`uv`](https://docs.astral.sh/uv/) by following the [installation instructions](https://docs.astral.sh/uv/getting-started/installation/) for your platform (or simply run `pip install uv`)
6463
* Clone this repository to a directory on your computer
65-
* From the terminal (or Conda command prompt), navigate to the directory to which you cloned this repository and run `conda env create -f environment.yml`
66-
* Then, `conda activate ogcore-dev`
67-
* Then install by `pip install -e .`
64+
* From the terminal, navigate to the directory to which you cloned this repository and run `uv pip install -e ".[dev]"` to install the package and all development dependencies
6865
* Navigate to `./run_examples`
6966
* Run the model with an example reform from terminal/command prompt by typing `python run_ogcore_example.py`
7067
* You can adjust the `./run_examples/run_ogcore_example.py` script by modifying model parameters specified in the `og_spec` dictionary.

environment.yml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ dependencies:
55
- python>3.11, <3.14
66
- numpy
77
- ipython
8-
- setuptools
98
- scipy>=1.7.1
109
- pandas>=1.2.5
1110
- numba
@@ -24,11 +23,10 @@ dependencies:
2423
- pytest>=6.0
2524
- pytest-cov
2625
- pytest-xdist
27-
- pylint
2826
- coverage
2927
- requests
3028
- openpyxl>=3.1.2
31-
- black>=24.1.1
29+
- ruff
3230
- pip
3331
- pip:
3432
- pygam

pyproject.toml

Lines changed: 93 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,99 @@
22
requires = ["setuptools>=61.0"]
33
build-backend = "setuptools.build_meta"
44

5-
# Configuration for Black.
5+
[project]
6+
name = "ogcore"
7+
version = "0.15.4"
8+
authors = [
9+
{name = "Jason DeBacker and Richard W. Evans"},
10+
]
11+
description = "A general equilibrium overlapping generations model for fiscal policy analysis"
12+
readme = "README.md"
13+
license = {text = "CC0 1.0 Universal (CC0 1.0) Public Domain Dedication"}
14+
requires-python = ">=3.11, <3.14"
15+
classifiers = [
16+
"Development Status :: 2 - Pre-Alpha",
17+
"Intended Audience :: Developers",
18+
"Natural Language :: English",
19+
"License :: CC0 1.0 Universal (CC0 1.0) Public Domain Dedication",
20+
"Operating System :: OS Independent",
21+
"Programming Language :: Python",
22+
"Programming Language :: Python :: 3",
23+
"Programming Language :: Python :: 3.11",
24+
"Programming Language :: Python :: 3.12",
25+
"Programming Language :: Python :: 3.13",
26+
"Topic :: Software Development :: Libraries :: Python Modules",
27+
]
28+
dependencies = [
29+
"numpy",
30+
"scipy>=1.7.1",
31+
"pandas>=1.2.5",
32+
"numba",
33+
"matplotlib",
34+
"dask>=2.30.0",
35+
"distributed>=2.30.1",
36+
"paramtools>=0.20.0",
37+
"requests",
38+
"pygam",
39+
]
640

7-
# NOTE: you have to use single-quoted strings in TOML for regular expressions.
8-
# It's the equivalent of r-strings in Python. Multiline strings are treated as
9-
# verbose regular expressions by Black. Use [ ] to denote a significant space
10-
# character.
41+
[project.urls]
42+
Homepage = "https://github.com/PSLmodels/OG-Core/"
43+
"Issue Tracker" = "https://github.com/PSLmodels/OG-Core/issues"
1144

12-
[tool.black]
45+
[project.optional-dependencies]
46+
dev = [
47+
"pytest>=6.0",
48+
"pytest-cov",
49+
"pytest-xdist",
50+
"coverage",
51+
"ruff",
52+
"openpyxl>=3.1.2",
53+
"linecheck",
54+
]
55+
docs = [
56+
"jupyter-book<2.0.0",
57+
"jupyter",
58+
"ipykernel",
59+
"sphinx>=3.5.4",
60+
"sphinx-argparse",
61+
"sphinxcontrib-bibtex>=2.0.0",
62+
"sphinx-math-dollar",
63+
"pydata-sphinx-theme",
64+
]
65+
66+
[tool.setuptools.packages.find]
67+
include = ["ogcore*"]
68+
69+
[tool.setuptools.package-data]
70+
ogcore = [
71+
"default_parameters.json",
72+
"model_variables.json",
73+
"OGcorePlots.mplstyle",
74+
]
75+
76+
[tool.ruff]
1377
line-length = 79
14-
target-version = ["py312", "py313"]
15-
include = '\.pyi?$'
78+
target-version = "py312"
79+
80+
[tool.ruff.lint]
81+
select = ["E", "F", "W"]
82+
83+
[tool.pytest.ini_options]
84+
minversion = "6.0"
85+
testpaths = ["tests"]
86+
filterwarnings = [
87+
"ignore::RuntimeWarning:.*invalid value encountered.*",
88+
"ignore::RuntimeWarning:.*divide by zero encountered in divide.*",
89+
"ignore::RuntimeWarning:.*invalid value encountered in power.*",
90+
]
91+
markers = [
92+
"local: marks tests that run locally and not on GH Actions (mostly due to run time)",
93+
"benchmark: marks tests that measure performance and memory usage",
94+
"distributed: marks tests that use distributed Dask clients",
95+
"memory: marks tests focused on memory usage measurement",
96+
"performance: marks tests focused on compute time measurement",
97+
"slow: marks tests that take longer to run",
98+
"real: marks tests using real OG-Core tax function code",
99+
"platform: marks tests for platform-specific optimization",
100+
]

0 commit comments

Comments
 (0)