Sample code:
import argparse
import cmd2
import sys
def create_subparser(a_parser = None):
if a_parser is None:
new_parser = argparse.ArgumentParser()
else:
new_parser = a_parser.add_parser("single")
new_parser.add_argument("--single-param", "-sp")
return new_parser
def single_print(some_param):
print("single operation " + str(some_param))
def other_print():
print("other operation")
class TestCmd(cmd2.Cmd):
single_parser = create_subparser()
@cmd2.with_argparser(single_parser)
def do_single(self, opts):
print(opts)
single_print(opts.single_param)
def do_other(self, opts):
other_print()
if __name__ == "__main__":
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers(help="commands", dest="mode")
create_subparser(subparsers)
cmd_parser = subparsers.add_parser("cmd", help="shell")
args = parser.parse_args()
if args.mode == "single":
single_print(args.single_param)
else:
sys.argv = [sys.argv[0]] # cmd2 complains about unknown parameters without
cmd = TestCmd()
cmd.cmdloop()
In the example, I'm trying to make a program that can either run in single mode (program.py single -sp test
) or in cmd/prompt mode (program.py cmd
), which then would call single mode or other operation (inside the shell, write single -sp test
or other
. Anyway, if I try to get all the values for the argparse being used in the do_single inside the cmd2 class, I get EXCEPTION of type 'RecursionError' occurred with message: 'maximum recursion depth exceeded in comparison'
. Using cmd2's debug, it goes:
Traceback (most recent call last):
File "/home/.../site-packages/cmd2/cmd2.py", line 2011, in onecmd_plus_hooks
stop = self.onecmd(statement, add_to_history=add_to_history)
File "/home/.../site-packages/cmd2/cmd2.py", line 2441, in onecmd
stop = func(statement)
File "/home/.../site-packages/cmd2/decorators.py", line 308, in cmd_wrapper
return func(*args_list, **kwargs)
File "test.py", line 28, in do_single
print(opts)
File "/usr/lib/python3.7/argparse.py", line 131, in __repr__
arg_strings.append('%s=%r' % (name, value))
File "/usr/lib/python3.7/argparse.py", line 131, in __repr__
arg_strings.append('%s=%r' % (name, value))
File "/usr/lib/python3.7/argparse.py", line 131, in __repr__
arg_strings.append('%s=%r' % (name, value))
[Previous line repeated 326 more times]
File "/usr/lib/python3.7/argparse.py", line 129, in __repr__
for name, value in self._get_kwargs():
File "/usr/lib/python3.7/argparse.py", line 139, in _get_kwargs
return sorted(self.__dict__.items())
RecursionError: maximum recursion depth exceeded in comparison
The reason I'm using the create_subparser
function is because I'm creating the subparsers to be used by the cmd2.Cmd subclass, but I want to use the same parser for the modes when invoked from the main shell. This is basically a minimum working example, my code has a lot more flags and whatnot.
One other thing, the problem seems to happen because of print(opts)
. It seems it tries to do vars(opts)
and when it tries enumerating all the variables, it runs out of memory due to recursion somewhere. If I don't try to list all the variables inside the object (for example, if I used just opts.single_param
), it would work. It seems to be related to me trying to use the same argparser both inside cmd2 and with the main program, but I don't understand why exactly it's happening and if it can be fixed.
Without
cmd2
I can't run your code. But I can make a namespace that exhibits your problem.You could test the individual attributes until you find the one that's the problem: