docs(tools): name the boundary that rejects a padded integer, and what the flavor-guard test actually reads
pyScalar's docstring attributed the rejection of a String-spelled beyond-safe-range integer to "the Python runtime". No published backend makes that call on this base. The fact that does not depend on one: the padded digits name an integer no double holds, and passing it back would have to cross the argument boundary as a JSON number. Say that, and say why String rounds at all -- Number::toString is shortest round-trip, so 2 ** 60 emits the 16 digits that re-read to the same double and pads. Mirror both in the test comment. The note's Decision sentence said a test covers the flavor guard through ctx.tools.schemas(). The test reads the definition's getter directly, under a language absent from both tables; schemas() reaches the same getter but has no assertion. Name what is read, and record that a renderer-without-flavor language is drift this guards against rather than an existing input -- the two key sets are identical today.
This commit is contained in:
@@ -259,11 +259,14 @@ function childClassName(base: string, segment: string): string {
|
||||
* `String`: Python integers are arbitrary-precision, so the emitted digits ARE
|
||||
* the value the model programs against, and `String` gives a different integer
|
||||
* than the double holds (`2 ** 60` prints the rounded `...847000`, not the
|
||||
* exact `...846976`) or no integer literal at all (`1e21` prints `1e+21`). The
|
||||
* Python runtime then rejects the advertised literal as not exactly
|
||||
* representable as a JavaScript number, so the SDK would document a value no
|
||||
* program can pass. The TS flavor needs no counterpart: its literal is re-read
|
||||
* by a JS parser back into the same double.
|
||||
* exact `...846976`) or no integer literal at all (`1e21` prints `1e+21`).
|
||||
* `String`'s rounding is not a bug in it: `Number::toString` is shortest
|
||||
* round-trip, so it emits the 16 digits that re-read to the same double and
|
||||
* pads with zeros, and those padded digits name an integer no double holds.
|
||||
* Passing one back would have to cross the argument boundary as a JSON number
|
||||
* — a double again — so the SDK would document a value no program can pass.
|
||||
* The TS flavor needs no counterpart: its literal is re-read by a JS parser
|
||||
* back into the same double.
|
||||
*
|
||||
* `JSON.stringify` is also what keeps this path's output parseable, and it is
|
||||
* the only thing that does. It covers both classes of hazard: the two kinds of
|
||||
|
||||
@@ -71,9 +71,13 @@ describe('jsonSchemaToPy', () => {
|
||||
// Python integers are arbitrary-precision, so the emitted digits ARE the
|
||||
// value the model programs against. `String(2 ** 60)` prints the rounded
|
||||
// ...847000, which is a DIFFERENT integer from the double's exact
|
||||
// ...846976 — the Python runtime would reject the advertised literal as
|
||||
// not exactly representable as a JavaScript number, so the SDK would
|
||||
// document a value no program can pass.
|
||||
// ...846976: `Number::toString` is shortest round-trip, so it emits the 16
|
||||
// digits that re-read to the same double and pads with zeros, and those
|
||||
// padded digits name an integer no double holds. Passing one back would
|
||||
// have to cross the argument boundary as a JSON number, so the SDK would
|
||||
// document a value no program can pass. This assertion is what separates
|
||||
// the two spellings; the 1e21 case below separates them again on the other
|
||||
// failure mode, where `String` gives no integer literal at all.
|
||||
expect(jsonSchemaToPy({ type: 'integer', const: 2 ** 60 })).toBe('Literal[1152921504606846976]')
|
||||
expect(jsonSchemaToPy({ type: 'integer', enum: [2 ** 60, -(2 ** 60)] }))
|
||||
.toBe('Literal[1152921504606846976, -1152921504606846976]')
|
||||
|
||||
Reference in New Issue
Block a user