You could disassemble (import dis) the lambda to biew the names of the lambdas.

@before(lambda self, key, _, length, get: self.length(), self.get(key))

Perhaps you could disassemble the function code and look at all operations or 
accesses that are done to “old.” and evaluate those expressions before the 
function runs. Then you could “replace” the expression.
@post(lambda self, key, old: old.get is None and old.length + 1 ==
self.length())

Either the system would grab old.get and old.length or be greedy and grab 
old.get is None and old.length + 1. It would then replace the old.get and 
old.length with injects that only respond to is None and +1.

Or, a syntax like this 
@post(lambda self, key, old: [old.get(old.key)] is None and [old.self.length() 
+ 1] ==
self.length())

Where the stuff inside the brackets is evaluated before the decorated function 
runs. It would be useful for networking functions or functions that do 
something ephemeral, where data related to the value being accessed needed for 
the expression no longer exists after the function. 

This does conflict with list syntax forever, so maybe either force people to do 
list((expr,)) or use an alternate syntax like one item set syntax { } or double 
set syntax {{ }} or double list syntax [[ ]]. Ditto with having to avoid the 
literals for the normal meaning.

You could modify Python to accept any expression for the lambda function and 
propose that as a PEP. (Right now it’s hardcoded as a dotted name and 
optionally a single argument list surrounded by parentheses.)

I suggest that instead of “@before” it’s “@snapshot” and instead of “old” it’s 
“snapshot”.

Python does have unary plus/minus syntax as well as stream operators (<<, >>) 
and list slicing syntax and the @ operator and operators & and | if you want to 
play with syntax. There’s also the line continuation character for crazy 
lambdas.

Personally I prefer
@post(lambda self, key, old: {{old.self.get(old.key)}} and {{old.self.length() 
+ 1}} ==
self.length())

because it’s explicit about what it does (evaluate the expressions within {{ }} 
before the function runs. I also find it elegant.

Alternatively, inside the {{ }} could be a special scope where locals() is all 
the arguments @pre could’ve received as a dictionary. For either option you can 
remove the old parameter from the lambda. Example:
@post(lambda self, key: {{self.get(key)}} and {{self.length() + 1}} ==
self.length())

Perhaps the convention should be to write {{ expr }} (with the spaces in 
between).

You’d probably have to use the ast module to inspect it instead of the dis 
modul. Then find some way to reconstruct the expressions inside the double 
brackets- perhaps by reconstructing the AST and compiling it to a code object, 
or perhaps by finding the part of the string the expression is located. dis can 
give you the code as a string and you can run a carefully crafted regex on it.
_______________________________________________
Python-ideas mailing list
[email protected]
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to