
On 01/25/2016 03:34 PM, Steven D'Aprano wrote:
On Wed, Jan 20, 2016 at 05:04:21PM -0800, Guido van Rossum wrote:
On Wed, Jan 20, 2016 at 4:10 PM, Steven D'Aprano wrote: [...]
(I'm saving my energy for Eiffel-like require/ensure blocks *wink*).
Now you're making me curious.
Okay, just to satisfy your curiosity, and not as a concrete proposal at this time, here is a sketch of the sort of thing Eiffel uses for Design By Contract.
Each function or method has an (optional, but recommended) pre-condition and post-condition. Using a hybrid Eiffel/Python syntax, here is a toy example:
class Lunch: def __init__(self, arg): self.meat = self.spam(arg)
def spam(self, n:int=5): """Set the lunch meat to n servings of spam.""" require: # Assert the pre-conditions of the method. assert n >= 1 ensure: # Assert the post-conditions of the method. assert self.meat.startswith('Spam') if ' ' in self.meat: assert ' spam' in self.meat # main body of the method, as usual serves = ['spam']*n serves[0] = serves.title() self.meat = ' '.join(serves)
I like that syntax. Currently, something not too ugly would be to use descriptors -- something like: from dbc import require, ensure class Frobnigate(object): @require def spammer(self, desc): desc.assertInRange(arg1, 0, 99) @spammer def _spammer(self, arg1, arg2): return arg1 // arg2 + arg1 @spammer.ensure def spammer(self, desc, res): if desc.arg2 % 2 == 1: desc.assertEqual(res % 2, 1) else: desc.assertEqual(res % 2, 0) @ensure def egger(self, desc, res): desc.assertIsType(res, str) @egger def _egger(self, egg_type): 'scrambled, poached, boiled, etc' return egg_type Where 'desc' in the above code is 'self' for the descriptor so saved arguments could be accessed, etc. I put a leading underscore on the body so it could be kept separate and more easily subclassed without losing the DBC portions. If 'require' is not needed, one can use 'ensure'; both create the DBC object which would take care of calling any/all requires, then the function, then any/all ensures, and also grabbing and saving the function signature and actual parameters. -- ~Ethan~