pll-python 0.2.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +7 -0
- package/README.md +64 -14
- package/cli.cjs +4429 -1123
- package/package.json +5 -3
- package/worker.cjs +835 -409
package/LICENSE
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
Copyright 2026 Daniel Patterson.
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
4
|
+
|
|
5
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
6
|
+
|
|
7
|
+
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/README.md
CHANGED
|
@@ -11,11 +11,13 @@ Needs **Node 22 or newer** (the oldest Node still receiving support).
|
|
|
11
11
|
npx pll-python hw.py
|
|
12
12
|
```
|
|
13
13
|
|
|
14
|
+
(Not `npx pll`, which is a different package.)
|
|
15
|
+
|
|
14
16
|
Or install it:
|
|
15
17
|
|
|
16
18
|
```bash
|
|
17
19
|
npm install -g pll-python
|
|
18
|
-
pll hw.py
|
|
20
|
+
pll hw.py # or: pll-python hw.py
|
|
19
21
|
```
|
|
20
22
|
|
|
21
23
|
## Language levels
|
|
@@ -41,25 +43,31 @@ same way everywhere, which is the point of putting it in the file.
|
|
|
41
43
|
|
|
42
44
|
## Tests
|
|
43
45
|
|
|
44
|
-
`test_*` functions in the same file run
|
|
45
|
-
the editor
|
|
46
|
+
`test_*` functions in the same file run once the program finishes, against
|
|
47
|
+
what it defined, as they do in the editor. A test that prints shows what it
|
|
48
|
+
printed under its result; `@pytest.mark.skip`, `skipif` and `xfail` work as
|
|
49
|
+
in pytest:
|
|
46
50
|
|
|
47
51
|
```bash
|
|
48
|
-
pll hw.py #
|
|
52
|
+
pll hw.py # the program, then its tests
|
|
49
53
|
pll hw.py --no-tests # just the program
|
|
50
54
|
```
|
|
51
55
|
|
|
52
56
|
## Options
|
|
53
57
|
|
|
54
58
|
```
|
|
55
|
-
--no-tests do not run the file's test_* functions
|
|
59
|
+
--no-tests do not run the file's test_* functions, which
|
|
60
|
+
otherwise run once the program finishes
|
|
56
61
|
--save-images <dir> write pictures there as .svg
|
|
57
|
-
-q, --quiet only the program's own output
|
|
62
|
+
-q, --quiet only the program's own output and what went wrong:
|
|
63
|
+
errors, failed tests, files not loaded or not saved
|
|
58
64
|
--no-color never use ANSI colour
|
|
59
65
|
-h, --help
|
|
60
|
-
-
|
|
66
|
+
-V, --version
|
|
61
67
|
```
|
|
62
68
|
|
|
69
|
+
`-v` is not an option: Python's `-v` means something else entirely.
|
|
70
|
+
|
|
63
71
|
## Authoring Examplar bundles
|
|
64
72
|
|
|
65
73
|
Examplar assesses a *test suite* rather than an implementation: students
|
|
@@ -147,6 +155,11 @@ Publish the bundle at a URL and point students at it from their file:
|
|
|
147
155
|
#examplar https://cs2000.example/hw3.json
|
|
148
156
|
```
|
|
149
157
|
|
|
158
|
+
The check runs wherever the file does - in the editor, and with `pll
|
|
159
|
+
hw3.py`, which prints the same cards to stderr. Fetched bundles are cached
|
|
160
|
+
(under `$PLL_CACHE_DIR`, `$XDG_CACHE_HOME` or `~/.cache`), so a run without a
|
|
161
|
+
network still gets its verdict. The verdict does not change the exit code.
|
|
162
|
+
|
|
150
163
|
If any of your students use **vscode.dev** or a codespace, the extension host
|
|
151
164
|
there is a browser, so serve the bundle with CORS
|
|
152
165
|
(`samples/examplar_serve.mjs` in the repository is a dependency-free server
|
|
@@ -188,14 +201,22 @@ be fast and honest rather than secret.
|
|
|
188
201
|
| Code | Meaning |
|
|
189
202
|
| --- | --- |
|
|
190
203
|
| 0 | Ran, and any tests passed |
|
|
191
|
-
| 1 | The program raised |
|
|
204
|
+
| 1 | The program raised, or Ctrl+C stopped it (even if it caught the `KeyboardInterrupt`; its tests are then not run) |
|
|
192
205
|
| 2 | Level checks found problems, so it was not run |
|
|
193
206
|
| 3 | A test failed |
|
|
194
|
-
| 64 | Bad usage, or
|
|
207
|
+
| 64 | Bad usage, or Python could not start (it is given two minutes) |
|
|
208
|
+
| 130 | A second Ctrl+C gave up waiting for the program to stop |
|
|
209
|
+
| 141 | Its output could no longer be read - `pll hw.py \| head` |
|
|
210
|
+
| 143 | It was ended by SIGTERM |
|
|
195
211
|
|
|
196
212
|
Distinct codes so an autograder can tell "the level rejected this" from
|
|
197
213
|
"the tests failed" from "it crashed".
|
|
198
214
|
|
|
215
|
+
A program that ends itself with `sys.exit(n)` exits with `n` instead, as it
|
|
216
|
+
would under `python` - so a program can produce any of these codes itself.
|
|
217
|
+
`sys.exit()` is 0, and `sys.exit("message")` prints the message and is 1.
|
|
218
|
+
A status other than 0 outranks a failed test's 3.
|
|
219
|
+
|
|
199
220
|
## Piping
|
|
200
221
|
|
|
201
222
|
The program's own stdout is the **only** thing on stdout. Everything
|
|
@@ -206,22 +227,29 @@ goes to stderr. So this captures exactly what the program printed:
|
|
|
206
227
|
pll hw.py > output.txt
|
|
207
228
|
```
|
|
208
229
|
|
|
209
|
-
`input()`
|
|
230
|
+
`input()` and `sys.stdin.read()` read stdin, exactly as given, so piping
|
|
231
|
+
works too:
|
|
210
232
|
|
|
211
233
|
```bash
|
|
212
234
|
printf 'Ada\n' | pll greet.py
|
|
213
235
|
```
|
|
214
236
|
|
|
237
|
+
Ctrl+C stops the program wherever it is - waiting for input, in
|
|
238
|
+
`time.sleep`, or waiting for an address to answer - as it would under
|
|
239
|
+
`python`.
|
|
240
|
+
|
|
215
241
|
## What differs from the editor
|
|
216
242
|
|
|
217
243
|
- **Pictures cannot be drawn in a terminal.** Each one prints a note with
|
|
218
|
-
its size; `--save-images` writes them as `.svg` instead.
|
|
244
|
+
its size; `--save-images` writes them as `.svg` instead. A matplotlib
|
|
245
|
+
figure is a picture like any other: `plt.show()` prints the note.
|
|
219
246
|
- **Reactors (`big_bang`, `animate`) do not run.** They need the editor's
|
|
220
247
|
interactions panel to animate; here they print a note and the rest of the
|
|
221
248
|
program continues. Their logic is still testable — `simulate_trace(n)`
|
|
222
249
|
works fine and needs no clock.
|
|
223
250
|
- **Tables do print**, as text. Their content is already text, so there is
|
|
224
|
-
nothing to lose
|
|
251
|
+
nothing to lose; a tab, a new line or an escape in a cell is written out,
|
|
252
|
+
as `\t`, `\n` and `\x1b`.
|
|
225
253
|
|
|
226
254
|
Everything else is the same code: the same Pyodide worker, the same Python
|
|
227
255
|
libraries, the same analyzers and the same wording for errors.
|
|
@@ -229,8 +257,30 @@ libraries, the same analyzers and the same wording for errors.
|
|
|
229
257
|
## Files next to your program
|
|
230
258
|
|
|
231
259
|
`open("data.csv")` and `pd.read_csv("data.csv")` read files in the same
|
|
232
|
-
folder as the script
|
|
233
|
-
|
|
260
|
+
folder as the script or a folder inside it (`open("data/2024.csv")`), and
|
|
261
|
+
`__file__` is set, so `Path(__file__).parent` works. Files the program
|
|
262
|
+
writes appear there afterwards, and files it deletes are deleted — the same
|
|
263
|
+
as in the editor, with the same limits: at most 100 files, each at most
|
|
264
|
+
2 MB and 8 MB in all, nearest first; hidden and tools' folders (`.git`,
|
|
265
|
+
`venv`, `node_modules`) are left out. Files move as bytes, so a CSV in
|
|
266
|
+
another encoding or a picture arrives exactly as it is.
|
|
267
|
+
|
|
268
|
+
What is not loaded or not saved is said, even with `-q`, with why. A
|
|
269
|
+
file is never saved over when the program was not given it (it was over a
|
|
270
|
+
limit, say: saving would replace it with only what the program wrote), when
|
|
271
|
+
it changed on disk while the program ran, or when it is an existing `.py`.
|
|
272
|
+
|
|
273
|
+
## Packages
|
|
274
|
+
|
|
275
|
+
`import pandas`, `numpy`, `matplotlib`, `requests`, pytest (for the tests)
|
|
276
|
+
and the rest of Pyodide's packages are downloaded the first time they are
|
|
277
|
+
used, which needs the network; `pll` says so. They are found from the
|
|
278
|
+
program's imports wherever they are written, and from those of the files of
|
|
279
|
+
yours it imports. A URL read with `urllib`, `requests` or pandas arrives
|
|
280
|
+
byte for byte; an error page raises `HTTPError`, and an address that does
|
|
281
|
+
not answer gives up after 60 seconds, or the program's own `timeout`. They are kept beside Pyodide in the install, or in your cache
|
|
282
|
+
(`$XDG_CACHE_HOME/pll-python` or `~/.cache/pll-python`) when the install
|
|
283
|
+
cannot be written to.
|
|
234
284
|
|
|
235
285
|
## Licence
|
|
236
286
|
|