-
Notifications
You must be signed in to change notification settings - Fork 10.5k
Move legacy argparser #11872
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
Move legacy argparser #11872
Conversation
You mentioned a preset that is broken. Can you elaborate? |
@gottesmm Do you have any opinion about splitting out a build_swift package like this? |
My new test suite uncovered an unsupported flag in the |
As for splitting out to a new I'm open to other suggestions or names for the module, I landed on |
I don't have a problem with the refactoring. I would prefer the name swift_build though. We already have precedent in that area with llvm_build and swift_build_support. But let me look at this in more depth. |
] | ||
|
||
|
||
class ApplyDefaultsArgumentParser(argparse.ArgumentParser): |
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.
Just to loop back from our conversation, can you do this in a separate commit. I want to be able to eyeball the move of code and then see the refactoring done upon the nicely refactored code. It will make it easier for me to review.
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.
Sure thing! I'll chunk out the two large code-moves into separate PRs.
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.
Thanks! = )
01a8e72
to
a5d453f
Compare
2544c33
to
0c8ac1f
Compare
@swift-ci please smoke test |
f82d4fc
to
bc4f87b
Compare
…er (ab)using metaclasses to dynamically generate unit-tests for each valid argument and preset.
bc4f87b
to
1749f98
Compare
@swift-ci please smoke test |
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 fine to me.
"""Option that is not supported.""" | ||
|
||
def __init__(self, *args, **kwargs): | ||
kwargs['dest'] = kwargs.get('dest') |
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.
What are you trying to do here?
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.
That line facilitates allowing instances of UnsupportedOption
to skip passing in the dest
argument since it doesn't seem necessary for that sort of option. I would be better written as kwards['dest'] = kwargs.pop('dest', None)
which pops dest
off the input keyword args or resolves to None and sets the value manually when passed into the superclass constructor.
I had originally tried to add dest
as positional argument in the UnsupportedOption
init function, but I was running into issues with dest
being passed twice to the superclass constructor. This was the best way I found after some searching to achieve the desired effect.
|
||
EXPECTED_OPTIONS = [ | ||
# Ignore the help options since they always call sys.exit(0) | ||
_BaseOption('-h', dest='help', default=argparse.SUPPRESS), |
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 not make a special thing for help rather than using _BaseOption.
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.
That would probably clean this up a bit. I'll make that change.
|
||
# NOTE: We'll need to manually test the behavior of these since they | ||
# validate compiler version strings. | ||
_BaseOption('--clang-compiler-version', |
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.
Same here. Can you make a wrapper rather than using an _ class? Looks weird to me.
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.
Will do!
@swift-ci please smoke test |
…ould give better output in case the default tests fail.
@swift-ci please smoke test |
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.
Some post commit review.
@@ -252,16 +260,25 @@ class UnsupportedOption(_BaseOption): | |||
"""Option that is not supported.""" | |||
|
|||
def __init__(self, *args, **kwargs): | |||
kwargs['dest'] = kwargs.get('dest') | |||
kwargs['dest'] = kwargs.pop('dest', 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 is still really weird to me. What are you trying to do here?
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'm injecting my own definition for dest
such that the UnsupportedOption
class does not need to be instantiated with it manually passed. Here I'm passing through any manually set dest
or setting it by default to None. In all cases it's defined in the kwargs
and satisfies the _BaseOption
constructor.
@@ -220,6 +227,8 @@ def generate_option_test(cls, option): | |||
return cls._generate_append_option_test(option) | |||
elif option.__class__ is expected_options.ChoicesOption: | |||
return cls._generate_choices_option_test(option) | |||
elif option.__class__ is expected_options.HelpOption: | |||
return cls._generate_help_option_test(option) |
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 can be done cleaner via a dictionary.
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.
When you say 'via a dictionary' do you mean I should have a dictionary from class to function? I'm not sure I'm following along.
@@ -143,6 +143,13 @@ def test(self): | |||
return test | |||
|
|||
@classmethod | |||
def _generate_help_option_test(cls, option): | |||
def test(self): |
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 doesn't do anything, no? You aren't invoking test. What is the purpose of this?
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.
The meta-class here is used to generate unit-test cases dynamically. When Python is invoked with the unittest
argument it will execute all methods on classes subclassing unittest.TestCase
that begin with the word test
. It's not required in any Python unittest code to invoke the test cases yourself.
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.
On a second look you're right, I forgot to return the actual test here. I'll fix this in the next PR
Purpose
This PR is part of the staging necessary for #11827 and builds on the staging from #11880 and #11882. Put simply this PR bundles up the current argument parser and the
_apply_default_arguments
function into anApplyDefaultsArgumentParser
class that will call_apply_default_arguments
anytime theparse_args
method is called. The new parser bundles up these two interconnected behaviors making it easier to test the expected outputs.In addition I've also taken the time to implement a new suite of unit-tests to ensure the expected behavior for the argument parser. These tests should make it easier to transition to the new system in #11827, giving reviewers more confidence that it actually works.
The unit-test suite (ab)uses Python meta classes to dynamically generate tests for each preset and argument, ensuring that they all have coverage. There's still a handful of tests types left to implement for the arguments and these tests have uncovered a preset that is broken (which will either be removed or fixed).
rdar://problem/34336890