Skip to content

Fix overload declaration for format#295

Merged
smaye81 merged 3 commits intomainfrom
sayers/fix_format_decls
May 31, 2025
Merged

Fix overload declaration for format#295
smaye81 merged 3 commits intomainfrom
sayers/fix_format_decls

Conversation

@smaye81
Copy link
Contributor

@smaye81 smaye81 commented May 30, 2025

After some investigation, it seems the reason some of the cel conformance tests weren't running was because the overload declaration for format inside protovalidate-java was too narrow and was only allowing primitive types inside lists.

This simplifies the declaration so that any DynType is accepted, which allows maps as well as custom Protobuf types to be passed inside a list to format.

test: {
name: "bytes support for string with invalid utf-8 encoding"
expr: '"%s".format([b"\xF0abc\x8C\xF0xyz"])'
expr: '"%s".format([b"\\xF0abc\\x8C\\xF0xyz"])'
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Drive-by change. I realized in Python that loading this file with actual invalid utf-8 bytes will prevent it from being loaded. So, just escaping the \x so that it loads as a normal string. Updated the PR to the cel-spec also.

"object not allowed",
// found no matching overload for 'format' applied to 'string.(list(map(int, dyn)))'
"object inside map");
private static List<String> SKIPPED_TESTS = Arrays.asList();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't love that this is here an unused. We could remove it, but I like having it here in case we need it. If there's a better way, I'm all ears.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Could use Collections.emptyList(), but might be good just to remove?

@smaye81 smaye81 requested review from a user and pkwarren May 30, 2025 19:30
StringBuilder builder = new StringBuilder();
builder.append('{');

List<String> entries = new ArrayList<String>();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
List<String> entries = new ArrayList<String>();
List<String> entries = new ArrayList<>();

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 fixed instances in FormatTest also.

// The formatted string should be sorted by keys
Collections.sort(entries);

builder.append(String.join(", ", entries)).append('}');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Using a builder isn't really that efficient this way since we're still building all the individual strings and joining them. I don't think this is going to be very performance sensitive code but might be good to optimize it at some point.

builder.append('}');

// The formatted string should be sorted by keys
Collections.sort(entries);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorting the keys after we've concatenated the : <val> won't always give what you expect:

  public static void main(String[] args) {
    List<String> keys = Arrays.asList("a9", "a");
    Collections.sort(keys);
    System.out.println(keys);
    
    List<String> vals = Arrays.<String>asList("a9: val", "a: val");
    Collections.sort(vals);
    System.out.println(vals);
  }

This prints different values for sorting by keys vs. sorting by key values:

[a, a9]
[a9: val, a: val]

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great catch, thank you.

"object not allowed",
// found no matching overload for 'format' applied to 'string.(list(map(int, dyn)))'
"object inside map");
private static List<String> SKIPPED_TESTS = Arrays.asList();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Could use Collections.emptyList(), but might be good just to remove?

@smaye81 smaye81 requested a review from pkwarren May 30, 2025 20:22
@smaye81 smaye81 merged commit b5d806e into main May 31, 2025
4 checks passed
@smaye81 smaye81 deleted the sayers/fix_format_decls branch May 31, 2025 14:34
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

Successfully merging this pull request may close these issues.

2 participants