From b2c86bfe6a25703424e62d7107a6f38a0e411282 Mon Sep 17 00:00:00 2001 From: zach Date: Wed, 10 Jul 2019 20:46:57 +0300 Subject: [PATCH 1/3] Make type bool support some string representations of truth --- Lib/argparse.py | 4 ++++ Lib/test/test_argparse.py | 23 +++++++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/Lib/argparse.py b/Lib/argparse.py index 4f3aea928bf6f4..953794e1aa324c 100644 --- a/Lib/argparse.py +++ b/Lib/argparse.py @@ -89,6 +89,7 @@ import sys as _sys from gettext import gettext as _, ngettext +from distutils.util import strtobool as _strtobool SUPPRESS = '==SUPPRESS==' @@ -1664,6 +1665,9 @@ def identity(string): return string self.register('type', None, identity) + # register bool with a type_func that translates string into bool instance logically and gracefully + self.register('type', bool, lambda v: bool(_strtobool(v))) + # add help argument if necessary # (using explicit default to override global argument_default) default_prefix = '-' if '-' in prefix_chars else prefix_chars[0] diff --git a/Lib/test/test_argparse.py b/Lib/test/test_argparse.py index 9079d4bc7aa7fd..5aec281081a1a9 100644 --- a/Lib/test/test_argparse.py +++ b/Lib/test/test_argparse.py @@ -1650,6 +1650,29 @@ class TestTypeCallable(ParserTestCase): ('1024.675', NS(eggs=None, spam=1024.675)), ] +class TestTypeBool(ParserTestCase): + """Test some args with bool type:""" + + argument_signatures = [ + Sig('mybool', type=bool), + ] + failures = ['wrong','123','-1','abc','!@#'] + successes = [ + ('True', NS(mybool=True)), + ('False', NS(mybool=False)), + ('tRuE', NS(mybool=True)), + ('fAlSe', NS(mybool=False)), + ('yes', NS(mybool=True)), + ('no', NS(mybool=False)), + ('y', NS(mybool=True)), + ('n', NS(mybool=False)), + ('t', NS(mybool=True)), + ('f', NS(mybool=False)), + ('on', NS(mybool=True)), + ('off', NS(mybool=False)), + ('1', NS(mybool=True)), + ('0', NS(mybool=False)), + ] class TestTypeUserDefined(ParserTestCase): """Test a user-defined option/argument type""" From 7e7cfda6f0d2654393898ee659f248be8856fc76 Mon Sep 17 00:00:00 2001 From: zach Date: Sun, 14 Jul 2019 12:04:51 +0300 Subject: [PATCH 2/3] Replace the import of strtobool from distutils.util with local implementation of this method that returns bool type instead of int 0/1. --- Lib/argparse.py | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/Lib/argparse.py b/Lib/argparse.py index 953794e1aa324c..1b192badc024d3 100644 --- a/Lib/argparse.py +++ b/Lib/argparse.py @@ -89,7 +89,6 @@ import sys as _sys from gettext import gettext as _, ngettext -from distutils.util import strtobool as _strtobool SUPPRESS = '==SUPPRESS==' @@ -1603,6 +1602,22 @@ def _remove_action(self, action): self._container._remove_action(action) self._group_actions.remove(action) +def _strtobool (val): + """Convert a string representation of truth to true or false. + + 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 True + elif val in ('n', 'no', 'f', 'false', 'off', '0'): + return False + else: + raise ValueError("invalid truth value %r" % (val,)) class ArgumentParser(_AttributeHolder, _ActionsContainer): """Object for parsing command line strings into Python objects. @@ -1666,7 +1681,7 @@ def identity(string): self.register('type', None, identity) # register bool with a type_func that translates string into bool instance logically and gracefully - self.register('type', bool, lambda v: bool(_strtobool(v))) + self.register('type', bool, _strtobool) # add help argument if necessary # (using explicit default to override global argument_default) From c3d375132c05c97b6943458326250b6ef5dc7335 Mon Sep 17 00:00:00 2001 From: zach Date: Tue, 16 Jul 2019 01:19:24 +0300 Subject: [PATCH 3/3] Adding news entry in Misc/NEWS.d/next/ for argparse library regarding type=bool handling --- .../next/Library/2019-07-15-22-00-00.bpo-37564.L4ftF7.rst | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2019-07-15-22-00-00.bpo-37564.L4ftF7.rst diff --git a/Misc/NEWS.d/next/Library/2019-07-15-22-00-00.bpo-37564.L4ftF7.rst b/Misc/NEWS.d/next/Library/2019-07-15-22-00-00.bpo-37564.L4ftF7.rst new file mode 100644 index 00000000000000..33002a63dd48c3 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-07-15-22-00-00.bpo-37564.L4ftF7.rst @@ -0,0 +1,3 @@ +Fix ArgumentParser to treat ``type=bool`` according to common truth values. +Values 'y', 'yes', 't', 'true', 'on', and '1' will be evaluated as True value, +while 'n', 'no', 'f', 'false', 'off', and '0 will be evaluated as False value. \ No newline at end of file