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

Handle negative count arg in string.replace #9228

Closed
wants to merge 5 commits into from

Conversation

zegl
Copy link
Contributor

@zegl zegl commented Aug 22, 2019

Also update the name of the argument to be "count" instead of "maxsplit",
to match the Starlark spec.

This fixes #9181

@iirina
Copy link
Contributor

iirina commented Aug 29, 2019

@laurentlb @c-parsons can you take a look? Thanks!

@zegl
Copy link
Contributor Author

zegl commented Sep 7, 2019

I've rebased and force-pushed to resolve conflicts in EvaluationTest.java.

@@ -278,23 +278,23 @@ public String strip(String self, Object charsOrNone) {
type = String.class,
doc = "The string to replace with."),
@Param(
name = "maxsplit",
name = "count",
Copy link
Contributor

Choose a reason for hiding this comment

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

I think renaming this would be a breaking change. May need to keep the old name for now.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, it's clearly breaking! The question is if it's a change that's allowed to be made according to the compatability policy, the Backwards Compatability document does not mention what's allowed and not in these edge cases.

To draw some inspiration from other projects: the Go1 compatability document states:

If a compiler or library has a bug that violates the specification, a program that depends on the buggy behavior may break if the bug is fixed. We reserve the right to fix such bugs.

I think that this is an example of that, as the Starlark implementation in Bazel does not satisfy the spec.

I'll leave it up to you and the team to figure this out, but I do think that it would be nice to allow to make some breaking changes without increasing the major-version number in the future.

Copy link
Contributor

Choose a reason for hiding this comment

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

This is definitely a breaking change which is not allowed by our policy -- apologies this is not clear by the policy doc, but this is definitely going to break some users and cause some pain if we change it.

We should avoid renaming this for now.
The parameter is tagged with legacyNamed = true, so, subject to the rollout of #8147, this parameter will be positional-only in the future. We can then rename the parameter safely for documentation purposes.

Copy link
Member

Choose a reason for hiding this comment

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

To clarify, there's two breaking changes: the rename and the behavior for negative values.

The rename is subsumed by #8147, so we should definitely not do any extra work here. You can add a comment reminding us to get back to it:

// TODO(#8147): rename param to "count" once it's positional-only.

The behavioral change for negatives is also breaking. I feel like it's not very likely people will be broken by it, but it seems like the kind of thing we should guard with a flag. Look for other examples of using incompatible flags in Starlark builtins -- for instance, incompatibleDisableDepsetItems in the depset constructor later in this file, and its corresponding definitions in StarlarkSemantics and StarlarkSemanticsOptions.

Copy link
Contributor Author

@zegl zegl Apr 28, 2020

Choose a reason for hiding this comment

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

Ok, let's do this the proper way, by marking the negative value behaviour change as breaking.

Other than adding the flag and the handling of it, is there anything else that needs to be done? What's the process for creating issues with the incompatible-change and breaking-change-* labels?

Copy link
Contributor

Choose a reason for hiding this comment

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

When you file the GitHub issue, you can cc me so that I add the labels.
If your change is ready this week, we can include it in Bazel 3.2.

Thanks!

Copy link
Member

Choose a reason for hiding this comment

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

@alandonovan points out to me that we actually already flipped and deleted --incompatible_restrict_named_params, so I'll do the rename as part of the follow-up.

@aiuto
Copy link
Contributor

aiuto commented Feb 12, 2020

Ping

@aiuto
Copy link
Contributor

aiuto commented Apr 23, 2020

Another ping

@aiuto aiuto self-assigned this Apr 23, 2020
@zegl
Copy link
Contributor Author

zegl commented Apr 23, 2020

@aiuto Are you pinging me?

What would be the process of getting this change in now? I'm guessing that it's still not allowed breakage, or is it?

@zegl
Copy link
Contributor Author

zegl commented Apr 23, 2020

I resolved the conflicts (Runtime.NONE has been renamed to Starlark.NONE), and fixed the issues found by c-parsons.

Also update the name of the argument to be "count" instead of "maxsplit",
to match the Starlark spec.
@laurentlb
Copy link
Contributor

Can you take a look at https://www.bazel.build/breaking-changes-guide.html?
If you put the change behind a flag, we'll be able to import it and ensure a smooth rollout.

Thanks!

@aiuto
Copy link
Contributor

aiuto commented Apr 25, 2020

I was pinging all the stale PRs so we can finish them or close them.

@@ -278,23 +278,23 @@ public String strip(String self, Object charsOrNone) {
type = String.class,
doc = "The string to replace with."),
@Param(
name = "maxsplit",
name = "count",
Copy link
Member

Choose a reason for hiding this comment

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

To clarify, there's two breaking changes: the rename and the behavior for negative values.

The rename is subsumed by #8147, so we should definitely not do any extra work here. You can add a comment reminding us to get back to it:

// TODO(#8147): rename param to "count" once it's positional-only.

The behavioral change for negatives is also breaking. I feel like it's not very likely people will be broken by it, but it seems like the kind of thing we should guard with a flag. Look for other examples of using incompatible flags in Starlark builtins -- for instance, incompatibleDisableDepsetItems in the depset constructor later in this file, and its corresponding definitions in StarlarkSemantics and StarlarkSemanticsOptions.

…behaviour if true

The previous (pre PR) change has been re-added, and is used by default.
This allows to test with different values of the incompatible flag

StarlarkSemantics semantics = thread.getSemantics();
if (semantics.incompatibleStringReplaceCount()) {
if (count != Starlark.NONE && (Integer) count >= 0) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Also: 'None' is not a legal argument for count, according to the Starlark spec (which matches Pythons 2 and 3 and go.starlark.net implementation).

Copy link
Member

Choose a reason for hiding this comment

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

Hm, I'll write a quick followup to change the default value to the internal UNBOUND sentinel and have the incompatible flag also reject the value None.

Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks. I suggest to:

  • Change the default value to unbound
  • Raise an error if the argument is None and the incompatible flag is enabled
  • After the flag flip, remove noneable=True

@brandjon
Copy link
Member

brandjon commented May 1, 2020

FYI in the internal merge we retained some of the test cases in string_misc.sky and added a TODO to port StringModuleTest back over to those once the incompatible flag is no longer a blocker. We do prefer that tests of pure Starlark features be written in Starlark where possible (we've got enough verbose Java tests :) ).

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

Successfully merging this pull request may close these issues.

string.replace incorrectly handles negative value for count
9 participants