1

I'm writing a click command that accepts an argument of both int and str types, and I need to figure out the passed argument type within the function as in this example:

import click

@click.command()
@click.argument('num')
def command(num):
    if type(num) is int:
        click.echo("integer")
    elif type(num) is str:
        click.echo("string")

if __name__ == '__main__':
    command()

This example doesn't work, because the argument type is always unicode.

$ python script.py text
<type 'unicode'>
$ python script.py 123
<type 'unicode'>

I'm looking for a way to make executing this command return this:

$ python script.py text
<type 'str'>
$ python script.py 123
<type 'int'>
Stephen Rauch
  • 47,830
  • 31
  • 106
  • 135
MMSs
  • 455
  • 6
  • 19

2 Answers2

1

Positional arguments in click or even using sys.argv will always be of type str as this is what you pass to the command line, a string.

What you need to do is parse the input and convert it to a string or adapt your code to look as follows:

import click

@click.command()
@click.argument('num')
def command(num):
    if num.isnumeric():
        click.echo("integer")
    else:  # Will always be a str no need to check for type.
        click.echo("string")

if __name__ == '__main__':
    command()

This uses isnumeric() to check if the str passed is numeric, e.g. u"123"

"The method isnumeric() checks whether the string consists of only numeric characters. This method is present only on unicode objects."

You could also do it this way:

import click

@click.command()
@click.argument('num')
def command(num):
    if num.isnumeric():
        num = int(num)
    if isinstance(num, int):
        click.echo("integer")
    else:       
        click.echo("string")

if __name__ == '__main__':
    command()

However this is completely redundant unless you intend to use num later along the way and you need it to be of type int.

And lastly you should use isinstance(num, int) and not type().

More info here: Differences between isinstance() and type() in python

alexisdevarennes
  • 5,437
  • 4
  • 24
  • 38
0

It is generally considered more Pythonic to ask for forgiveness not permission.

try:
    int(num)
    click.echo("integer")
except ValueError:
    click.echo("string")

That would be implemented here by attempting to convert to an int in a try block. If the string can be converted to an int, then it must be an int, otherwise, a string.

Stephen Rauch
  • 47,830
  • 31
  • 106
  • 135