-- is a handy way of saying 'positional arguments start here'.
With your parser, these work:
program.py refresh # sets ids=None
program.py refresh --ids 1 2 3
program.py --ids 1 2 3 -- refresh
You could give the --ids argument a default (e.g. []) if you don't like the None.
Any problems with program.py refesh --ids 1,2,3 are due to how the shell splits your command line. Look at the sys.argv list.
Problems with program.py --ids 1 2 3 refresh arise because when handling --ids, the parser tries to use all strings that follow that aren't obviously flags (e.g. with '-'). It does not use the 'int' type to test which ones to use and which to leave.
Now if the ids were positional, it would handle the 1 2 3 refresh:
parser.add_argument('ids',type=int,nargs='+')
parser.add_argument('cmd')
parser.parse_args('1 2 3 refresh'.split())
But that's because the parser uses a different strategy to allocate strings to several positional arguments. It uses a re matcher that looks like A+A.
Kevin's type approach might be better implemented with a simple function:
def mytype(astring):
ll = astring.split(',')
return [int(l) for l in ll]
parser.add_argument('--ids', type=mytype)
It could be generalized to handle quoted strings like "1 2 3". type can be any function that takes a string, and returns the desired value(s), and raises an error if it can't do the conversion.