Commit 6aec4784 authored by Kirill Smelkov's avatar Kirill Smelkov

gpython: Fix how --long-option=value=something is processed

Carlos reports that when pymain is invoked as

    > python --login='uid=username,ou=people,dc=something,dc=de' my_script.py

it crashes as

    Traceback (most recent call last):
      File "/srv/slapgrid/slappart5/software_release/bin/python", line 312, in <module>
        pymain(sys.argv)
      File "/opt/slapgrid/133edb8b6bfc135bce30900e2b50555e/parts/pygolang/gpython/__init__.py", line 113, in pymain
        for (opt, arg) in igetopt:
      File "/opt/slapgrid/133edb8b6bfc135bce30900e2b50555e/parts/pygolang/gpython/__init__.py", line 552, in __next__
        opt, arg = opt.split('=')

While @jerome correctly notices that the problem here is due to --login
is passed to python instead of my_script.py it still highlights a
problem on gpython side in its _IGetOpt parser for which I made a thinko
in 26058b5b (gpython: Factor-out options parsing into getopt-style
_IGetOpt helper) without considering that a value for
--long-option=value could itself contain another '=' symbols.

-> Fix this thinko.

Without the fix gpython --unknown=x=y crashes as

    Traceback (most recent call last):
      File "/home/kirr/src/wendelin/venv/py39.venv/bin/gpython", line 8, in <module>
        sys.exit(main())
      File "/home/kirr/src/tools/go/pygolang-master/gpython/__init__.py", line 402, in main
        for (opt, arg) in igetopt:
      File "/home/kirr/src/tools/go/pygolang-master/gpython/__init__.py", line 562, in __next__
        opt, arg = opt.split('=')
    ValueError: too many values to unpack (expected 2)

but after the fix it reports more user-friendly

    RuntimeError: unexpected option --unknown

/reported-and-reviewed-by @vnmabus
/reported-on https://lab.nexedi.com/nexedi/pygolang/-/issues/1
/reviewed-on !32
parent 50b3808c
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2018-2024 Nexedi SA and Contributors. # Copyright (C) 2018-2025 Nexedi SA and Contributors.
# Kirill Smelkov <kirr@nexedi.com> # Kirill Smelkov <kirr@nexedi.com>
# #
# This program is free software: you can Use, Study, Modify and Redistribute # This program is free software: you can Use, Study, Modify and Redistribute
...@@ -559,7 +559,7 @@ class _IGetOpt: ...@@ -559,7 +559,7 @@ class _IGetOpt:
# long option # long option
arg = None arg = None
if '=' in opt: if '=' in opt:
opt, arg = opt.split('=') opt, arg = opt.split('=', 1)
if opt not in self._opts: if opt not in self._opts:
raise RuntimeError('unexpected option %s' % opt) raise RuntimeError('unexpected option %s' % opt)
arg_required = self._opts[opt] arg_required = self._opts[opt]
......
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2019-2024 Nexedi SA and Contributors. # Copyright (C) 2019-2025 Nexedi SA and Contributors.
# Kirill Smelkov <kirr@nexedi.com> # Kirill Smelkov <kirr@nexedi.com>
# #
# This program is free software: you can Use, Study, Modify and Redistribute # This program is free software: you can Use, Study, Modify and Redistribute
...@@ -404,6 +404,23 @@ def test_pymain_ver(runtime): ...@@ -404,6 +404,23 @@ def test_pymain_ver(runtime):
ret, out, err = _pyrun(['--version'], stdout=PIPE, stderr=PIPE, env=gpyenv(runtime)) ret, out, err = _pyrun(['--version'], stdout=PIPE, stderr=PIPE, env=gpyenv(runtime))
assert (ret, out, b(err)) == (0, b'', b(vok)) assert (ret, out, b(err)) == (0, b'', b(vok))
# pymain --unknown/-Z option
# gpython_only because output differs from !gpython
@gpython_only
def test_pymain_unknown():
from golang import b
def check(argv, errok):
ret, out, err = _pyrun(argv, stdout=PIPE, stderr=PIPE)
assert b(errok) in b(err)
assert ret != 0
check(['-Z'], "unexpected option -Z")
check(['-Z=xyz'], "unexpected option -Z")
check(['-Z=xyz=pqr'], "unexpected option -Z")
check(['--unknown'], "unexpected option --unknown")
check(['--unknown=xyz'], "unexpected option --unknown")
check(['--unknown=xyz=pqr'], "unexpected option --unknown")
# verify that ./bin/gpython runs ok. # verify that ./bin/gpython runs ok.
@gpython_only @gpython_only
def test_pymain_run_via_relpath(): def test_pymain_run_via_relpath():
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment