Files
CoolProp/dev/extract_version.py
Ian Bell 70d03056e0 Modernize Python build system to use scikit-build-core (#2632)
* Modernize Python build system to use scikit-build-core

This commit replaces the old setuptools-based build system with a modern
scikit-build-core + CMake build system for the Python bindings.

Key changes:
- Replace setup.py with pyproject.toml using scikit-build-core backend
- Create new CMakeLists.txt for Cython module compilation
- Add FindCython.cmake helper module
- Update README from .rst to .md format
- Enable incremental builds with proper CMake dependency tracking
- Support Python 3.8-3.14 with proper Cython directives

Benefits:
- Incremental builds work correctly (only rebuild changed files)
- Modern PEP 517/518 compliant build system
- Build artifacts cached in build/{wheel_tag} directories
- Better integration with pip and modern Python tooling
- No more need for custom _py_backend build hooks

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Add build-time file generation and ignore generated files

This commit adds the missing build-time steps from setup.py:
- Header generation from JSON files (generate_headers.py)
- Cython constants module generation (generate_constants_module.py)
- Copying headers, fmtlib, and BibTeX file to package directory

Also updates .gitignore to ignore:
- wrappers/Python/CoolProp/include/ (generated during build)
- wrappers/Python/CoolProp/CoolPropBibTeXLibrary.bib (copied during build)

Includes test script to verify wheel contents match between old and new build approaches.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Set CMAKE_POSITION_INDEPENDENT_CODE for shared library build

Enable -fPIC flag for all targets to ensure proper shared library compilation.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Remove deprecated buildbot configuration

The buildbot system is deprecated and no longer in use.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Update extract_version.py to use .version file instead of setup.py

With the migration to scikit-build-core, version information is now stored
in the .version file and read by pyproject.toml. Updated the script to:

- Rename replace_setup_py() to replace_version_file()
- Update .version file instead of modifying setup.py
- Change --replace-setup-py flag to --replace-version

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Update build scripts and documentation for scikit-build-core

Changes:
- Updated documentation to show modern pip-based installation
- Updated manylinux build script to use pip wheel instead of setup.py
- Updated conda metadata generator to use pip install
- Removed deprecated PyPI preparation script (replaced by `python -m build --sdist`)

All build infrastructure now uses the new scikit-build-core build system.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Update manylinux Docker script for scikit-build-core

Removed SETUP_PY_ARGS since cmake options are no longer passed via
setup.py arguments. The new build system uses CMake directly via
scikit-build-core. Also fixed typo and updated install_root path.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Remove deprecated _py_backend custom build backend

The _py_backend was a custom setuptools build backend wrapper used
with the old setup.py build system. It's no longer needed with
scikit-build-core.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Add uv package manager documentation

Added section on using uv (Astral's fast Python package manager) to
install and work with CoolProp. Includes examples for:
- Installing in current environment
- Creating new projects with CoolProp
- Running scripts with automatic environment management
- Development installations from source

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Fix sdist packaging and update scikit-build-core config

Changes:
- Updated pyproject.toml to use newer scikit-build-core config syntax
  - cmake.minimum-version → cmake.version
  - cmake.verbose → build.verbose
- Added sdist.include to ensure .version file is in source distributions
- Added .version to MANIFEST.in for completeness

This fixes the issue where building a wheel from an sdist would fail
due to missing .version file. Now sdist → wheel builds work correctly.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Rename setup.py to deprecated_setup.py

The old setuptools-based build system has been fully replaced with
scikit-build-core. Renaming setup.py to deprecated_setup.py to:
- Clearly indicate it's no longer the primary build method
- Keep it available for reference and backward compatibility
- Prevent accidental use of the old build system

Users should now use: pip install .

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Update GitHub Actions workflows for new build system

Changes:
- Replace --replace-setup-py with --replace-version flag
- Update sdist build to use 'python -m build --sdist' instead of deprecated prepare_pypi.py
- Workflows now work with scikit-build-core build system

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Fix cibuildwheel to build from repository root

With scikit-build-core, the pyproject.toml is at the repository root,
not in wrappers/Python/. Updated cibuildwheel configuration:
- Changed package-dir from ./wrappers/Python/ to .
- Removed redundant CIBW_BEFORE_BUILD (dependencies are in pyproject.toml)
- Build dependencies are now automatically installed by pip from pyproject.toml

This fixes the "Multiple top-level packages discovered" error.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Set macOS deployment target to 11.0 in pyproject.toml

Configure MACOSX_DEPLOYMENT_TARGET=11.0 (Big Sur) in cibuildwheel config.
This matches the setting in GitHub Actions and ensures wheels are built
with consistent compatibility for macOS 11.0 and later.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Remove old pyproject.toml from wrappers/Python

This file was used by the old setuptools build system. With
scikit-build-core, the main pyproject.toml at the repository root
is now used for all Python packaging configuration.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Remove redundant PyPy skip selector from cibuildwheel

The 'pp*' skip selector was causing a warning because PyPy isn't enabled
in the build matrix anyway. Since we explicitly specify only CPython
versions in the build directive (cp38-*, cp39-*, etc.), the pp* skip is
unnecessary.

Fixes warning: "Invalid skip selector: 'pp*'. This selector matches a
group that wasn't enabled."

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Update fmtlib from 11.1.3 to 12.0.0

Updated the fmtlib submodule to the latest stable release (12.0.0).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Remove pdsim

---------

Co-authored-by: Claude <noreply@anthropic.com>
2025-10-11 13:07:10 -04:00

138 lines
4.2 KiB
Python

import datetime
import argparse
import re
import requests
from packaging import version
from pathlib import Path
ROOT_DIR = Path(__file__).parent.parent
def parse_pypi_version(pypi=False):
if pypi:
response = requests.get('https://pypi.org/pypi/CoolProp/json')
else:
response = requests.get('https://test.pypi.org/pypi/CoolProp/json')
response.raise_for_status()
data = response.json()
releases = [version.parse(v) for v in data['releases'].keys()]
return releases
def parse_cmake_version_info():
with open(ROOT_DIR / 'CMakeLists.txt', 'r') as f:
content = f.read()
no_comments_lines = []
for line in content.splitlines():
l = line.strip().split('#')[0]
if l:
no_comments_lines.append(l)
content = "\n".join(no_comments_lines)
m_major = re.search(r'set\s*\(COOLPROP_VERSION_MAJOR (\d+)\)', content)
m_minor = re.search(r'set\s*\(COOLPROP_VERSION_MINOR (\d+)\)', content)
m_patch = re.search(r'set\s*\(COOLPROP_VERSION_PATCH (\d+)\)', content)
m_rev = re.search(r'set\s*\(COOLPROP_VERSION_REVISION "*(.*?)"*\)', content)
coolprop_version = ''
if m_major:
COOLPROP_VERSION_MAJOR = m_major.groups()[0]
coolprop_version += COOLPROP_VERSION_MAJOR
if m_minor:
COOLPROP_VERSION_MINOR = m_minor.groups()[0]
coolprop_version += "." + COOLPROP_VERSION_MINOR
if m_patch:
COOLPROP_VERSION_PATCH = m_patch.groups()[0]
coolprop_version += "." + COOLPROP_VERSION_PATCH
if m_rev:
try:
COOLPROP_VERSION_REV = str(m_rev.groups()[0])
if len(COOLPROP_VERSION_REV) > 0:
coolprop_version += "-" + COOLPROP_VERSION_REV
except:
pass
return coolprop_version
def replace_version_file(new_v: version.Version):
"""Update the .version file which is used by pyproject.toml"""
fp = ROOT_DIR / '.version'
with open(fp, 'w') as f:
f.write(str(new_v))
print(f"Updated version '{new_v}' in {fp}")
if __name__ == '__main__':
parser = argparse.ArgumentParser(
description="Find the right version from pypi/testpypi")
parser.add_argument("--cmake-only", default=False,
action='store_true',
help="Print the version from cmake only")
parser.add_argument("--pypi", default=False,
action='store_true',
help="Check pypi instead of testpypi")
parser.add_argument("--current", default=False,
action='store_true',
help="Check current version instead of incrementing by one")
parser.add_argument("--replace-version", default=False,
action='store_true',
help="Update .version file")
parser.add_argument("--version", type=str, help="Use this version")
args = parser.parse_args()
current_v = parse_cmake_version_info()
if args.cmake_only:
print(current_v, end="")
exit(0)
current_v = version.Version(current_v)
releases = parse_pypi_version(pypi=args.pypi)
matched_releases = [v for v in releases
if v.base_version == current_v.base_version]
new_v = current_v.base_version
if matched_releases:
max_v = max(matched_releases)
if max_v.pre:
pre_iden, pre_v = max_v.pre
if args.current:
new_v += f"{pre_iden}{pre_v}"
else:
new_v += f"{pre_iden}{pre_v + 1}"
elif max_v.dev:
dev_iden, dev_v = max_v.dev
if args.current:
new_v += f"post{dev_v}"
else:
new_v += f"post{dev_v + 1}"
else:
if args.version:
new_v += f'.post{args.version}'
else:
raise ValueError("For non-release versions, please provide --version argument")
else:
new_v = str(current_v)
new_v = version.Version(new_v)
if args.replace_version:
remote = "PyPi" if args.pypi else "TestPyPi"
print(f"Version to be injected on {remote}: {new_v}")
replace_version_file(new_v=new_v)
else:
print(new_v, end="")