Source code for PyPoE.shared.config.validator

"""
Additional validators 

Overview
===============================================================================

+----------+------------------------------------------------------------------+
| Path     | PyPoE/shared/config/validator.py                                 |
+----------+------------------------------------------------------------------+
| Version  | 1.0.0a0                                                          |
+----------+------------------------------------------------------------------+
| Revision | $Id: d9d1759ffa17c6e6a8716007ce6e18047e73bc73 $                  |
+----------+------------------------------------------------------------------+
| Author   | Omega_K2                                                         |
+----------+------------------------------------------------------------------+

Description
===============================================================================

Additional validators for configobj and validate.

Validator Function Generators
-------------------------------------------------------------------------------

.. autoclass:: IntEnumValidator

  .. automethod:: __call__

Validator Functions
-------------------------------------------------------------------------------

.. autofunction:: is_file

.. autofunction:: is_directory

Agreement
===============================================================================

See PyPoE/LICENSE
"""

# =============================================================================
# Imports
# =============================================================================

# Python
import os
from enum import IntEnum

# 3rd Party
from validate import ValidateError, is_boolean

# =============================================================================
# Globals
# =============================================================================

__all__ = ['IntEnumValidator', 'is_directory', 'is_file', 'functions']


# =============================================================================
# Classes
# =============================================================================


[docs]class IntEnumValidator(object): """ Class to create a dynamic validator for IntEnum classes """
[docs] def __init__(self, enum, default=None): """ Parameters ---------- enum : :py:class:`enum.IntEnum` base enum class for this validator default : :py:class:`enum.IntEnum` | int | None default attribute of the enum Raises ------ TypeError if enum is not an :py:class:`enum.IntEnum` class TypeError if default parameter is of invalid type """ if not issubclass(enum, IntEnum): raise TypeError('enum must be an IntEnum subclass') self._enum = enum if default is None: self._default = None elif isinstance(default, enum): self._default = default elif isinstance(default, int): self._default = enum(int) else: raise TypeError('default must be a subtype of default') self._default = None
def _get_enum_from_val(self, value): """ Parameters ---------- value : object the value to pass to the enum class from class creation Returns ------- IntEnum IntEnum instance based on the class upon class creation Raises ------ ValidateError if the the value isn't a member of the IntEnum class """ try: return self._enum(value) except ValueError: raise ValidateError( '%s The value is not accepted by the enum.' % self._enum.__name__ )
[docs] def __call__(self, value): """ Parameters ---------- value : object The value to validate Returns ------- IntEnum the int enum instance if successfully validated or None Raises ------ ValidateError if the the value can't be validated """ if isinstance(value, str): try: value = int(value) except ValueError: # If the value was stored, it will be stored as # MyEnum.attribute # # This will get rid of the class portion for casting if present if value.startswith(self._enum.__name__ + '.'): value = value[len(self._enum.__name__) + 1:] try: value = getattr(self._enum, value) except AttributeError: raise ValidateError( 'The value is neither an integer or a valid %s ' \ 'attribute' % self._enum.__name__ ) else: value = self._get_enum_from_val(value) elif isinstance(value, int): value = self._get_enum_from_val(value) elif value is None: return self._default else: raise ValidateError('Invalid type') return value
# ============================================================================= # Functions # ============================================================================= def _exists(value, exists): if not isinstance(exists, bool): # Raises VdtTypeError on fail exists = is_boolean(exists) if exists and not os.path.exists(value): raise ValidateError('Path "%s" does not exist.' % value)
[docs]def is_file(value, *args, exists=True, allow_empty=False, **kwargs): """ Checks whether the value is a valid file path (and optionally whether it exists). Parameters ---------- value : object The value to validate exists : bool whether the file is required to exist to pass the validation check allow_empty : bool whether empty strings are allowed Returns ------- IntEnum the int enum instance if successfully validated or None Raises ------ ValidateError if the the value can't be validated """ if allow_empty and value == '': return '' else: _exists(value, exists) if not os.path.isfile(value): raise ValidateError('"%s" is not a file.' % value) return value
[docs]def is_directory(value, *args, exists=True, allow_empty=False, **kwargs): """ Checks whether the value is a valid directory path (and optionally whether it exists). Parameters ---------- value : object The value to validate exists : bool whether the directory is required to exist to pass the validation check allow_empty : bool whether empty strings are allowed Returns ------- IntEnum the int enum instance if successfully validated or None Raises ------ ValidateError if the the value can't be validated """ if allow_empty and value == '': return '' else: _exists(value, exists) if not os.path.isdir(value): raise ValidateError('"%s" is not a directory.' % value) return value
# ============================================================================= # Globals # ============================================================================= functions = { 'is_file': is_file, 'is_directory': is_directory, }