Are decorators really that different from metaclasses...

Jeff Epler jepler at
Thu Sep 2 04:42:21 CEST 2004

I think it's crazy to change the language so that some of these
functions give NameErrors when called, and others succeed.

    def f():         # Succeeds
        if 1:
            __x__ = None
        return __x__

    def f2():        # Fails (but identical to above, today)
        __x__ = None
        return __x__

    def f3():        # but this one succeeds
        global z
        __x__ = None
        return __x__

    def f4():        # and so does this one
        for __x__ in (None,): pass
        return __x__

    def g():         # Succeeds
        import os as __x__
        return __x__

    def g2():        # Fails (but identical to above, today)
        __x__ = __import__("os")
        return __x__

    def h():         # Succeeds
        class __x__(object): pass
        return __x__
    def h2():        # Fails (but identical to above, today)
        __x__ = type('__x__', (), {})

    def j():         # Succeeds
        def __x__(): pass
        return __x__

    def j2():        # Fails (but identical to above, today)
        __x__ = lambda: None
        return __x__

You complicate the language when you create a new type of assignment
that is special not because of the syntax, but because of the location
in the suite of "def".

You violate the law that most several special statements are expressible
in terms of assignment (import, class, and def in terms of __import__,
type(), and lambda:) or assignment plus looping (for in terms of while +
except + assignment).

You also add a new constraint not expressible directly in the Grammar

What about these?  Are 2/3 of them now to be invalid syntax (and the
remaining gives NameError)?  Or will they all compile, and 2/3 of them
give an exception?

    def k():
        __x__, y = range(2)
        return __x__

    def k2():
        y, __x__ = range(2)
        return __x__

    def k3():
        __y__, __x__ = range(2)
        return __x__

Have you defined what happens in this case (I imagine that 'False' is
the proper output, but I also believe that many would be surprised to
get True)?

    __x__ = False
    def m():
        __x__ = True
        __y__ = __x__ 
    print m.__y__

-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 196 bytes
Desc: not available
URL: <>

More information about the Python-list mailing list