Skip to content

Commit 045ea93

Browse files
authored
Switch to pyproject.toml (#49)
1 parent 0378f4d commit 045ea93

File tree

16 files changed

+7990
-3462
lines changed

16 files changed

+7990
-3462
lines changed

.github/workflows/pytest-builds.yml

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name: unit-tests
22

33
on:
44
push:
5-
branches: [ master ]
5+
branches: [ main ]
66
pull_request:
77

88
jobs:
@@ -12,7 +12,7 @@ jobs:
1212
strategy:
1313
fail-fast: false
1414
matrix:
15-
python-version: ['3.7', '3.8', '3.9', '3.10', '3.11']
15+
python-version: ['3.8', '3.9', '3.10', '3.11', '3.12']
1616
arch: ['x64', 'x86']
1717

1818
steps:
@@ -50,7 +50,7 @@ jobs:
5050
strategy:
5151
fail-fast: false
5252
matrix:
53-
python-version: ['3.7', '3.8', '3.9', '3.10', '3.11']
53+
python-version: ['3.8', '3.9', '3.10', '3.11', '3.12']
5454

5555
steps:
5656
- uses: actions/checkout@v2
@@ -86,7 +86,7 @@ jobs:
8686
strategy:
8787
fail-fast: false
8888
matrix:
89-
python-version: ['3.7', '3.8', '3.9', '3.10', '3.11']
89+
python-version: ['3.8', '3.9', '3.10', '3.11', '3.12']
9090

9191
steps:
9292
- uses: actions/checkout@v2
@@ -117,6 +117,7 @@ jobs:
117117
pytest --cov=libjpeg --cov-append libjpeg/tests
118118
119119
- name: Switch to pydicom dev and rerun pytest
120+
if: ${{ contains('3.10 3.11 3.12', matrix.python-version) }}
120121
run: |
121122
pip uninstall -y pydicom
122123
pip install git+https://github.com/pydicom/pydicom

.github/workflows/release-wheels.yml

Lines changed: 22 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ jobs:
1010
runs-on: ubuntu-latest
1111
timeout-minutes: 10
1212
steps:
13-
- uses: actions/checkout@v3
13+
- uses: actions/checkout@v4
1414
with:
1515
submodules: true
1616

@@ -38,9 +38,6 @@ jobs:
3838
matrix:
3939
include:
4040
# Windows 32 bit
41-
- os: windows-latest
42-
python: 37
43-
platform_id: win32
4441
- os: windows-latest
4542
python: 38
4643
platform_id: win32
@@ -53,6 +50,9 @@ jobs:
5350
- os: windows-latest
5451
python: 311
5552
platform_id: win32
53+
- os: windows-latest
54+
python: 312
55+
platform_id: win32
5656

5757
# Windows 64 bit
5858
- os: windows-latest
@@ -70,26 +70,11 @@ jobs:
7070
- os: windows-latest
7171
python: 311
7272
platform_id: win_amd64
73-
74-
# Linux 64 bit manylinux2010
75-
- os: ubuntu-latest
76-
python: 37
77-
platform_id: manylinux_x86_64
78-
manylinux_image: manylinux2010
79-
- os: ubuntu-latest
80-
python: 38
81-
platform_id: manylinux_x86_64
82-
manylinux_image: manylinux2010
83-
- os: ubuntu-latest
84-
python: 39
85-
platform_id: manylinux_x86_64
86-
manylinux_image: manylinux2010
73+
- os: windows-latest
74+
python: 312
75+
platform_id: win_amd64
8776

8877
# Linux 64 bit manylinux2014
89-
- os: ubuntu-latest
90-
python: 37
91-
platform_id: manylinux_x86_64
92-
manylinux_image: manylinux2014
9378
- os: ubuntu-latest
9479
python: 38
9580
platform_id: manylinux_x86_64
@@ -106,11 +91,12 @@ jobs:
10691
python: 311
10792
platform_id: manylinux_x86_64
10893
manylinux_image: manylinux2014
94+
- os: ubuntu-latest
95+
python: 312
96+
platform_id: manylinux_x86_64
97+
manylinux_image: manylinux2014
10998

11099
# Linux aarch64
111-
- os: ubuntu-latest
112-
python: 37
113-
platform_id: manylinux_aarch64
114100
- os: ubuntu-latest
115101
python: 38
116102
platform_id: manylinux_aarch64
@@ -123,11 +109,11 @@ jobs:
123109
- os: ubuntu-latest
124110
python: 311
125111
platform_id: manylinux_aarch64
112+
- os: ubuntu-latest
113+
python: 312
114+
platform_id: manylinux_aarch64
126115

127116
# MacOS x86_64
128-
- os: macos-latest
129-
python: 37
130-
platform_id: macosx_x86_64
131117
- os: macos-latest
132118
python: 38
133119
platform_id: macosx_x86_64
@@ -140,6 +126,9 @@ jobs:
140126
- os: macos-latest
141127
python: 311
142128
platform_id: macosx_x86_64
129+
- os: macos-latest
130+
python: 312
131+
platform_id: macosx_x86_64
143132

144133
# MacOS arm64
145134
- os: macos-latest
@@ -154,9 +143,12 @@ jobs:
154143
- os: macos-latest
155144
python: 311
156145
platform_id: macosx_arm64
146+
- os: macos-latest
147+
python: 312
148+
platform_id: macosx_arm64
157149

158150
steps:
159-
- uses: actions/checkout@v3
151+
- uses: actions/checkout@v4
160152
with:
161153
submodules: true
162154

@@ -202,7 +194,7 @@ jobs:
202194
strategy:
203195
fail-fast: false
204196
matrix:
205-
python-version: ['3.7', '3.8', '3.9', '3.10', '3.11']
197+
python-version: ['3.8', '3.9', '3.10', '3.11', '3.12']
206198

207199
steps:
208200
- name: Set up Python ${{ matrix.python-version }}

MANIFEST.in

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

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
## pylibjpeg-libjpeg
77

8-
A Python 3.7+ wrapper for Thomas Richter's
8+
A Python 3.8+ wrapper for Thomas Richter's
99
[libjpeg](https://github.com/thorfdbg/libjpeg), with a focus on use as a
1010
plugin for [pylibjpeg](http://github.com/pydicom/pylibjpeg).
1111

build.py

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
2+
import os
3+
from pathlib import Path
4+
import platform
5+
import shutil
6+
import subprocess
7+
import sys
8+
from typing import Any, List, Dict
9+
10+
11+
PACKAGE_DIR = Path(__file__).parent / "libjpeg"
12+
LIBJPEG_SRC = PACKAGE_DIR / 'src' / 'libjpeg'
13+
INTERFACE_SRC = PACKAGE_DIR / 'src' / 'interface'
14+
15+
16+
def build(setup_kwargs: Any) -> Any:
17+
from setuptools import Extension
18+
from setuptools.dist import Distribution
19+
import Cython.Compiler.Options
20+
from Cython.Build import build_ext, cythonize
21+
import numpy
22+
23+
# Compiler and linker arguments
24+
extra_compile_args = []
25+
extra_link_args = []
26+
if platform.system() == 'Windows':
27+
os.environ['LIB'] = os.path.abspath(
28+
os.path.join(sys.executable, '../', 'libs')
29+
)
30+
extra_compile_args = get_mscv_args()
31+
elif platform.system() in ['Darwin', 'Linux']:
32+
# Skip configuration if running with `sdist`
33+
if 'sdist' not in sys.argv:
34+
opts = get_gcc_args()
35+
extra_compile_args += opts['ADDOPTS']
36+
extra_link_args += opts['EXTRA_LIBS']
37+
38+
ext = Extension(
39+
'_libjpeg',
40+
[os.fspath(p) for p in get_source_files()],
41+
language='c++',
42+
include_dirs=[
43+
os.fspath(LIBJPEG_SRC),
44+
os.fspath(INTERFACE_SRC),
45+
numpy.get_include(),
46+
],
47+
extra_compile_args=extra_compile_args,
48+
extra_link_args=extra_link_args,
49+
)
50+
51+
ext_modules = cythonize(
52+
[ext],
53+
include_path=ext.include_dirs,
54+
language_level=3,
55+
)
56+
57+
dist = Distribution({"ext_modules": ext_modules})
58+
cmd = build_ext(dist)
59+
cmd.ensure_finalized()
60+
cmd.run()
61+
62+
for output in cmd.get_outputs():
63+
output = Path(output)
64+
relative_ext = output.relative_to(cmd.build_lib)
65+
shutil.copyfile(output, relative_ext)
66+
67+
return setup_kwargs
68+
69+
70+
def get_mscv_args() -> List[str]:
71+
"""Return a list of compiler args for MSVC++'s compiler."""
72+
flags = [
73+
'/GS', # Buffer security check
74+
'/W3', # Warning level
75+
'/Zc:wchar_t', # Use windows char type
76+
'/Zc:inline', # Remove unreferenced function or data (...)
77+
'/Zc:forScope',
78+
'/Od', # Disable optimisation
79+
'/Oy-', # (x86 only) don't omit frame pointer
80+
'/openmp-', # Disable #pragma omp directive
81+
'/FC', # Display full path of source code files
82+
'/fp:precise', # Floating-point behaviour
83+
'/Gd', # (x86 only) use __cdecl calling convention
84+
'/GF-', # Disable string pooling
85+
'/GR', # Enable run-time type info
86+
'/RTC1', # Enable run-time error checking
87+
'/MT', # Create multithreading executable
88+
# /D defines constants and macros
89+
'/D_UNICODE',
90+
'/DUNICODE',
91+
]
92+
93+
# Set the architecture based on system architecture and Python
94+
is_x64 = platform.architecture()[0] == '64bit'
95+
if is_x64 and sys.maxsize > 2**32:
96+
flags.append('/DWIN64=1')
97+
else:
98+
# Architecture is 32-bit, or Python is 32-bit
99+
flags.append('/DWIN32=1')
100+
101+
return flags
102+
103+
104+
def get_gcc_args() -> Dict[str, str]:
105+
"""Return a list of compiler and linker args for GCC/clang.
106+
107+
The args are determined by running the src/libjpeg/configure script then
108+
parsing src/libjpeg/automakefile for the relevant values.
109+
110+
Returns
111+
-------
112+
dict
113+
A dict with keys COMPILER_CMD, CC_ONLY, SETTINGS, PREFIX,
114+
PTHREADCFLAGS, PTHREADLDFLAGS, PTHREADLIBS, HWTYPE, HAVE_ADDONS,
115+
BITSIZE, ADDOPTS, LIB_OPTS, EXTRA_LIBS, CPU, TUNE.
116+
"""
117+
# Run configure script once
118+
# Using GCC or clang, run `configure` bash script once
119+
if 'config.log' not in os.listdir(LIBJPEG_SRC):
120+
# Needs to be determined before changing the working dir
121+
fpath = os.path.abspath(LIBJPEG_SRC)
122+
# Needs to be run from within the src/libjpeg directory
123+
current_dir = os.getcwd()
124+
os.chdir(LIBJPEG_SRC)
125+
subprocess.call([os.path.join(fpath, 'configure')])
126+
os.chdir(current_dir)
127+
128+
# Get compilation options
129+
with open(os.path.join(LIBJPEG_SRC, 'automakefile')) as fp:
130+
lines = fp.readlines()
131+
132+
lines = [ll for ll in lines if not ll.startswith('#')]
133+
opts = [ll.split('=', 1) for ll in lines]
134+
opts = {vv[0].strip():list(vv[1].strip().split(' ')) for vv in opts}
135+
136+
return opts
137+
138+
139+
def get_source_files() -> List[Path]:
140+
"""Return a list of paths to the source files to be compiled."""
141+
source_files = [
142+
PACKAGE_DIR / '_libjpeg.pyx',
143+
INTERFACE_SRC /'decode.cpp',
144+
INTERFACE_SRC /'streamhook.cpp',
145+
]
146+
for p in LIBJPEG_SRC.glob('*/*'):
147+
if p.suffix == '.cpp':
148+
source_files.append(p)
149+
150+
# Source files must always be relative to the setup.py directory
151+
source_files = [p.relative_to(PACKAGE_DIR.parent) for p in source_files]
152+
153+
return source_files

docs/changes/v2.0.0.rst

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
.. _v2.0.0:
2+
3+
2.0.0
4+
=====
5+
6+
Changes
7+
.......
8+
9+
* Supports Python 3.8-3.12
10+
* Switched build to ``pyproject.toml``

0 commit comments

Comments
 (0)