Skip to content

Commit 0852bc8

Browse files
committed
Refactored wheel building and testing
1 parent 92aac7d commit 0852bc8

3 files changed

Lines changed: 93 additions & 31 deletions

File tree

.github/workflows/build-wheels.yml

Lines changed: 14 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -153,44 +153,32 @@ jobs:
153153
CIBW_BEFORE_BUILD_WINDOWS: "set CMAKE_RC_COMPILER= && set PYHELIOS_CUDA_ARCHITECTURES=50;60;70;75;80;86;90 && python build_scripts/prepare_wheel.py --buildmode release --verbose"
154154
CIBW_BEFORE_BUILD_LINUX: "export PYHELIOS_CUDA_ARCHITECTURES=50;60;70;75;80;86;90 && python build_scripts/prepare_wheel.py --buildmode release --verbose"
155155

156-
# Test wheel installation with comprehensive asset validation
156+
# Comprehensive wheel testing using pytest suite
157157
CIBW_TEST_COMMAND: |
158158
python -c "
159159
import pyhelios
160160
print(f'PyHelios {pyhelios.__version__} imported successfully')
161161
162-
# Validate asset path management
162+
# Quick asset validation
163163
from pyhelios.assets import get_asset_manager
164164
manager = get_asset_manager()
165-
166-
# Check HELIOS_BUILD path resolution
167165
helios_build = manager._get_helios_build_path()
168166
if helios_build:
169167
print(f'HELIOS_BUILD assets found at: {helios_build}')
170168
else:
171-
print('WARNING: HELIOS_BUILD assets not found')
172-
173-
# Validate packaged assets
174-
from pathlib import Path
175-
package_root = Path(pyhelios.__file__).parent
176-
expected_assets = package_root / 'assets' / 'build' / 'lib' / 'images'
177-
if expected_assets.exists():
178-
asset_count = len(list(expected_assets.glob('*')))
179-
print(f'Found {asset_count} core assets in packaged location')
180-
if asset_count == 0:
181-
raise RuntimeError('Core assets directory exists but is empty')
182-
else:
183-
print('WARNING: Expected packaged assets not found')
169+
raise RuntimeError('CRITICAL: HELIOS_BUILD assets not found')
184170
185-
# Test asset validation function
186-
results = manager.validate_assets()
187-
for plugin, result in results.items():
188-
if result['exists']:
189-
print(f'{plugin}: {result[\"files_found\"]} asset files')
190-
191-
print('Asset validation completed')
192-
"
193-
CIBW_TEST_REQUIRES: "pytest"
171+
# Plugin status check
172+
from pyhelios.plugins import print_plugin_status
173+
print_plugin_status()
174+
print('Initial validation completed')
175+
" &&
176+
python -m pytest {project}/tests/test_cross_platform.py {project}/tests/test_datatypes.py --tb=short -v
177+
178+
CIBW_TEST_REQUIRES: "pytest pytest-forked"
179+
180+
# Skip problematic platforms for testing
181+
CIBW_TEST_SKIP: "*-win32 *-manylinux_i686 *-musllinux*"
194182

195183
# Repair wheels to bundle dependencies
196184
CIBW_REPAIR_WHEEL_COMMAND_MACOS: "delocate-wheel --require-archs {delocate_archs} -w {dest_dir} -v {wheel}"

pyhelios/__init__.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,38 @@
22
from .Logger import Logger
33
from .Context import Context, PrimitiveType
44

5+
# Version information with robust fallback strategies
6+
def _get_version():
7+
"""Get version with multiple fallback strategies."""
8+
try:
9+
from ._version import version
10+
return version
11+
except ImportError:
12+
pass
13+
14+
try:
15+
# Try setuptools-scm directly for development installs
16+
from setuptools_scm import get_version
17+
from pathlib import Path
18+
return get_version(root=Path(__file__).parent.parent)
19+
except (ImportError, LookupError):
20+
pass
21+
22+
try:
23+
# Try pkg_resources/importlib.metadata as final fallback
24+
try:
25+
from importlib.metadata import version
26+
except ImportError:
27+
# Python < 3.8 fallback
28+
from importlib_metadata import version
29+
return version('pyhelios')
30+
except Exception:
31+
pass
32+
33+
return "unknown"
34+
35+
__version__ = _get_version()
36+
537
# Initialize asset paths for C++ plugins
638
try:
739
from .assets import initialize_asset_paths

pyhelios/assets/__init__.py

Lines changed: 47 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,19 @@ def get_helios_core_path(self) -> Optional[Path]:
6060
"""Get the path to the helios-core directory."""
6161
return self._find_helios_core()
6262

63+
def _is_wheel_install(self) -> bool:
64+
"""
65+
Detect if we're running from an installed wheel package.
66+
67+
Returns:
68+
True if running from wheel installation, False otherwise
69+
"""
70+
package_root = Path(__file__).parent
71+
pyhelios_parent = package_root.parent.parent # Go up to site-packages level
72+
73+
# Look for .dist-info directory which indicates wheel installation
74+
return any(pyhelios_parent.glob('pyhelios-*.dist-info'))
75+
6376
def _get_helios_build_path(self) -> Optional[Path]:
6477
"""
6578
Find the HELIOS_BUILD directory containing assets.
@@ -74,18 +87,47 @@ def _get_helios_build_path(self) -> Optional[Path]:
7487
Returns:
7588
Path to build directory, or None if not found
7689
"""
77-
# PRIORITY 1: For pip-installed PyHelios, check packaged assets first
78-
# This ensures pip users always get proper assets even if dev dirs exist
7990
package_root = Path(__file__).parent
80-
packaged_build = package_root / 'build'
91+
packaged_build = package_root / 'build' # pyhelios/assets/build/
8192

82-
# Check for packaged assets structure with comprehensive validation
93+
# Check if we're in a wheel installation
94+
is_wheel_install = self._is_wheel_install()
95+
96+
if is_wheel_install:
97+
# WHEEL INSTALL: Only check packaged assets location
98+
if (packaged_build.exists() and
99+
(packaged_build / 'lib' / 'images').exists() and
100+
len(list((packaged_build / 'lib' / 'images').glob('*'))) > 0):
101+
logger.debug(f"Using wheel-installed assets: {packaged_build}")
102+
return packaged_build
103+
else:
104+
# This is a critical packaging error for wheels
105+
raise RuntimeError(
106+
f"Wheel installation detected but assets not found at {packaged_build}. "
107+
f"This indicates a packaging error. Expected structure:\n"
108+
f" {packaged_build / 'lib' / 'images'} with image files"
109+
)
110+
111+
# DEVELOPMENT INSTALL: Check packaged assets first, then development paths
112+
113+
# PRIORITY 1: Check for packaged assets (even in development)
83114
if (packaged_build.exists() and
84115
(packaged_build / 'lib' / 'images').exists() and
85116
len(list((packaged_build / 'lib' / 'images').glob('*'))) > 0):
86-
logger.debug(f"Using pip-installed assets: {packaged_build}")
117+
logger.debug(f"Using development packaged assets: {packaged_build}")
87118
return packaged_build
88119

120+
# Log diagnostic information if packaged assets are missing or incomplete
121+
if packaged_build.exists():
122+
logger.debug(f"Packaged assets directory exists but incomplete: {packaged_build}")
123+
if not (packaged_build / 'lib' / 'images').exists():
124+
logger.debug(" Missing lib/images directory")
125+
else:
126+
image_count = len(list((packaged_build / 'lib' / 'images').glob('*')))
127+
logger.debug(f" Found {image_count} images (need > 0 for validation)")
128+
else:
129+
logger.debug(f"Packaged assets directory does not exist: {packaged_build}")
130+
89131
# PRIORITY 2: For development, look for pyhelios_build/build directory
90132
# Only used if pip-installed assets are not available
91133
helios_core = self.get_helios_core_path()

0 commit comments

Comments
 (0)