Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Why is %s formatting of list/map only mostly a CEL expression of that list/map? #438

Open
warhammerkid opened this issue Feb 1, 2025 · 1 comment

Comments

@warhammerkid
Copy link

warhammerkid commented Feb 1, 2025

Specifically I'm concerned here with the encoding of NaN/Infinity (but also types, which don't have any examples in the conformance suite).

The implication here seems to be that "%s".format([a_list_or_map_here]) should be a valid CEL expression for the list or map literal. String keys/values must be properly quoted, byte strings need a b prefix, doubles must be clearly identifiable as doubles with a forced decimal separator, durations and timestamps need to use duration("str") or timestamp("str") syntax, and types should also use the type(str) syntax (there's no conformance tests though for this, and cel-go attempts to do this but fails due to a bug in the code).

However, NaN and infinity doubles get converted to strings rather than double("str") literals.

  test: {
    name: "map support (all key types)"
    expr: '"map with multiple key types: %s".format([{1: "value1", uint(2): "value2", true: double("NaN")}])'
    value: {
      string_value: 'map with multiple key types: {1:"value1", 2:"value2", true:"NaN"}',
    }
  }

The odds that an implementation would have some kind of "debug string" method that can take any CEL value and convert it to a valid CEL expression for that value seems pretty high, but then there are special cases like this where that would be incorrect in implementing %s formatting for lists/maps. I'm wondering if it's intentional that this is just a string rather than double("NaN") or double("Inf")?

(The other thing lost here is that uints are defined as not having a u suffix when they show up in a list/map, which is also described in the conformance test above. I would have expected uint(2) to show up in the output as 2u.)

@TristonianJones
Copy link
Collaborator

@warhammerkid good question ... we're actually updating the string.format() spec to support formatted statements which don't consider locales since this proved to be too difficult to do well across all language stacks.

The use of Infinity instead of Inf is likely a mistake and we'll preserve backward compatibility, and possibly special handling to support the conversion of double('NaN') (and others) since we do this under the cover during proto->json serialization. The missing u suffix would also be a good conformance test.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants