From 9fe80032933d7148c5f1508222b3e835ea2ff359 Mon Sep 17 00:00:00 2001 From: Esben Sonne Date: Sat, 21 Jan 2017 21:04:03 +0100 Subject: [PATCH 1/7] First steps into adding parsing helpers This first one is does booleans. --- envargs/__init__.py | 1 + envargs/inputs.py | 13 +++++++++++++ tests/test_funcs.py | 19 +++++++++++++++++++ 3 files changed, 33 insertions(+) create mode 100644 envargs/inputs.py create mode 100644 tests/test_funcs.py diff --git a/envargs/__init__.py b/envargs/__init__.py index dd98677..69233d6 100644 --- a/envargs/__init__.py +++ b/envargs/__init__.py @@ -1,4 +1,5 @@ """Exposed internals of envparse.""" +from . import inputs from .models import Var from .parser import parse_dict from .parser import parse_env diff --git a/envargs/inputs.py b/envargs/inputs.py new file mode 100644 index 0000000..09173b4 --- /dev/null +++ b/envargs/inputs.py @@ -0,0 +1,13 @@ +"""Default value parsers. Does common things simply.""" + + +def boolean(value): + """Return true if the value indicates a truthiness.""" + options = { + 'true', + 't', + '1', + 'yes', + } + + return value.lower() in options diff --git a/tests/test_funcs.py b/tests/test_funcs.py new file mode 100644 index 0000000..4e7b353 --- /dev/null +++ b/tests/test_funcs.py @@ -0,0 +1,19 @@ +"""Testing the default parser functions.""" +import pytest + +from envargs import inputs + + +@pytest.mark.parametrize('case, expected', [ + ('true', True), + ('t', True), + ('True', True), + ('1', True), + ('yes', True), + ('0', False), + ('false', False), + ('no', False), +]) +def test_boolean_parser(case, expected): + """Test the default boolean parser.""" + assert inputs.boolean(case) == expected From 95a0265f2cf57ba04b87e4c39e9ca25606724194 Mon Sep 17 00:00:00 2001 From: Esben Sonne Date: Sun, 22 Jan 2017 13:57:53 +0100 Subject: [PATCH 2/7] Comma splitting --- envargs/inputs.py | 5 +++++ tests/test_funcs.py | 9 +++++++++ 2 files changed, 14 insertions(+) diff --git a/envargs/inputs.py b/envargs/inputs.py index 09173b4..efac217 100644 --- a/envargs/inputs.py +++ b/envargs/inputs.py @@ -11,3 +11,8 @@ def boolean(value): } return value.lower() in options + + +def split_by_comma(value): + """Return the value split by commas.""" + return value.split(',') diff --git a/tests/test_funcs.py b/tests/test_funcs.py index 4e7b353..cf1dfb6 100644 --- a/tests/test_funcs.py +++ b/tests/test_funcs.py @@ -17,3 +17,12 @@ def test_boolean_parser(case, expected): """Test the default boolean parser.""" assert inputs.boolean(case) == expected + + +@pytest.mark.parametrize('case, expected', [ + ('1', ['1']), + ('1,2,3', ['1', '2', '3']), +]) +def test_split_by_comma(case, expected): + """Test the splitter.""" + assert inputs.split_by_comma(case) == expected From 06d89526836323726f6c9238d760eca2283c9df6 Mon Sep 17 00:00:00 2001 From: Esben Sonne Date: Fri, 28 Apr 2017 12:07:08 +0200 Subject: [PATCH 3/7] Moved inputs to helpers --- envargs/__init__.py | 2 +- envargs/helpers.py | 21 +++++++++++++++------ envargs/inputs.py | 18 ------------------ envargs/models.py | 4 ++-- envargs/utils.py | 9 +++++++++ tests/test_funcs.py | 6 +++--- 6 files changed, 30 insertions(+), 30 deletions(-) delete mode 100644 envargs/inputs.py create mode 100644 envargs/utils.py diff --git a/envargs/__init__.py b/envargs/__init__.py index 69233d6..85d86ae 100644 --- a/envargs/__init__.py +++ b/envargs/__init__.py @@ -1,5 +1,5 @@ """Exposed internals of envparse.""" -from . import inputs +from . import helpers from .models import Var from .parser import parse_dict from .parser import parse_env diff --git a/envargs/helpers.py b/envargs/helpers.py index c4dad82..efac217 100644 --- a/envargs/helpers.py +++ b/envargs/helpers.py @@ -1,9 +1,18 @@ -"""Smaller helper functions for taking care of repeated things.""" +"""Default value parsers. Does common things simply.""" -def callables(potential_callables): - """Ensure that the callables are in fact a sequence.""" - if callable(potential_callables): - return [potential_callables] +def boolean(value): + """Return true if the value indicates a truthiness.""" + options = { + 'true', + 't', + '1', + 'yes', + } - return potential_callables + return value.lower() in options + + +def split_by_comma(value): + """Return the value split by commas.""" + return value.split(',') diff --git a/envargs/inputs.py b/envargs/inputs.py deleted file mode 100644 index efac217..0000000 --- a/envargs/inputs.py +++ /dev/null @@ -1,18 +0,0 @@ -"""Default value parsers. Does common things simply.""" - - -def boolean(value): - """Return true if the value indicates a truthiness.""" - options = { - 'true', - 't', - '1', - 'yes', - } - - return value.lower() in options - - -def split_by_comma(value): - """Return the value split by commas.""" - return value.split(',') diff --git a/envargs/models.py b/envargs/models.py index 7ad71b4..c01d7ed 100644 --- a/envargs/models.py +++ b/envargs/models.py @@ -1,6 +1,6 @@ """Everthing about vars.""" from . import errors -from . import helpers +from . import utils class Var: @@ -12,7 +12,7 @@ class Var: def __init__(self, use, validate=None, load_from=None, default=None, err_msg=None): """Return a new instance.""" self.use = use - self.validate_with = helpers.callables(validate) + self.validate_with = utils.callables(validate) self.load_from = load_from self.default = default self.err_msg = err_msg diff --git a/envargs/utils.py b/envargs/utils.py new file mode 100644 index 0000000..c4dad82 --- /dev/null +++ b/envargs/utils.py @@ -0,0 +1,9 @@ +"""Smaller helper functions for taking care of repeated things.""" + + +def callables(potential_callables): + """Ensure that the callables are in fact a sequence.""" + if callable(potential_callables): + return [potential_callables] + + return potential_callables diff --git a/tests/test_funcs.py b/tests/test_funcs.py index cf1dfb6..6d85229 100644 --- a/tests/test_funcs.py +++ b/tests/test_funcs.py @@ -1,7 +1,7 @@ """Testing the default parser functions.""" import pytest -from envargs import inputs +from envargs import helpers @pytest.mark.parametrize('case, expected', [ @@ -16,7 +16,7 @@ ]) def test_boolean_parser(case, expected): """Test the default boolean parser.""" - assert inputs.boolean(case) == expected + assert helpers.boolean(case) == expected @pytest.mark.parametrize('case, expected', [ @@ -25,4 +25,4 @@ def test_boolean_parser(case, expected): ]) def test_split_by_comma(case, expected): """Test the splitter.""" - assert inputs.split_by_comma(case) == expected + assert helpers.split_by_comma(case) == expected From f1a8c01c3a4b5ae0f7bc39c134aec5ddc21be5ac Mon Sep 17 00:00:00 2001 From: Esben Sonne Date: Fri, 28 Apr 2017 12:30:54 +0200 Subject: [PATCH 4/7] Generalized the split_by_comma function --- envargs/helpers.py | 10 ++++++++-- tests/test_funcs.py | 13 ++++++++++++- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/envargs/helpers.py b/envargs/helpers.py index efac217..9177a50 100644 --- a/envargs/helpers.py +++ b/envargs/helpers.py @@ -13,6 +13,12 @@ def boolean(value): return value.lower() in options -def split_by_comma(value): +def split_by(separator, converter=None): """Return the value split by commas.""" - return value.split(',') + def splitter(value): + return [ + converter(each) if converter else each + for each in value.split(',') + ] + + return splitter diff --git a/tests/test_funcs.py b/tests/test_funcs.py index 6d85229..3567f6a 100644 --- a/tests/test_funcs.py +++ b/tests/test_funcs.py @@ -25,4 +25,15 @@ def test_boolean_parser(case, expected): ]) def test_split_by_comma(case, expected): """Test the splitter.""" - assert helpers.split_by_comma(case) == expected + splitter = helpers.split_by(',') + assert splitter(case) == expected + + +@pytest.mark.parametrize('case, expected', [ + ('1', [1]), + ('1,2,3', [1, 2, 3]), +]) +def test_split_by_comma_and_convert(case, expected): + """Test the splitter.""" + splitter = helpers.split_by(',', converter=int) + assert splitter(case) == expected From e21869f12a13d62c9d76ba79b512a489d48c8400 Mon Sep 17 00:00:00 2001 From: Esben Sonne Date: Fri, 28 Apr 2017 12:42:13 +0200 Subject: [PATCH 5/7] Changed tests to use the new helpers --- tests/test_parsing.py | 21 ++++----------------- 1 file changed, 4 insertions(+), 17 deletions(-) diff --git a/tests/test_parsing.py b/tests/test_parsing.py index cab0fae..d2646c0 100644 --- a/tests/test_parsing.py +++ b/tests/test_parsing.py @@ -4,6 +4,7 @@ from envargs import parse_dict from envargs import parse_env from envargs import Var +from envargs import helpers def test_simple_dict_parsing(): @@ -144,17 +145,9 @@ def test_default_name(): def test_custom_function_boolean(): """Test that we can use a custom function to parse with.""" - def parse_bool(value): - return value.lower() in { - 'true', - 'yes', - 'y', - '1', - } - args = { 'a_bool': Var( - use=parse_bool, + use=helpers.boolean, validate=lambda parsed: isinstance(parsed, bool) ), } @@ -170,15 +163,9 @@ def parse_bool(value): def test_custom_function_int_list(): """Test that we can have more complex parsing functions.""" - def parse_list(value): - return [ - int(each) - for each in value.split(',') - ] - args = { 'a_list': Var( - use=parse_list, + use=helpers.split_by(',', converter=int), validate=( lambda parsed: isinstance(parsed, list), lambda parsed: all(isinstance(each, int) for each in parsed), @@ -199,7 +186,7 @@ def test_complex_defaulting(): """Test that when defaulting, the functions are not used.""" args = { 'a_bool': Var( - use=lambda x: x.lower() in {'1', 't', 'true'}, + use=helpers.boolean, validate=lambda x: isinstance(x, bool), default=False, ), From ee540f0f6ec9548c0997694fab82f98c5ad35297 Mon Sep 17 00:00:00 2001 From: Esben Sonne Date: Fri, 28 Apr 2017 12:47:08 +0200 Subject: [PATCH 6/7] Added a new lambda based test --- tests/test_parsing.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/tests/test_parsing.py b/tests/test_parsing.py index d2646c0..f966c35 100644 --- a/tests/test_parsing.py +++ b/tests/test_parsing.py @@ -197,3 +197,21 @@ def test_complex_defaulting(): assert parse_dict(values, args) == { 'a_bool': False, } + + +def test_setting_value(): + """Test parsing with a lambda.""" + args = { + 'a_set': Var( + use=lambda x: set(x.split(',')), + validate=lambda x: isinstance(x, set), + ), + } + + values = { + 'a_set': 'one,two', + } + + assert parse_dict(values, args) == { + 'a_set': {'one', 'two'}, + } From a629e409d2dc56828fde5e3098adb16733abb094 Mon Sep 17 00:00:00 2001 From: Esben Sonne Date: Fri, 28 Apr 2017 12:48:04 +0200 Subject: [PATCH 7/7] Updated readme to use new splitting --- README.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.rst b/README.rst index 6cee24b..fb37508 100644 --- a/README.rst +++ b/README.rst @@ -21,7 +21,7 @@ Using .. code-block:: python - from envargs import Var, parse_env + from envargs import Var, parse_env, helpers required_vars = { 'A_INT': Var( @@ -29,7 +29,7 @@ Using validate=lambda x: x >= 0, ), 'A_LIST': Var( - use=lambda x: x.split(','), + use=helpers.split_by(','), validate=( lambda x: len(x) == 2, lambda x: x[0] == 'first element',