Luigi: Cannot pass BooleanParameter in as argument from commandline

Created on 8 Oct 2013  路  11Comments  路  Source: spotify/luigi

With a very simple class defined as:

import luigi
class TestBooleanParameter(luigi.Task):
    switch = luigi.BooleanParameter()

    def run(self):
        print self.switch

And run from the commandline as either

python test.py TestBooleanParameter --switch=True

or

python test.py TestBooleanParameter --switch=1

Fails with:

test.py TestBooleanParameter: error: argument --switch: ignored explicit argument 'True'

or, alternatively

test.py TestBooleanParameter: error: argument --switch: ignored explicit argument '1'

Most helpful comment

BooleanParameters work as False unless the switch is set in which case they are True

python test.py TestBooleanParameter
switch == False

python test.py TestBooleanParameter --switch
switch == True

All 11 comments

BooleanParameters work as False unless the switch is set in which case they are True

python test.py TestBooleanParameter
switch == False

python test.py TestBooleanParameter --switch
switch == True

Ah, that makes sense. But that means I can create odd behavior like this:

import luigi
class TestBooleanParameter(luigi.Task):
    switch = luigi.BooleanParameter(default=True)

    def run(self):
        print self.switch

and then, I'll never be able to turn it off from the commandline?

import luigi
class TestBooleanParameter(luigi.Task):
    disable_switch = luigi.BooleanParameter()

    def run(self):
        print (not self.disable_switch)

FTFY

I know what you're getting at though, maybe it should be possible to do an =False or =True explicitly, but I don't see it as a bug that needs fixing as such. Feel free to make a PR for it if you want it though.

Yeah BooleanParameters should definitely only allow default=False. It's something I've planned to address for a while.

Disagree, if this is going to be fixed then changing the allowable default is a weird way to do it. Intuitively I'd expect the following behaviour:

switch = BooleanParameter()
default -> switch == False
--switch -> switch == True
--switch=True -> switch == True
--switch=False -> switch == False

switch = BooleanParameter(default=True)
default -> switch == True
--switch -> switch == True
--switch=True -> switch == True
--switch=False -> switch == False

ok, that makes sense too. didn't know you could do --switch=False with boolean arguments in argparse

The GNU way to do it is to introduce --no-switch for a switch which defaults to true.

i'm cool with that too

We ran into this issue... why is this closed?

I suppose correct thing to do would be to modify luigi.interface.ArgParseInterface

it currently does store_true for any boolean parameter. It should look at the default value and pass in store_false if default value is set to True.

        elif param.is_boolean:
            action = "store_true"

should change to

        elif param.is_boolean and param.default():
            action = "store_false"
        elif param.is_boolean:
            action = "store_true"

It probably makes more sense to disallow default=True and recommend using a negative one instead, like Andy pointed out

Support for --foo and --no-foo arguments for BoolParameter: https://github.com/spotify/luigi/pull/1598

Was this page helpful?
0 / 5 - 0 ratings

Related issues

tiamot picture tiamot  路  4Comments

mwheeler-hdai picture mwheeler-hdai  路  6Comments

stephenpascoe picture stephenpascoe  路  4Comments

fmorency picture fmorency  路  5Comments

gioelelm picture gioelelm  路  5Comments