Repository: beetbox/confuse

Issue:
None as Template should use None as default
When I do this for a key that doesn't exist in `config_default.yaml`, I would expect the key to contain `None` by default.
```python
config['something'].get({
    'key': None
})
```

But instead, I get:
```
confuse.NotFoundError: something.key not found
```

This is because of this line in `as_template`:
https://github.com/beetbox/confuse/blob/b82d3faacb972b8964487a648805c3d0e06c0212/confuse.py#L1718-L1719

What I would propose:
```python
# throws NotFoundError - '...' is often used to denote a missing value
config['something'].get({
    'key': ...
})

# returns None
config['something'].get({
    'key': None
})
```

Discussion:

Patch:
diff --git a/confuse/core.py b/confuse/core.py
index 193bfc3..5015705 100644
--- a/confuse/core.py
+++ b/confuse/core.py
@@ -335,7 +335,7 @@ class ConfigView(object):
                     od[key] = view.get()
         return od
 
-    def get(self, template=None):
+    def get(self, template=templates.REQUIRED):
         """Retrieve the value for this view according to the template.
 
         The `template` against which the values are checked can be
diff --git a/confuse/templates.py b/confuse/templates.py
index 640ba66..984c341 100644
--- a/confuse/templates.py
+++ b/confuse/templates.py
@@ -626,6 +626,8 @@ def as_template(value):
     elif isinstance(value, float):
         return Number(value)
     elif value is None:
+        return Template(None)
+    elif value is REQUIRED:
         return Template()
     elif value is dict:
         return TypeTemplate(abc.Mapping)
diff --git a/docs/index.rst b/docs/index.rst
index 64f9d69..b8ac11b 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -393,6 +393,10 @@ v1.3.0
 
 - Break up the `confuse` module into a package. (All names should still be
   importable from `confuse`.)
+- When using `None` as a template, the result is a value whose default is
+  `None`. Previously, this was equivalent to leaving the key off entirely,
+  i.e., a template with no default. To get the same effect now, use
+  `confuse.REQUIRED` in the template.
 
 v1.2.0
 ''''''


Test patch:
diff --git a/test/test_valid.py b/test/test_valid.py
index ec7cf6b..4ba8125 100644
--- a/test/test_valid.py
+++ b/test/test_valid.py
@@ -171,6 +171,11 @@ class AsTemplateTest(unittest.TestCase):
     def test_none_as_template(self):
         typ = confuse.as_template(None)
         self.assertIs(type(typ), confuse.Template)
+        self.assertEqual(typ.default, None)
+
+    def test_required_as_template(self):
+        typ = confuse.as_template(confuse.REQUIRED)
+        self.assertIs(type(typ), confuse.Template)
         self.assertEqual(typ.default, confuse.REQUIRED)
 
     def test_dict_type_as_template(self):