[Python-ideas] Current status of PEP 403 (was Re: peps: Switch back to named functions, since the Ellipsis version degenerated badly)

Nick Coghlan ncoghlan at gmail.com
Fri Feb 24 04:48:32 CET 2012

(switching lists to python-ideas, dropping python-dev and python-checkins)

Context for anyone not following python-checkins: I recently moved PEP
3150 (statement local namespaces) to Withdrawn, rewrote PEP 403 with a
different syntax proposal, retitled it to "Statement local class and
function definitions" and moved it to Deferred.

On Fri, Feb 24, 2012 at 2:37 AM, Jim Jewett <jimjjewett at gmail.com> wrote:
> I understand that adding a colon and indent has its own problems, but
> ... I'm not certain this is better, and I am certain that the desire
> for indentation is strong enough to at least justify discussion in the
> PEP.

Fair point.

The reason for the flat structure is that allowing a full suite screws
with the scoping rules and gets us into the land of insane complexity
that was PEP 3150. A decorator-inspired syntax makes it very clear
(both to the reader and to the compiler) that there's only *one* name
being forward referenced, rather than potentially hiding declarations
of forward references an arbitrary distance from the statement that
uses them. This doesn't actually lose any flexibility, since you can
just make a forward reference to a class instead and use that as your
local namespace (with ordinary attribute access semantics), rather
than the brain-bender that was the proposed scoping rules for PEP
3150's given clause.

The only other alternative syntax would be to use a custom suite
definition that allowed only a single class or function definition
statement, but I think having something that looks like a suite, but
isn't one would be significantly worse than the current proposed
syntax that merely allows a function (or class) definition's implied
local name binding to be overridden with a custom statement.

To (almost*) recreate the effect of an ordinary function definition
with the in statement, you could write:

in f = f
def f():

And a decorated definition like:

def f():

Could (almost*) be expressed as:

in f = deco1(deco2(deco3(f)))
def f():

* The reason for the "almost" caveat is that, given the current PEP
403 semantics, recursive references to f() will resolve differently
for the "in" statement cases - for the in statement, they will resolve
directly to the innermost function definition, while for ordinary
definitions they will be resolved according to the scoping rules for
any name lookup.

This could be an argument in favour of allowing *decorated* function
and class definitions, rather than requiring that they be undecorated
- if decorators are allowed, then recursive references would resolve
directly to the post-decorated version. Alternatively, people could
adopt a convention of prepending an underscore to the actual function
name in cases where it mattered, meaning they would have easy access
to *both* forms of the function (decorated and undecorated):

in f = deco1(deco2(deco3(_f)))
def _f():
    return f, _f  # decorated, undecorated

In either case, whereas an ordinary recursive function definition can
get confused by reassignments in the outer scope, an in-statement
based definition would be truly recursive (via a cell reference) and
hence ignore any subsequent changes in the outer namespace.

Something else the PEP should mention explicitly is that, like
__class__, a class object obviously won't be available while the class
body is being executed. Only methods will be able to refer to the
class by name, just as only methods can use __class__.

Updates to PEP 403 are going to be pretty sporadic until some time
after 3.3 release though - it's still very much in "this is a problem
I am thinking about" territory rather than "this is a language
addition I am proposing" (the latest round of updates were just to
make sure I recorded my latest idea before I forgot about the


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

More information about the Python-ideas mailing list