diff --git a/cibuildwheel/util.py b/cibuildwheel/util.py index f0062e25..bfc54d5a 100644 --- a/cibuildwheel/util.py +++ b/cibuildwheel/util.py @@ -1,4 +1,6 @@ +import fnmatch import functools +import itertools import os import platform as platform_module import re @@ -7,11 +9,11 @@ import sys import textwrap import urllib.request from enum import Enum -from fnmatch import fnmatch from pathlib import Path from time import sleep from typing import Dict, List, NamedTuple, Optional, Set +import bracex import certifi import toml @@ -61,9 +63,12 @@ class BuildSelector: self.skip_patterns = skip_config.split() def __call__(self, build_id: str) -> bool: - def match_any(patterns: List[str]) -> bool: - return any(fnmatch(build_id, pattern) for pattern in patterns) - return match_any(self.build_patterns) and not match_any(self.skip_patterns) + build_patterns = itertools.chain.from_iterable(bracex.expand(p) for p in self.build_patterns) + skip_patterns = itertools.chain.from_iterable(bracex.expand(p) for p in self.skip_patterns) + + build: bool = any(fnmatch.fnmatch(build_id, pat) for pat in build_patterns) + skip: bool = any(fnmatch.fnmatch(build_id, pat) for pat in skip_patterns) + return build and not skip def __repr__(self) -> str: if not self.skip_patterns: diff --git a/docs/options.md b/docs/options.md index 7b2398a7..a65a5796 100644 --- a/docs/options.md +++ b/docs/options.md @@ -75,7 +75,7 @@ Space-separated list of builds to build and skip. Each build has an identifier l When both options are specified, both conditions are applied and only builds with a tag that matches `CIBW_BUILD` and does not match `CIBW_SKIP` will be built. -When setting the options, you can use shell-style globbing syntax (as per [`fnmatch`](https://docs.python.org/3/library/fnmatch.html)). All the build identifiers supported by cibuildwheel are shown below: +When setting the options, you can use shell-style globbing syntax, as per [`fnmatch`](https://docs.python.org/3/library/fnmatch.html) with the addition of curly bracket syntax `{option1,option2}`, provided by [`bracex`](https://pypi.org/project/bracex/). All the build identifiers supported by cibuildwheel are shown below:
@@ -89,7 +89,7 @@ When setting the options, you can use shell-style globbing syntax (as per [`fnma | Python 3.9 | cp39-macosx_x86_64 | cp39-manylinux_x86_64 | cp39-manylinux_i686 | cp39-win_amd64 | cp39-win32 | cp39-manylinux_aarch64 | cp39-manylinux_ppc64le | cp39-manylinux_s390x | | PyPy 2.7 v7.3.3 | pp27-macosx_x86_64 | pp27-manylinux_x86_64 | | | pp27-win32 | | | | | PyPy 3.6 v7.3.3 | pp36-macosx_x86_64 | pp36-manylinux_x86_64 | | | pp36-win32 | | | | -| PyPy 3.7 (beta) v7.3.3 | pp37-macosx_x86_64 | pp37-manylinux_x86_64 | | | pp37-win32 | | | | +| PyPy 3.7 (beta) v7.3.3 | pp37-macosx_x86_64 | pp37-manylinux_x86_64 | | | pp37-win32 | | | | The list of supported and currently selected build identifiers can also be retrieved by passing the `--print-build-identifiers` flag to `cibuildwheel`. @@ -124,12 +124,12 @@ CIBW_SKIP: cp27-* cp35-* # Skip Python 3.6 on Linux CIBW_SKIP: cp36-manylinux* -# Only build on Python 3 and skip 32-bit builds -CIBW_BUILD: cp3?-* +# Only build on Python 3 (ready for 3.10 when it comes) and skip 32-bit builds +CIBW_BUILD: {cp,pp}3*-* CIBW_SKIP: "*-win32 *-manylinux_i686" # Only build PyPy and CPython 3 -CIBW_BUILD: pp* cp3?-* +CIBW_BUILD: pp* cp3*-* # Disable building PyPy wheels on all platforms CIBW_SKIP: pp* diff --git a/setup.cfg b/setup.cfg index 2220ab45..da6fe65b 100644 --- a/setup.cfg +++ b/setup.cfg @@ -31,6 +31,7 @@ install_requires = bashlex!=0.13 toml certifi + bracex typing_extensions; python_version < '3.8' importlib_resources>=1.4; python_version < '3.9' @@ -119,6 +120,9 @@ ignore_missing_imports = True [mypy-toml.*] ignore_missing_imports = True +[mypy-bracex.*] +ignore_missing_imports = True + [tool:isort] profile=black multi_line_output=3 diff --git a/unit_test/build_selector_test.py b/unit_test/build_selector_test.py index 8737ee6b..6e00fc76 100644 --- a/unit_test/build_selector_test.py +++ b/unit_test/build_selector_test.py @@ -59,3 +59,13 @@ def test_build_and_skip(): assert not build_selector('cp27-win_amd64') assert build_selector('cp36-win_amd64') assert not build_selector('cp37-win_amd64') + + +def test_build_braces(): + build_selector = BuildSelector(build_config="cp{36,37}*", skip_config="") + + assert not build_selector('cp27-manylinux1_x86_64') + assert build_selector('cp36-manylinux1_x86_64') + assert build_selector('cp37-manylinux1_x86_64') + assert not build_selector('cp38-manylinux1_x86_64') + assert not build_selector('cp39-manylinux1_x86_64')