Repository: rochacbruno/dynaconf
Pull request #406 (2020-09-11 14:03:17)

Test all names in Validator("foo", "bar", must_exist=False)
`Validator(must_exist=False)` incorrectly checks first name only.

Given `settings.yaml`:

    bar: some_value

and app.py:

```python
from dynaconf import Dynaconf
from dynaconf import Validator

settings = Dynaconf(
    settings_files=['settings.yaml', '.secrets.yaml'],
    validators=[Validator("foo", "bar", must_exist=False)],
)
settings.validators.validate()
```

Running `app.py` does not result in `ValidationError` being rised - even though "bar" is defined.

tests:
```
$ pytest -v -k test_validation_error tests/
===================================================================================== test session starts =====================================================================================
platform linux -- Python 3.8.5, pytest-6.0.1, py-1.9.0, pluggy-0.13.1 -- /home/mzalewsk/.virtualenvs/dynaconf/bin/python3
cachedir: .pytest_cache
rootdir: /home/mzalewsk/sources/dynaconf, configfile: pytest.ini
plugins: cov-2.10.1, mock-3.3.1, lovely-pytest-docker-0.1.0
collected 294 items / 290 deselected / 4 selected                                                                                                                                             

tests/test_validators.py::test_validation_error[validator_instance0] PASSED                                                                                                             [ 25%]
tests/test_validators.py::test_validation_error[validator_instance1] PASSED                                                                                                             [ 50%]
tests/test_validators.py::test_validation_error[validator_instance2] PASSED                                                                                                             [ 75%]
tests/test_validators.py::test_validation_error[validator_instance3] PASSED                                                                                                             [100%]
======================================================================== 4 passed, 290 deselected, 5 warnings in 0.47s ========================================================================

```

codecov[bot]: # [Codecov](https://codecov.io/gh/rochacbruno/dynaconf/pull/406?src=pr&el=h1) Report
> Merging [#406](https://codecov.io/gh/rochacbruno/dynaconf/pull/406?src=pr&el=desc) into [master](https://codecov.io/gh/rochacbruno/dynaconf/commit/6c568d687e29ca5ed9806a74f1f4fb7e4b96be2f?el=desc) will **not change** coverage.
> The diff coverage is `100.00%`.

[![Impacted file tree graph](https://codecov.io/gh/rochacbruno/dynaconf/pull/406/graphs/tree.svg?width=650&height=150&src=pr&token=GXszVzJcqW)](https://codecov.io/gh/rochacbruno/dynaconf/pull/406?src=pr&el=tree)

```diff
@@            Coverage Diff            @@
##            master      #406   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files           17        17           
  Lines          817       817           
=========================================
  Hits           817       817           
```


| [Impacted Files](https://codecov.io/gh/rochacbruno/dynaconf/pull/406?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [dynaconf/validator.py](https://codecov.io/gh/rochacbruno/dynaconf/pull/406/diff?src=pr&el=tree#diff-ZHluYWNvbmYvdmFsaWRhdG9yLnB5) | `100.00% <100.00%> (ø)` | |

------

[Continue to review full report at Codecov](https://codecov.io/gh/rochacbruno/dynaconf/pull/406?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/rochacbruno/dynaconf/pull/406?src=pr&el=footer). Last update [6c568d6...135a03c](https://codecov.io/gh/rochacbruno/dynaconf/pull/406?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).


Patch:
diff --git a/dynaconf/validator.py b/dynaconf/validator.py
index 05cc370..4f8d3a4 100644
--- a/dynaconf/validator.py
+++ b/dynaconf/validator.py
@@ -195,7 +195,7 @@ class Validator(object):
                     )
                 )
             elif self.must_exist in (False, None) and value is empty:
-                return
+                continue
 
             # is there a callable condition?
             if self.condition is not None:


Test patch:
diff --git a/tests/test_validators.py b/tests/test_validators.py
index 7cc593d..101d8da 100644
--- a/tests/test_validators.py
+++ b/tests/test_validators.py
@@ -167,6 +167,7 @@ def test_dotted_validators(settings):
         Validator("TESTVALUE", eq="hello_world"),
         Validator("PROJECT", condition=lambda x: False, env="development"),
         Validator("TESTVALUEZZ", must_exist=True),
+        Validator("TESTVALUEZZ", "PROJECT", must_exist=False),
     ],
 )
 def test_validation_error(validator_instance, tmpdir):