Formatter

MergedOptionStringFormatter is provided as a base class for creating a special formatter that can format strings using a MergedOptions object.

from delfick_error import DelfickError

class BadOptionFormat(DelfickError): pass

class MyFormatter(MergedOptionStringFormatter):
    def get_string(self, key):
        if key not in self.all_options:
            kwargs = {}
            if len(self.chain) > 1:
                kwargs['source'] = Meta(self.all_options, self.chain[-2]).source
            raise BadOptionFormat("Can't find key in options", key=key, chain=self.chain, **kwargs)

        return super(MyFormatter, self).get_string(key)

    def special_get_field(self, value, args, kwargs, format_spec=None):
        if format_spec in ("env", ):
            return value, ()

        if value in self.chain:
            raise BadOptionFormat("Recursive option", chain=self.chain + [value])

    def special_format_field(self, obj, format_spec):
        if format_spec == "env":
            return "${{{0}}}".format(obj)

m = MergedOptions.using({"a": {"b": 3}, "c": 5})
formatted = MyFormatter(m, "", "a.b: {a.b} and c={c}").format()
assert formatted == "a.b: 3 and c=5"

Instance Methods

class option_merge.formatter.MergedOptionStringFormatter(all_options, option_path, chain=None, value=<class 'option_merge.formatter.NotSpecified'>)

Resolve format options into a MergedOptions dictionary

format()

Format our option_path into all_options

get_string(key)

Get a string from all_options

it is recommended you override this method and raise an error if the key does not exist in self.all_options..

special_format_field(obj, format_spec)

Must be implemented

In this function you match against format_spec and return either a formatted version of obj or None.

class MyFormatter(MergedOptionStringFormatter):
    def special_get_field(self, value, args, kwargs, format_spec=None):
        if format_spec == "plus_one":
            return value, ()

    def special_format_field(obj, format_spec):
        if format_spec == "plus_one":
            return int(obj) + 1

m = MergedOptions.using({"a": 3})
formatted = MyFormatter(m, "", "{a:plus_one}").format()
assert formatted == "4"
special_get_field(value, args, kwargs, format_spec=None)

Must be implemented

In this function it is recommended you do something similar to:

if value in self.chain:
    raise ValueError("Recursive option")

But raise a more meaningful error!

You may also return (value, ()) if format_spec is a custom format.

with_option_path(value)

Clone this instance with the new value as option_path and no override value