The following code is part of a real estate data processing API.It is being invoked by several modules of a software that translates real estate data in-between different formats (ORM models, DOMs, JSON objects, CSV records, etc).I'd like to have feedback on general code style and possible improvements of the data parsing functions and the Factory class.Factories library to provide data conversionfunctions and an abstract base factory.from datetime import datetime__all__ = [    'BOOL_STRINGS',    'DATE_FORMAT',    'BuildError',    'bool_to_str',    'float_to_decimal',    'parse_int',    'parse_float',    'parse_decimal',    'parse_bool',    'parse_str',    'parse_date',    'Factory']BOOL_STRINGS = {    '1': True, 'T': True, 'TRUE': True, 'Y': True, 'YES': True, 'J': True,    'JA': True, 'W': True, 'WAHR': True, '0': False, 'F': False,    'FALSE': False, 'FALSCH': False, 'N': False, 'NO': False, 'NEIN': False}DATE_FORMAT = '%Y-%m-%d'class BuildError(Exception):    Indicates an error while building inside a Factory.    BuildErrors should always be handled within the superordinate factory.    If a BuildError occurs inside a root factory and cannot be resolved,    a ConversionError should be risen from it and forwarded to the respective    Interface rather than the BuildError itself.        def __init__(self, target=None):        Sets an optional target, which failed        to build and derives a message from it.                if target is not None:            if isinstance(target, str):                msg = target            else:                self.target = target                msg = 'Error building: {}.'.format(str(target))        else:            msg = None        super().__init__(msg)def bool_to_str(val, default=None, true='true', false='false'):    Converts a boolean value into a string    representation defined by @true and @false.    If @val is None, None will be returned unless @default is boolean,    in which case @true respectively @false will be returned.        if val is None:        if default is True:            return true        elif default is False:            return false        return default    elif val:        return true    return falsedef float_to_decimal(val, digits=2, default=None):    Converts a float value into a decimal string.    If @val is None, @default will be returned.        if val is not None:        return '{{0:.{}f}}'.format(digits).format(val)    return defaultdef parse_int(val, default=None, rnd=False):    Tries to convert the given value into an integer or    returns @default on failure.    If @val is a float, it may be rounded by setting @rnd to True.        if rnd:        try:            return round(val)        except (TypeError, ValueError):            return default    else:        try:            return int(val)        except (TypeError, ValueError):            return defaultdef parse_float(val, default=None):    Tries to convert the given value into a float or    returns @default on failure.        try:        return float(val)    except ValueError:        try:            val = val.replace(',', '.')        except (AttributeError, TypeError, ValueError):            return default        else:            try:                return float(val)            except ValueError:                return default    except TypeError:        return defaultdef parse_decimal(val, digits=2, default=None):    Tries to convert the given value into a decimal string or    returns @default on failure.        return float_to_decimal(        parse_float(val, default=None), digits=digits, default=default)def parse_bool(val, default=None):    Tries to convert the given value into a boolean or    returns @default on failure.        if val in (True, False) or isinstance(val, (float, int)):        return bool(val)    return BOOL_STRINGS.get(str(val).upper(), default)def parse_str(val, default=None, minlen=None, maxlen=None, crop=True):    Tries to convert the given value into a string or    returns @default on failure.    Optionally, @minlen and @maxlen constraints of the    resulting string may be specified.    If so, the resulting string will be cropped to the maximum    length if it exceeds it unless @crop is False-ish.    If @crop is a string, the resulting cropped string    will be terminated with it.        if val is None:        return default    else:        string = str(val)        if not minlen and not maxlen:            return string        length = len(string)        if minlen is None or length >= minlen:            if maxlen is None or length <= maxlen:                return string            if crop:                if isinstance(crop, str):                    return string[0:maxlen - len(crop)] + crop                return string[0:maxlen]        return defaultdef parse_date(val, default=None, frmt=DATE_FORMAT):    Tries to parse a date from a given    value and returns @default on failure.        try:        return datetime.strptime(val, frmt)    except (TypeError, ValueError):        return defaultclass Factory():    A basic, abstract factory to build (real estate) data.    def __init__(self, master):        Initializes the factory from its master.        @master may be a superordinate Factory or an Interface.                self.logger = master.logger.inherit(self.__class__.__name__)        self.temporary_data_context = master.temporary_data_context    def __call__(self, *args, **kwargs):        Redirects to the factory's build method.        This method should be used to invoke the Factory's build()        method instead of calling it directly since Factory should        behave like a simple function.                return self.build(*args, **kwargs)    def mktemp(self, mode='w+b', encoding=None, newline=None, suffix=):        Delegates the temporary file creation to        the temporary data context.                return self.temporary_data_context.mktemp(            mode=mode, encoding=encoding, newline=newline, suffix=suffix)    def mkdtemp(self, suffix=''):        Delegates the temporary directory creation to        the temporary data context.                return self.temporary_data_context.mkdtemp(suffix=suffix)    def build(self, *_, **__):        Abstract template for the build method.        raise NotImplementedError()
Factory module to convert DOM / ORM data structures
python;python 3.x;interface;abstract factory