On Wed, May 26, 2021 at 08:58:51AM +0200, Stéfane Fermigier wrote:
For the use cases I have in mind, some kind of context information would need to be passed too, like:
class Customer:
@permissions({"read": USER, "write": MANAGER}) first_name: str
the function primary_key should be called with the class being constructed for it to make sense.
What function primary_key? Never mind, it probably doesn't matter. According to this proposal, that example would be illegal. You have a decorator with no variable. You could write this instead: @permissions({"read": USER, "write": MANAGER}) first_name: str which would be transformed to: first_name:str = permissions('first_name', {"read": USER, "write": MANAGER}) I think that's a minor win in that you don't have to repeat the variable name. Using my counter-proposal for a googly-eyes symbol: first_name:str = permissions(@@, {"read": USER, "write": MANAGER}) I think that's better as it is explicit that an assignment is happening.
Here are some alternatives:
1) Set metadata directly on some magical attribute:
class Customer: __permissions__ = { 'first_name': { READ: ..., WRITE: ... } }
first_name: str
cons: risk of mispelling or forgetting some attributes; lack of locality; how do we deal with inheritance ?
The inheritance question applies equally to the decorator version. [...]
class Customer: first_name: str
@acl({"read": USER, "write": MANAGER}) def meta_first_name(self): pass
I.e. use a method decorator on a dummy function named similarly to the variable (e.g. by prepending some magical prefix).
Good lord. All that trouble to avoid typing the name of the variable as a function argument, and then you still end up typing it in the dummy function name :-( first_name = acl('first_name', {"read": USER, "write": MANAGER}) is *much* clearer and simpler than any of the hacks you have shown, especially the one with the dummy method. Seriously, you end up typing an extra 21 characters plus newlines and indents to avoid typing 'first_name' as a function argument. That's just sad. Thank you for your examples. They suggest to me that: - There are more uses for knowing the assignment target than I expected. - Frameworks go through a huge amount of (unnecessary?) work to avoid writing the name of a varible -- and then end up writing it anyway. - Decorators are a hammer, and some people think that every problem is a nail. - There is good case for having a feature that gives the right-hand side of assignment statements access to the assignment targets as strings. - But I still don't think that decorator syntax is the right solution. -- Steve