-
-
Notifications
You must be signed in to change notification settings - Fork 636
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
Switch to using the native options parser values #21385
Conversation
But still compare against the legacy parser.
legacy_values = self.get_parser(scope).parse_args( | ||
parse_args_request, log_warnings=log_parser_warnings | ||
) | ||
native_values = self.get_parser(scope).parse_args_native(self._native_parser) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now we always create the native values but only create the legacy values if we need to do the discrepancy check, which is the converse of what we did before.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sweet!
@@ -499,8 +499,7 @@ def log(log_func): | |||
raise Exception( | |||
"Option value mismatches detected, see logs above for details. Aborting." | |||
) | |||
# TODO: In a future release, switch to the native_values as authoritative. | |||
return legacy_values | |||
return native_values |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if we want to allow a user to fallback to the legacy values if things are wildly wrong. E.g. [GLOBAL].use_deprecated_legacy_options_values = true
or something. Thoughts?
(Happy to get this PR merged ASAP, as is, and we can cherry-pick any tweaks along these back to 2.23.x if we decide on them)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we do - 2.22.x is where you're supposed to discover if things are wildly wrong.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
minor exception message nitpick issue. Otherwise LGTM.
src/python/pants/option/options.py
Outdated
parse_args_request = self._make_parse_args_request(flags_in_scope, values_builder) | ||
legacy_values = self.get_parser(scope).parse_args( | ||
parse_args_request, log_warnings=log_parser_warnings | ||
) | ||
except Exception as e: | ||
native_mismatch_msgs.append( | ||
f"Failed to parse options with native parser due to error:\n {e}" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
f"Failed to parse options with native parser due to error:\n {e}" | |
f"Failed to parse options with legacy parser due to error:\n {e}" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not a nitpick, that was actually wrong. Fixed, but also looking into the test failures, which are due to things either not failing when they should (presumably because the checks happen later or not at all on the native parser) or just failing with a slightly different error message.
- Fix missing validations on the native side. - Change the python error type raised by the native parser. - Various error types and error message differences.
This is going to take another day or so, as I figure out one thing that the tests uncovered, namely that we still rely on the legacy parser to detect unconsumed cmd-line flags. Will have a little think on how best to address this, probably in another PR. |
No worries. Is there a chance we could keep the 2.23 releases moving forward by either:
(My thinking here is that we're a bit stuck in a spiral of long releases because delays lead to bigger releases lead to more things that can go wrong lead to delays 😄 ) |
I think delaying the switch to 2.24 makes the most sense. Cherry-picking back to 2.23 is fine if the issues can be resolved quickly. |
I don't want to delay, but we can cherry-pick. |
Okay, I'll merge #21383 to start that rolling |
OK, tracking arg consumption is implemented here: #21410 |
So we can error if unrecognized args are found.
@@ -443,28 +448,6 @@ def register(opts: Options) -> None: | |||
assert vals2.qux == "uu" | |||
|
|||
|
|||
def test_scope_deprecation_default_config_section(caplog) -> None: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was testing emergent behavior, not API-defined behavior. Implementing this behavior in the native parser would be tricky and IMO not worth it:
A) It's not at all clear that this is the correct behavior. Generally we treat a config entry in DEFAULT as-if it was in the relevant section, so special-casing this seems unnecessary.
B) This behavior is only triggered when we deprecate an entire scope, which we haven't done in a while, and currently have no such deprecations pending, so no user will see any effect.
@@ -12,6 +11,8 @@ use options::{ | |||
|
|||
use std::collections::HashMap; | |||
|
|||
pyo3::import_exception!(pants.option.errors, ParseError); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We now raise our own ParseError instead of the generic ValueError. However it seemed like overkill to raise a bunch of ParseError subtypes (they were probably overkill to begin with even in the legacy parser).
This is ready for another look, thanks! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks reasonable.
I feel obliged to flag my discomfort with landing such a large chunk of new code so late in the release cycle, vs. just letting the switchover slip to 2.24 (and thus potentially being more likely to be able to stick to a regular/short release cycle due to fewer last-minute issues).
This is just discomfort, not a blocking concern, so lets get this in and hope for the best.
# We set allow_unknown_options=True to ensure that it's the native | ||
# parser that checks for unconsumed args, and not the legacy parser. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why does setting this arg have this effect? It seems a bit indirect?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, if we don't set it then it will fail earlier, in for_scope()
, and never get to the explicit verification call.
@@ -27,12 +27,9 @@ def test_invalid_options() -> None: | |||
"ERROR] Invalid option 'bad_option' under [pytest]", | |||
] | |||
|
|||
# We error on invalid CLI options before validating the config file. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We now validate the config file and options together?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a version where the order was different but it's actually not now, so I have restored this test to how it was.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM as long as tests pass
@@ -41,7 +41,9 @@ def handle_unknown_flags(self, err: UnknownFlagsError): | |||
possibilities.update(oshi.collect_scoped_flags()) | |||
|
|||
for flag in err.flags: | |||
print(f"Unknown flag {self.maybe_red(flag)} on {err.arg_scope or 'global'} scope") | |||
print( | |||
f"Unknown flag {self.maybe_red(flag)} in {(err.arg_scope + ' goal') if err.arg_scope else 'global'} context" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is more precise phrasing. We don't actually know the scope of the flag, we just know its CLI context (global position or goal position).
@huonw thanks for expressing your discomfort, which I acknowledge. I can wait to 2.24.x if you are more comfortable with that (and it sounds like @cognifloyd prefers that too). For now I will merge (once tests pass) without the auto-cherrypick, so we have a chance to discuss further. |
But still compare against the legacy parser so we can warn about
discrepancies.