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

migrate to uv #344

Merged
merged 4 commits into from
Nov 12, 2024
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
71 changes: 34 additions & 37 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,47 +23,44 @@ jobs:
steps:
- uses: actions/checkout@v4

- name: install poetry
run: |
pipx install poetry
poetry config virtualenvs.create true --local
poetry config virtualenvs.in-project true --local

- uses: actions/setup-python@v5
- uses: scientific-python/repo-review@v0.11.2
with:
python-version: "3.11"
cache: poetry

- name: poetry check
run: poetry check

- name: poetry install
run: poetry install --without debug,docs --all-extras

- name: repo-review
run: poetry run repo-review .
plugins: sp-repo-review

- name: markdownlint
uses: DavidAnson/markdownlint-cli2-action@v17
with:
config: ".markdownlint.yaml"
globs: "*.md"

- name: Install uv
uses: astral-sh/setup-uv@v3
with:
enable-cache: true

- name: uv sync
run: >
uv sync
--frozen
--python 3.11
--no-group debug
--no-group docs

- name: blacken-docs
run: git ls-files -z -- '*.md' | xargs -0 poetry run blacken-docs
run: git ls-files -z -- '*.md' | xargs -0 uv run blacken-docs

- name: codespell
run: poetry run codespell .
run: uv run codespell .

- name: ruff check
run: |
poetry run ruff check --output-format=github
poetry run ruff format --check
uv run ruff check --output-format=github
uv run ruff format --check

- name: basedpyright
run: |
poetry run basedpyright
poetry run basedpyright --ignoreexternal --verifytypes lmo
uv run basedpyright
uv run basedpyright --ignoreexternal --verifytypes lmo

test:
timeout-minutes: 20
Expand All @@ -73,7 +70,7 @@ jobs:
matrix:
os: [ubuntu-latest, windows-latest]
python-version: ["3.11", "3.13"]
pandas: ["without", "with"]
pandas: ["--no-group pandas", ""]
exclude:
- python-version: "3.13"
pandas: "with"
Expand All @@ -83,20 +80,20 @@ jobs:
steps:
- uses: actions/checkout@v4

- name: install poetry
run: pipx install poetry

- uses: actions/setup-python@v5
- name: setup uv
uses: astral-sh/setup-uv@v3
with:
python-version: ${{ matrix.python-version }}
cache: poetry
enable-cache: true

- name: setup python ${{ matrix.python-version }}
run: uv python install ${{ matrix.python-version }}

- name: poetry install
- name: uv sync
run: >
poetry install
--without debug,docs
--with github
--${{ matrix.pandas }} pandas
uv sync
--no-group debug
--no-group docs
${{ matrix.pandas }}

- name: pytest
run: poetry run pytest
run: uv run pytest
12 changes: 3 additions & 9 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ ci:
autoupdate_commit_msg: "update pre-commit hooks"
skip:
- markdownlint
- poetry-check
- codespell
- ruff
- ruff-format
Expand Down Expand Up @@ -67,18 +66,13 @@ repos:
- id: blacken-docs
additional_dependencies: [black==24.*]

- repo: https://github.com/python-poetry/poetry
rev: 1.8.4
hooks:
- id: poetry-check

- repo: https://github.com/codespell-project/codespell
rev: v2.3.0
hooks:
- id: codespell

- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.7.2
rev: v0.7.3
hooks:
- id: ruff
args: [--fix, --show-fixes]
Expand All @@ -88,13 +82,13 @@ repos:
hooks:
- id: basedpyright
name: basedpyright
entry: poetry run basedpyright
entry: uv run basedpyright
language: system
types_or: [python, pyi]

- id: basedpyright-verifytypes
name: basedpyright --verifytypes
entry: poetry run basedpyright --ignoreexternal --verifytypes lmo
entry: uv run basedpyright --ignoreexternal --verifytypes lmo
language: system
always_run: true
pass_filenames: false
21 changes: 7 additions & 14 deletions docs/contributing.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,12 @@ the bug.

## Environment setup

Ensure you have [poetry](https://python-poetry.org/docs/#installation)
Ensure you have [uv](https://docs.astral.sh/uv/getting-started/installation/)
installed.
It can help to use Lmo's lowest-supported Python version, so that you don't
accidentally use those bleeding-edge Python features that you shouldn't, e.g.
You can install the dev dependencies using

```bash
poetry env use python3.10
```

Now you can install the dev dependencies using

```bash
poetry install --sync
uv sync
```

### pre-commit
Expand All @@ -33,13 +26,13 @@ Lmo uses [pre-commit](https://pre-commit.com/) to ensure that the code is
formatted and typed correctly when committing the changes.

```bash
poetry run pre-commit install
uv run pre-commit install
```

It can also be manually run:

```bash
poetry run pre-commit --all-files
uv run pre-commit --all-files
```

### Testing
Expand All @@ -51,7 +44,7 @@ framework.
The tests can be run using

```bash
poetry run pytest
uv run pytest
```

## Documentation
Expand All @@ -60,7 +53,7 @@ If your change involves documentation updates, you can conjure up a live
preview:

```bash
poetry run mkdocs serve
uv run mkdocs serve
```

This will require `pandoc` and `pandoc-citeproc` to be installed on your
Expand Down
4 changes: 2 additions & 2 deletions lmo/contrib/scipy_stats.py
Original file line number Diff line number Diff line change
Expand Up @@ -573,7 +573,7 @@ def l_moments_cov(
/,
*args: Any,
trim: lmt.AnyTrim = 0,
quad_opts: lspt.NQuadOptions | None = None,
quad_opts: lspt.QuadOptions | None = None,
**kwds: Any,
) -> _ArrF8:
r"""
Expand Down Expand Up @@ -1419,7 +1419,7 @@ def l_moments_cov( # noqa: D102
r_max: int,
/,
trim: lmt.AnyTrim = 0,
quad_opts: lspt.NQuadOptions | None = None,
quad_opts: lspt.QuadOptions | None = None,
) -> _ArrF8:
return self.dist.l_moments_cov(
r_max,
Expand Down
2 changes: 1 addition & 1 deletion lmo/inference/_l_gmm.py
Original file line number Diff line number Diff line change
Expand Up @@ -440,7 +440,7 @@ def fit( # noqa: C901
args=(_l_moment_fn, _r, l_r, _trim, w_rr),
**kwds,
)
i += cast(int, res.nfev)
i += res.nfev
fun = res.fun
theta = res.x

Expand Down
7 changes: 2 additions & 5 deletions lmo/theoretical/_f_to_lcm.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from __future__ import annotations

from functools import partial
from typing import TYPE_CHECKING, Protocol, TypeAlias, TypeVar, cast
from typing import TYPE_CHECKING, Protocol, TypeAlias, TypeVar

import numpy as np
import numpy.typing as npt
Expand Down Expand Up @@ -241,10 +241,7 @@ def integrand(*xs: float, i: int, j: int) -> float:
)
elif _r:
fn = partial(integrand, i=i, j=j)
# TODO(jorenham): remove this casting with the next scipy-stubs release
# https://github.com/jorenham/scipy-stubs/issues/155
nquad_opts = cast("lspt.NQuadOptions", quad_opts) if quad_opts else None
l_r[i, j] = nquad(fn, limits, opts=nquad_opts)[0]
l_r[i, j] = nquad(fn, limits, opts=quad_opts)[0]

return round0(l_r)

Expand Down
12 changes: 2 additions & 10 deletions lmo/theoretical/_f_to_lm_cov.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def l_moment_cov_from_cdf(
trim: lmt.AnyTrim = 0,
*,
support: _Pair[float] | None = None,
quad_opts: lspt.NQuadOptions | None = None,
quad_opts: lspt.QuadOptions | None = None,
) -> _ArrF8:
r"""
L-moments that are estimated from $n$ samples of a distribution with CDF
Expand Down Expand Up @@ -295,15 +295,7 @@ def l_stats_cov_from_cdf(
"""
rs = clean_order(num, "num", 0)

ll_kr = l_moment_cov_from_cdf(
cdf,
rs,
trim,
support=support,
# TODO(jorenham): remove this casting with the next scipy-stubs release
# https://github.com/jorenham/scipy-stubs/issues/155
quad_opts=cast("lspt.NQuadOptions", quad_opts) if quad_opts else None,
)
ll_kr = l_moment_cov_from_cdf(cdf, rs, trim, support=support, quad_opts=quad_opts)
if rs <= 2:
return ll_kr

Expand Down
2 changes: 1 addition & 1 deletion lmo/theoretical/_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ def tighten_cdf_support(
def nquad(
integrand: Callable[Concatenate[float, float, _Tss], float],
domains: Sequence[tuple[float, float] | Callable[..., tuple[float, float]],],
opts: lspt.NQuadOptions | None = None,
opts: lspt.QuadOptions | None = None,
*args: _Tss.args,
**kwds: _Tss.kwargs,
) -> float:
Expand Down
29 changes: 8 additions & 21 deletions lmo/typing/scipy.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@

import numpy as np
import numpy.typing as npt
from numpy._typing import (
_ArrayLikeFloat_co, # noqa: TCH002 # pyright: ignore[reportPrivateUsage]
)
from scipy.stats._distn_infrastructure import (
rv_continuous,
rv_continuous_frozen,
Expand All @@ -32,9 +35,8 @@
from typing_extensions import ParamSpec, Protocol, TypeVar, runtime_checkable

if TYPE_CHECKING:
from collections.abc import ItemsView, Iterator, KeysView, Sequence, ValuesView
from collections.abc import ItemsView, Iterator, KeysView, ValuesView

import optype as op
import optype.numpy as onpt

import lmo.typing.np as lnpt
Expand All @@ -43,7 +45,6 @@
__all__ = (
"RV",
"FitResult",
"NQuadOptions",
"OptimizeResult",
"QuadOptions",
"QuadWeights",
Expand All @@ -69,8 +70,8 @@
"cauchy",
]

_IntLike: TypeAlias = int | np.int64 | np.int32 | np.int16
_FloatLike: TypeAlias = float | np.float64 | np.float32
_IntLike: TypeAlias = int | np.integer[Any]
_FloatLike: TypeAlias = float | np.floating[Any]


class QuadOptions(TypedDict, total=False):
Expand All @@ -82,24 +83,10 @@ class QuadOptions(TypedDict, total=False):
epsabs: _FloatLike
epsrel: _FloatLike
limit: _IntLike
points: Sequence[float] | onpt.CanArray[Any, np.dtype[np.float64 | np.float32]]
points: _ArrayLikeFloat_co
weight: QuadWeights
wvar: _FloatLike | tuple[_FloatLike, _FloatLike]
wopts: tuple[int, npt.NDArray[np.float64 | np.float32]]
maxp1: _IntLike
limlst: _IntLike


class NQuadOptions(TypedDict, total=False): # noqa: D101
# TODO(jorenham): Replace this with `QuadOptions` after the next scipy-stubs
# https://github.com/jorenham/scipy-stubs/issues/155
epsabs: float
epsrel: float
limit: int
points: op.CanGetitem[int, float | np.floating[Any] | np.integer[Any] | np.bool_]
weight: QuadWeights
wvar: float | tuple[float, float]
wopts: tuple[int, npt.NDArray[np.float32 | np.float64]]
wopts: tuple[_IntLike, npt.NDArray[np.float32 | np.float64]]


# scipy.optimize
Expand Down
Loading