0

I am trying to make a serial terminal app with two different functions. One function lists out available serial ports and the other function opens the specified serial port at the specified baud rate.

What I am trying to attempt is be able to select between either listing the ports or opening a port, if the user selects opening a port then argparse will accept two arguments; the port number and the baud rate.

Using the offical documentation I wrote this code:

# def listPorts():
# def openPort(port, baud):

parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)
subparsers = parser.add_subparsers(title="actions")

parser_list = subparsers.add_parser('list')
parser_list.set_defaults(func=listPorts)

parser_open = subparsers.add_parser('open')
parser_open.add_argument("COM Port", help="port to open serial terminal")
parser_open.add_argument("Baud Rate", help="frequency of serial communication")
parser_open.set_defaults(func=openPort)

config=parser.parse_args()
config.func(config)

I have managed to get it partially working - the first function, list ports, will work as expected as it has no parameters; but the second function, open port, won't work as expected because it has two parameters and instead I get the error:

python main.py open 5 9600

config.func(config._get_args) TypeError: openPort() missing 1 required positional argument: 'baud'

The issue is that I don't know how to get argparse to accept multiple arguments for it's subparsers.

Any help would be greatly appreciated, thanks in advance!

1 Answer 1

2

After:

config=parser.parse_args()

add a print(config).

You'll see it's a namespace object with listed attributes. One is config.func, which is the func you call.

In:

config.func(config)

You call the func, but you pass it the whole config object.

Both functions should accept one argument, this config object.

One can ignore it, since it won't have any attributes that it needs. The other can fetch the two attributes it needs.

Change these two lines so it is easier to fetch the attributes:

parser_open.add_argument("port", help="port to open serial terminal")
parser_open.add_argument("baud", help="frequency of serial communication")

in the function

def open(config):
    port = config.port
    baud = config.baud
    ....

In effect I am telling you same thing that the # sub-command functions example does in the argparse docs. (e.g. the foo and bar functions).

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks a lot! I am kind of embarrassed to see how basic the solution was lmao

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.