RUNTIME VALUE CONVERSIONS
Construct and transform strings from function inputs while the generated C runs. These examples use runtime value conversion.
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.
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.
| Expression | Behavior |
|---|---|
text + other, text * count | Construct 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 text | Substring 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.rsplit(sep=None, maxsplit=-1) | Split from the right, retaining normal left-to-right result order. Optional sep/maxsplit keywords work as with split. With whitespace and maxsplit=0, remove trailing whitespace only. |
text.splitlines(keepends=False) | Recognize Python's Unicode line boundaries, treating CRLF as one boundary. Retain line endings when keepends is true. Empty input gives an empty list; a final boundary does not add an extra empty line. |
text.partition(sep), text.rpartition(sep) | Return a three-item tuple around the first/last nonempty separator. With no match, partition returns (text, "", ""); rpartition returns ("", "", text). |
text.removeprefix(prefix), text.removesuffix(suffix) | Remove one exact matching prefix/suffix. Empty or unmatched arguments leave the value unchanged. These arguments and partition separators are positional-only 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 scalars or supported containers; !s/!r/!a, numeric precision, grouping and width/alignment share the format() implementation. |
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. |
Jump to line, field, and filename parsing examples.
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.
|
PyCForge caveats Build growing text with fragments. Repeated |
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 0Whitespace 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.
Read a text file with the Runtime file workflow, then process its returned string with these methods. This example uses embedded text so it can run directly.
def parse_settings(text):
values = {}
for line in text.splitlines():
if not line or line.startswith("#"):
continue
key, separator, value = line.partition("=")
if separator:
values[key.strip()] = value.strip()
return values
def main():
text = "# settings\r\nname=café\u2028path=reports/data.part.csv\n"
values = parse_settings(text)
print(values["name"])
path = values["path"].removeprefix("reports/")
print(path.removesuffix(".csv"))
print(path.rsplit(".", 1))
return 0
Expected output:
café data.part ['data.part', 'csv']
Partition keeps the separator as the middle item, so checking it distinguishes a missing separator from an empty value. rsplit limits the number of splits at the right-hand end; the returned list remains in reading order. Exact prefix/suffix removal differs from strip, which treats its argument as a set of characters.
def main():
stem, separator, extension = "archive.tar.gz".rpartition(".")
print(stem, extension)
print("plain".rpartition("."))
print("one\r\ntwo\u2028".splitlines(keepends=True))
print(" first second ".rsplit(maxsplit=0))
return 0
Expected output:
archive.tar gz
('', '', 'plain')
['one\r\n', 'two\u2028']
[' first second']
Line boundaries are LF, CR, CRLF, vertical tab, form feed, U+001C through U+001E, U+0085, U+2028, and U+2029. Tabs, U+001F, spaces, and embedded NUL do not split lines. Consecutive boundaries retain intervening empty lines; a terminal boundary adds no further line. keepends accepts a positional value or keyword and uses the normal truth value of supported Runtime values.
These methods preserve exact Unicode code points and embedded NUL. They do not normalize Unicode, apply locale rules, or interpret a separator as a regular expression. Empty separators for rsplit/partition/rpartition raise ValueError; maxsplit must be an integer. Invalid argument types raise TypeError. Bound methods and supplied-module helpers use the same contracts.
All results use the existing Runtime arena. Parsing and substring comparisons consume the shared work budget; repeated near-matches can exhaust it. Allocation and work exhaustion are terminal resource failures, with normal automatic file cleanup. Use explicit idle-boundary collection to reclaim unneeded values between C calls. These methods do not make collection automatic.
def receipt(name: str, quantity: int = 1, *, price: float = 2.5) -> str:
return f"{name.strip()}: {quantity} at {price:.2f}"
def main() -> int:
print(receipt(" notebook ", price=float("3.75"), quantity=int("2")))
return 0This prints notebook: 2 at 3.75. Fields are evaluated in source order. F-strings support !s, !r, !a, and calculated format specifications. The same formatter serves format(value, spec) and text.format(...).
| Formatting | Admitted forms |
|---|---|
| Text and padding | Unicode fill, width, left/right/center alignment (< > ^), string precision and s. |
| Numbers | Signs, zero padding, = alignment, alternate #, comma/underscore grouping; integer d b o x X; finite floating f F e E g G % with precision. |
| str.format fields | Automatic or numbered positions, names, attribute/item selection, escaped braces, conversions, and one level of nested replacement fields in a specification. Automatic and manual numbering cannot mix. |
| Representations | repr/!r quote strings and containers; ascii/!a also escape non-ASCII characters. Cyclic containers use Python-style markers. |
def main() -> int:
price = 12.345
print(f"{price:09.2f}", f"{'café'!r:>10}")
print("{name}: {price:{width}.2f}".format(name="Total", price=price, width=8))
print([1, "two", {"price": price}])
return 0
Width is limited to 1,000,000 code points and precision to 1,000. Locale-sensitive n, character c, the z option, custom formatting protocols and object/function/range/iterator representations are outside this profile. Invalid forms report checked runtime errors. Numeric formatting and round require the C numeric locale and round-to-nearest. These limits are additional to the shared memory/work budgets.
center(width, fillchar), ljust(width, fillchar), and rjust(width, fillchar) pad to a minimum Unicode character count. The optional fill is one character and defaults to a space. These arguments are positional-only. A width at or below the current length preserves the text; an invalid fill is still an error. Centering follows Python's odd-padding placement.
zfill(width) inserts ASCII zeroes after an initial ASCII plus or minus sign. It accepts one positional width. expandtabs(tabsize=8) replaces tabs using character columns, resets columns at carriage return and line feed, and removes tabs when tabsize is zero or negative. Tabsize accepts a positional argument or keyword and must fit a signed 32-bit integer. Widths and tab sizes accept builtin integers and booleans; custom index protocols are outside this profile.
def main():
print("Inventory".center(24, "="))
for code, name, count in [(7, "café", 12), (42, "tea", 3)]:
print(str(code).zfill(4) + " " + name.ljust(10) + str(count).rjust(4))
print("name\tcount\ncoffee\t12".expandtabs(tabsize=12))
return 0
Widths count Unicode code points, including combining characters, rather than terminal display cells. Embedded NUL is preserved. Bound methods and expanded calls use the same checks. Scans and output construction consume the existing work budget; oversized output and allocation failure are terminal resource errors. This does not add bytes formatting or new dependencies.
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.
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.