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

noreply@sourceforge.net noreply@sourceforge.net
Tue, 26 Dec 2000 15:00:26 -0800


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

Project: Python
Category: Python Library
Status: Open
Resolution: None
Bug Group: None
Priority: 5
Submitted by: nobody
Assigned to : nobody
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

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