Let's try it another way

This commit is contained in:
Maarten L. Hekkelman
2026-01-31 14:22:09 +01:00
parent 2f997664c6
commit bdb9818a73
4 changed files with 220 additions and 28 deletions

View File

@@ -36,17 +36,10 @@ jobs:
shell: bash
run: echo "build-output-dir=${{ github.workspace }}/build" >> "$GITHUB_OUTPUT"
- name: Install boost
if: matrix.os == 'windows-latest'
uses: MarkusJx/install-boost@v2
id: install-boost
with:
boost_version: 1.88.0
- name: Install Catch2 Ubuntu
if: matrix.os == 'ubuntu-latest'
run: >
sudo apt-get update && sudo apt-get install catch2 libpython3-all-dev libboost1.88-all-dev
sudo apt-get update && sudo apt-get install catch2 libpython3-all-dev
- name: setup python
uses: actions/setup-python@v6
@@ -56,7 +49,7 @@ jobs:
- name: Install Catch2 macOS
if: matrix.os == 'macos-latest'
run: >
brew install catch2 boost
brew install catch2
- name: Install dependencies Window
if: matrix.os == 'windows-latest'
@@ -67,7 +60,6 @@ jobs:
run: >
cmake -B ${{ steps.strings.outputs.build-output-dir }}
-DCMAKE_CXX_COMPILER=${{ matrix.cpp_compiler }}
-DCMAKE_PREFIX_PATH=${{ steps.install-boost.outputs.BOOST_ROOT }}
-DCMAKE_BUILD_TYPE=Release
-DBUILD_TESTING=ON
-DBUILD_PYTHON_MODULE=ON

View File

@@ -35,7 +35,25 @@ if(NOT EXISTS ${Python_LIBRARIES})
endif()
# Boost 1.86 is required since it contains code required to use numpy 2.x
find_package(Boost 1.86 REQUIRED COMPONENTS python)
if(NOT WIN32) # On Windows we need to build boost ourselves, to find the correct python lib
find_package(Boost 1.86 QUIET COMPONENTS python)
endif()
if(WIN32 OR NOT Boost_FOUND)
# boost is a huge project and directly downloading the 'alternate release'
# from github is much faster than recursively cloning the repo.
CPMAddPackage(
NAME Boost
VERSION 1.90.0
URL https://archives.boost.io/release/1.90.0/source/boost_1_90_0.tar.bz2
URL_HASH SHA256=49551aff3b22cbc5c5a9ed3dbc92f0e23ea50a0f7325b0d198b705e8ee3fc305
OPTIONS
"BOOST_ENABLE_CMAKE ON"
"BOOST_INCLUDE_LIBRARIES python"
"BOOST_ENABLE_PYTHON ON"
"CMAKE_POSITION_INDEPENDENT_CODE ON"
)
endif()
# ---------
add_library(mkdssp_module SHARED dssp-python-plugin.cpp)

View File

@@ -1,33 +1,39 @@
CPMFindPackage(
NAME Catch2 3
GIT_REPOSITORY https://github.com/catchorg/Catch2.git
GIT_TAG v3.4.0
EXCLUDE_FROM_ALL YES)
NAME Catch2 3
GIT_REPOSITORY https://github.com/catchorg/Catch2.git
GIT_TAG v3.4.0
EXCLUDE_FROM_ALL YES)
add_executable(unit-test-dssp ${CMAKE_CURRENT_SOURCE_DIR}/unit-test-dssp.cpp ${PROJECT_SOURCE_DIR}/libdssp/src/dssp-io.cpp)
target_include_directories(unit-test-dssp PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/src
${CMAKE_CURRENT_SOURCE_DIR}/include
${CMAKE_CURRENT_SOURCE_DIR}/src
${CMAKE_CURRENT_SOURCE_DIR}/include
)
target_link_libraries(unit-test-dssp PRIVATE dssp cifpp::cifpp Catch2::Catch2)
if(MSVC)
# Specify unwind semantics so that MSVC knowns how to handle exceptions
target_compile_options(unit-test-dssp PRIVATE /EHsc)
# Specify unwind semantics so that MSVC knowns how to handle exceptions
target_compile_options(unit-test-dssp PRIVATE /EHsc)
endif()
add_test(NAME unit-test-dssp COMMAND $<TARGET_FILE:unit-test-dssp>
--data-dir ${CMAKE_CURRENT_SOURCE_DIR}
--rsrc-dir ${CIFPP_DATA_DIR})
--data-dir ${CMAKE_CURRENT_SOURCE_DIR}
--rsrc-dir ${CIFPP_DATA_DIR})
if(BUILD_PYTHON_MODULE)
find_package(Python REQUIRED Interpreter)
find_package(Python REQUIRED Interpreter)
add_test(NAME python_module COMMAND ${Python_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/test-python.py")
set_tests_properties(python_module PROPERTIES
ENVIRONMENT
"PYTHONPATH=$<TARGET_FILE_DIR:mkdssp_module>;LIBCIFPP_DATA_DIR=${CIFPP_DATA_DIR}"
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}")
endif()
add_test(NAME python_module COMMAND ${Python_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/test-python.py")
set_tests_properties(python_module PROPERTIES
ENVIRONMENT
"PYTHONPATH=$<TARGET_FILE_DIR:mkdssp_module>;LIBCIFPP_DATA_DIR=${CIFPP_DATA_DIR}"
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}")
add_test(NAME python_module_numpy COMMAND ${Python_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/test_numpy2_compat.py")
set_tests_properties(python_module_numpy PROPERTIES
ENVIRONMENT
"PYTHONPATH=$<TARGET_FILE_DIR:mkdssp_module>;LIBCIFPP_DATA_DIR=${CIFPP_DATA_DIR}"
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}")
endif()

176
test/test_numpy2_compat.py Normal file
View File

@@ -0,0 +1,176 @@
"""
DSSP numpy 2.x compatibility test script
This script tests whether the DSSP module works correctly with numpy 2.x
"""
import sys
import os
import gzip
import traceback
def find_test_file():
"""Find the test CIF file in the repository"""
# Possible paths relative to script location
possible_paths = [
"test/1cbs.cif.gz", # From repository root
"../test/1cbs.cif.gz", # From python-module directory
"1cbs.cif.gz", # From test directory
]
for path in possible_paths:
if os.path.exists(path):
return path
return None
def test_numpy_version():
"""Check numpy version"""
try:
import numpy as np
print(f"✓ numpy version: {np.__version__}")
major_version = int(np.__version__.split('.')[0])
if major_version >= 2:
print("✓ numpy 2.x detected")
else:
print(f"⚠ numpy {np.__version__} detected (not 2.x)")
return True
except ImportError as e:
print(f"✗ Failed to import numpy: {e}")
return False
def test_mkdssp_import():
"""Test mkdssp module import"""
try:
import mkdssp
print("✓ Successfully imported mkdssp module")
return True
except ImportError as e:
print(f"✗ Failed to import mkdssp: {e}")
traceback.print_exc()
return False
def test_basic_functionality():
"""Test basic functionality"""
try:
from mkdssp import dssp, TestBond, helix_type, chain_break_type, helix_position_type, structure_type
print("✓ Successfully imported all mkdssp classes/functions")
# Find test file
test_file = find_test_file()
if test_file is None:
print("✗ Could not find test file (1cbs.cif.gz)")
print(" Please run this script from the repository root or test directory")
return False
print(f"✓ Found test file: {test_file}")
# Read test file
try:
with gzip.open(test_file, "rt") as f:
file_content = f.read()
print("✓ Successfully read test file")
except Exception as e:
print(f"✗ Failed to read test file: {e}")
return False
# Test DSSP object creation
try:
dssp_obj = dssp(file_content)
print("✓ Successfully created DSSP object")
except Exception as e:
print(f"✗ Failed to create DSSP object: {e}")
traceback.print_exc()
return False
# Test statistics
try:
stats = dssp_obj.statistics
print(f"✓ Successfully retrieved statistics")
print(f" - Residues: {stats.residues}")
print(f" - Chains: {stats.chains}")
print(f" - H-bonds: {stats.H_bonds}")
except Exception as e:
print(f"✗ Failed to retrieve statistics: {e}")
traceback.print_exc()
return False
# Test iteration
try:
count = 0
for res in dssp_obj:
count += 1
if count == 1:
# Check first residue
print(f" - First residue: {res.asym_id} {res.seq_id} {res.compound_id}")
print(f"✓ Successfully iterated through {count} residues")
except Exception as e:
print(f"✗ Failed to iterate through residues: {e}")
traceback.print_exc()
return False
# Test TestBond function
try:
a = dssp_obj.get('A', 137)
b = dssp_obj.get('A', 6)
result = TestBond(a, b)
print(f"✓ Successfully tested TestBond function: {result}")
except Exception as e:
print(f"✗ Failed to test TestBond function: {e}")
traceback.print_exc()
return False
return True
except Exception as e:
print(f"✗ Basic functionality test failed: {e}")
traceback.print_exc()
return False
def main():
"""Main test function"""
print("=" * 60)
print("DSSP numpy 2.x Compatibility Test")
print("=" * 60)
print()
all_passed = True
# Test 1: Check numpy version
print("Test 1: Check numpy version")
if not test_numpy_version():
all_passed = False
print()
# Test 2: Import mkdssp
print("Test 2: Import mkdssp module")
if not test_mkdssp_import():
all_passed = False
print("\n⚠ Cannot import mkdssp, skipping remaining tests")
print_summary(False)
return 1
print()
# Test 3: Basic functionality
print("Test 3: Test basic functionality")
if not test_basic_functionality():
all_passed = False
print()
# Summary
print_summary(all_passed)
return 0 if all_passed else 1
def print_summary(all_passed):
"""Print test summary"""
print("=" * 60)
if all_passed:
print("✓ All tests passed!")
print("✓ DSSP appears to be compatible with numpy 2.x")
else:
print("✗ Some tests failed")
print("✗ There may be compatibility issues with numpy 2.x")
print("=" * 60)
if __name__ == "__main__":
sys.exit(main())