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.format should follow Python's rules and accept booleans for numeric codes (meaning std.jsonnet has a bug)
- (B) The implementation is correct —
std.format should 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: databricks/sjsonnet#1016
Summary
There is a conflict between the official documentation and the reference implementation (
std.jsonnet) regarding howstd.formathandles boolean values with numeric format codes.Documentation says
From https://jsonnet.org/ref/stdlib.html#std-format:
In Python,
boolis a subclass ofint, so all numeric format codes accept booleans:Reference implementation says
In
std.jsonnet, theformat_codehelper explicitly checks:Since
std.type(true)returns'boolean'(not'number'), all numeric format codes reject booleans:Only
%sworks:std.format("%s", true) → "true"The conflict
"%d" % true"1""%f" % true"1.000000""%x" % true"1""%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?
std.formatshould follow Python's rules and accept booleans for numeric codes (meaningstd.jsonnethas a bug)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: databricks/sjsonnet#1016