Allow continuation of verbosity level - #663
Conversation
IanLee1521
left a comment
There was a problem hiding this comment.
This looks fine to me overall.
One question is hat I'm a little unsure what your comment in line 2284 means... could you clarify?
| (options, args) = parser.parse_args(arglist) | ||
| options.reporter = None | ||
|
|
||
| if verbose: # If specified verbose, continue on verbosity |
There was a problem hiding this comment.
I don't think this is necessary, nor do I think the addition to the signature on 2260 is necessary I'll explain in a different comment. This, however, does not help someone who is trying to pass verbose=False directly meaning that this feature is a bit half-baked.
There was a problem hiding this comment.
Would you suggest alternatively having the keyword argument default to verbose=None, and just check like this?
if verbose is not None:
options.verbose = verbose| # build options from dict | ||
| options_dict = dict(*args, **kwargs) | ||
| arglist = None if parse_argv else options_dict.get('paths', None) | ||
| verbose = options_dict.get('verbose', False) |
There was a problem hiding this comment.
So we allow verbose to be in the options dictionary, yes? If it is, it was passed here explicitly. Otherwise, (in the case where someone isn't directly using the StyleGuide but is instead using the CLI) we'll parse it from the arguments. Below here, we do options.__dict__.update(options_dict) which means that after we've processed options, we update the values unconditionally so long as options_dict isn't an empty dictionary. That's all you should need.
There was a problem hiding this comment.
I'm a bit confused, what is the change you are suggesting I make?
There was a problem hiding this comment.
So, in your use case, you are going to do:
StyleGuide(verbose=True)
Which means that options_dict will look at least like {'verbose': True}. After we call process_options on L1999,L2000 we say if options_dict: options.__dict__.update(options_dict) which means that regardless of what's passed on the CLI we will set verbose to True. That means that you don't need to modify process_options.
I suspect the problem you're actually encountering and trying to solve by this PR is that everything in pycodestyle expects verbose to be an integer. See, as one example, this line:
Line 555 in 19e85d9
If you're not seeing the output you expect when using the Python API, it's because True is being treated as 1 by Python and you're only getting basic verbosity levels.
~ ❯❯❯ python -c 'print(True + 1)'
2
~ ❯❯❯ python3 -c 'print(True + 1)'
2
~ ❯❯❯ python -c 'print(True >= 1)'
True
~ ❯❯❯ python -c 'print(True >= 2)'
False
There was a problem hiding this comment.
I did not know that the verbose is meant to be a number, so I've changed that accordingly.
I do need to modify process_options somehow due to the fact that process_options calls read_config
Line 2343 in 19e85d9
And
read_config checks for options.verboseLines 2251 to 2252 in 19e85d9
Which does not get set until L1999 & L2000, after
read_config is called, unless you instantiate StyleGuide(paths=['-v']), which does set options.verbose to 1.
I do not think it makes sense to have to pass a CLI argument to the styleguide object to achieve full verbosity, as that is what the verbose argument is for.
There was a problem hiding this comment.
Sorry, I think you had mentioned this before. Thank you for reminding me.
So then the changes necessary here are the following:
verbose = options_dict.pop('verbose', 0)Then below pass it to process_options as you are. You can make the change there of having verbose=None in the argument list and only if verbose is not None will you set it on the options object.
I think a better path forward, however, is to refactor pycodestyle and remove config reading from CLI argument processing but that's not for this PR.
|
Hi @mjsir911 Do you have any intentions to fix this up? |
|
Sorry I haven't touched this PR, will start addressing concerns. |
sigmavirus24
left a comment
There was a problem hiding this comment.
Let me know if you have any questions. I think you're 90% of the way to a correct solution here.
| # build options from dict | ||
| options_dict = dict(*args, **kwargs) | ||
| arglist = None if parse_argv else options_dict.get('paths', None) | ||
| verbose = options_dict.get('verbose', False) |
There was a problem hiding this comment.
Sorry, I think you had mentioned this before. Thank you for reminding me.
So then the changes necessary here are the following:
verbose = options_dict.pop('verbose', 0)Then below pass it to process_options as you are. You can make the change there of having verbose=None in the argument list and only if verbose is not None will you set it on the options object.
I think a better path forward, however, is to refactor pycodestyle and remove config reading from CLI argument processing but that's not for this PR.
| options_dict = dict(*args, **kwargs) | ||
| arglist = None if parse_argv else options_dict.get('paths', None) | ||
| verbose = options_dict.get('verbose', False) | ||
| verbose = options_dict.get('verbose', 0) |
There was a problem hiding this comment.
Actually, I just realized, having the default of 0 here means we always override options.verbose to 0 even when it's not used via the API. So we can just do options_dict.pop('verbose', None). And yes, we want pop.
There was a problem hiding this comment.
pop will not work because at the end of read_config, options is overwritten with command line arguments, which means if -v was not passed somehow it would default to 0.
Lines 2303 to 2304 in 6faef2b
This problem has not been apparent because as you pointed out earlier, options_dict gets copied to options.__dict__, but if I pop the verbose key, will not get copied.
Alternatively, (options, __) = parser.parse_args(arglist, values=options) seems to work, but I'm not sure why the previous values=new_options was done the way it was.
| options_dict = dict(*args, **kwargs) | ||
| arglist = None if parse_argv else options_dict.get('paths', None) | ||
| verbose = options_dict.get('verbose', 0) | ||
| verbose = options_dict.get('verbose', None) |
There was a problem hiding this comment.
pop will not work because at the end of read_config, options is overwritten with command line arguments, which means if -v was not passed somehow it would default to 0.
Lines 2303 to 2304 in 6faef2b
This problem has not been apparent because as you pointed out earlier, options_dict gets copied to options.__dict__, but if I pop the verbose key, will not get copied.
Alternatively, (options, __) = parser.parse_args(arglist, values=options) seems to work, but I'm not sure why the previous values=new_options was done the way it was.
There was a problem hiding this comment.
Thanks for pointing that out. I missed that.
So if you look at the loop that builds up new_options it's pulling in values from config files. But in the chain of preferences, we always want CLI arguments to override those. This is why we one last time do parser.parse_args(arglist, values=new_options). We want to default to what's in the config file, and override those values with what's provided on the CLI.
I've been having to do
pycodestyle.StyleGuide(verbose=True, paths=['-v'])to achieve verbosity to the point where I can see the configuration files included such as:This simply allows
pycodestyle.StyleGuide(verbose=True)to display these verbosity messages.