From 27a17262544786b8f2df149679929121f9ead7d7 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:09:47 +0200 Subject: [PATCH] v2.16 added Directory --- CHANGELOG.md | 1 + docs/configuration/schema.rst | 28 +++++++++---- satella/__init__.py | 2 +- satella/configuration/schema/__init__.py | 3 +- satella/configuration/schema/basic.py | 52 +++++++++++++++++++++++- 5 files changed, 74 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index df366856..25e15965 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,4 @@ # v2.16 * changed semantics of `wrap_future` +* added `Directory` to schema configuration diff --git a/docs/configuration/schema.rst b/docs/configuration/schema.rst index ae14194c..ef83f298 100644 --- a/docs/configuration/schema.rst +++ b/docs/configuration/schema.rst @@ -17,6 +17,14 @@ you should instantiate a Descriptor. Descriptor reflects how your config is nest .. autoclass:: satella.configuration.schema.File +.. autoclass:: satella.configuration.schema.FileObject + :members: + +.. autoclass:: satella.configuration.schema.Directory + +.. autoclass:: satella.configuration.schema.DirectoryObject + :members: + .. autoclass:: satella.configuration.schema.basic.FileObject .. autoclass:: satella.configuration.schema.IPv4 @@ -71,15 +79,17 @@ Note that providing a short-hand, string type is impossible for descriptors that Available string types are: -* **int** - Integer -* **str** - String -* **list** - List -* **dict** - Dict -* **ipv4** - IPv4 -* **any** - Descriptor -* **bool** - Boolean -* **union** - Union -* **caster** - Caster +* **int** - :class:`~satella.configuration.schema.Integer` +* **str** - :class:`~satella.configuration.schema.String` +* **list** - :class:`~satella.configuration.schema.List` +* **dict** - :class:`~satella.configuration.schema.Dict` +* **ipv4** - :class:`~satella.configuration.schema.IPv4` +* **any** - :class:`~satella.configuration.schema.Descriptor` +* **bool** - :class:`~satella.configuration.schema.Boolean` +* **union** - :class:`~satella.configuration.schema.Union` +* **caster** - :class:`~satella.configuration.schema.Caster` +* **file** - :class:`~satella.configuration.schema.File` +* **dir** - :class:`~satella.configuration.schema.Directory` Lists you define as following diff --git a/satella/__init__.py b/satella/__init__.py index e74eabb2..50a1c84b 100644 --- a/satella/__init__.py +++ b/satella/__init__.py @@ -1 +1 @@ -__version__ = '2.16a1' +__version__ = '2.16' diff --git a/satella/configuration/schema/__init__.py b/satella/configuration/schema/__init__.py index a1f61b57..e1355704 100644 --- a/satella/configuration/schema/__init__.py +++ b/satella/configuration/schema/__init__.py @@ -1,9 +1,10 @@ from .base import CheckerCondition, Descriptor -from .basic import IPv4, Integer, String, Float, Boolean +from .basic import IPv4, Integer, String, Float, Boolean, File, Directory, FileObject, DirectoryObject from .from_json import descriptor_from_dict from .registry import register_custom_descriptor from .structs import Union, List, Dict, Caster, create_key __all__ = ['CheckerCondition', 'Descriptor', 'descriptor_from_dict', 'IPv4', 'Integer', 'String', 'Float', 'Boolean', 'Union', 'List', 'Dict', 'Caster', + 'File', 'FileObject', 'DirectoryObject', 'Directory', 'register_custom_descriptor', 'create_key'] diff --git a/satella/configuration/schema/basic.py b/satella/configuration/schema/basic.py index 5c16bd26..4eff8c35 100644 --- a/satella/configuration/schema/basic.py +++ b/satella/configuration/schema/basic.py @@ -71,7 +71,7 @@ class FileObject: return self.path def __eq__(self, other) -> bool: - return self.path == str(other) + return self.path == str(other) and isinstance(other, FileObject) def __hash__(self) -> int: return hash(self.path) @@ -95,6 +95,37 @@ class FileObject: return open(self.path, mode) +class DirectoryObject: + """ + What you get for values in schema of :class:`~satella.configuration.schema.Directory`. + + This object is comparable and hashable, and is equal to the string of it's path + """ + __slots__ = 'path', + + def __init__(self, path: str): + self.path = path + + def __repr__(self): + return '<Directory object %s>' % (self.path, ) + + def __str__(self): + return self.path + + def __eq__(self, other) -> bool: + return self.path == str(other) and isinstance(other, DirectoryObject) + + def __hash__(self) -> int: + return hash(self.path) + + def get_files(self) -> tp.Iterable[str]: + """ + Return a list of files inside this directory + :return: + """ + return os.listdir(self.path) + + @staticmethod def _make_file(v: str) -> bool: @@ -114,6 +145,25 @@ class File(Descriptor): BASIC_MAKER = _make_file +@staticmethod +def _make_directory(v: str) -> bool: + + if not os.path.isdir(v): + raise ConfigurationValidationError('Expected to find a directory under %s' + % (v,)) + return DirectoryObject(v) + + +@register_custom_descriptor('dir') +class Directory(Descriptor): + """ + This value must be a valid path to a file. The value in your schema will be + an instance of :class:`~satella.configuration.schema.basic.FileObject` + """ + + BASIC_MAKER = _make_directory + + class Regexp(String): """ Base class for declaring regexp-based descriptors. Overload it's attribute REGEXP. Use as -- GitLab