Exemple #1
0
 def test_get_items_with_key_prefix_from_sequence(self):
     items = [
         ('a.a', 1), ('a.b', 2),
         ('b.a', 1), ('b.b', 2),
     ]
     items_with_prefix = util.get_items_with_key_prefix(items, 'a.')
     expected = [('a', 1), ('b', 2)]
     self.assertEqual(items_with_prefix, expected)
Exemple #2
0
 def test_get_items_with_key_prefix(self):
     items = {
         'a.a': 1, 'a.b': 2,
         'b.a': 1, 'b.b': 2,
     }
     items_with_prefix = util.get_items_with_key_prefix(items, 'a.')
     expected = {'a': 1, 'b': 2}
     self.assertEqual(items_with_prefix, expected)
Exemple #3
0
 def test_get_items_with_key_prefix_from_sequence(self):
     items = [
         ('a.a', 1),
         ('a.b', 2),
         ('b.a', 1),
         ('b.b', 2),
     ]
     items_with_prefix = util.get_items_with_key_prefix(items, 'a.')
     expected = [('a', 1), ('b', 2)]
     self.assertEqual(items_with_prefix, expected)
Exemple #4
0
 def test_get_items_with_key_prefix(self):
     items = {
         'a.a': 1,
         'a.b': 2,
         'b.a': 1,
         'b.b': 2,
     }
     items_with_prefix = util.get_items_with_key_prefix(items, 'a.')
     expected = {'a': 1, 'b': 2}
     self.assertEqual(items_with_prefix, expected)
Exemple #5
0
def parse_settings(settings, conversion_map={}, defaults={}, required=(),
                   prefix=None, strip_prefix=True):
    """Convert the values of ``settings``.

    To convert only a subset of the settings, pass ``prefix``; only the
    settings with a key matching ``prefix`` will be returned (see
    :func:`get_items_with_key_prefix` for details).

    Settings passed via ``defaults`` will be added if they're not
    already present in ``settings`` (and they'll be converted too).

    Required fields can be listed in ``required``. If any required
    fields are missing, a ``ValueError`` will be raised.

    For each setting...

        - If the key for the setting specifies a converter via the
          ``(converter)key`` syntax, the specified converter will be
          called to convert its value (the converter must be a builtin
          or a function from :mod:`tangled.converters`).

        - If the key for the setting is in ``conversion_map``, the
          function it maps to will be used to convert its value.

        - If the special key '*' is in ``conversion_map``, the function
          it maps to will be used to convert the setting.

        - Otherwise, the value will be used as is (i.e., as a string).

    The original ``settings`` dict will not be changed.

    """
    parsed_settings = {}
    if prefix is not None:
        settings = get_items_with_key_prefix(settings, prefix, strip_prefix)
    for k, v in defaults.items():
        settings.setdefault(k, v)
    for k, v in settings.items():
        if isinstance(v, str):
            match = CONVERTER_KEY_RE.search(k)
            if match:
                k = match.group('k')
                converter = match.group('converter')
                converter = converters.get_converter(converter)
            elif k in conversion_map:
                converter = converters.get_converter(conversion_map[k])
            elif '*' in conversion_map:
                converter = converters.get_converter(conversion_map['*'])
            else:
                converter = lambda v: v
            v = converter(v)
        parsed_settings[k] = v
    if required:
        check_required(parsed_settings, required)
    return parsed_settings
Exemple #6
0
    def get_settings(self, settings=None, prefix='tangled.app.', **kwargs):
        """Get settings with names that start with ``prefix``.

        This is a front end for
        :func:`tangled.util.get_items_with_key_prefix` that sets
        defaults for ``settings`` and ``prefix``.

        By default, this will get the settings from ``self.settings``
        that have a ``'tangled.app.'`` prefix.

        Alternate ``settings`` and/or ``prefix`` can be specified.

        """
        if settings is None:
            settings = self.settings
        return get_items_with_key_prefix(settings, prefix, **kwargs)
Exemple #7
0
    def get_settings(self, settings=None, prefix='tangled.app.', **kwargs):
        """Get settings with names that start with ``prefix``.

        This is a front end for
        :func:`tangled.util.get_items_with_key_prefix` that sets
        defaults for ``settings`` and ``prefix``.

        By default, this will get the settings from ``self.settings``
        that have a ``'tangled.app.'`` prefix.

        Alternate ``settings`` and/or ``prefix`` can be specified.

        """
        if settings is None:
            settings = self.settings
        return get_items_with_key_prefix(settings, prefix, **kwargs)
Exemple #8
0
def parse_settings(settings, defaults={}, required=(), extra={}, prefix=None, strip_prefix=True):
    """Convert settings values.

    All settings values should be JSON-encoded strings. For example::

        debug = true
        factory:object = "tangled.web:Application"
        something:package.module:SomeClass = "value"

    Settings passed via ``defaults`` will be added if they're not
    already present in ``settings``.

    To convert only a subset of the settings, pass ``prefix``; only the
    settings with a key matching ``prefix`` will be returned (see
    :func:`get_items_with_key_prefix` for details).

    Required fields can be listed in ``required``. If any required
    fields are missing, a ``ValueError`` will be raised.

    For each setting:

        - If the key specifies a type using ``key:type`` syntax, the
          specified type will be used to parse the value. The type can
          refer to any callable that accepts a single string.

          If the type is specified as ``object``, :func:`.load_object()`
          will be used to parse the value.

          The ``:type`` will be stripped from the key.

        - Otherwise, the value will be passed to ``json.loads()``.

    The original ``settings`` dict will not be modified.

    """
    loads = json.loads
    parsed_settings = {}
    parsed_settings.update(defaults)

    if prefix is not None:
        settings = get_items_with_key_prefix(settings, prefix, strip_prefix)

    for key, value in settings.items():
        value = value.strip()
        if not value:
            value = None
        else:
            key, *rest = key.split(':', 1)
            try:
                value = loads(value)
            except ValueError:
                message = 'Could not parse JSON value for {key}'.format(key=key)
                raise ValueError(message) from None
            if rest:
                kind = get_type(rest[0])
                value = kind(value)
        parsed_settings[key] = value

    parsed_settings.update(extra)

    if required:
        check_required(parsed_settings, required)

    return parsed_settings
Exemple #9
0
def parse_settings(settings,
                   defaults={},
                   required=(),
                   extra={},
                   prefix=None,
                   strip_prefix=True):
    """Convert settings values.

    All settings values should be JSON-encoded strings. For example::

        debug = true
        factory:object = "tangled.web:Application"
        something:package.module:SomeClass = "value"

    Settings passed via ``defaults`` will be added if they're not
    already present in ``settings``.

    To convert only a subset of the settings, pass ``prefix``; only the
    settings with a key matching ``prefix`` will be returned (see
    :func:`get_items_with_key_prefix` for details).

    Required fields can be listed in ``required``. If any required
    fields are missing, a ``ValueError`` will be raised.

    For each setting:

        - If the key specifies a type using ``key:type`` syntax, the
          specified type will be used to parse the value. The type can
          refer to any callable that accepts a single string.

          If the type is specified as ``object``, :func:`.load_object()`
          will be used to parse the value.

          The ``:type`` will be stripped from the key.

        - Otherwise, the value will be passed to ``json.loads()``.

    The original ``settings`` dict will not be modified.

    """
    loads = json.loads
    parsed_settings = {}
    parsed_settings.update(defaults)

    if prefix is not None:
        settings = get_items_with_key_prefix(settings, prefix, strip_prefix)

    for key, value in settings.items():
        value = value.strip()
        if not value:
            value = None
        else:
            key, *rest = key.split(':', 1)
            try:
                value = loads(value)
            except ValueError:
                message = 'Could not parse JSON value for {key}'.format(
                    key=key)
                raise ValueError(message) from None
            if rest:
                kind = get_type(rest[0])
                value = kind(value)
        parsed_settings[key] = value

    parsed_settings.update(extra)

    if required:
        check_required(parsed_settings, required)

    return parsed_settings