|
20 | 20 | """ |
21 | 21 |
|
22 | 22 | import os |
| 23 | +import shutil |
23 | 24 | import subprocess |
24 | 25 | import sys |
25 | 26 |
|
|
34 | 35 |
|
35 | 36 |
|
36 | 37 | def probe(heap_k, entry, workdir): |
37 | | - src = ("import kandinsky, ion, time, gc, sys\n" |
38 | | - "sys.path.insert(0, %r)\n" |
| 38 | + """Import `entry` on a heap of exactly `heap_k` KB. Returns None if it did |
| 39 | + not fit. |
| 40 | +
|
| 41 | + Nothing here mentions an absolute path. An earlier version inserted the |
| 42 | + work directory into sys.path, which made the answer depend on how deep the |
| 43 | + checkout sat: the longer string shifted the baseline by a couple of hundred |
| 44 | + bytes, that pushed a parse allocation over a chunk boundary, and the |
| 45 | + reported minimum jumped 3 KB. Same game, different number, depending on the |
| 46 | + machine. The interpreter runs with the work directory as its own cwd |
| 47 | + instead, and MicroPython's default sys.path already starts with '', so the |
| 48 | + modules and the stubs are found with no path string at all. |
| 49 | + """ |
| 50 | + src = ("import kandinsky, ion, time, gc\n" |
39 | 51 | "gc.collect()\n" |
40 | 52 | "b = gc.mem_free()\n" |
41 | 53 | "import %s\n" |
42 | 54 | "gc.collect()\n" |
43 | | - "print('OK', b - gc.mem_free(), gc.mem_free())\n" % (workdir, entry)) |
44 | | - path = os.path.join(STUBS, "_probe.py") |
| 55 | + "print('OK', b - gc.mem_free(), gc.mem_free())\n" % entry) |
| 56 | + path = os.path.join(workdir, "_probe.py") |
45 | 57 | with open(path, "w") as fh: |
46 | 58 | fh.write(src) |
47 | 59 | try: |
48 | 60 | r = subprocess.run([MP, "-X", "heapsize=%dk" % heap_k, "_probe.py"], |
49 | | - capture_output=True, text=True, cwd=STUBS, timeout=90) |
| 61 | + capture_output=True, text=True, cwd=workdir, timeout=90) |
50 | 62 | except subprocess.TimeoutExpired: |
51 | 63 | return None |
52 | 64 | if r.stdout.startswith("OK"): |
@@ -96,11 +108,15 @@ def main(argv): |
96 | 108 | workdir = os.path.join(ROOT, "tools", "mp", "work") |
97 | 109 | os.makedirs(workdir, exist_ok=True) |
98 | 110 |
|
99 | | - # Every dist/*.py module must be importable, so stage them all. |
| 111 | + # Every dist/*.py module must be importable, so stage them all -- and the |
| 112 | + # kandinsky/ion stubs beside them, since the probe imports by cwd alone. |
100 | 113 | dist = os.path.join(ROOT, "dist") |
101 | 114 | for f in sorted(os.listdir(dist)): |
102 | 115 | if f.endswith(".py"): |
103 | 116 | prepare(os.path.join(dist, f), workdir) |
| 117 | + for f in sorted(os.listdir(STUBS)): |
| 118 | + if f.endswith(".py") and not f.startswith("_"): |
| 119 | + shutil.copyfile(os.path.join(STUBS, f), os.path.join(workdir, f)) |
104 | 120 |
|
105 | 121 | print("%-22s %8s %10s %10s %8s" % |
106 | 122 | ("module", "bytes", "min heap", "resident", "verdict")) |
|
0 commit comments