Skip to content

Commit 7e2ba2d

Browse files
authored
refactor: switch to uv (#67)
* refactor: switched to uv * refactor: switched to uv * ci: enable uv caching * build: added pyright config to the pyproject.toml * fix: added package manifest * refactor: removed un-needed docker-compose version * build: moved the project version to the pyproject.toml * fix: test cases * chore: address pr comments
1 parent e5a2cc8 commit 7e2ba2d

File tree

16 files changed

+1080
-1501
lines changed

16 files changed

+1080
-1501
lines changed

.github/scripts/update_version.py

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
# /// script
2+
# requires-python = ">=3.13"
3+
# dependencies = [
4+
# "packaging",
5+
# "toml",
6+
# ]
7+
# ///
8+
9+
import sys
10+
from pathlib import Path
11+
from sys import stdout
12+
13+
import toml
14+
from packaging.version import parse
15+
16+
17+
def update_version_rust(new_version: str):
18+
cargo_path = Path("Cargo.toml")
19+
if not cargo_path.exists():
20+
stdout.write("Cargo.toml not found, skipping version update")
21+
return
22+
23+
filedata = toml.loads(cargo_path.read_text())
24+
25+
# If the new version is a pre-release version, we need to reformat it
26+
# to align with Cargo standards
27+
# pip format uses "0.1.0.dev1" while Cargo uses "0.1.0-dev1"
28+
cargo_version = format_cargo_version(new_version)
29+
30+
if "package" not in filedata:
31+
raise ValueError("Cargo.toml is missing the [package] section")
32+
33+
filedata["package"]["version"] = cargo_version
34+
35+
cargo_path.write_text(toml.dumps(filedata))
36+
37+
38+
def format_cargo_version(new_version: str) -> str:
39+
parsed_version = parse(new_version)
40+
41+
cargo_version = (
42+
f"{parsed_version.major}.{parsed_version.minor}.{parsed_version.micro}"
43+
)
44+
if parsed_version.is_prerelease and parsed_version.pre is not None:
45+
pre_release = ".".join(str(x) for x in parsed_version.pre)
46+
cargo_version += f"-{pre_release.replace('.', '')}"
47+
if parsed_version.is_postrelease and parsed_version.post is not None:
48+
cargo_version += f"-post{parsed_version.post}"
49+
if parsed_version.is_devrelease and parsed_version.dev is not None:
50+
cargo_version += f"-dev{parsed_version.dev}"
51+
52+
return cargo_version
53+
54+
55+
def update_version_python(new_version: str):
56+
pyproject_path = Path("pyproject.toml")
57+
if not pyproject_path.exists():
58+
print("pyproject.toml not found, skipping version update") # noqa: T201
59+
return
60+
61+
filedata = toml.loads(pyproject_path.read_text())
62+
63+
# Parse the new version to ensure it's valid and potentially reformat
64+
python_version = format_python_version(new_version)
65+
66+
updated = False
67+
68+
# Update poetry version if it exists
69+
if "tool" in filedata and "poetry" in filedata["tool"]:
70+
filedata["tool"]["poetry"]["version"] = python_version
71+
updated = True
72+
73+
# Update project.version if it exists
74+
if "project" in filedata and "version" in filedata["project"]:
75+
filedata["project"]["version"] = python_version
76+
updated = True
77+
78+
if not updated:
79+
print( # noqa: T201
80+
"Warning: Neither [tool.poetry] nor [project] sections found in pyproject.toml"
81+
)
82+
return
83+
84+
pyproject_path.write_text(toml.dumps(filedata))
85+
86+
87+
def format_python_version(new_version: str) -> str:
88+
parsed_version = parse(new_version)
89+
# Assuming semantic versioning, format it as needed
90+
python_version = (
91+
f"{parsed_version.major}.{parsed_version.minor}.{parsed_version.micro}"
92+
)
93+
if parsed_version.is_prerelease and parsed_version.pre is not None:
94+
pre_release = ".".join(str(x) for x in parsed_version.pre)
95+
python_version += (
96+
f".dev{parsed_version.pre[-1]}"
97+
if pre_release.startswith("dev")
98+
else f"b{parsed_version.pre[-1]}"
99+
)
100+
if parsed_version.is_postrelease and parsed_version.post is not None:
101+
python_version += f".post{parsed_version.post}"
102+
if parsed_version.is_devrelease and parsed_version.dev is not None:
103+
python_version += f".dev{parsed_version.dev}"
104+
return python_version
105+
106+
107+
if __name__ == "__main__":
108+
if len(sys.argv) != 2:
109+
stdout.write("Usage: python update_version.py <new_version>")
110+
sys.exit(1)
111+
new_version = sys.argv[1].lstrip("v")
112+
update_version_rust(new_version)
113+
update_version_python(new_version)
114+
stdout.write(f"Updated version to: {new_version}")
115+
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
version = 1
2+
revision = 1
3+
requires-python = ">=3.13"
4+
5+
[manifest]
6+
requirements = [
7+
{ name = "packaging" },
8+
{ name = "toml" },
9+
]
10+
11+
[[package]]
12+
name = "packaging"
13+
version = "24.2"
14+
source = { registry = "https://pypi.org/simple" }
15+
sdist = { url = "https://files.pythonhosted.org/packages/d0/63/68dbb6eb2de9cb10ee4c9c14a0148804425e13c4fb20d61cce69f53106da/packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f", size = 163950 }
16+
wheels = [
17+
{ url = "https://files.pythonhosted.org/packages/88/ef/eb23f262cca3c0c4eb7ab1933c3b1f03d021f2c48f54763065b6f0e321be/packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759", size = 65451 },
18+
]
19+
20+
[[package]]
21+
name = "toml"
22+
version = "0.10.2"
23+
source = { registry = "https://pypi.org/simple" }
24+
sdist = { url = "https://files.pythonhosted.org/packages/be/ba/1f744cdc819428fc6b5084ec34d9b30660f6f9daaf70eead706e3203ec3c/toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f", size = 22253 }
25+
wheels = [
26+
{ url = "https://files.pythonhosted.org/packages/44/6f/7120676b6d73228c96e17f1f794d8ab046fc910d781c8d151120c3f1569e/toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b", size = 16588 },
27+
]

.github/workflows/test.yml

Lines changed: 21 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ jobs:
1414
fail-fast: false
1515
matrix:
1616
os: [ubuntu-latest]
17-
python-version: ["3.11", "3.12"]
17+
python-version: ["3.11", "3.12", "3.13"]
1818
services:
1919
postgres:
2020
image: postgres:latest
@@ -30,33 +30,26 @@ jobs:
3030
--health-timeout 5s
3131
--health-retries 5
3232
steps:
33-
- uses: actions/checkout@v3
34-
- name: Set up Python ${{ matrix.python-version }}
35-
uses: actions/setup-python@v4
33+
- uses: actions/checkout@v4
34+
- name: Install uv and with python version ${{ matrix.python-version }}
35+
uses: astral-sh/setup-uv@v5
3636
with:
37+
enable-cache: true
3738
python-version: ${{ matrix.python-version }}
38-
- name: Install Poetry
39-
uses: snok/install-poetry@v1
40-
- name: Install dependencies
41-
run: poetry install
4239
- name: Run tests
43-
run: |
44-
poetry run pytest -v --continue-on-collection-errors
40+
run: uv run pytest -v --continue-on-collection-errors
4541
env:
4642
ICEAXE_LOG_LEVEL: DEBUG
4743

4844
lint:
4945
runs-on: ubuntu-latest
5046
steps:
51-
- uses: actions/checkout@v3
52-
- name: Set up Python
53-
uses: actions/setup-python@v4
47+
- uses: actions/checkout@v4
48+
- name: Install uv with Python 3.13
49+
uses: astral-sh/setup-uv@v5
5450
with:
55-
python-version: "3.12"
56-
- name: Install Poetry
57-
uses: snok/install-poetry@v1
58-
- name: Install dependencies
59-
run: poetry install
51+
enable-cache: true
52+
python-version: 3.13
6053
- name: Run lint
6154
run: make lint
6255

@@ -68,15 +61,17 @@ jobs:
6861
os: [ubuntu-latest, macos-latest]
6962
runs-on: ${{ matrix.os }}
7063
steps:
71-
- uses: actions/checkout@v3
72-
73-
- name: Set up Python
74-
uses: actions/setup-python@v4
64+
- uses: actions/checkout@v4
65+
- name: Install uv with Python 3.13
66+
uses: astral-sh/setup-uv@v5
7567
with:
76-
python-version: "3.12"
68+
enable-cache: true
69+
python-version: 3.13
7770

78-
- name: Install Poetry
79-
uses: snok/install-poetry@v1
71+
- name: Update version
72+
if: startsWith(github.ref, 'refs/tags/v')
73+
shell: bash
74+
run: uv run .github/scripts/update_version.py ${{ github.ref_name }}
8075

8176
- name: Clean build artifacts
8277
run: |
@@ -87,13 +82,6 @@ jobs:
8782
find . -type f -name "*.o" -delete
8883
find . -type f -name "*.c" -delete
8984
90-
- name: Update version in pyproject.toml
91-
if: startsWith(github.ref, 'refs/tags/v')
92-
run: |
93-
VERSION=${GITHUB_REF#refs/tags/v}
94-
poetry version $VERSION
95-
shell: bash
96-
9785
- name: Set up QEMU
9886
if: runner.os == 'Linux'
9987
uses: docker/setup-qemu-action@v3
@@ -102,7 +90,7 @@ jobs:
10290

10391
- name: Build SDist
10492
if: matrix.os == 'ubuntu-latest'
105-
run: poetry build --format sdist
93+
run: uv build --sdist
10694

10795
- name: Build wheels
10896
uses: pypa/[email protected]

MANIFEST.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
include iceaxe/*.pyx

Makefile

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -23,19 +23,19 @@ lint-validation: lint-validation-iceaxe
2323
# Testing target
2424
test: test-iceaxe
2525

26-
# Install all sub-project dependencies with poetry
26+
# Install all sub-project dependencies with uv
2727
install-deps: install-deps-iceaxe
2828

2929
install-deps-iceaxe:
3030
@echo "Installing dependencies for $(ICEAXE)..."
31-
@(cd $(ICEAXE) && poetry install)
31+
@(cd $(ICEAXE) && uv sync)
3232

33-
# Clean the current poetry.lock files, useful for remote CI machines
33+
# Clean the current uv.lock files, useful for remote CI machines
3434
# where we're running on a different base architecture than when
3535
# developing locally
36-
clean-poetry-lock:
37-
@echo "Cleaning poetry.lock files..."
38-
@rm -f $(ICEAXE)/poetry.lock
36+
clean-uv-lock:
37+
@echo "Cleaning uv.lock files..."
38+
@rm -f $(ICEAXE)/uv.lock
3939

4040
# Standard linting - local development, with fixing enabled
4141
lint-iceaxe:
@@ -59,25 +59,25 @@ test-iceaxe:
5959

6060
define test-common
6161
echo "Running tests for $(2)..."
62-
@(cd $(1) && poetry run pytest -W error -vv $(test-args) $(2))
62+
@(cd $(1) && uv run pytest -W error -vv $(test-args) $(2))
6363
endef
6464

6565
define lint-common
6666
echo "Running linting for $(2)..."
67-
@(cd $(1) && poetry run ruff format $(2))
68-
@(cd $(1) && poetry run ruff check --fix $(2))
67+
@(cd $(1) && uv run ruff format $(2))
68+
@(cd $(1) && uv run ruff check --fix $(2))
6969
echo "Running pyright for $(2)..."
70-
@(cd $(1) && poetry run pyright $(2))
70+
@(cd $(1) && uv run pyright $(2))
7171
endef
7272

7373
define lint-validation-common
7474
echo "Running lint validation for $(2)..."
75-
@(cd $(1) && poetry run ruff format --check $(2))
76-
@(cd $(1) && poetry run ruff check $(2))
75+
@(cd $(1) && uv run ruff format --check $(2))
76+
@(cd $(1) && uv run ruff check $(2))
7777
echo "Running mypy for $(2)..."
78-
@(cd $(1) && poetry run mypy $(2))
78+
@(cd $(1) && uv run mypy $(2))
7979
echo "Running pyright for $(2)..."
80-
@(cd $(1) && poetry run pyright $(2))
80+
@(cd $(1) && uv run pyright $(2))
8181
endef
8282

8383

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ To auto-optimize your self hosted Postgres install, check out our new [autopg](h
2828
If you're using poetry to manage your dependencies:
2929

3030
```bash
31-
poetry add iceaxe
31+
uv add iceaxe
3232
```
3333

3434
Otherwise install with pip:
@@ -229,7 +229,7 @@ network connections in the first place.
229229
We have basic benchmarking tests in the `__tests__/benchmarks` directory. To run them, you'll need to execute the pytest suite:
230230

231231
```bash
232-
poetry run pytest -m integration_tests
232+
uv run pytest -m integration_tests
233233
```
234234

235235
Current benchmarking as of October 11 2024 is:
@@ -242,8 +242,8 @@ Current benchmarking as of October 11 2024 is:
242242
## Development
243243

244244
If you update your Cython implementation during development, you'll need to re-compile the Cython code. This can be done with
245-
a simple poetry install. Poetry is set up to create a dynamic `setup.py` based on our `build.py` definition.
245+
a simple uv sync.
246246

247247
```bash
248-
poetry install
248+
uv sync
249249
```

build.py

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

docker-compose.test.yml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
version: "3.8"
2-
31
services:
42
postgres:
53
image: postgres:16

docs/guides/logging/page.mdx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,13 @@ SQL queries that are actually sent to your database. You can set the `ICEAXE_LOG
77
variable to `DEBUG` to enable verbose logging:
88

99
```bash
10-
ICEAXE_LOG_LEVEL=DEBUG poetry run runserver
10+
ICEAXE_LOG_LEVEL=DEBUG uv run runserver
1111
```
1212

1313
This results in a lot of output, so you may want to pipe it to a file:
1414

1515
```bash
16-
ICEAXE_LOG_LEVEL=DEBUG poetry run runserver > debug.log
16+
ICEAXE_LOG_LEVEL=DEBUG uv run runserver > debug.log
1717
```
1818

1919
Each entry in the log will be a JSON formatted, single-lined

0 commit comments

Comments
 (0)