classification
Title: 2.7 distutils getopt chokes on unicode option names
Type: Stage: resolved
Components: Distutils Versions: Python 2.7
process
Status: closed Resolution: out of date
Dependencies: Superseder:
Assigned To: eric.araujo Nosy List: Arfrever, eric.araujo, jaraco, tarek, zach.ware
Priority: low Keywords:

Created on 2013-09-05 20:03 by jaraco, last changed 2020-04-26 17:07 by zach.ware. This issue is now closed.

Messages (3)
msg197020 - (view) Author: Jason R. Coombs (jaraco) * (Python committer) Date: 2013-09-05 20:03
Today I encountered a bug where I was using a Distutils.Command subclass, which uses getopt for option parsing. The implementation is here: https://bitbucket.org/jaraco/jaraco.packaging/src/2.2/jaraco/packaging/depends.py?at=default

Around line 59, the options are defined, but because the syntax is Python 3 style with unicode literals, under Python 2.7, those get created as unicode objects.

When I invoke that Command under Python 2.7, I get this error:

Traceback (most recent call last):
  File "setup.py", line 160, in <module>
    setup(**setup_params)
  File "/usr/lib/python2.7/distutils/core.py", line 138, in setup
    ok = dist.parse_command_line()
  File "build/bdist.linux-x86_64/egg/setuptools/dist.py", line 250, in parse_command_line
  File "/usr/lib/python2.7/distutils/dist.py", line 467, in parse_command_line
    args = self._parse_command_opts(parser, args)
  File "build/bdist.linux-x86_64/egg/setuptools/dist.py", line 533, in _parse_command_opts
  File "/usr/lib/python2.7/distutils/dist.py", line 564, in _parse_command_opts
    (args, opts) = parser.getopt(args[1:])
  File "/usr/lib/python2.7/distutils/fancy_getopt.py", line 253, in getopt
    self._grok_option_table()
  File "/usr/lib/python2.7/distutils/fancy_getopt.py", line 171, in _grok_option_table
    "must be a string of length >= 2") % long
distutils.errors.DistutilsGetoptError: invalid long option 'requirement=': must be a string of length >= 2

That error is raised because 'requirement=' is a Unicode, but the test in fancy_getopt is isinstance(opt, str).

I can work around the issue by wrapping all of the options in str() calls, which leaves them unchanged on Python 3 and downcasts them to strings on Python 2, but that's not pretty.

I suggest that fancy_getopt should either include 'unicode' in the isinstance test or (if unicode values really aren't supported), encode unicode values first.
msg197299 - (view) Author: Jason R. Coombs (jaraco) * (Python committer) Date: 2013-09-08 17:54
oh. My mistake. I didn't realize the error was in 'distutils.fancy_getopt' and not in the getopt module itself. Indeed, the problem doesn't exist under getopt itself, so is specific to distutils and fancy_getopt.

>>> from __future__ import unicode_literals
>>> import getopt
>>> getopt.getopt('-x', 'x', ('--longx',))
([], u'-x')
>>>
msg367320 - (view) Author: Zachary Ware (zach.ware) * (Python committer) Date: 2020-04-26 17:07
As 2.7 is now EOL, I'm closing the issue.
History
Date User Action Args
2020-04-26 17:07:44zach.waresetstatus: open -> closed

nosy: + zach.ware
messages: + msg367320

resolution: out of date
stage: resolved
2013-09-10 21:21:34Arfreversetnosy: + Arfrever
2013-09-08 17:54:07jaracosetmessages: + msg197299
2013-09-07 06:13:20terry.reedysetnosy: + tarek, eric.araujo

assignee: eric.araujo
components: + Distutils, - Library (Lib)
title: getopt chokes on unicode option names -> 2.7 distutils getopt chokes on unicode option names
2013-09-05 20:03:08jaracocreate