diff --git a/CHANGELOG.md b/CHANGELOG.md index b875887ae..b5fb0bf6f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## Unreleased ### Added +- Added docstrings to the bundled stubs in release wheels for Python 3.10 and later. - Added more type annotations and deprecation markers to the stubs. - Added tests for `getObjVal()` and `getVal()` - Added `addConsLinear()` to add linear constraints from variables and coefficients without building an expression diff --git a/pyproject.toml b/pyproject.toml index a9a1bedd8..764927e50 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -61,6 +61,10 @@ unzip scip.zip mv scip_install scip ''' environment = { SCIPOPTDIR="$(pwd)/scip", LD_LIBRARY_PATH="$(pwd)/scip/lib:$LD_LIBRARY_PATH", DYLD_LIBRARY_PATH="$(pwd)/scip/lib:$DYLD_LIBRARY_PATH", PATH="$(pwd)/scip/bin:$PATH", PKG_CONFIG_PATH="$(pwd)/scip/lib/pkgconfig:$PKG_CONFIG_PATH", RELEASE="true"} +repair-wheel-command = [ + "auditwheel repair -w {dest_dir} {wheel}", + 'python "{project}/scripts/add_wheel_stub_docstrings.py" "{dest_dir}"', +] [tool.cibuildwheel.macos] @@ -93,13 +97,12 @@ for prefix in /usr/local /opt/homebrew; do done ''' environment = {SCIPOPTDIR="$(pwd)/src/scip", LD_LIBRARY_PATH="$(pwd)/src/scip/lib:LD_LIBRARY_PATH", DYLD_LIBRARY_PATH="$(pwd)/src/scip/lib:$DYLD_LIBRARY_PATH", PATH="$(pwd)/src/scip/bin:$PATH", PKG_CONFIG_PATH="$(pwd)/src/scip/lib/pkgconfig:$PKG_CONFIG_PATH", MACOSX_DEPLOYMENT_TARGET="11.0", RELEASE="true"} -repair-wheel-command = ''' - bash -c ' - export MACOSX_DEPLOYMENT_TARGET=11.0 - delocate-listdeps {wheel} - delocate-wheel --require-archs {delocate_archs} -w {dest_dir} {wheel} - ' -''' +repair-wheel-command = [ + "export MACOSX_DEPLOYMENT_TARGET=11.0", + "delocate-listdeps {wheel}", + "delocate-wheel --require-archs {delocate_archs} -w {dest_dir} {wheel}", + 'python "{project}/scripts/add_wheel_stub_docstrings.py" "{dest_dir}"', +] [tool.cibuildwheel.windows] @@ -113,4 +116,7 @@ before-all = [ ] before-build = "pip install delvewheel" environment = { SCIPOPTDIR='D:\\a\\PySCIPOpt\\PySCIPOpt\\scip', RELEASE="true" } -repair-wheel-command = "delvewheel repair --add-path c:/bin;c:/lib;c:/bin/src;c:/lib/src;D:/a/PySCIPOpt/PySCIPOpt/scip/;D:/a/PySCIPOpt/PySCIPOpt/scip/lib/;D:/a/PySCIPOpt/PySCIPOpt/scip/bin/ -w {dest_dir} {wheel}" +repair-wheel-command = [ + "delvewheel repair --add-path c:/bin;c:/lib;c:/bin/src;c:/lib/src;D:/a/PySCIPOpt/PySCIPOpt/scip/;D:/a/PySCIPOpt/PySCIPOpt/scip/lib/;D:/a/PySCIPOpt/PySCIPOpt/scip/bin/ -w {dest_dir} {wheel}", + 'python "{project}/scripts/add_wheel_stub_docstrings.py" "{dest_dir}"', +] diff --git a/scripts/add_wheel_stub_docstrings.py b/scripts/add_wheel_stub_docstrings.py new file mode 100644 index 000000000..2e4d438e8 --- /dev/null +++ b/scripts/add_wheel_stub_docstrings.py @@ -0,0 +1,47 @@ +"""Copy runtime docstrings into the type stubs of a repaired wheel. + +Usage: python add_wheel_stub_docstrings.py +Skipped on Python <3.10, which docstring-adder requires. +""" + +import os +import shutil +import subprocess +import sys +from pathlib import Path +from tempfile import TemporaryDirectory + +DOCSTRING_ADDER = "git+https://github.com/astral-sh/docstring-adder@8377e23ca0c1533bef3e744209709d6d783782b6" + + +def run(*args, **kwargs): + subprocess.run([sys.executable, *args], check=True, **kwargs) + + +def main(): + if sys.version_info < (3, 10): + print("Skipping stub docstrings: docstring-adder requires Python >=3.10") + return + + wheel_dir = Path(sys.argv[1]).resolve() + (wheel,) = wheel_dir.glob("*.whl") + run("-m", "pip", "install", "wheel==0.48.0", "numpy", f"docstring-adder @ {DOCSTRING_ADDER}") + + with TemporaryDirectory() as tmp: + tmp = Path(tmp) + run("-m", "wheel", "unpack", str(wheel), "-d", str(tmp / "unpacked")) + (root,) = (tmp / "unpacked").iterdir() + + env = dict(os.environ, PYTHONPATH=str(root), PYTHONDONTWRITEBYTECODE="1") + run("-c", "import pyscipopt.scip", env=env, cwd=tmp) + run("-m", "add_docstrings", "--packages", str(root / "pyscipopt"), env=env, cwd=tmp) + + (tmp / "packed").mkdir() + run("-m", "wheel", "pack", str(root), "-d", str(tmp / "packed")) + (packed,) = (tmp / "packed").glob("*.whl") + wheel.unlink() + shutil.move(packed, wheel_dir / packed.name) + + +if __name__ == "__main__": + main()