[Python-bugs-list] [Bug #126863] getopt long option handling broken

noreply@sourceforge.net noreply@sourceforge.net
Mon, 08 Jan 2001 08:08:08 -0800


Bug #126863, was updated on 2000-Dec-26 15:00
Here is a current snapshot of the bug.

Project: Python
Category: Documentation
Status: Closed
Resolution: Fixed
Bug Group: None
Priority: 5
Submitted by: nobody
Assigned to : fdrake
Summary: getopt long option handling broken

Details: This problem is still present in the CVS version.


[Forwarded from the Debian bug tracking system, Bug#80243]
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=80243&repeatmerged=yes

Sender: Matt Kraai <kraai@debian.org>
Package: python-base
Version: 1.5.2-10

If a long option which takes an argument is a prefix of a longer
option, and if the first new character of the longer option is
less than '=' in ascii, getopt returns an incorrect message that
the prefix is not unique.  For example,

Script started on Thu Dec 21 14:19:44 2000
kraai@opensource:~$ python
Python 1.5.2 (#0, Apr  3 2000, 14:46:48)  [GCC 2.95.2 20000313 (Debian
GNU/Linux)] on linux2
Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam
>>> import getopt
>>> getopt.getopt(["--foo", "bar"], "", ["foo=", "foobar"])
([('--foo', 'bar')], [])
>>> getopt.getopt(["--foo", "bar"], "", ["foo=", "foo-bar"])
Traceback (innermost last):
  File "<stdin>", line 1, in ?
  File "/usr/lib/python1.5/getopt.py", line 58, in getopt
    opts, args = do_longs(opts, args[0][2:], longopts, args[1:])
  File "/usr/lib/python1.5/getopt.py", line 71, in do_longs
    has_arg, opt = long_has_args(opt, longopts)
  File "/usr/lib/python1.5/getopt.py", line 93, in long_has_args
    raise error, 'option --%s not a unique prefix' % opt
getopt.error: option --foo not a unique prefix
>>> 
kraai@opensource:~$ 
Script done on Thu Dec 21 14:20:02 2000

The problem is that the trailing '=' causes the foo-bar option to
precede the foo one, whereas the code assumes that the shortest
option is first.  The appended patch fixes this by sorting based
on the option itself, not including the extra '='.  I assume there
is a better way to do this.

--- getopt.py.orig      Mon Apr  3 06:49:15 2000
+++ getopt.py   Thu Dec 21 13:31:21 2000
@@ -49,7 +49,7 @@
         longopts = [longopts]
     else:
         longopts = list(longopts)
-    longopts.sort()
+    longopts.sort(longopt_compare)
     while args and args[0][:1] == '-' and args[0] != '-':
         if args[0] == '--':
             args = args[1:]
@@ -115,6 +115,18 @@
         if opt == shortopts[i] != ':':
             return shortopts[i+1:i+2] == ':'
     raise error, 'option -%s not recognized' % opt
+
+def longopt_compare(opt1, opt2):
+    if opt1[-1] == '=':
+       opt1 = opt1[:-1]
+    if opt2[-1] == '=':
+       opt2 = opt2[:-1]
+    if opt1 < opt2:
+       return -1
+    elif opt1 == opt2:
+       return 0
+    else:
+       return 1
 
 if __name__ == '__main__':
     import sys
Matt

Follow-Ups:

Date: 2001-Jan-08 08:07
By: fdrake

Comment:
Documentation updated in Doc/lib/libgetopt.tex revision 1.16.
-------------------------------------------------------

Date: 2000-Dec-27 03:47
By: flight

Comment:
Ooops, forgot to login before sending this bug. In case of questions,
please ask me <flight@debian.org>
-------------------------------------------------------

Date: 2000-Dec-27 00:08
By: tim_one

Comment:
Assigned to Fred and changed category to Doc:  Fred, the getopt docs don't
say anything now about accepting a unique prefix for long option names.

The logic error here is fixed in CVS now, getopt.py rev 1.12 and
test_getopt.py rev 1.3.  Function long_has_args was excruciating, so
rewrote it.
-------------------------------------------------------

For detailed info, follow this link:
http://sourceforge.net/bugs/?func=detailbug&bug_id=126863&group_id=5470