Skip to content

Commit f43f5bb

Browse files
committed
Add python stubs to built wheels
Adds support for IDE type completion and static type analysis
1 parent 8983451 commit f43f5bb

35 files changed

+3044
-71
lines changed

.github/workflows/wheel_workflow.yml

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,14 +144,21 @@ jobs:
144144
- name: Build wheels
145145
uses: pypa/[email protected]
146146
env:
147+
# pass GITHUB_ACTIONS through to the build container so that custom
148+
# processes can tell they are running in CI.
149+
CIBW_ENVIRONMENT_PASS_LINUX: GITHUB_ACTIONS
147150
CIBW_BUILD: ${{ matrix.python }}
148151
CIBW_ARCHS: ${{ matrix.arch }}
149152
CIBW_MANYLINUX_X86_64_IMAGE: ${{ matrix.manylinux }}
150153

151154
- uses: actions/upload-artifact@v4
152155
with:
153156
name: cibw-wheels-${{ matrix.python }}-${{ matrix.manylinux }}
154-
path: ./wheelhouse/*.whl
157+
path: |
158+
./wheelhouse/*.whl
159+
./wheelhouse/PyOpenColorIO/__init__.pyi
160+
# if stub validation fails we want to upload the stubs for users to review
161+
if: success() || failure()
155162

156163
# ---------------------------------------------------------------------------
157164
# Linux ARM Wheels
@@ -213,7 +220,11 @@ jobs:
213220
- uses: actions/upload-artifact@v4
214221
with:
215222
name: cibw-wheels-${{ matrix.python }}-${{ matrix.manylinux }}
216-
path: ./wheelhouse/*.whl
223+
path: |
224+
./wheelhouse/*.whl
225+
./wheelhouse/PyOpenColorIO/__init__.pyi
226+
# if stub validation fails we want to upload the stubs for users to review
227+
if: success() || failure()
217228

218229
# ---------------------------------------------------------------------------
219230
# macOS Wheels

pyproject.toml

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,35 @@ before-build = "share/ci/scripts/macos/install_docs_env.sh"
4040
# Disable for now as wheels are built with static dependencies.
4141
environment = { PATH="$GITHUB_WORKSPACE/doxygen;$PATH", OCIO_PYTHON_LOAD_DLLS_FROM_PATH="0" }
4242
before-build = 'bash -c "share/ci/scripts/windows/install_docs_env.sh $GITHUB_WORKSPACE/doxygen"'
43+
44+
[[tool.cibuildwheel.overrides]]
45+
# Trigger the build & validation of the python stubs for certain platforms.
46+
# The test command acts as a kind of "post-build" callback where it's possible
47+
# for the stub-generator to import the freshly-built wheel.
48+
# There are two entry-points which are designed to call generate_stubs.py through
49+
# this test command:
50+
# - `make pystubs` is called during local development to generate the
51+
# stubs and copy them into the git repo to be committed and reviewed.
52+
# - in CI, the cibuildwheel action is used to validate that the stubs match what
53+
# has been committed to the repo.
54+
test-requires = "mypy~=1.15.0 stubgenlib~=0.2.0"
55+
# Note: the python version here must be kept in sync with src/python/stubs/CMakeLists.txt
56+
select = "cp311-manylinux_*64"
57+
inherit.test-command = "append"
58+
test-command = [
59+
"python {project}/src/bindings/python/stubs/generate_stubs.py --out-path '/output' --validate-path '{project}/src/bindings/python/stubs/PyOpenColorIO/__init__.pyi'",
60+
]
61+
62+
[tool.mypy]
63+
files = [
64+
"tests/python/",
65+
"src/bindings/python/stubs",
66+
]
67+
#mypy_path = [
68+
# "src/bindings/python/stubs",
69+
#]
70+
allow_redefinition = true
71+
check_untyped_defs = true
72+
disable_error_code = [
73+
"func-returns-value",
74+
]

src/bindings/python/CMakeLists.txt

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -258,4 +258,30 @@ install(TARGETS PyOpenColorIO
258258
LIBRARY DESTINATION ${_PyOpenColorIO_SITE_PACKAGE_DIR}
259259
)
260260

261-
install(FILES package/__init__.py DESTINATION ${_PyOpenColorIO_SITE_PACKAGE_DIR})
261+
install(FILES stubs/PyOpenColorIO/__init__.pyi DESTINATION ${_PyOpenColorIO_SITE_PACKAGE_DIR})
262+
install(FILES stubs/PyOpenColorIO/py.typed DESTINATION ${_PyOpenColorIO_SITE_PACKAGE_DIR})
263+
264+
###############################################################################
265+
266+
# Note: the python version must be kept in sync with `[[tool.cibuildwheel.overrides]]` in pyproject.toml.
267+
# The stubs are generated within a container so the version of python does not need to match
268+
# the version of python that OpenColorIO is being built against.
269+
# Note: the version of cibuildwheel should be kept in sync with .github/workflows/wheel.yml
270+
add_custom_command (COMMAND ${Python_EXECUTABLE} ${CMAKE_SOURCE_DIR}/src/bindings/python/stubs/generate_stubs_local.py
271+
--repo-root ${CMAKE_SOURCE_DIR} --python-version="3.11" --cibuildwheel-version="2.22.0"
272+
--output-dir "${CMAKE_BINARY_DIR}/wheelhouse"
273+
OUTPUT "${CMAKE_BINARY_DIR}/wheelhouse/PyOpenColorIO/__init__.pyi"
274+
DEPENDS "${CMAKE_SOURCE_DIR}/src/bindings/python/stubs/generate_stubs.py"
275+
DEPENDS "${CMAKE_SOURCE_DIR}/src/bindings/python/stubs/generate_stubs_local.py"
276+
COMMENT "pystubs: Generating python stubs"
277+
)
278+
279+
add_custom_command (COMMAND ${CMAKE_COMMAND} -E copy
280+
"${CMAKE_BINARY_DIR}/wheelhouse/PyOpenColorIO/__init__.pyi"
281+
"${CMAKE_SOURCE_DIR}/src/bindings/python/stubs/PyOpenColorIO/__init__.pyi"
282+
OUTPUT "${CMAKE_SOURCE_DIR}/src/bindings/python/stubs/PyOpenColorIO/__init__.pyi"
283+
DEPENDS "${CMAKE_BINARY_DIR}/wheelhouse/PyOpenColorIO/__init__.pyi"
284+
COMMENT "pystubs: Copying generated stubs to source"
285+
)
286+
287+
add_custom_target (pystubs DEPENDS "${CMAKE_SOURCE_DIR}/src/bindings/python/stubs/PyOpenColorIO/__init__.pyi")

0 commit comments

Comments
 (0)