classification
Title: getopt should strip whitespace from long arguments
Type: enhancement Stage: resolved
Components: Library (Lib) Versions: Python 3.6
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: berker.peksag, r.david.murray, serhiy.storchaka, steven.daprano
Priority: normal Keywords: patch

Created on 2016-07-26 00:50 by steven.daprano, last changed 2017-03-07 18:47 by serhiy.storchaka. This issue is now closed.

Files
File name Uploaded Description Edit
getopt.patch steven.daprano, 2016-07-26 00:50 review
getopt.patch steven.daprano, 2016-07-26 04:17 review
getopdemo.c steven.daprano, 2016-07-26 17:06
Messages (13)
msg271310 - (view) Author: Steven D'Aprano (steven.daprano) * (Python committer) Date: 2016-07-26 00:50
As reported here:

https://mail.python.org/pipermail/python-list/2016-July/711333.html

there's a possible annoyance with getopt when you accidentally leave whitespace on a long option. On my Centos system, getopt ignores leading and trailing whitespace on long options.

[steve@ando ~]$ getopt -o "" -l " spam , eggs " -- --spam --eggs arg
 --spam --eggs -- 'arg'


Python's getopt should do the same. (Patch attached.)
msg271319 - (view) Author: Berker Peksag (berker.peksag) * (Python committer) Date: 2016-07-26 03:16
I left some review comments on Rietveld. I think we can treat this as a bug and fix it in 3.5 too.
msg271320 - (view) Author: Steven D'Aprano (steven.daprano) * (Python committer) Date: 2016-07-26 04:17
Thanks for the quick review, I've fixed the issues you mentioned.
msg271321 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2016-07-26 04:50
> On my Centos system, getopt ignores leading and trailing whitespace on long options.

This is not related to how getopt_long in C works with leading and trailing whitespace on long options, but is related to how command-line utility getopt parses a list of long options.

My answer: if you don't want a space in your long_option, don't put a space in there. There is no a bug in Python, and the patch just complicates the code in attempt to fix one particular user error.
msg271322 - (view) Author: Steven D'Aprano (steven.daprano) * (Python committer) Date: 2016-07-26 04:56
On Tue, Jul 26, 2016 at 04:50:33AM +0000, Serhiy Storchaka wrote:

> My answer: if you don't want a space in your long_option, don't put a 
> space in there. There is no a bug in Python, 

That's why I listed it as an enhancement, not a bug.

> and the patch just complicates the code in attempt to fix one 
> particular user error.

Sure. But the extra complexity is tiny, and the benefit is real, and it 
makes Python getopt behave more like the shell getopt, which I think is 
appropriate.
msg271323 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2016-07-26 05:01
It makes Python getopt behave less like the C getopt.
msg271359 - (view) Author: Steven D'Aprano (steven.daprano) * (Python committer) Date: 2016-07-26 12:11
Serhiy Storchaka added the comment:
> It makes Python getopt behave less like the C getopt.

Exactly! If C getopt allows whitespace in long options, it's a GOOD 
thing to avoid such a poor design. Who would want a option --foo  (note 
the trailing space)?
msg271361 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2016-07-26 12:39
Who would want options --f o o, --f￾oo, or --fоо?
msg271378 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2016-07-26 15:27
I agree with Serhiy.  Python is a programming language, not a shell.  It seems to me that it should not be second guessing a constant specified by the programmer.  If the programmer puts spaces in the specification string, Python should respect that.  I have no idea why one would do that, but such an option *can* be specified in the command line invocation, even using the shell.  And yes, misspecifying a constant is a common source of program bugs, but I think, as Serhiy pointed out, it would be worse to have some "obvious nonsense" fixed but not others.

Now, would we want to enhance getopt to validate the longopts in a more general way and raise an error?  I'm not sure it is worth the effort, especially since getopt is explicitly emulating the C getopt, and it does not do so.
msg271395 - (view) Author: Steven D'Aprano (steven.daprano) * (Python committer) Date: 2016-07-26 17:06
On Tue, Jul 26, 2016 at 03:27:29PM +0000, R. David Murray wrote:
[...]
> getopt is explicitly emulating the C getopt

There are lots of differences between the C getopt and the Python 
version, and the Python version is described as offering an API 
"designed to be familiar" to uses of the C version, not to emulate all 
the idiosyncrasies of the C version. For instance, the Python version 
raises an exception on errors, rather than returning -1; the C version 
requires argc ("argument count"), but the Python version doesn't.

But most critically, the C version DOES strip whitespace from long 
arguments. On my Centos box, it only strips *trailing* spaces, not 
leading spaces, but it does strip them. So if your argument is that we 
must do what the C getopt does, then we must likewise at least strip 
trailing spaces.

Attached is a demo, adapted from the code given by `man 3 getopt`.

[steve@ando ~]$ gcc getopdemo.c
[steve@ando ~]$ ./a.out "--  spam" 1 --eggs 2 "--  cheese" 3
option   spam   with arg 1
option eggs   with arg 2
option   cheese with arg 3

If Serhiy is going to insist that getopt.py must follow the C getopt 
precisely, then the failure to strip trailing spaces is certainly a bug.
msg271400 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2016-07-26 17:49
C getopt doesn't strip trailing spaces. What you mistook for stripping trailing spaces is actually a feature of GNU getopt that allows you to use shortened variant of long option.

$ ./getopdemo "--  sp" 1 --eg 2 "--  ch" 3
option   spam   with arg 1
option eggs   with arg 2
option   cheese with arg 3
msg271403 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2016-07-26 18:38
I realized some time after I posted that my comment about it emulating C getopt needed a gloss.  What I meant was that C getopt is the model, so there should be a sufficient argument that adding a feature is worthwhile.  You are making that argument, but Serhiy and I disagree that it is worthwhile, or consistent with the fact that Python is a programming language and not a shell.

We may be in the minority, though, for all we know.
msg277201 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2016-09-22 06:51
I think this should just be closed.
History
Date User Action Args
2017-03-07 18:47:43serhiy.storchakasetstatus: pending -> closed
stage: patch review -> resolved
2016-09-22 06:51:32serhiy.storchakasetstatus: open -> pending

messages: + msg277201
2016-07-26 18:38:41r.david.murraysetmessages: + msg271403
2016-07-26 17:49:05serhiy.storchakasetmessages: + msg271400
2016-07-26 17:06:27steven.dapranosetfiles: + getopdemo.c

messages: + msg271395
2016-07-26 15:27:29r.david.murraysetnosy: + r.david.murray
messages: + msg271378
2016-07-26 12:39:25serhiy.storchakasetmessages: + msg271361
2016-07-26 12:11:00steven.dapranosetmessages: + msg271359
2016-07-26 05:01:20serhiy.storchakasetmessages: + msg271323
2016-07-26 04:56:37steven.dapranosetmessages: + msg271322
2016-07-26 04:50:33serhiy.storchakasetresolution: not a bug

messages: + msg271321
nosy: + serhiy.storchaka
2016-07-26 04:17:35steven.dapranosetfiles: + getopt.patch

messages: + msg271320
2016-07-26 03:16:34berker.peksagsetnosy: + berker.peksag

messages: + msg271319
stage: patch review
2016-07-26 00:50:17steven.dapranocreate