From 8d618b95be505e930b8e616ce3218969fe19856c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Piotr=20Ma=C5=9Blanka?= <piotr.maslanka@henrietta.com.pl>
Date: Mon, 10 May 2021 17:35:29 +0200
Subject: [PATCH] bugfix for 2.16

---
 CHANGELOG.md                              |  2 ++
 satella/__init__.py                       |  2 +-
 satella/configuration/schema/from_json.py |  4 ++--
 satella/configuration/schema/registry.py  |  7 ++++++-
 satella/configuration/schema/structs.py   |  8 ++++----
 tests/test_configuration/test_schema.py   | 14 ++++++++++++++
 6 files changed, 29 insertions(+), 8 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5f1b6348..40c4b772 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1 +1,3 @@
 # v2.16.1
+
+* **bugfix release for 2.16**
diff --git a/satella/__init__.py b/satella/__init__.py
index 0c7c65f6..37a2f4fd 100644
--- a/satella/__init__.py
+++ b/satella/__init__.py
@@ -1 +1 @@
-__version__ = '2.16.1a1'
+__version__ = '2.16.1'
diff --git a/satella/configuration/schema/from_json.py b/satella/configuration/schema/from_json.py
index fd61daeb..edcef8f0 100644
--- a/satella/configuration/schema/from_json.py
+++ b/satella/configuration/schema/from_json.py
@@ -3,13 +3,13 @@ import typing as tp
 from satella.exceptions import ConfigurationSchemaError
 from satella.imports import import_class
 from .base import Descriptor
-from .registry import BASE_LOOKUP_TABLE
+from .registry import BASE_LOOKUP_TABLE, PLAIN_ENTRIES
 from .structs import create_key, Dict
 
 
 def _get_descriptor_for_str(key: str, value: str) -> Descriptor:
     try:
-        if value in ('int', 'float', 'str', 'ipv4', 'any', 'bool', 'file'):
+        if value in PLAIN_ENTRIES:
             return create_key(BASE_LOOKUP_TABLE[value](),
                               key, False, None)
     except KeyError:
diff --git a/satella/configuration/schema/registry.py b/satella/configuration/schema/registry.py
index 8d200198..7e98a2b9 100644
--- a/satella/configuration/schema/registry.py
+++ b/satella/configuration/schema/registry.py
@@ -1,7 +1,8 @@
 BASE_LOOKUP_TABLE = {}
+PLAIN_ENTRIES = set()
 
 
-def register_custom_descriptor(name: str):
+def register_custom_descriptor(name: str, is_plain: bool = True):
     """
     A decorator used for registering custom descriptors in order to be loadable via
     descriptor_from_dict
@@ -13,9 +14,13 @@ def register_custom_descriptor(name: str):
     >>>     REGEXP = '(([0-9a-f]{1,4}:)' ...
 
     :param name: under which it is supposed to be invokable
+    :param is_plain: is this a nested structure?
     """
 
     def inner(cls):
+        global BASE_LOOKUP_TABLE, PLAIN_ENTRIES
+        if is_plain:
+            PLAIN_ENTRIES.add(name)
         BASE_LOOKUP_TABLE[name] = cls
         return cls
 
diff --git a/satella/configuration/schema/structs.py b/satella/configuration/schema/structs.py
index ac6883c4..7d55518e 100644
--- a/satella/configuration/schema/structs.py
+++ b/satella/configuration/schema/structs.py
@@ -7,7 +7,7 @@ from .base import Descriptor, must_be_type, ConfigDictValue
 from .registry import register_custom_descriptor
 
 
-@register_custom_descriptor('list')
+@register_custom_descriptor('list', is_plain=False)
 class List(Descriptor):
     """
     This must be a list, made of entries of a descriptor (this is optional)
@@ -42,7 +42,7 @@ def create_key(descriptor: Descriptor, name: str, optional: bool = False,
     return descriptor
 
 
-@register_custom_descriptor('caster')
+@register_custom_descriptor('caster', is_plain=False)
 class Caster(Descriptor):
     """
     A value must be ran through a function.
@@ -62,7 +62,7 @@ class Caster(Descriptor):
         return self.to_cast(value)
 
 
-@register_custom_descriptor('dict')
+@register_custom_descriptor('dict', is_plain=False)
 class Dict(Descriptor):
     """
     This entry must be a dict, having at least specified keys.
@@ -124,7 +124,7 @@ class Dict(Descriptor):
         return output
 
 
-@register_custom_descriptor('union')
+@register_custom_descriptor('union', is_plain=False)
 class Union(Descriptor):
     """
     The type of one of the child descriptors. If posed as such:
diff --git a/tests/test_configuration/test_schema.py b/tests/test_configuration/test_schema.py
index 4a2d624e..90755d8b 100644
--- a/tests/test_configuration/test_schema.py
+++ b/tests/test_configuration/test_schema.py
@@ -1,5 +1,6 @@
 import enum
 import os
+import shutil
 import tempfile
 import unittest
 
@@ -30,6 +31,19 @@ class TestSchema(unittest.TestCase):
         ps = Caster(Environment)
         self.assertEqual(ps(0), Environment.PRODUCTION)
 
+    def test_directory(self):
+        schema = {
+            "directory": "dir"
+        }
+
+        if os.path.exists('directory'):
+            shutil.rmtree('directory')
+
+        s = descriptor_from_dict(schema)
+        self.assertRaises(ConfigurationValidationError, lambda: s({'directory': 'directory'}))
+        os.mkdir('directory')
+        self.assertEqual(s({'directory': 'directory'})['directory'], DirectoryObject('directory'))
+
     def test_descriptor_from_schema_caster(self):
         schema = {
             "key": {
-- 
GitLab