radiasoft / pykern

Apache License 2.0
5 stars 7 forks source link

py3.11 fixes #502

Open robnagler opened 2 weeks ago

robnagler commented 2 weeks ago

After fixing a deprecated call, getting an error in pkcli_test:test_main1:

  File "/home/vagrant/src/radiasoft/pykern/tests/pkcli_test.py", line 68, in test_main1
    _conf(rp, ["conf1", "cmd2"], first_time=False)
  File "/home/vagrant/src/radiasoft/pykern/tests/pkcli_test.py", line 128, in _conf
    pkeq(0, _main(root_pkg, argv), "Unexpected exit")
            ^^^^^^^^^^^^^^^^^^^^^
  File "/home/vagrant/src/radiasoft/pykern/tests/pkcli_test.py", line 174, in _main
    return pkcli.main(root_pkg)
           ^^^^^^^^^^^^^^^^^^^^
  File "/home/vagrant/src/radiasoft/pykern/pykern/pkcli/__init__.py", line 167, in main
    argh.add_commands(
  File "/home/vagrant/.pyenv/versions/3.11.5/envs/warpx/lib/python3.11/site-packages/argh/assembling.py", line 685, in add_commands
    command_parser = subparsers_action.add_parser(cmd_name, **func_parser_kwargs)
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/vagrant/.pyenv/versions/3.11.5/lib/python3.11/argparse.py", line 1192, in add_parser
    raise ArgumentError(self, _('conflicting subparser: %s') % name)
argparse.ArgumentError: argument {cmd1}: conflicting subparser: cmd1

This only happens in the test, because it calls main multiple times. We do call main in some places in sirepo and pykern so I think this has to be fixed. There's some code in argh reaching inside argparse:

    # note that ArgumentParser._subparsers is *not* what is returned by
    # ArgumentParser.add_subparsers().
    if parser._subparsers:
        actions = [
            a for a in parser._actions if isinstance(a, argparse._SubParsersAction)
        ]
        return actions[0]

The subparser is getting reused by argh for some reason. It may be protecting this very error so perhaps this is an error in argparse holding state somewhere.

getargspec has been deprecated since 3.0 so use getfullargspec:

index c83524a..7a1866a 100644
--- a/pykern/pkcli/__init__.py
+++ b/pykern/pkcli/__init__.py
@@ -244,8 +244,8 @@ def _default_command(cmds, argv):
     if len(cmds) != 1 or cmds[0].__name__ != DEFAULT_COMMAND:
         return None
     dc = cmds[0]
-    spec = inspect.getargspec(dc)
-    if not (spec.varargs and spec.keywords):
+    spec = inspect.getfullargspec(dc)
+    if not (spec.varargs and spec.varkw):
         return dc
     save_argv = argv[:]