Skip to content
Open
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
2 changes: 1 addition & 1 deletion .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

version: 2
updates:
- package-ecosystem: "pip"
- package-ecosystem: "uv"
directory: "/"
schedule:
interval: "weekly"
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/nightly-pypi-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,13 @@ jobs:
with:
python-version: 3.12

- name: Install Poetry
run: make install-poetry
- name: Install UV
run: make install-uv

- name: Set version
id: set-version
run: |
CURRENT_VERSION=$(poetry version --short)
CURRENT_VERSION=$(uv version --short)
TIMESTAMP=$(date +%Y%m%d%H%M%S)
echo "VERSION=${CURRENT_VERSION}.dev${TIMESTAMP}" >> "$GITHUB_OUTPUT"

Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/pypi-build-artifacts.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,18 +47,18 @@ jobs:
3.11
3.12

- name: Install poetry
run: make install-poetry
- name: Install UV
run: make install-uv

- name: Set version with RC
env:
VERSION: ${{ inputs.VERSION }}
run: python -m poetry version "${{ env.VERSION }}"
run: uv version "${{ env.VERSION }}"

# Publish the source distribution with the version that's in
# the repository, otherwise the tests will fail
- name: Compile source distribution
run: python3 -m poetry build --format=sdist
run: uv build --sdist
if: startsWith(matrix.os, 'ubuntu')

- name: Build wheels
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/python-ci-docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ jobs:
- uses: actions/setup-python@v6
with:
python-version: 3.12
- name: Install poetry
run: make install-poetry
- name: Install UV
run: make install-uv
- name: Install
run: make docs-install
- name: Build docs
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/python-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ jobs:
- uses: actions/setup-python@v6
with:
python-version: ${{ matrix.python }}
- name: Install poetry
run: make install-poetry
- name: Install UV
run: make install-uv
- name: Install system dependencies
run: sudo apt-get update && sudo apt-get install -y libkrb5-dev # for kerberos
- name: Install
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/python-release-docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ jobs:
- uses: actions/setup-python@v6
with:
python-version: ${{ matrix.python }}
- name: Install poetry
run: make install-poetry
- name: Install UV
run: make install-uv
- name: Install docs
run: make docs-install
- name: Build docs
Expand Down
14 changes: 7 additions & 7 deletions .github/workflows/python-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -97,20 +97,20 @@ jobs:
with:
python-version: 3.12

- name: Install Poetry
run: make install-poetry
- name: Install UV
run: make install-uv

- name: Validate current pyiceberg version
env:
VERSION: ${{ needs.validate-inputs.outputs.VERSION }}
run: |
# Extract the current version from Poetry
current_pyiceberg_version=$(poetry version --short)
echo "Detected Poetry version: $current_pyiceberg_version"
# Extract the current version from UV
current_pyiceberg_version=$(uv version --short)
echo "Detected UV version: $current_pyiceberg_version"

# Compare the input version with the Poetry version
# Compare the input version with the UV version
if [[ "$VERSION" != "$current_pyiceberg_version" ]]; then
echo "Error: Input version ($VERSION) does not match the Poetry version ($current_pyiceberg_version)"
echo "Error: Input version ($VERSION) does not match the UV version ($current_pyiceberg_version)"
exit 1
fi

Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/svn-build-artifacts.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,13 @@ jobs:
3.11
3.12

- name: Install poetry
run: make install-poetry
- name: Install UV
run: make install-uv

# Publish the source distribution with the version that's in
# the repository, otherwise the tests will fail
- name: Compile source distribution
run: python3 -m poetry build --format=sdist
run: uv build --sdist
if: startsWith(matrix.os, 'ubuntu')

- name: Build wheels
Expand Down
61 changes: 29 additions & 32 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,10 @@ COVERAGE ?= 0 # Set COVERAGE=1 to enable coverage: make test COVERAGE=1
COVERAGE_FAIL_UNDER ?= 85 # Minimum coverage % to pass: make coverage-report COVERAGE_FAIL_UNDER=70
KEEP_COMPOSE ?= 0 # Set KEEP_COMPOSE=1 to keep containers after integration tests

PIP = python -m pip

POETRY_VERSION = 2.2.1
POETRY = python -m poetry

ifeq ($(COVERAGE),1)
TEST_RUNNER = $(POETRY) run coverage run --parallel-mode --source=pyiceberg -m
TEST_RUNNER = uv run coverage run --parallel-mode --source=pyiceberg -m
else
TEST_RUNNER = $(POETRY) run
TEST_RUNNER = uv run
endif

ifeq ($(KEEP_COMPOSE),1)
Expand All @@ -55,24 +50,26 @@ help: ## Display this help message

##@ Setup

install-poetry: ## Ensure Poetry is installed at the specified version
@if ! command -v ${POETRY} &> /dev/null; then \
echo "Poetry not found. Installing..."; \
${PIP} install poetry==$(POETRY_VERSION); \
install-uv: ## Ensure uv is installed
@if ! command -v uv &> /dev/null; then \
echo "uv not found. Installing..."; \
curl -LsSf https://astral.sh/uv/install.sh | sh; \
else \
echo "uv is already installed."; \
fi

setup-venv: ## Create virtual environment
@if [ ! -d .venv ]; then \
echo "Creating virtual environment."; \
uv venv; \
else \
INSTALLED_VERSION=$$(${PIP} show poetry | grep Version | awk '{print $$2}'); \
if [ "$$INSTALLED_VERSION" != "$(POETRY_VERSION)" ]; then \
echo "Updating Poetry to version $(POETRY_VERSION)..."; \
${PIP} install --upgrade poetry==$(POETRY_VERSION); \
else \
echo "Poetry version $(POETRY_VERSION) already installed."; \
fi; \
echo "Virtual environment already exists."; \
fi

install-dependencies: ## Install all dependencies including extras
$(POETRY) install --all-extras
install-dependencies: setup-venv ## Install all dependencies including extras
uv sync --all-extras

install: install-poetry install-dependencies ## Install Poetry and dependencies
install: install-uv install-dependencies ## Install uv and dependencies

# ===============
# Code Validation
Expand All @@ -84,7 +81,7 @@ check-license: ## Check license headers
./dev/check-license

lint: ## Run code linters via prek (pre-commit hooks)
$(POETRY) run prek run -a
uv run prek run -a

# ===============
# Testing Section
Expand All @@ -101,7 +98,7 @@ test-integration-setup: ## Start Docker services for integration tests
docker compose -f dev/docker-compose-integration.yml kill
docker compose -f dev/docker-compose-integration.yml rm -f
docker compose -f dev/docker-compose-integration.yml up -d --wait
$(POETRY) run python dev/provision.py
uv run python dev/provision.py

test-integration-exec: ## Run integration tests (excluding provision)
$(TEST_RUNNER) pytest tests/ -m integration $(PYTEST_ARGS)
Expand Down Expand Up @@ -133,25 +130,25 @@ test-coverage: COVERAGE=1
test-coverage: test test-integration test-s3 test-adls test-gcs coverage-report ## Run all tests with coverage and report

coverage-report: ## Combine and report coverage
${POETRY} run coverage combine
${POETRY} run coverage report -m --fail-under=$(COVERAGE_FAIL_UNDER)
${POETRY} run coverage html
${POETRY} run coverage xml
uv run coverage combine
uv run coverage report -m --fail-under=$(COVERAGE_FAIL_UNDER)
uv run coverage html
uv run coverage xml

# ================
# Documentation
# ================

##@ Documentation

docs-install: ## Install docs dependencies
${POETRY} install --with docs
docs-install: ## Install docs dependencies (included in default groups)
uv sync --group docs

docs-serve: ## Serve local docs preview (hot reload)
${POETRY} run mkdocs serve -f mkdocs/mkdocs.yml
uv run mkdocs serve -f mkdocs/mkdocs.yml

docs-build: ## Build the static documentation site
${POETRY} run mkdocs build -f mkdocs/mkdocs.yml --strict
uv run mkdocs build -f mkdocs/mkdocs.yml --strict

# ===================
# Project Maintenance
Expand All @@ -161,7 +158,7 @@ docs-build: ## Build the static documentation site

clean: ## Remove build artifacts and caches
@echo "Cleaning up Cython and Python cached files..."
@rm -rf build dist *.egg-info
@rm -rf build dist *.egg-info .venv
@find . -name "*.so" -exec echo Deleting {} \; -delete
@find . -name "*.pyc" -exec echo Deleting {} \; -delete
@find . -name "__pycache__" -exec echo Deleting {} \; -exec rm -rf {} +
Expand Down
82 changes: 43 additions & 39 deletions build-module.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,54 +18,58 @@
import os
import shutil
from pathlib import Path
from typing import Any

allowed_to_fail = os.environ.get("CIBUILDWHEEL", "0") != "1"
from hatchling.builders.hooks.plugin.interface import BuildHookInterface

allowed_to_fail = os.environ.get("CIBUILDWHEEL", "0") != "1"

def build_cython_extensions() -> None:
import Cython.Compiler.Options
from Cython.Build import build_ext, cythonize
from setuptools import Extension
from setuptools.dist import Distribution

Cython.Compiler.Options.annotate = True
class CythonBuildHook(BuildHookInterface):
def build_cython_extensions(self) -> None:
import Cython.Compiler.Options
from Cython.Build import build_ext, cythonize
from setuptools import Extension
from setuptools.dist import Distribution

if os.name == "nt": # Windows
extra_compile_args = [
"/O2",
]
else: # UNIX-based systems
extra_compile_args = [
"-O3",
]
Cython.Compiler.Options.annotate = True

package_path = "pyiceberg"
if os.name == "nt": # Windows
extra_compile_args = [
"/O2",
]
else: # UNIX-based systems
extra_compile_args = [
"-O3",
]

extension = Extension(
# Your .pyx file will be available to cpython at this location.
name="pyiceberg.avro.decoder_fast",
sources=[
os.path.join(package_path, "avro", "decoder_fast.pyx"),
],
extra_compile_args=extra_compile_args,
language="c",
)
package_path = "pyiceberg"

ext_modules = cythonize([extension], include_path=list(package_path), language_level=3, annotate=True)
dist = Distribution({"ext_modules": ext_modules})
cmd = build_ext(dist)
cmd.ensure_finalized()
extension = Extension(
# Your .pyx file will be available to cpython at this location.
name="pyiceberg.avro.decoder_fast",
sources=[
os.path.join(package_path, "avro", "decoder_fast.pyx"),
],
extra_compile_args=extra_compile_args,
language="c",
)

cmd.run()
ext_modules = cythonize([extension], include_path=list(package_path), language_level=3, annotate=True)
dist = Distribution({"ext_modules": ext_modules})
cmd = build_ext(dist)
cmd.ensure_finalized()

for output in cmd.get_outputs():
output = Path(output)
relative_extension = output.relative_to(cmd.build_lib)
shutil.copyfile(output, relative_extension)
cmd.run()

for output in cmd.get_outputs():
output = Path(output)
relative_extension = output.relative_to(cmd.build_lib)
shutil.copyfile(output, relative_extension)

try:
build_cython_extensions()
except Exception:
if not allowed_to_fail:
raise
def initialize(self, version: str, build_data: dict[str, Any]) -> None:
try:
self.build_cython_extensions()
except Exception:
if not allowed_to_fail:
raise
2 changes: 1 addition & 1 deletion dev/.rat-excludes
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@
build
.git
.gitignore
poetry.lock
uv.lock
mkdocs/*
Loading