003753c21a
* fix(ids): stamp uuid7 from the clock, not from the previous id
uuid6's uuid7 orders ids inside one millisecond by bumping the
timestamp past the previous one. The borrowed value becomes the next
call's floor, so the error compounds: a burst of 5000 ids stamps every
later one 4991 ms into the future, and it stays there until the clock
catches up. These are workspace and session ids, used as time-ordered
database keys.
Mint the id here instead, with RFC 9562's dedicated counter in rand_a:
48-bit timestamp, 12-bit intra-millisecond counter, 62 random bits. The
timestamp is only ever a real clock reading, and an exhausted
millisecond waits for the next rather than borrowing.
Drops the uuid6 dependency, which nothing else used. TypeScript already
had this right, via the uuid package's counter.
* feat(python3): parse CPython's option table, and seed sys.path on pyodide
python3's spec carried one option, -c, and a free-text rest, so every
other switch fell through to the operand slot: 'python3 -u s.py' ran
'/-u' as the script and failed, 'python3 -zz -c ...' exited 0 with the
flag swallowed, and -V and -h were read as paths.
Two spec knobs fix the class rather than the command. stop_at_operand
turns off the parser's dash-operand leniency and ends option parsing at
the first operand, which is CPython's own rule; ends_options marks the
options that carry a program (-c, -m), so the words after them are the
program's argv rather than python3's. Both mirror in TypeScript.
On top of that: -m runs through runpy, with a find_spec probe so a
missing module is CPython's one line instead of a traceback; the four
source doors each report the argv[0] CPython gives them; and the
interpreter-init switches ride in RunArgs.flags, honored where the
engine can and reported on stderr where it cannot.
argv[0] needed one more piece. The local and wasi tiers hand CPython
the program through -c, so it hardcoded argv[0] to '-c' and named every
frame '<string>'. bootstrap() re-compiles under the real name, which
fixes argv[0] and the traceback filename together.
Pyodide gains sysPath, which glob-expands and prepends mount paths once
the mounts are in place, so a vendored wheel imports without the
sys.path.append incantation. A glob that matches nothing is reported on
the run's stderr; the seed cannot report it itself, since it runs
before stderr is captured. packages, packageBaseUrl and lockFileURL
reach a prebuilt distribution, and the wrapper honors -O, -B, -W, -X,
-E and -I.
Verified against CPython 3.13.7: all 14 probed lines match on stdout,
stderr and exit code.
* refactor(spec): borrow argparse's REMAINDER instead of two bespoke parser knobs
python3's line needs opposite treatment of an unknown dash word on
either side of the script: `-zz` before it is python3's usage error,
`--foo` after it is data the script must receive. The first pass added
CommandSpec.stop_at_operand and Option.ends_options to say that, which
put two per-command dialect fields on dataclasses every command shares.
The first half is not ours to invent: it is argparse's
nargs=argparse.REMAINDER, and POSIX's own option order (GNU's permuting
default is the extension, which `POSIXLY_CORRECT=1 ls a -1` shows).
argparse spells it on the positional slot, so it goes on Operand under
argparse's name, and CommandSpec is untouched.
The second half argparse cannot express at all: `add_argument('-c')`
beside nargs=REMAINDER answers `unrecognized arguments: -u`, and CPython
parses its own command line in C for that reason. So it stays out of the
grammar. POSIX already spells the handoff `--`, and the parser already
consumes one, so a table in workspace/route inserts it after -c/-m's
value, beside the other command-name-keyed line rules. The marker is
added unconditionally: CPython passes a typed `--` through as data
(`python3 -c p -- -u` gives the program ['-c','--','-u']), so the parser
eats exactly the one added here.
Net: Option and CommandSpec return to what they were, Operand gains one
borrowed field. CLAUDE.md now states the rule as a literal test, since a
CLISpec is a CommandSpec and cannot be used to escape it.
* docs: require POSIX and argparse, not either, for a shared grammar field
POSIX alone specifies an option whose argument is a program (sh -c, and
python3's own synopsis), so an either-or rule would license the Option
field the section exists to refuse.
* fix(python3): address review on init switches, and declare the four missing ones
- pyodide restores warnings.filters after a run, so -W error no longer
follows every later line on the warm interpreter
- -OOO saturates at compile()'s max of 2 rather than raising ValueError
- -E/-I stop deleting PYTHON* from os.environ: CPython's -E stops those
variables configuring startup, it does not hide them from the program
- pyodide reports -E/-I/-s/-S through unhonoredNotice instead of faking
them; unhonored() grew a honored subset, and now reports -OO too
- declare -b, -P, -x and --check-hash-based-pycs, which CPython accepts
and mirage was refusing. -x is answered by the source resolver, since
handing it to an engine that runs code via -c would honor it nowhere
- end_options_after_program walks a short cluster letter by letter, so
-uc 'p' -v hands -v to the program, and steps over long value options
* fix(integ): argv[0] for a payload is -c on every engine, monty included
Monty's DEFAULT_PROG placeholder only applied because nothing ever told
it a name. The python3 command now supplies CPython's own answer, so
these four policy-routing steps read -c. They still distinguish monty
from local, since argv is a monty global and CPython would NameError.
Also picks up the formatting of the new flags test: it was untracked
when pre-commit ran, and --all-files goes through git ls-files.
* fix(python3): do not rewrite a shadowed name, and stop over-claiming -W and -X
- the `--` handoff is skipped when a shell function shadows python3.
bash's rule gives the function the line, and it has no CPython option
table to read a marker with. `command python3` masks the function for
its inner run, so the rewrite applies there again. A CLI cannot reach
this at all: register_cli refuses a shell builtin's name.
- an invalid -W filter is reported as CPython reports it and the program
still runs, instead of _OptionError escaping the wrapper and killing a
line every other runtime completes.
- a known -X name is reported as unhonored, since populating
sys._xoptions is all a warm interpreter can do for one. An arbitrary
name stays silent, which is all CPython does with it either.
- -O's reach is written down: the payload is compiled at the requested
level, a module imported from sys.path is not, and sys.flags stays 0.
126 lines
2.9 KiB
JSON
126 lines
2.9 KiB
JSON
{
|
|
"_meta": {
|
|
"by_resource": {
|
|
"": {
|
|
"filetypes": [],
|
|
"has_aggregate": false,
|
|
"has_provision": false,
|
|
"has_write": false
|
|
}
|
|
},
|
|
"filetypes": [],
|
|
"has_aggregate": false,
|
|
"has_provision": false,
|
|
"has_write": false,
|
|
"resources": []
|
|
},
|
|
"description": "Run Python on the workspace's bound runtime.",
|
|
"options": [
|
|
{
|
|
"description": "Run the next argument as a program.",
|
|
"short": "-c",
|
|
"type": "str"
|
|
},
|
|
{
|
|
"description": "Run the named module as __main__.",
|
|
"short": "-m",
|
|
"type": "str"
|
|
},
|
|
{
|
|
"description": "(Ignored) Unbuffered output. Mirage buffers every stream and returns it whole.",
|
|
"short": "-u",
|
|
"type": "bool"
|
|
},
|
|
{
|
|
"count": true,
|
|
"description": "Warn on str(bytes) and on comparing bytes with str; -bb raises instead.",
|
|
"short": "-b",
|
|
"type": "bool"
|
|
},
|
|
{
|
|
"description": "Do not write .pyc files on import.",
|
|
"short": "-B",
|
|
"type": "bool"
|
|
},
|
|
{
|
|
"description": "Ignore PYTHON* environment variables.",
|
|
"short": "-E",
|
|
"type": "bool"
|
|
},
|
|
{
|
|
"description": "Isolated mode: implies -E and -s.",
|
|
"short": "-I",
|
|
"type": "bool"
|
|
},
|
|
{
|
|
"count": true,
|
|
"description": "Remove assert and __debug__ blocks; -OO also strips docstrings.",
|
|
"short": "-O",
|
|
"type": "bool"
|
|
},
|
|
{
|
|
"description": "Do not prepend the script's directory to sys.path.",
|
|
"short": "-P",
|
|
"type": "bool"
|
|
},
|
|
{
|
|
"description": "(Ignored) Suppress the version banner. Mirage prints none.",
|
|
"short": "-q",
|
|
"type": "bool"
|
|
},
|
|
{
|
|
"description": "Do not add the user site directory to sys.path.",
|
|
"short": "-s",
|
|
"type": "bool"
|
|
},
|
|
{
|
|
"description": "Do not run 'import site' on initialization.",
|
|
"short": "-S",
|
|
"type": "bool"
|
|
},
|
|
{
|
|
"description": "Set a warning control filter.",
|
|
"multiple": true,
|
|
"short": "-W",
|
|
"type": "str"
|
|
},
|
|
{
|
|
"description": "Skip the script file's first line, for a non-Unix #! form.",
|
|
"short": "-x",
|
|
"type": "bool"
|
|
},
|
|
{
|
|
"description": "Set an implementation-specific option.",
|
|
"multiple": true,
|
|
"short": "-X",
|
|
"type": "str"
|
|
},
|
|
{
|
|
"choices": [
|
|
"always",
|
|
"default",
|
|
"never"
|
|
],
|
|
"description": "How to validate hash-based .pyc files.",
|
|
"long": "--check-hash-based-pycs",
|
|
"type": "str"
|
|
},
|
|
{
|
|
"description": "Show this help message and exit.",
|
|
"long": "--help",
|
|
"short": "-h",
|
|
"type": "bool"
|
|
},
|
|
{
|
|
"description": "Show version information and exit.",
|
|
"long": "--version",
|
|
"short": "-V",
|
|
"type": "bool"
|
|
}
|
|
],
|
|
"rest": {
|
|
"remainder": true,
|
|
"type": "str"
|
|
}
|
|
}
|