std.format spec conflict: docs say "follows Python rules" but std.jsonnet rejects booleans for numeric format codes
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 38/100
- Issue type
- Bug
- Clarity
- Mostly clear
- Activity status
- Quiet
- Domain
- compilers
Research direction
Start with the std.format documentation at the linked stdlib reference and the format_code helper in std.jsonnet, then compare the behavior described there with the examples in the issue. Review the linked sjsonnet PR for implementation context; done means the intended boolean behavior is decided and the documentation and reference implementation no longer conflict.
Written by the indexing model from the issue text.
Description
Summary
There is a conflict between the official documentation and the reference implementation (std.jsonnet) regarding how std.format handles boolean values with numeric format codes.
Documentation says
From https://jsonnet.org/ref/stdlib.html#std-format:
The string formatting follows the same rules as Python.
In Python, bool is a subclass of int, so all numeric format codes accept booleans:
>>> "%d" % True
'1'
>>> "%f" % True
'1.000000'
>>> "%x" % True
'1'
>>> "%s" % True
'True'
Reference implementation says
In std.jsonnet, the format_code helper explicitly checks:
if std.type(val) != 'number' then
error 'Format required number at ' + i + ', got ' + std.type(val)
Since std.type(true) returns 'boolean' (not 'number'), all numeric format codes reject booleans:
std.format("%d", true) → ERROR: "Format required number at 0, got boolean"
std.format("%f", true) → ERROR
std.format("%x", true) → ERROR
Only %s works: std.format("%s", true) → "true"
The conflict
| Expression | Python behavior (per docs) | std.jsonnet behavior (per impl) |
|---|---|---|
"%d" % true |
"1" |
ERROR |
"%f" % true |
"1.000000" |
ERROR |
"%x" % true |
"1" |
ERROR |
"%s" % true |
"True" |
"true" |
This causes confusion for implementors: should a compliant Jsonnet implementation follow the documented Python behavior (accept booleans) or the std.jsonnet implementation (reject booleans)?
Question
Which is the intended behavior?
- (A) The documentation is correct —
std.formatshould follow Python's rules and accept booleans for numeric codes (meaningstd.jsonnethas a bug) - (B) The implementation is correct —
std.formatshould reject booleans for numeric codes (meaning the documentation should be updated to remove the "follows Python" statement)
Context
This was discovered in sjsonnet where we initially implemented option (A) (following Python), then reverted to match std.jsonnet's behavior. See: https://github.com/databricks/sjsonnet/pull/1016
- Dominant language
- Jsonnet
- Stars
- 7.6k
- Forks
- 475
- PR merge metrics
- No merged PRs in 30d
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from google/jsonnet
-
Difficulty 1/5 1-3 hours Newbie friendliness 88/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 62/100
-
Difficulty 3/5 1-2 days Newbie friendliness 78/100
-
std.format: wrong digits for %f/%d on large values; malformed output for non-integer * precision Open
Difficulty 4/5 3-5 days Newbie friendliness 52/100
-
Difficulty 5/5 Over a week Newbie friendliness 42/100
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
objectionary/eo#8869 · 1 comment ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
EricSpencer00/Resilient#4824 · 1 comment ·
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
objectionary/jeo-maven-plugin#1758 ·
-
generics
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
-
mlir
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
llvm/llvm-project#224908 · 1 comment ·