
"Phillip J. Eby" <pje@telecommunity.com> writes:
I agree with the need to put information about a method near the definition, but I don't think that we need a separate syntax specifically for function attributes. I think that with PEP 318 or some variant thereof, it is trivial to create an 'attrs(foo=bar, baz=spam)' function that can be used as a decorator, eg. in conjunction with classmethod.
To be honest, the *only* serious reason for any of this syntax (PEP 318, something for attributes, whatever) is to keep metadata near the definition (or at least, the def statement, rather than after the code...) I like Michael Hudson's variation on PEP 318, def f() [mod1, mod2]: pass It's minimal, flexible, and has an implementation. The downsides that I see are: 1. It doesn't help with properties. To be honest, I don't see this as much of an issue, as properties are a very different beast (they effectively combine multiple functions in one). People have demonstrated clever hacks to make properties possible, which leads me nicely to... 2. It's possibly *too* flexible. The temptation to define clever hacks may be just a little high. The example of attrs() mentioned above is a good example. It satisfies a real need, it's simple, and it's easy to implement via the [...] syntax. But is it really the best way of handling function attributes? I really don't know, without trying it out. And that leads me onto... 3. It's almost impossible to tell whether it will look right in practice, without implementing it and trying it out. And once that happens, it'll probably never get removed, even if it's *not* the right answer. The canonical function modifier is classmethod (or staticmethod), and for that, Michael's syntax def f(...) [classmethod]: pass looks great. My canonical case for function attributes comes from the parser Spark, which (mis-)uses docstrings to contain the grammar rule for which the function is an action: def p_expr_term(self, args): ''' expr ::= expr + term term ::= term * factor ''' return AST(type=args[1], left=args[0], right=args[2]) To me, this certainly *isn't* going to work with something like attrs() - imagine def p_expr_term(self, args) [attrs( rule=''' expr ::= expr + term term ::= term * factor ''')]: return AST(type=args[1], left=args[0], right=args[2]) Yuk. The current function attribute syntax def p_expr_term(self, args): return AST(type=args[1], left=args[0], right=args[2]) p_expr_term.rule = ''' expr ::= expr + term term ::= term * factor ''' looks better than that, IMHO. I'm sorry, this rambled on a bit. I think that, in summary, my points are: * My preferred solution for PEP 318 is Michael Hudson's patch. * It may be too general, in tempting people to mis-use the feature in inappropriate ways (but what the heck, anything can be misused, at some level). * I don't think there's an obvious solution for function attributes yet. * I think properties are another unsolved problem. It's also interesting to note that classmethod/staticmethod and properties get used in spite of the lack of syntactic support, whereas function attributes generally don't seem to. I'm not quite sure what this implies about the usefulness of function attributes... Hope this was useful, Paul -- This signature intentionally left blank