RUNTIME VALUE CONVERSIONS

Runtime strings

Construct and transform strings from function inputs while the generated C runs. These examples use runtime value conversion.

Create strings from inputs

def decorate(text: str, marker: str, count: int) -> str:
    return marker * count + text + marker * count

decorate("café", "*", 2) returns **café**. Concatenation and repetition create new strings. A zero or negative repetition count produces an empty string.

String values are immutable

def keep_original(text: str) -> tuple[str, str]:
    original = text
    text += "!"
    return original, text

keep_original("hello") returns ("hello", "hello!"). Reassigning a name does not change the value held by another name. Individual character assignment is unsupported.

Supported string operations

ExpressionBehavior
text + other, text * countConstruct a new string; repetition also accepts count * text.
len(text), text[index]Unicode code-point length and one-character strings; negative indices count from the end.
text[start:stop:step]Unicode slicing with omitted bounds, calculated indices, and positive or negative nonzero steps.
==, !=, <, <=, >, >=Content comparisons between strings.
needle in text, needle not in textSubstring membership.
text.startswith(prefix), text.endswith(suffix)One string argument, without optional bounds or tuple alternatives.
text.find(needle)Character index of the first match, or -1. No start/end arguments.
text.split(sep=None, maxsplit=-1)Split on Unicode whitespace when sep is omitted or None, or on an explicit nonempty string. Both optional arguments accept keywords. Return a list of strings.
text.strip(chars), lstrip(chars), rstrip(chars)Remove leading/trailing characters from an optional set. Omitted chars or None removes Unicode whitespace.
text.lower(), text.upper()Unicode case conversion, including multi-character mappings and contextual Greek final sigma.
f"{value}", f"{value!s}"Insert strings, integers, finite floats, Booleans, or None; escaped braces are supported.
separator.join(parts)Join a list or tuple whose elements are all strings.
text.replace(old, new), text.replace(old, new, count)Replace all matches or at most count matches. A negative count replaces all matches.

Split, replace, and join

def clean_fields(text: str) -> str:
    fields = text.split("|")
    cleaned = [field.replace("_", " ") for field in fields]
    return ", ".join(cleaned)

clean_fields("red_apple|green_pear") returns red apple, green pear. An explicit separator preserves empty fields, including those at either end.

Clean up text and split whitespace

def normalize(text: str) -> str:
    return " ".join(text.strip().lower().split())

def main() -> int:
    print(normalize("  Straße   CAFÉ  "))
    print("|".join("  one  two  three  ".split(maxsplit=1)))
    print("**hello**".strip("*"))
    return 0

Whitespace splitting collapses runs and removes empty fields at the ends. With maxsplit=0, it removes leading whitespace and returns the remaining nonempty text as one field. With a positive limit, the final field preserves the remaining text. An explicit separator preserves empty fields; negative maxsplit means unlimited splitting.

strip(chars) treats chars as a set of individual characters, not as a prefix or suffix. Case mappings and whitespace properties use Unicode 15.0. No locale-specific casing or normalization is applied.

Compose text with f-strings

def receipt(name: str, quantity: int = 1, *, price: float = 2.5) -> str:
    return f"{name.strip()}: {quantity} at {price}"

def main() -> int:
    print(receipt(" notebook ", price=float("3.75"), quantity=int("2")))
    return 0

This prints notebook: 2 at 3.75. Fields are evaluated and converted in source order. Ordinary fields, !s, and an empty format specification are supported. !r, !a, alignment, precision, numeric format codes, and arbitrary str.format() calls are unsupported and receive conversion diagnostics when visible in the source.

Unicode indexing and slices

def inspect_text(text: str) -> tuple[int, str, str]:
    return len(text), text[1:2], text[::-1]

For "hé😀", the result is (3, "é", "😀éh"). Length and positions count Unicode code points, not bytes or visible grapheme clusters. No normalization is applied; composed and decomposed forms can compare differently.

Inputs and errors

Strings use owned UTF-8 storage with an explicit byte length; embedded NUL characters are supported. A C caller must supply valid UTF-8 to pv_string. Unpaired Unicode surrogates are outside the supported text domain.

Out-of-range indexing, a zero slice step, an empty split separator, or incompatible arguments report runtime errors. Methods and argument forms not listed above are unsupported. Calls on a literal or an explicitly annotated receiver report a source diagnostic when the unsupported method or argument form can be identified during conversion; dynamic receivers retain runtime checks. Some additional operations on constant text belong to typed conversion.