Skip to content

Commit e333e15

Browse files
Copilotletmaik
andauthored
Add type annotations, modernise build, publish sdist, add agent harness (#275)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: letmaik <530988+letmaik@users.noreply.github.com> Co-authored-by: Maik Riechert <letmaik@outlook.com>
1 parent a411daa commit e333e15

40 files changed

+3276
-786
lines changed

.github/scripts/build-linux.sh

Lines changed: 2 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -63,23 +63,6 @@ cmake -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Release \
6363
make install -j$(nproc)
6464
popd
6565

66-
# Install libraw
67-
libraw_dir=$(pwd)/external/LibRaw
68-
pushd external/LibRaw-cmake
69-
mkdir build
70-
cd build
71-
cmake .. \
72-
-DCMAKE_INSTALL_PREFIX=/usr \
73-
-DLIBRAW_PATH=$libraw_dir \
74-
-DENABLE_X3FTOOLS=ON \
75-
-DENABLE_6BY9RPI=ON \
76-
-DENABLE_EXAMPLES=OFF \
77-
-DENABLE_RAWSPEED=OFF \
78-
-DCMAKE_BUILD_TYPE=Release
79-
make
80-
make install -j$(nproc)
81-
popd
82-
8366
# Install matplotlib (a scikit-image dependency) dependencies
8467
retry dnf install -y libpng-devel freetype-devel
8568

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

93-
# install compile-time dependencies
94-
retry ${PYBIN}/pip install numpy==${NUMPY_VERSION} cython setuptools
95-
9676
# List installed packages
9777
${PYBIN}/pip freeze
9878

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

10384
# Bundle external shared libraries into wheel and fix the wheel tags
10485
mkdir dist

.github/scripts/build-macos.sh

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ popd
3434
python -m pip install --upgrade pip
3535
export PIP_PREFER_BINARY=1
3636

37-
# Install dependencies
38-
pip install numpy==$NUMPY_VERSION cython wheel delocate setuptools
37+
# Install delocate for bundling shared libraries into the wheel
38+
pip install delocate
3939

4040
# List installed packages
4141
pip freeze
@@ -110,7 +110,7 @@ export LDFLAGS=$CFLAGS
110110
export ARCHFLAGS=$CFLAGS
111111

112112
# Build wheel
113-
python setup.py bdist_wheel
113+
pip wheel . --wheel-dir dist --no-deps
114114

115115
DYLD_LIBRARY_PATH=$LIB_INSTALL_PREFIX/lib delocate-listdeps --all --depending dist/*.whl # lists library dependencies
116116
DYLD_LIBRARY_PATH=$LIB_INSTALL_PREFIX/lib delocate-wheel --verbose --require-archs=${PYTHON_ARCH} dist/*.whl # copies library dependencies into wheel

.github/scripts/build-windows.ps1

Lines changed: 9 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -13,52 +13,6 @@ function exec {
1313
}
1414
}
1515

16-
function Initialize-Python {
17-
if ($env:USE_CONDA -eq 1) {
18-
$env:CONDA_ROOT = $pwd.Path + "\external\miniconda_$env:PYTHON_ARCH"
19-
& .\.github\scripts\install-miniconda.ps1
20-
& $env:CONDA_ROOT\shell\condabin\conda-hook.ps1
21-
exec { conda update --yes -n base -c defaults conda }
22-
}
23-
# Check Python version
24-
exec { python -c "import platform; assert platform.python_version().startswith('$env:PYTHON_VERSION')" }
25-
}
26-
27-
function Create-VEnv {
28-
[CmdletBinding()]
29-
param([Parameter(Position=0,Mandatory=1)][string]$name)
30-
if ($env:USE_CONDA -eq 1) {
31-
exec { conda create --yes --name $name -c defaults --strict-channel-priority python=$env:PYTHON_VERSION --force }
32-
} else {
33-
exec { python -m venv env\$name }
34-
}
35-
}
36-
37-
function Enter-VEnv {
38-
[CmdletBinding()]
39-
param([Parameter(Position=0,Mandatory=1)][string]$name)
40-
if ($env:USE_CONDA -eq 1) {
41-
conda activate $name
42-
} else {
43-
& .\env\$name\scripts\activate
44-
}
45-
}
46-
47-
function Create-And-Enter-VEnv {
48-
[CmdletBinding()]
49-
param([Parameter(Position=0,Mandatory=1)][string]$name)
50-
Create-VEnv $name
51-
Enter-VEnv $name
52-
}
53-
54-
function Exit-VEnv {
55-
if ($env:USE_CONDA -eq 1) {
56-
conda deactivate
57-
} else {
58-
deactivate
59-
}
60-
}
61-
6216
function Initialize-VS {
6317
# https://wiki.python.org/moin/WindowsCompilers
6418
# setuptools automatically selects the right compiler for building
@@ -113,12 +67,11 @@ if (!$env:PYTHON_VERSION) {
11367
if ($env:PYTHON_ARCH -ne 'x86' -and $env:PYTHON_ARCH -ne 'x86_64') {
11468
throw "PYTHON_ARCH env var must be x86 or x86_64"
11569
}
116-
if (!$env:NUMPY_VERSION) {
117-
throw "NUMPY_VERSION env var missing"
118-
}
11970

12071
Initialize-VS
121-
Initialize-Python
72+
73+
# Check Python version
74+
exec { python -c "import platform; assert platform.python_version().startswith('$env:PYTHON_VERSION')" }
12275

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

136-
137-
# Build the wheel.
138-
Create-And-Enter-VEnv build
139-
exec { python -m pip install --upgrade pip wheel setuptools }
140-
exec { python -m pip install --only-binary :all: numpy==$env:NUMPY_VERSION cython }
141-
exec { python -u setup.py bdist_wheel }
142-
Exit-VEnv
89+
# Build the wheel in a virtual environment
90+
exec { python -m venv env\build }
91+
& .\env\build\scripts\activate
92+
exec { python -m pip install --upgrade pip }
93+
exec { python -m pip wheel . --wheel-dir dist --no-deps }
94+
deactivate

.github/scripts/install-miniconda.ps1

Lines changed: 0 additions & 68 deletions
This file was deleted.
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
#!/bin/bash
2+
# Test sdist: install from source in a clean venv and run the test suite.
3+
# This validates that the sdist contains everything needed to build.
4+
#
5+
# When RAWPY_USE_SYSTEM_LIBRAW=1 is set, the sdist is built against the
6+
# system libraw and linkage is verified (no bundled libraw_r.so, ldd
7+
# points to system library).
8+
set -e -x
9+
10+
PYTHON_BIN="python${PYTHON_VERSION}"
11+
12+
# Install system build dependencies
13+
sudo apt-get update -q
14+
sudo apt-get install -y -q \
15+
liblcms2-dev \
16+
libjpeg-dev
17+
18+
# Create a clean venv
19+
${PYTHON_BIN} -m venv sdist-test-env
20+
source sdist-test-env/bin/activate
21+
python -m pip install --upgrade pip
22+
23+
# Install the sdist (pip will build from source with build isolation)
24+
# RAWPY_USE_SYSTEM_LIBRAW is inherited from the environment if set.
25+
SDIST=$(ls dist/rawpy-*.tar.gz | head -1)
26+
pip install "${SDIST}[test]"
27+
28+
# Run tests from a temp directory to avoid importing from the source tree
29+
mkdir tmp_for_test
30+
pushd tmp_for_test
31+
32+
# Verify system libraw linkage when applicable
33+
if [ "$RAWPY_USE_SYSTEM_LIBRAW" = "1" ]; then
34+
python -c "
35+
import rawpy._rawpy as _rawpy
36+
import os, subprocess, sys
37+
38+
ext_path = _rawpy.__file__
39+
pkg_dir = os.path.dirname(ext_path)
40+
print(f'Extension: {ext_path}')
41+
42+
# No bundled libraw_r.so in the package directory
43+
bundled = [f for f in os.listdir(pkg_dir) if f.startswith('libraw_r.so')]
44+
if bundled:
45+
print(f'FAIL: Found bundled libraw files: {bundled}')
46+
sys.exit(1)
47+
print('OK: No bundled libraw_r.so in package directory')
48+
49+
# ldd shows system libraw, not a local path
50+
result = subprocess.run(['ldd', ext_path], capture_output=True, text=True)
51+
libraw_lines = [l.strip() for l in result.stdout.splitlines() if 'libraw_r' in l]
52+
if not libraw_lines:
53+
print('FAIL: libraw_r.so not found in ldd output')
54+
sys.exit(1)
55+
for line in libraw_lines:
56+
print(f'ldd: {line}')
57+
if pkg_dir in line:
58+
print('FAIL: libraw_r.so resolves to the package directory')
59+
sys.exit(1)
60+
print('OK: libraw_r.so links to system library')
61+
"
62+
fi
63+
64+
pytest --verbosity=3 -s ../test
65+
popd
66+
67+
deactivate
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#!/bin/bash
2+
# Test sdist: install from source in a clean venv and run the test suite.
3+
# This validates that the sdist contains everything needed to build on macOS.
4+
set -e -x
5+
6+
# Install build dependencies
7+
brew install jasper
8+
9+
# Create a clean venv
10+
python${PYTHON_VERSION} -m venv sdist-test-env
11+
source sdist-test-env/bin/activate
12+
python -m pip install --upgrade pip
13+
14+
# Install the sdist (pip will build from source with build isolation)
15+
SDIST=$(ls dist/rawpy-*.tar.gz | head -1)
16+
pip install "${SDIST}[test]"
17+
18+
# Run tests from a temp directory to avoid importing from the source tree
19+
mkdir tmp_for_test
20+
pushd tmp_for_test
21+
pytest --verbosity=3 -s ../test
22+
popd
23+
24+
deactivate
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
$ErrorActionPreference = 'Stop'
2+
3+
function exec {
4+
[CmdletBinding()]
5+
param([Parameter(Position=0,Mandatory=1)][scriptblock]$cmd)
6+
Write-Host "$cmd"
7+
$ErrorActionPreference = 'Continue'
8+
& $cmd
9+
$ErrorActionPreference = 'Stop'
10+
if ($lastexitcode -ne 0) {
11+
throw ("ERROR exit code $lastexitcode")
12+
}
13+
}
14+
15+
function Initialize-VS {
16+
$VS_ROOTS = @(
17+
"C:\Program Files\Microsoft Visual Studio",
18+
"C:\Program Files (x86)\Microsoft Visual Studio"
19+
)
20+
$VS_VERSIONS = @("2017", "2019", "2022")
21+
$VS_EDITIONS = @("Enterprise", "Professional", "Community")
22+
$VS_INIT_CMD_SUFFIX = "Common7\Tools\vsdevcmd.bat"
23+
24+
$VS_ARCH = if ($env:PYTHON_ARCH -eq 'x86') { 'x86' } else { 'x64' }
25+
$VS_INIT_ARGS = "-arch=$VS_ARCH -no_logo"
26+
27+
$found = $false
28+
:outer foreach ($VS_ROOT in $VS_ROOTS) {
29+
foreach ($version in $VS_VERSIONS) {
30+
foreach ($edition in $VS_EDITIONS) {
31+
$VS_INIT_CMD = "$VS_ROOT\$version\$edition\$VS_INIT_CMD_SUFFIX"
32+
if (Test-Path $VS_INIT_CMD) {
33+
$found = $true
34+
break outer
35+
}
36+
}
37+
}
38+
}
39+
40+
if (!$found) {
41+
throw ("No suitable Visual Studio installation found")
42+
}
43+
44+
Write-Host "Executing: $VS_INIT_CMD $VS_INIT_ARGS"
45+
46+
& "${env:COMSPEC}" /s /c "`"$VS_INIT_CMD`" $VS_INIT_ARGS && set" | foreach-object {
47+
$name, $value = $_ -split '=', 2
48+
try {
49+
set-content env:\"$name" $value
50+
} catch {
51+
}
52+
}
53+
}
54+
55+
if (!$env:PYTHON_VERSION) {
56+
throw "PYTHON_VERSION env var missing, must be x.y"
57+
}
58+
if ($env:PYTHON_ARCH -ne 'x86' -and $env:PYTHON_ARCH -ne 'x86_64') {
59+
throw "PYTHON_ARCH env var must be x86 or x86_64"
60+
}
61+
62+
Initialize-VS
63+
64+
# Check Python version
65+
exec { python -c "import platform; assert platform.python_version().startswith('$env:PYTHON_VERSION')" }
66+
67+
# Install vcpkg dependencies (needed for building from source)
68+
if (!(Test-Path ./vcpkg)) {
69+
exec { git clone https://github.com/microsoft/vcpkg -b 2025.01.13 --depth 1 }
70+
exec { ./vcpkg/bootstrap-vcpkg }
71+
}
72+
exec { ./vcpkg/vcpkg install zlib libjpeg-turbo[jpeg8] jasper lcms --triplet=x64-windows-static --recurse }
73+
$env:CMAKE_PREFIX_PATH = $pwd.Path + "\vcpkg\installed\x64-windows-static"
74+
75+
# Create a clean venv and install the sdist
76+
exec { python -m venv sdist-test-env }
77+
& .\sdist-test-env\scripts\activate
78+
exec { python -m pip install --upgrade pip }
79+
80+
$sdist = Get-ChildItem dist\rawpy-*.tar.gz | Select-Object -First 1
81+
exec { pip install "$($sdist.FullName)[test]" }
82+
83+
# Run tests from a temp directory to avoid importing from the source tree
84+
mkdir -f tmp_for_test | out-null
85+
pushd tmp_for_test
86+
exec { pytest --verbosity=3 -s ../test }
87+
popd
88+
89+
deactivate

0 commit comments

Comments
 (0)