Skip to content

Commit 47d815a

Browse files
authored
Merge pull request #1000 from dodona-edu/fix/dont-clear-files-on-start
Don't clear files in the state on execution start
2 parents 1023e42 + 81ea8ba commit 47d815a

File tree

3 files changed

+46
-7
lines changed

3 files changed

+46
-7
lines changed

src/backend/workers/python/papyros/papyros.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ def _flush_open_files(self):
160160
pass
161161
self._tracked_files -= closed
162162

163-
def _emit_created_files(self, emit_empty=False):
163+
def _emit_created_files(self):
164164
with self._without_file_tracking():
165165
cwd = os.getcwd()
166166
result = {}
@@ -186,11 +186,10 @@ def _emit_created_files(self, emit_empty=False):
186186
except Exception:
187187
return
188188
snapshot = json.dumps(result, sort_keys=True)
189-
if snapshot == self._last_emitted_snapshot and not emit_empty:
189+
if snapshot == self._last_emitted_snapshot:
190190
return
191191
self._last_emitted_snapshot = snapshot
192-
if result or emit_empty:
193-
self.callback("files", data=snapshot, contentType="text/json")
192+
self.callback("files", data=snapshot, contentType="text/json")
194193

195194
@contextmanager
196195
def _execute_context(self):
@@ -232,7 +231,7 @@ async def run_async(self, source_code, mode="exec", top_level_await=True):
232231
from tracer import JSONTracer
233232
def frame_callback(frame):
234233
self._flush_open_files()
235-
self._emit_created_files(emit_empty=True)
234+
self._emit_created_files()
236235
self.callback("frame", data=frame, contentType="application/json")
237236

238237
result = JSONTracer(frame_callback=frame_callback, module_name=MODULE_NAME).runscript(source_code)

src/frontend/state/InputOutput.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,6 @@ export class InputOutput extends State {
232232
this.output = [];
233233
this.prompt = "";
234234
this.awaitingInput = false;
235-
this.files = [];
236235
this.activeEditorTab = CODE_TAB;
237236
}
238237
}

test/__tests__/state/Files.test.ts

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { Papyros } from "../../../src/frontend/state/Papyros";
22
import { expect, it, describe } from "vitest";
33
import { ProgrammingLanguage } from "../../../src/ProgrammingLanguage";
4-
import { waitForFiles, waitForPapyrosReady, waitForInputReady, waitForOutput } from "../../helpers";
4+
import { waitForFiles, waitForPapyrosReady, waitForInputReady, waitForOutput, waitForAwaitingInput } from "../../helpers";
55
import { isValidFileName } from "../../../src/util/Util";
66

77
describe("isValidFileName", () => {
@@ -117,6 +117,47 @@ raise ValueError("intentional error")
117117
expect(papyros.io.files[0].content).toBe("before crash");
118118
});
119119

120+
it("files from previous run persist while awaiting input in next run", async () => {
121+
const papyros = new Papyros();
122+
await papyros.launch();
123+
papyros.runner.programmingLanguage = ProgrammingLanguage.Python;
124+
papyros.runner.code = `open("persist.txt", "w").write("hello")`;
125+
await waitForInputReady();
126+
await papyros.runner.start();
127+
await waitForFiles(papyros, 1);
128+
expect(papyros.io.files.length).toBe(1);
129+
expect(papyros.io.files[0].name).toBe("persist.txt");
130+
131+
papyros.runner.code = `x = input("name?")`;
132+
await waitForPapyrosReady(papyros);
133+
void papyros.runner.start();
134+
await waitForAwaitingInput(papyros);
135+
expect(papyros.io.files.length).toBe(1);
136+
expect(papyros.io.files[0].name).toBe("persist.txt");
137+
138+
papyros.io.provideInput("test");
139+
await waitForPapyrosReady(papyros);
140+
expect(papyros.io.files.length).toBe(1);
141+
expect(papyros.io.files[0].name).toBe("persist.txt");
142+
});
143+
144+
it("files from previous run are cleared when next run deletes them", async () => {
145+
const papyros = new Papyros();
146+
await papyros.launch();
147+
papyros.runner.programmingLanguage = ProgrammingLanguage.Python;
148+
papyros.runner.code = `open("temp.txt", "w").write("hello")`;
149+
await waitForInputReady();
150+
await papyros.runner.start();
151+
await waitForFiles(papyros, 1);
152+
expect(papyros.io.files.length).toBe(1);
153+
expect(papyros.io.files[0].name).toBe("temp.txt");
154+
155+
papyros.runner.code = `import os; os.remove("temp.txt")`;
156+
await papyros.runner.start();
157+
await waitForPapyrosReady(papyros);
158+
expect(papyros.io.files.length).toBe(0);
159+
});
160+
120161
it("updateFileContent updates the in-memory content of an existing file", async () => {
121162
const papyros = new Papyros();
122163
await papyros.launch();

0 commit comments

Comments
 (0)