RUNTIME VALUE CONVERSIONS

File bookmarks and exclusive creation

Revisit text you have already read, or create a new output file while protecting an existing destination.

Select Transpile → Runtime. These operations use the existing direct with open(..., encoding="utf-8") workflow. File access happens only when the generated C program runs. See File-processing workflows for reads, writes, Unicode, and cleanup.

Save and revisit a position

Call tell() to save a bookmark, read ahead, then pass that unchanged bookmark to seek() on the same open handle. A bookmark identifies a text-stream position. Treat its integer representation as opaque: it is not a character index, a portable byte offset, or a value to perform arithmetic on.

This example creates or overwrites bookmark-demo.txt. It revisits a line containing a multibyte Unicode character after reading CRLF and CR line endings.

def main():
    with open("bookmark-demo.txt", "w", encoding="utf-8", newline="") as out:
        out.write("header\r\ncafé\rnext\n")
    with open("bookmark-demo.txt", encoding="utf-8") as source:
        print(source.readline().strip())
        bookmark = source.tell()
        first = source.readline()
        source.seek(bookmark)
        print(first == source.readline())
        source.seek(0)
        print(source.readline().strip())
        source.seek(0, 2)
        print(source.read() == "")
    return 0

Expected output:

header
True
header
True

Bookmarks preserve the next text to be read with both newline=None and newline="", including newline lookahead. Helpers, aliases, and bound methods share the handle's cursor and bookmarks.

Supported seeks

CallBehavior
tell()Return the current bookmark. Output is flushed before the position is reported.
seek(bookmark), seek(bookmark, 0)Restore a bookmark previously returned by tell or seek on this open handle.
seek(0), seek(0, 0)Rewind to the beginning. A saved bookmark is not required.
seek(0, 1)Keep the current logical text position. Requires telling to be enabled.
seek(0, 2)Move to the end of the file.

Each successful seek returns the resulting bookmark. Arguments are positional integers. Nonzero relative seeks are unsupported. Unrecorded nonzero absolute positions are rejected, even when they happen to identify a valid byte boundary. Do not transfer bookmarks to another handle or keep using them after close/reopen. Their numerical values need not match CPython's text cookies.

Calling next(handle), or advancing a for loop over the file, disables tell and seek(0, 1) until a successful absolute/end seek or iterator exhaustion. Use readline() when taking a bookmark between each line. Breaking a file loop or calling flush does not restore telling in this profile.

Positioning also works on write, append, and exclusive-create handles. Seeking on an append handle does not change append behavior: the next write still goes to the end. Seeking does not truncate a file. Replacing text in place can damage UTF-8 when replacement bytes have a different length; prefer writing a complete new output when changing content.

Create without overwriting

Mode "x" creates a new text file. If the destination already exists, opening fails with FileExistsError and leaves that file untouched. The host's exclusive-create operation performs the check and creation together; PyCForge does not implement a separate existence check followed by truncation.

def save_once(path, text):
    try:
        with open(path, "x", encoding="utf-8", newline="") as output:
            output.write(text)
        return True
    except FileExistsError:
        return False

def main():
    print(save_once("new-report.txt", "First report\n"))
    print(save_once("new-report.txt", "Replacement\n"))
    with open("new-report.txt", encoding="utf-8") as source:
        print(source.read().strip())
    return 0

In a directory where new-report.txt does not exist, expected output is:

True
False
First report

Running the example again preserves the existing file and reports False for both attempts. OSError and Exception also catch FileExistsError. Other open failures use OSError. Exclusive creation does not make the subsequent write transactional: an error after creation can leave a partial new file.

Limits and errors

The existing explicit memory collection boundary is unchanged: collection refuses while a file is open. After close, a retained file value can still report its closed state, but its bookmarks no longer authorize any I/O.