Skip to content

Commit a4d3c97

Browse files
committed
Add a test for this warning
1 parent 42da0d7 commit a4d3c97

File tree

4 files changed

+105
-61
lines changed

4 files changed

+105
-61
lines changed

cibuildwheel/platforms/ios.py

+7-5
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
download,
3333
move_file,
3434
)
35-
from ..util.helpers import prepare_command, unwrap
35+
from ..util.helpers import prepare_command, unwrap_preserving_paragraphs
3636
from ..util.packaging import (
3737
combine_constraints,
3838
find_compatible_wheel,
@@ -597,14 +597,16 @@ def build(options: Options, tmp_path: Path) -> None:
597597
test_command_parts = shlex.split(build_options.test_command)
598598
if test_command_parts[0:2] != ["python", "-m"]:
599599
log.warning(
600-
unwrap(f"""
601-
iOS tests run with test command '{build_options.test_command}' that
602-
doesn't start with 'python -m'. iOS tests must execute python
603-
modules - other entrypoints are not supported.
600+
unwrap_preserving_paragraphs(f"""
601+
iOS tests configured with a test command which doesn't start with
602+
'python -m'. iOS tests must execute python modules - other
603+
entrypoints are not supported.
604604
605605
cibuildwheel will try to execute it as if it started with 'python
606606
-m'. If this works, all you need to do is add that to your test
607607
command.
608+
609+
Test command: {build_options.test_command}
608610
""")
609611
)
610612
else:

cibuildwheel/util/helpers.py

+15
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,21 @@ def unwrap(text: str) -> str:
7676
return re.sub(r"\s+", " ", text)
7777

7878

79+
def unwrap_preserving_paragraphs(text: str) -> str:
80+
"""
81+
Unwraps multi-line text to a single line, but preserves paragraphs
82+
"""
83+
# remove initial line indent
84+
text = textwrap.dedent(text)
85+
# remove leading/trailing whitespace
86+
text = text.strip()
87+
88+
paragraphs = text.split("\n\n")
89+
# remove consecutive whitespace
90+
paragraphs = [re.sub(r"\s+", " ", paragraph) for paragraph in paragraphs]
91+
return "\n\n".join(paragraphs)
92+
93+
7994
def parse_key_value_string(
8095
key_value_string: str,
8196
positional_arg_names: Sequence[str] | None = None,

test/test_ios.py

+50-46
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import platform
55
import shutil
66
import subprocess
7+
import textwrap
78

89
import pytest
910

@@ -80,21 +81,10 @@ def test_ios_platforms(tmp_path, build_config, monkeypatch, capfd):
8081
)
8182

8283
# The expected wheels were produced.
83-
ios_version = os.getenv("IPHONEOS_DEPLOYMENT_TARGET", "13.0").replace(".", "_")
84-
platform_machine = platform.machine()
85-
86-
if platform_machine == "x86_64":
87-
expected_wheels = {
88-
f"spam-0.1.0-cp313-cp313-ios_{ios_version}_x86_64_iphonesimulator.whl",
89-
}
90-
91-
elif platform_machine == "arm64":
92-
expected_wheels = {
93-
f"spam-0.1.0-cp313-cp313-ios_{ios_version}_arm64_iphoneos.whl",
94-
f"spam-0.1.0-cp313-cp313-ios_{ios_version}_arm64_iphonesimulator.whl",
95-
}
96-
97-
assert set(actual_wheels) == expected_wheels
84+
expected_wheels = utils.expected_wheels(
85+
"spam", "0.1.0", platform="ios", python_abi_tags=["cp313-cp313"]
86+
)
87+
assert set(actual_wheels) == set(expected_wheels)
9888

9989
# The user was notified that the cross-build tool was found.
10090
captured = capfd.readouterr()
@@ -180,21 +170,10 @@ def test_no_xbuild_tool_definition(tmp_path, capfd):
180170
)
181171

182172
# The expected wheels were produced.
183-
ios_version = os.getenv("IPHONEOS_DEPLOYMENT_TARGET", "13.0").replace(".", "_")
184-
platform_machine = platform.machine()
185-
186-
if platform_machine == "x86_64":
187-
expected_wheels = {
188-
f"spam-0.1.0-cp313-cp313-ios_{ios_version}_x86_64_iphonesimulator.whl",
189-
}
190-
191-
elif platform_machine == "arm64":
192-
expected_wheels = {
193-
f"spam-0.1.0-cp313-cp313-ios_{ios_version}_arm64_iphoneos.whl",
194-
f"spam-0.1.0-cp313-cp313-ios_{ios_version}_arm64_iphonesimulator.whl",
195-
}
196-
197-
assert set(actual_wheels) == expected_wheels
173+
expected_wheels = utils.expected_wheels(
174+
"spam", "0.1.0", platform="ios", python_abi_tags=["cp313-cp313"]
175+
)
176+
assert set(actual_wheels) == set(expected_wheels)
198177

199178
# The user was notified that there was no cross-build tool definition.
200179
captured = capfd.readouterr()
@@ -225,23 +204,48 @@ def test_empty_xbuild_tool_definition(tmp_path, capfd):
225204
},
226205
)
227206

228-
# The expected wheels were produced.
229-
ios_version = os.getenv("IPHONEOS_DEPLOYMENT_TARGET", "13.0").replace(".", "_")
230-
platform_machine = platform.machine()
231-
232-
if platform_machine == "x86_64":
233-
expected_wheels = {
234-
f"spam-0.1.0-cp313-cp313-ios_{ios_version}_x86_64_iphonesimulator.whl",
235-
}
236-
237-
elif platform_machine == "arm64":
238-
expected_wheels = {
239-
f"spam-0.1.0-cp313-cp313-ios_{ios_version}_arm64_iphoneos.whl",
240-
f"spam-0.1.0-cp313-cp313-ios_{ios_version}_arm64_iphonesimulator.whl",
241-
}
242-
243-
assert set(actual_wheels) == expected_wheels
207+
expected_wheels = utils.expected_wheels(
208+
"spam", "0.1.0", platform="ios", python_abi_tags=["cp313-cp313"]
209+
)
210+
assert set(actual_wheels) == set(expected_wheels)
244211

245212
# The warnings about cross-build notifications were silenced.
246213
captured = capfd.readouterr()
247214
assert "Your project configuration does not define any cross-build tools." not in captured.err
215+
216+
217+
def test_ios_test_command_without_python_dash_m(tmp_path, capfd):
218+
"""Test command should be able to run without python -m."""
219+
if utils.platform != "macos":
220+
pytest.skip("this test can only run on macOS")
221+
if utils.get_xcode_version() < (13, 0):
222+
pytest.skip("this test only works with Xcode 13.0 or greater")
223+
224+
project_dir = tmp_path / "project"
225+
project = test_projects.new_c_project()
226+
project.files["tests_module/__init__.py"] = ""
227+
project.files["tests_module/__main__.py"] = textwrap.dedent("""
228+
if __name__ == "__main__":
229+
print("Hello from tests_module")
230+
""")
231+
project.generate(project_dir)
232+
233+
actual_wheels = utils.cibuildwheel_run(
234+
project_dir,
235+
add_env={
236+
"CIBW_PLATFORM": "ios",
237+
"CIBW_BUILD": "cp313-*",
238+
"CIBW_TEST_COMMAND": "tests_module",
239+
"CIBW_TEST_SOURCES": "tests_module",
240+
"CIBW_XBUILD_TOOLS": "",
241+
},
242+
)
243+
244+
expected_wheels = utils.expected_wheels(
245+
"spam", "0.1.0", platform="ios", python_abi_tags=["cp313-cp313"]
246+
)
247+
assert set(actual_wheels) == set(expected_wheels)
248+
249+
out, err = capfd.readouterr()
250+
251+
assert "iOS tests configured with a test command which doesn't start with 'python -m'" in err

test/utils.py

+33-10
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,9 @@ def expected_wheels(
158158
manylinux_versions: list[str] | None = None,
159159
musllinux_versions: list[str] | None = None,
160160
macosx_deployment_target: str = "10.9",
161+
iphoneos_deployment_target: str = "13.0",
161162
machine_arch: str | None = None,
163+
platform: str = platform,
162164
python_abi_tags: list[str] | None = None,
163165
include_universal2: bool = False,
164166
single_python: bool = False,
@@ -190,15 +192,17 @@ def expected_wheels(
190192
wheel
191193
for architecture in architectures
192194
for wheel in _expected_wheels(
193-
package_name,
194-
package_version,
195-
architecture,
196-
manylinux_versions,
197-
musllinux_versions,
198-
macosx_deployment_target,
199-
python_abi_tags,
200-
include_universal2,
201-
single_python,
195+
package_name=package_name,
196+
package_version=package_version,
197+
machine_arch=architecture,
198+
manylinux_versions=manylinux_versions,
199+
musllinux_versions=musllinux_versions,
200+
macosx_deployment_target=macosx_deployment_target,
201+
iphoneos_deployment_target=iphoneos_deployment_target,
202+
platform=platform,
203+
python_abi_tags=python_abi_tags,
204+
include_universal2=include_universal2,
205+
single_python=single_python,
202206
)
203207
]
204208

@@ -210,6 +214,8 @@ def _expected_wheels(
210214
manylinux_versions: list[str] | None,
211215
musllinux_versions: list[str] | None,
212216
macosx_deployment_target: str,
217+
iphoneos_deployment_target: str,
218+
platform: str,
213219
python_abi_tags: list[str] | None,
214220
include_universal2: bool,
215221
single_python: bool,
@@ -234,7 +240,9 @@ def _expected_wheels(
234240

235241
if platform == "pyodide" and python_abi_tags is None:
236242
python_abi_tags = ["cp312-cp312"]
237-
if python_abi_tags is None:
243+
elif platform == "ios" and python_abi_tags is None:
244+
python_abi_tags = ["cp313-cp313"]
245+
elif python_abi_tags is None:
238246
python_abi_tags = [
239247
"cp38-cp38",
240248
"cp39-cp39",
@@ -314,6 +322,21 @@ def _expected_wheels(
314322

315323
if include_universal2:
316324
platform_tags.append(f"macosx_{min_macosx.replace('.', '_')}_universal2")
325+
326+
elif platform == "ios":
327+
if machine_arch == "x86_64":
328+
platform_tags = [
329+
f"ios_{iphoneos_deployment_target.replace('.', '_')}_x86_64_iphonesimulator"
330+
]
331+
elif machine_arch == "arm64":
332+
platform_tags = [
333+
f"ios_{iphoneos_deployment_target.replace('.', '_')}_arm64_iphoneos",
334+
f"ios_{iphoneos_deployment_target.replace('.', '_')}_arm64_iphonesimulator",
335+
]
336+
else:
337+
msg = f"Unsupported architecture {machine_arch!r} for iOS"
338+
raise Exception(msg)
339+
317340
else:
318341
msg = f"Unsupported platform {platform!r}"
319342
raise Exception(msg)

0 commit comments

Comments
 (0)