Repository: en0/dnry-config

Issue:
Optional flag for yaml files is not obeyed
When trying to add an optional YamlSource where the given yaml file does not exist, the following error is raised:

```expected str, bytes or os.PathLike object, not NoneType```

It appears the YamlSource load method is checking if the source is required or not to raise a runtime error. It correctly skips raising the error but still tries to read the file using open().  This results in the TypeError.

Line 14 of `dnry/config/yaml/source.py`
```python
    def load(self, fact: IConfigFactory, conf: IConfigSection) -> dict:
        path = self.__get_first_existing_path()
        if path is None and self.__required:
            paths = ",".join(self.__paths)
            raise RuntimeError(f"Configuration Error: None of these paths could be found: {paths}")

        with open(path, 'r') as f:
            return yaml.load(f, Loader=self.__loader```

Discussion:

Patch:
diff --git a/dnry/config/yaml/source.py b/dnry/config/yaml/source.py
index 8742b25..23d9e8d 100644
--- a/dnry/config/yaml/source.py
+++ b/dnry/config/yaml/source.py
@@ -17,6 +17,9 @@ class YamlSource(IConfigSource):
             paths = ",".join(self.__paths)
             raise RuntimeError(f"Configuration Error: None of these paths could be found: {paths}")
 
+        elif path is None and not self.__required:
+            return dict()
+
         with open(path, 'r') as f:
             return yaml.load(f, Loader=self.__loader) or dict()
 


Test patch:
diff --git a/test/test_bugs.py b/test/test_bugs.py
index e34fa06..e83dc27 100644
--- a/test/test_bugs.py
+++ b/test/test_bugs.py
@@ -9,7 +9,7 @@ from dnry.config.yaml import YamlSource
 class TestBugs(unittest.TestCase):
 
     def test_empty_yaml_file(self):
-        temp_file = f"./${uuid4()}.yaml"
+        temp_file = f"./{uuid4()}.yaml"
         with open(temp_file, 'w') as fd:
             fd.write('\n')
         try:
@@ -21,3 +21,10 @@ class TestBugs(unittest.TestCase):
 
         finally:
             os.remove(temp_file)
+
+    def test_optional_flag(self):
+        fact = ConfigFactory()
+        fact.add_source(YamlSource(f"./{uuid4()}", required=False))
+        conf = fact.build()
+        none_val = conf.get("no:key")
+        self.assertIsNone(none_val)