feat: File* save/load actions, hashlib/uuid, dict spread and small renpy helpers in the player
CI / frontend (push) Failing after 21s
CI / backend (push) Failing after 36s

Games with their own save screens work: FileAction/FileSave/FileLoad/FileDelete/FilePage*, FileLoadable,
FileTime, FileSaveName, FileJson and friends use browser slots (a slot has no screenshot). Added
renpy.has_image/has_screen/list_files/get_mouse_pos/log/jump_out_of_context/random.seed,
renpy.translation.translate_string, type/id/vars/Flatten/LiveComposite/Composite, bare defaultdict/
deepcopy, md5/sha256 (checked against test vectors), uuid4, time.monotonic, re.compile().fullmatch,
math.isfinite and `{**a, "k": v}`. The converter whitelists them and accepts the hashlib/uuid imports.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
mrleo1nidandClaude Sonnet 5.5 committed 2026-10-26 04:02:22 +03:00
1 parent 5c1e1aee01
commit 16ba20816c
8 files changed
+366 -20

No files matched your search

+18
View File
@@ -205,3 +205,21 @@ def test_hide_windows_context_call_is_a_click_wait():
assert not data.blockers
other = parse('label start:\n $ renpy.call_in_new_context("something_else")\n return\n')
assert other.modules["t.rpy"][0]["body"][0]["op"] == "exec"
def test_dict_spread_and_new_modules_are_accepted():
from app.converter import pyexpr
code = pyexpr.parse_stmts("import hashlib\nimport uuid\nmerged = {**base, 'k': 1}\n")
entries = code[0]["v"]["v"]
assert entries[0][0] == {"k": "star", "v": {"k": "name", "id": "base"}}
assert entries[1][0] == {"k": "const", "v": "k"}
def test_translated_speaker_name_and_capitalised_parameterised_transform():
data = parse('transform FadeIn():\n alpha 0.0\n linear 0.5 alpha 1.0\n'
'screen s():\n frame:\n at FadeIn()\n'
'label start:\n __("Girl") "Hello there"\n call screen s\n')
say = data.modules["t.rpy"][0]["body"][0]
assert say["op"] == "say" and say["what"] == "Hello there"
assert not data.blockers