On Tue, 8 Mar 2016 20:26:36 -0800
Mike Orr <sluggos...@gmail.com> wrote:

> On Tue, Mar 8, 2016 at 4:22 PM, Michael Merickel <mmeri...@gmail.com>
> wrote:

> > I think with the advent of montague by Joe Rosenbaugh as well as
> > 12-factor app design I know, personally, that I'm ready to start
> > having a conversation about what to do in this space. PasteDeploy
> > is definitely a point of contention amongst the users of Pyramid
> > and bringing it into core will not be happening. It's already an
> > issue that our CLI tools are dependent on the ini files and I think
> > these are things that everyone wishes were fixed but we've never
> > had a discussion on coming up with a standard solution because
> > everyone has their own use-cases to deal with.  
> Are people using the 12-factor app design widely, particularly the
> part about putting settings in environment variables? I looked into
> doing that but but came up with more problems than advantages:

> 2. Hierarchical namespaces are useful, and INI at least gives you two:
> sections and options. Prefixing envvar keys makes then inconveniently
> long.

> 4. The biggest problem with declarative settings is parsing the text
> values and formatting them, and envvars are no better at this than INI
> settings. (I use FormEncode to validate/convert settings on startup.)

> Still, it would be nice to have something cleaner than INI and
> PasteDeploy in Pyramid's default, but I also don't know what would be
> a good candidate for that.

Raw python literal expressions parsed with ast.literal_eval(),
read from a file.

You can enforce whatever data conventions you like.  Say,
only a dict containing nested dicts or otherwise only constant 
values, no lists or tuples.  (The latter for the sake of example.)

So, no text parsing in the application.  "Arbitrary"
data structures, as allowed, with no nesting limits.

If this is stupid I'd appreciate hearing why.

Sounds fun, but my python-fu is not strong.  Here's
a horrible example:

import ast

def force_literal(node):
    '''Node must be a literal.'''
    if (not isinstance(node, ast.Num)
        and not isinstance(node, ast.Str)
        and not isinstance(node, ast.NameConstant)):
        raise Exception('Not a literal')

def validate_config(st):
    '''Allow only nested dicts, and various literals and constants in
    if isinstance(st, ast.Dict):
        for fieldname, values in ast.iter_fields(st):
            if fieldname == 'keys':
                for value in values:
                for value in values:

def parse_config(conf_str):
    '''Parse a config string, returning a python dict.'''
    st = ast.parse(conf_str)
    if not isinstance(st, ast.Module):
        raise Exception('not a Module')

    mod_children = [node for node in ast.iter_child_nodes(st)]
    if len(mod_children) != 1:
        raise Exception('unknown Module content')
    mod_child = mod_children[0]
    if not isinstance(mod_child, ast.Expr):
        raise Exception('Module does not contain Expr')

    expr_children = [node for node in ast.iter_child_nodes(mod_child)]
    if len(expr_children) != 1:
        raise Exception('unknown Expr content')
    expr_child = expr_children[0]
    if not isinstance(expr_child, ast.Dict):
        raise Exception('Config is not a dict')


    return ast.literal_eval(expr_child)

Since it's python, you could shelve after parsing for speed.
That might introduce security issues unless you have
a separate utility to do the shelving.  (You get
all the horribleness of "compiled" config files,
but maybe somebody likes the trade-off.)


Karl <k...@meme.com>
Free Software:  "You don't pay back, you pay forward."
                 -- Robert A. Heinlein

You received this message because you are subscribed to the Google Groups 
"pylons-devel" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to pylons-devel+unsubscr...@googlegroups.com.
To post to this group, send email to pylons-devel@googlegroups.com.
Visit this group at https://groups.google.com/group/pylons-devel.
For more options, visit https://groups.google.com/d/optout.

Reply via email to