RUNTIME VALUE CONVERSIONS

Mutable lists and mixed tuples

Lists and tuples may contain different supported value types, including nested containers and class instances. These examples use runtime value conversion.

Share and change a list

def update(values: list[int | str]) -> None:
    values[0] = "changed"
    values.append(9)

def shared_values() -> list[int | str]:
    values: list[int | str] = [1, "two"]
    alias = values
    update(alias)
    return values

shared_values() returns ["changed", "two", 9]. Assignment and function calls keep the same list object; they do not make independent copies.

Supported list operations

FormBehavior
[], [value, ...]Empty or populated lists with mixed and nested supported values.
values[index], values[index] = valueCalculated integer indices; negative indices count from the end.
values.append(value)Add one element to the same list.
values += other, values *= countMutate the shared list. The right operand of += may be a list or tuple.
left + right, values * countCreate a new outer list; concatenation requires two lists.
values[start:stop:step]Create a shallow slice, including negative steps.
len, iteration, in/not in, count(value)Inspect elements in sequence order.
==, !=, is, is notCompare list contents or test shared list identity.

Nested mutable elements remain shared in slices, copies, concatenation, and repetition. A new outer container is not a deep copy. Slice assignment, deletion, sorting, and general iterable extension are unsupported.

Different types at tuple positions

def describe(name: str, count: int) -> tuple[str, int, bool]:
    row: tuple[str, int, bool] = (name, count, count > 0)
    return row

tuple[str, int, bool] checks each position separately. Use tuple[int, ...] for a variable-length tuple of integers. Unannotated tuples can also contain mixed supported values.

Immutable tuple slots, shared contents

def nested_values() -> tuple[str, list[int]]:
    values = [1, 2]
    row = ("items", values)
    row[1].append(3)
    return row

The result is ("items", [1, 2, 3]). A tuple slot cannot be replaced, but a list referenced by that slot can change. Tuples support indexing, slices, concatenation with tuples, repetition, equality, membership, count(value), and iteration. Scalar and tuple identity tests are unsupported; use equality for value comparisons.

Packing, conversion, and unpacking

def unpack_row(row: tuple[str, int]) -> str:
    name, count = row
    return name + ": " + str(count)

Use fixed unpacking targets with a matching element count. Starred targets are unsupported. list(value) and tuple(value) accept a supported string, list, tuple, or range. A string yields one-character strings. list() and tuple(), or [] and (), create empty containers.

Container annotation checks

list[int | str] accepts integer and string elements at an annotated boundary. These checks inspect the current contents; they do not attach a permanent element schema to the shared object. A later write through an alias can change contents, and the next annotated boundary checks them again. See Function and assignment checks.

Container growth is constrained by the runtime context's memory and work limits. Dictionaries and sets use the separate typed conversion forms.