diff --git a/cibuildwheel/util.py b/cibuildwheel/util.py index 135ea1d95..2b1c28447 100644 --- a/cibuildwheel/util.py +++ b/cibuildwheel/util.py @@ -48,14 +48,56 @@ ) +def format_safe(template: str, **kwargs: Any) -> str: + """ + Works similarly to `template.format(**kwargs)`, except that unmatched + fields in `template` are passed through untouched. + + >>> format_safe('{a} {b}', a='123') + '123 {b}' + >>> format_safe('{a} {b[4]:3f}', a='123') + '123 {b[4]:3f}' + + To avoid variable expansion, precede with a single backslash e.g. + >>> format_safe('\\{a} {b}', a='123') + '{a} {b}' + """ + + result = template + + for key, value in kwargs.items(): + find_pattern = re.compile( + fr""" + (? str: """ Preprocesses a command by expanding variables like {python}. For example, used in the test_command option to specify the path to the - project's root. + project's root. Unmatched syntax will mostly be allowed through. """ - return command.format(python="python", pip="pip", **kwargs) + return format_safe(command, python="python", pip="pip", **kwargs) def get_build_verbosity_extra_flags(level: int) -> List[str]: diff --git a/docs/options.md b/docs/options.md index 3b9aaeb36..53ff1c4f5 100644 --- a/docs/options.md +++ b/docs/options.md @@ -1259,6 +1259,10 @@ Platform-specific environment variables are also available:
« subprocess_run("cibuildwheel", "--help") » ``` +## Placeholders + +Some options support placeholders, like `{project}`, `{package}` or `{wheel}`, that are substituted by cibuildwheel before they are used. If, for some reason, you need to write the literal name of a placeholder, e.g. literally `{project}` in a command that would ordinarily substitute `{project}`, prefix it with a hash character - `#{project}`. This is only necessary in commands where the specific string between the curly brackets would be substituted - otherwise, strings not modified. +