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'
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
Most helpful comment
BooleanParameters work as False unless the switch is set in which case they are True
python test.py TestBooleanParameterswitch == False
python test.py TestBooleanParameter --switchswitch == True