The Python Oracle

How to pass bool argument to fabric command

This video explains
How to pass bool argument to fabric command

--

Become part of the top 3% of the developers by applying to Toptal
https://topt.al/25cXVn

--

Music by Eric Matyas
https://www.soundimage.org
Track title: Techno Intrigue Looping

--

Chapters
00:00 Question
00:30 Accepted answer (Score -3)
01:01 Answer 2 (Score 40)
02:03 Answer 3 (Score 14)
02:31 Answer 4 (Score 5)
03:33 Thank you

--

Full question
https://stackoverflow.com/questions/1164...

Accepted answer links:
[fabric docs]: http://docs.fabfile.org/en/1.4.3/usage/f...

Answer 4 links:
[https://pypi.python.org/pypi/boolfab/]: https://pypi.python.org/pypi/boolfab/

--

Content licensed under CC BY-SA
https://meta.stackexchange.com/help/lice...

--

Tags
#python #boolean #fabric

#avk47



ANSWER 1

Score 40


I'm using this:

from distutils.util import strtobool

def func(arg1="default", arg2=False):
    if arg2:
        arg2 = bool(strtobool(arg2))

So far works for me. it will parse values (ignoring case):

'y', 'yes', 't', 'true', 'on', '1'
'n', 'no', 'f', 'false', 'off', '0'

strtobool returns 0 or 1 that's why bool is needed to convert to True/False boolean.

For completeness, here's strtobool's implementation:

def strtobool (val):
    """Convert a string representation of truth to true (1) or false (0).

    True values are 'y', 'yes', 't', 'true', 'on', and '1'; false values
    are 'n', 'no', 'f', 'false', 'off', and '0'.  Raises ValueError if
    'val' is anything else.
    """
    val = val.lower()
    if val in ('y', 'yes', 't', 'true', 'on', '1'):
        return 1
    elif val in ('n', 'no', 'f', 'false', 'off', '0'):
        return 0
    else:
        raise ValueError("invalid truth value %r" % (val,))

Slightly better version (thanks for comments mVChr)

from distutils.util import strtobool

def _prep_bool_arg(arg): 
    return bool(strtobool(str(arg)))

def func(arg1="default", arg2=False):
    arg2 = _prep_bool_arg(arg2)



ANSWER 2

Score 14


I would use a function:

def booleanize(value):
    """Return value as a boolean."""

    true_values = ("yes", "true", "1")
    false_values = ("no", "false", "0")

    if isinstance(value, bool):
        return value

    if value.lower() in true_values:
        return True

    elif value.lower() in false_values:
        return False

    raise TypeError("Cannot booleanize ambiguous value '%s'" % value)

Then in the task:

@task
def mytask(arg):
    arg = booleanize(arg)



ANSWER 3

Score 5


If the func in question uses "if argN:" instead of "if argN is True:" to test if a boolean value is true, you could use "" for False and "anything" for True.

See also: http://docs.python.org/library/stdtypes.html#truth-value-testing




ANSWER 4

Score 3


A better way would be to use ast.literal_eval:

from ast import literal_eval

def my_task(flag):
    if isinstance(flag, basestring): # also supports calling from other tasks
        flag = literal_eval(flag)

Although this doesn't take into consideration values like 'yes' or 'no', it is slightly cleaner and safer than eval...