[Python-ideas] Statement local functions and classes (aka PEP 3150 is dead, say 'Hi!' to PEP 403)

Nick Coghlan ncoghlan at gmail.com
Mon Oct 17 03:23:54 CEST 2011


On Mon, Oct 17, 2011 at 10:30 AM, Steven D'Aprano <steve at pearwood.info> wrote:
> Either way, out of order execution hurts readability. There's a reason that
> even mathematicians usually define terms before using them.

I think out of order execution hurts readability *most* of the time,
but that not having it is an annoyance most frequently encountered in
the form "Python should have multi-line lambdas". When people hit that
mental break, they're thinking of a problem in terms of splitting a
single operation down into subcomponents rather than building that
statement up via a sequence of steps.

I was thinking argparse might be a potential use case for the new
syntax, and was reminded that it actually has its own somewhat novel
approach to provide a 'declarative' interface: it offers methods that
return 'incomplete' objects, which you then fill in after the fact.

So, for example, instead of constructing a subparser [1] and then
adding the whole thing to the parent parser, you instead write code
like the following:

    # create the top-level parser
    parser = argparse.ArgumentParser(prog='PROG')
    parser.add_argument('--foo', action='store_true', help='foo help')

    # Declare that we're going to be adding subparsers
    subparsers = parser.add_subparsers(help='sub-command help')

    # One of those subparsers will be for the "a" command
    parser_a = subparsers.add_parser('a', help='a help')
    parser_a.add_argument('bar', type=int, help='bar help')

   # And the other will be for the "b" command
   parser_b = subparsers.add_parser('b', help='b help')
   parser_b.add_argument('--baz', choices='XYZ', help='baz help')

[1] http://docs.python.org/library/argparse#argparse.ArgumentParser.add_subparsers

Note, however, that in order to get a declarative API, argparse has
been forced to couple the subparsers to the parent parser - you can't
create subparsers as independent objects and only later attach them to
the parent parser. If argparse offered such an API today, it wouldn't
be declarative any more, since you'd have to completely define a
subparser before you could attach it to the parent parser. PEP 3150
would let the API designer have the best of both worlds, allowing
subparsers to be accepted as fully defined objects without giving up
the ability to have a declarative API:

    # create the top-level parser
    parser = argparse.ArgumentParser(prog='PROG')
    parser.add_argument('--foo', action='store_true', help='foo help')

   # Add a subparser for the "a" command
   parser.add_subparser(parse_a) given:
       parse_a = argparse.ArgumentParser(prog='a')
       parse_a.add_argument('bar', type=int, help='bar help')

   # Add a subparser for the "b" command
   parser.add_subparser(parse_b) given:
       parse_b = argparse.ArgumentParser(prog='b')
       parser_b.add_argument('--baz', choices='XYZ', help='baz help')

(FWIW, I'm glossing over some complications relating to the way
argparse populates 'prog' attributes on subparsers, but hopefully this
gives the general idea of what I mean by a declarative API)

> But for what it's worth, if we end up with this feature, I agree that it
> should introduce a new scope, and the "given" syntax is the nicest I've yet
> seen.

I'm significantly happier with the ideas in PEP 3150 now that I've
reframed them in my own head as: "You know that magic fairy dust we
already use inside the interpreter to support out of order execution
for decorators, comprehensions and generator expressions? Let's give
that a syntax and let people create their own declarative APIs"

Cheers,
Nick.

-- 
Nick Coghlan   |   ncoghlan at gmail.com   |   Brisbane, Australia



More information about the Python-ideas mailing list