Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
73 commits
Select commit Hold shift + click to select a range
0f87af2
Initial plan
Copilot Jan 26, 2026
35f3a8a
Add type stub file for rawpy module
Copilot Jan 26, 2026
c2c7c18
Fix enum definitions in type stubs and add type checking test
Copilot Jan 26, 2026
b0f476a
Address code review feedback: use actual defaults and improve type na…
Copilot Jan 26, 2026
d03dcd1
Replace type stub file with inline type annotations
Copilot Jan 27, 2026
cc05560
Use __future__ annotations to avoid quoted type hints
Copilot Jan 27, 2026
fd893dc
Add inline type annotations to _rawpy.pyx
Copilot Jan 27, 2026
f812037
Fix Cython type annotations for CI compatibility
Copilot Jan 27, 2026
2a4bf2c
Fix Cython type declaration warnings at lines 1119, 1121, 1125
Copilot Jan 27, 2026
07abbe0
Remove all quoted type annotations to fix Cython 3.2.4 compilation
Copilot Jan 28, 2026
f643431
Merge main branch - resolve conflicts and add type annotations to new…
Copilot Jan 28, 2026
491901b
Merge latest main and fix test_type_stubs.py to use existing test image
Copilot Jan 28, 2026
4b056b3
Merge branch 'main' into copilot/add-type-stubs-for-rawpy
letmaik Jan 28, 2026
2c47972
Migrate all properties from legacy Cython syntax to Python @property …
Copilot Jan 28, 2026
37566b9
Apply suggestions from code review
letmaik Jan 29, 2026
0215109
Apply suggestion from @letmaik
letmaik Jan 29, 2026
1860259
Apply suggestion from @letmaik
letmaik Jan 29, 2026
ba39f02
Add _rawpy.pyi stub file for Cython module API
Copilot Jan 29, 2026
aa5a5fa
Change Enums to IntEnum and add full docstrings to .pyi stub file
Copilot Jan 29, 2026
54f232c
Revert IntEnum back to Enum in both .pyx and .pyi files
Copilot Jan 29, 2026
2fed94e
Update .pyx return annotations to match .pyi with NDArray types for c…
Copilot Jan 29, 2026
a3cc6ea
Add test using mypy stubtest to verify .pyi matches runtime signatures
Copilot Jan 29, 2026
1a24d20
Delete test/test_type_stubs.py
letmaik Jan 29, 2026
1bbdf6c
Make stubtest a required test by removing skips
Copilot Jan 29, 2026
c0beb40
Use allowlist and --ignore-disjoint-bases to exclude internal impleme…
Copilot Jan 29, 2026
b8143b3
Apply suggestion from @letmaik
letmaik Jan 29, 2026
99700fa
Use BinaryIO type for fileobj parameter and add mypy validation test
Copilot Jan 29, 2026
cdc5cde
Simplify test_mypy.py to check both folders at once
Copilot Jan 29, 2026
e8c6661
Fix mypy test errors by adding TYPE_CHECKING import and --install-typ…
Copilot Jan 30, 2026
5cd8aba
Add TYPE_CHECKING imports for all types exported by rawpy
Copilot Jan 30, 2026
2fd5e57
Apply suggestion from @letmaik
letmaik Jan 30, 2026
b5b9c1a
Use isinstance() check and @overload for better type narrowing withou…
Copilot Jan 30, 2026
c3d3005
Remove redundant @overload declarations from imread()
Copilot Jan 30, 2026
38a1e74
Merge branch 'main' into copilot/add-type-stubs-for-rawpy
letmaik Jan 30, 2026
05b111d
Fix UnboundLocalError in test_type_imports.py and add --ignore-missin…
Copilot Jan 30, 2026
bdff970
Build absolute paths based on __file__ in test_mypy.py
Copilot Jan 30, 2026
b530a04
Replace --ignore-missing-imports flag with mypy.ini config file
Copilot Jan 30, 2026
45775f7
Simplify test_mypy.py to use cwd parameter instead of absolute paths
Copilot Jan 30, 2026
7cc4a82
Fix all mypy type errors from CI
Copilot Jan 30, 2026
8227922
Remove all type: ignore comments and fix type issues properly
Copilot Jan 30, 2026
1120846
Add numpy and pytest to mypy.ini ignore_missing_imports
Copilot Jan 30, 2026
9c75c84
Remove numpy and pytest from mypy.ini - they have proper type support
Copilot Jan 30, 2026
a4478eb
Fix remaining mypy errors and add imageio.v3 to ignore list
Copilot Jan 30, 2026
d087277
Remove test file
Copilot Jan 30, 2026
2189c9f
Remove redundant explicit assignments of flags and libraw_version
Copilot Jan 30, 2026
2351d97
agents & cleanup
letmaik Feb 4, 2026
70ce47d
possible fixes
letmaik Feb 8, 2026
63fc48c
cleanup
letmaik Feb 8, 2026
9aa2651
fix numpy compat
letmaik Feb 8, 2026
e6ce20a
cleanup ci
letmaik Feb 8, 2026
f9bcd3b
fix tests
letmaik Feb 8, 2026
66f64ff
fix windows wheels
letmaik Feb 8, 2026
240d5fd
fix typing
letmaik Feb 8, 2026
cc80c41
agent: setup python/numpy versions
letmaik Feb 8, 2026
9a1dcf1
mostly sdist + agent harness
letmaik Feb 9, 2026
1e3c299
check flags
letmaik Feb 9, 2026
b87472a
more fixes
letmaik Feb 9, 2026
8f26321
fix sdist ci test
letmaik Feb 9, 2026
c124ab0
allow libjasper to be missing in sdist tests in CI
letmaik Feb 9, 2026
5115504
skip redundant pkg install on windows ci
letmaik Feb 9, 2026
1c5988d
add cross-links to py docs
letmaik Feb 9, 2026
9f0983f
cleanup
letmaik Feb 9, 2026
2c5d86d
Merge remote-tracking branch 'origin/main' into copilot/add-type-stub…
letmaik Feb 9, 2026
f6c244b
test for cblack regression
letmaik Feb 10, 2026
e29fee3
skip slow example crash tests on aarch64 (qemu)
letmaik Feb 10, 2026
651487c
re-enable openmp on linux
letmaik Feb 10, 2026
1cf3bfc
re-enable parallel build on linux (libraw)
letmaik Feb 10, 2026
4699d1d
remove -j from cmake build to avoid OOM on QEMU aarch64
letmaik Feb 10, 2026
9e5b151
publish sdist to PyPI alongside wheels
letmaik Feb 10, 2026
4ae93c5
minor cleanup
letmaik Feb 10, 2026
1459b11
use custom build_ext to get rid of hack
letmaik Feb 10, 2026
65a999c
fix
letmaik Feb 10, 2026
c66fd76
cleanuo
letmaik Feb 10, 2026
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
23 changes: 2 additions & 21 deletions .github/scripts/build-linux.sh
Original file line number Diff line number Diff line change
Expand Up @@ -63,23 +63,6 @@ cmake -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Release \
make install -j$(nproc)
popd

# Install libraw
libraw_dir=$(pwd)/external/LibRaw
pushd external/LibRaw-cmake
mkdir build
cd build
cmake .. \
-DCMAKE_INSTALL_PREFIX=/usr \
-DLIBRAW_PATH=$libraw_dir \
-DENABLE_X3FTOOLS=ON \
-DENABLE_6BY9RPI=ON \
-DENABLE_EXAMPLES=OFF \
-DENABLE_RAWSPEED=OFF \
-DCMAKE_BUILD_TYPE=Release
make
make install -j$(nproc)
popd

# Install matplotlib (a scikit-image dependency) dependencies
retry dnf install -y libpng-devel freetype-devel

Expand All @@ -90,15 +73,13 @@ retry dnf install -y lapack-devel blas-devel
${PYBIN}/python -m pip install --upgrade pip
export PIP_PREFER_BINARY=1

# install compile-time dependencies
retry ${PYBIN}/pip install numpy==${NUMPY_VERSION} cython setuptools

# List installed packages
${PYBIN}/pip freeze

# Build rawpy wheel
# Relies on pyproject.toml to create an isolated build env with the correct numpy version
export LDFLAGS="-Wl,--strip-debug"
${PYBIN}/python setup.py bdist_wheel --dist-dir dist-tmp
${PYBIN}/pip wheel . --wheel-dir dist-tmp --no-deps

# Bundle external shared libraries into wheel and fix the wheel tags
mkdir dist
Expand Down
6 changes: 3 additions & 3 deletions .github/scripts/build-macos.sh
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ popd
python -m pip install --upgrade pip
export PIP_PREFER_BINARY=1

# Install dependencies
pip install numpy==$NUMPY_VERSION cython wheel delocate setuptools
# Install delocate for bundling shared libraries into the wheel
pip install delocate

# List installed packages
pip freeze
Expand Down Expand Up @@ -110,7 +110,7 @@ export LDFLAGS=$CFLAGS
export ARCHFLAGS=$CFLAGS

# Build wheel
python setup.py bdist_wheel
pip wheel . --wheel-dir dist --no-deps

DYLD_LIBRARY_PATH=$LIB_INSTALL_PREFIX/lib delocate-listdeps --all --depending dist/*.whl # lists library dependencies
DYLD_LIBRARY_PATH=$LIB_INSTALL_PREFIX/lib delocate-wheel --verbose --require-archs=${PYTHON_ARCH} dist/*.whl # copies library dependencies into wheel
Expand Down
66 changes: 9 additions & 57 deletions .github/scripts/build-windows.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -13,52 +13,6 @@ function exec {
}
}

function Initialize-Python {
if ($env:USE_CONDA -eq 1) {
$env:CONDA_ROOT = $pwd.Path + "\external\miniconda_$env:PYTHON_ARCH"
& .\.github\scripts\install-miniconda.ps1
& $env:CONDA_ROOT\shell\condabin\conda-hook.ps1
exec { conda update --yes -n base -c defaults conda }
}
# Check Python version
exec { python -c "import platform; assert platform.python_version().startswith('$env:PYTHON_VERSION')" }
}

function Create-VEnv {
[CmdletBinding()]
param([Parameter(Position=0,Mandatory=1)][string]$name)
if ($env:USE_CONDA -eq 1) {
exec { conda create --yes --name $name -c defaults --strict-channel-priority python=$env:PYTHON_VERSION --force }
} else {
exec { python -m venv env\$name }
}
}

function Enter-VEnv {
[CmdletBinding()]
param([Parameter(Position=0,Mandatory=1)][string]$name)
if ($env:USE_CONDA -eq 1) {
conda activate $name
} else {
& .\env\$name\scripts\activate
}
}

function Create-And-Enter-VEnv {
[CmdletBinding()]
param([Parameter(Position=0,Mandatory=1)][string]$name)
Create-VEnv $name
Enter-VEnv $name
}

function Exit-VEnv {
if ($env:USE_CONDA -eq 1) {
conda deactivate
} else {
deactivate
}
}

function Initialize-VS {
# https://wiki.python.org/moin/WindowsCompilers
# setuptools automatically selects the right compiler for building
Expand Down Expand Up @@ -113,12 +67,11 @@ if (!$env:PYTHON_VERSION) {
if ($env:PYTHON_ARCH -ne 'x86' -and $env:PYTHON_ARCH -ne 'x86_64') {
throw "PYTHON_ARCH env var must be x86 or x86_64"
}
if (!$env:NUMPY_VERSION) {
throw "NUMPY_VERSION env var missing"
}

Initialize-VS
Initialize-Python

# Check Python version
exec { python -c "import platform; assert platform.python_version().startswith('$env:PYTHON_VERSION')" }

# Prefer binary packages over building from source
$env:PIP_PREFER_BINARY = 1
Expand All @@ -133,10 +86,9 @@ if (!(Test-Path ./vcpkg)) {
exec { ./vcpkg/vcpkg install zlib libjpeg-turbo[jpeg8] jasper lcms --triplet=x64-windows-static --recurse }
$env:CMAKE_PREFIX_PATH = $pwd.Path + "\vcpkg\installed\x64-windows-static"


# Build the wheel.
Create-And-Enter-VEnv build
exec { python -m pip install --upgrade pip wheel setuptools }
exec { python -m pip install --only-binary :all: numpy==$env:NUMPY_VERSION cython }
exec { python -u setup.py bdist_wheel }
Exit-VEnv
# Build the wheel in a virtual environment
exec { python -m venv env\build }
& .\env\build\scripts\activate
exec { python -m pip install --upgrade pip }
exec { python -m pip wheel . --wheel-dir dist --no-deps }
deactivate
68 changes: 0 additions & 68 deletions .github/scripts/install-miniconda.ps1

This file was deleted.

67 changes: 67 additions & 0 deletions .github/scripts/test-sdist-linux.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#!/bin/bash
# Test sdist: install from source in a clean venv and run the test suite.
# This validates that the sdist contains everything needed to build.
#
# When RAWPY_USE_SYSTEM_LIBRAW=1 is set, the sdist is built against the
# system libraw and linkage is verified (no bundled libraw_r.so, ldd
# points to system library).
set -e -x

PYTHON_BIN="python${PYTHON_VERSION}"

# Install system build dependencies
sudo apt-get update -q
sudo apt-get install -y -q \
liblcms2-dev \
libjpeg-dev

# Create a clean venv
${PYTHON_BIN} -m venv sdist-test-env
source sdist-test-env/bin/activate
python -m pip install --upgrade pip

# Install the sdist (pip will build from source with build isolation)
# RAWPY_USE_SYSTEM_LIBRAW is inherited from the environment if set.
SDIST=$(ls dist/rawpy-*.tar.gz | head -1)
pip install "${SDIST}[test]"

# Run tests from a temp directory to avoid importing from the source tree
mkdir tmp_for_test
pushd tmp_for_test

# Verify system libraw linkage when applicable
if [ "$RAWPY_USE_SYSTEM_LIBRAW" = "1" ]; then
python -c "
import rawpy._rawpy as _rawpy
import os, subprocess, sys

ext_path = _rawpy.__file__
pkg_dir = os.path.dirname(ext_path)
print(f'Extension: {ext_path}')

# No bundled libraw_r.so in the package directory
bundled = [f for f in os.listdir(pkg_dir) if f.startswith('libraw_r.so')]
if bundled:
print(f'FAIL: Found bundled libraw files: {bundled}')
sys.exit(1)
print('OK: No bundled libraw_r.so in package directory')

# ldd shows system libraw, not a local path
result = subprocess.run(['ldd', ext_path], capture_output=True, text=True)
libraw_lines = [l.strip() for l in result.stdout.splitlines() if 'libraw_r' in l]
if not libraw_lines:
print('FAIL: libraw_r.so not found in ldd output')
sys.exit(1)
for line in libraw_lines:
print(f'ldd: {line}')
if pkg_dir in line:
print('FAIL: libraw_r.so resolves to the package directory')
sys.exit(1)
print('OK: libraw_r.so links to system library')
"
fi

pytest --verbosity=3 -s ../test
popd

deactivate
24 changes: 24 additions & 0 deletions .github/scripts/test-sdist-macos.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#!/bin/bash
# Test sdist: install from source in a clean venv and run the test suite.
# This validates that the sdist contains everything needed to build on macOS.
set -e -x

# Install build dependencies
brew install jasper

# Create a clean venv
python${PYTHON_VERSION} -m venv sdist-test-env
source sdist-test-env/bin/activate
python -m pip install --upgrade pip

# Install the sdist (pip will build from source with build isolation)
SDIST=$(ls dist/rawpy-*.tar.gz | head -1)
pip install "${SDIST}[test]"

# Run tests from a temp directory to avoid importing from the source tree
mkdir tmp_for_test
pushd tmp_for_test
pytest --verbosity=3 -s ../test
popd

deactivate
89 changes: 89 additions & 0 deletions .github/scripts/test-sdist-windows.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
$ErrorActionPreference = 'Stop'

function exec {
[CmdletBinding()]
param([Parameter(Position=0,Mandatory=1)][scriptblock]$cmd)
Write-Host "$cmd"
$ErrorActionPreference = 'Continue'
& $cmd
$ErrorActionPreference = 'Stop'
if ($lastexitcode -ne 0) {
throw ("ERROR exit code $lastexitcode")
}
}

function Initialize-VS {
$VS_ROOTS = @(
"C:\Program Files\Microsoft Visual Studio",
"C:\Program Files (x86)\Microsoft Visual Studio"
)
$VS_VERSIONS = @("2017", "2019", "2022")
$VS_EDITIONS = @("Enterprise", "Professional", "Community")
$VS_INIT_CMD_SUFFIX = "Common7\Tools\vsdevcmd.bat"

$VS_ARCH = if ($env:PYTHON_ARCH -eq 'x86') { 'x86' } else { 'x64' }
$VS_INIT_ARGS = "-arch=$VS_ARCH -no_logo"

$found = $false
:outer foreach ($VS_ROOT in $VS_ROOTS) {
foreach ($version in $VS_VERSIONS) {
foreach ($edition in $VS_EDITIONS) {
$VS_INIT_CMD = "$VS_ROOT\$version\$edition\$VS_INIT_CMD_SUFFIX"
if (Test-Path $VS_INIT_CMD) {
$found = $true
break outer
}
}
}
}

if (!$found) {
throw ("No suitable Visual Studio installation found")
}

Write-Host "Executing: $VS_INIT_CMD $VS_INIT_ARGS"

& "${env:COMSPEC}" /s /c "`"$VS_INIT_CMD`" $VS_INIT_ARGS && set" | foreach-object {
$name, $value = $_ -split '=', 2
try {
set-content env:\"$name" $value
} catch {
}
}
}

if (!$env:PYTHON_VERSION) {
throw "PYTHON_VERSION env var missing, must be x.y"
}
if ($env:PYTHON_ARCH -ne 'x86' -and $env:PYTHON_ARCH -ne 'x86_64') {
throw "PYTHON_ARCH env var must be x86 or x86_64"
}

Initialize-VS

# Check Python version
exec { python -c "import platform; assert platform.python_version().startswith('$env:PYTHON_VERSION')" }

# Install vcpkg dependencies (needed for building from source)
if (!(Test-Path ./vcpkg)) {
exec { git clone https://github.com/microsoft/vcpkg -b 2025.01.13 --depth 1 }
exec { ./vcpkg/bootstrap-vcpkg }
}
exec { ./vcpkg/vcpkg install zlib libjpeg-turbo[jpeg8] jasper lcms --triplet=x64-windows-static --recurse }
$env:CMAKE_PREFIX_PATH = $pwd.Path + "\vcpkg\installed\x64-windows-static"

# Create a clean venv and install the sdist
exec { python -m venv sdist-test-env }
& .\sdist-test-env\scripts\activate
exec { python -m pip install --upgrade pip }

$sdist = Get-ChildItem dist\rawpy-*.tar.gz | Select-Object -First 1
exec { pip install "$($sdist.FullName)[test]" }

# Run tests from a temp directory to avoid importing from the source tree
mkdir -f tmp_for_test | out-null
pushd tmp_for_test
exec { pytest --verbosity=3 -s ../test }
popd

deactivate
Loading