[Python-ideas] where statement in Pyret

Terry Reedy tjreedy at udel.edu
Mon Nov 11 02:21:33 CET 2013


On 11/10/2013 5:06 AM, Tarek Ziadé wrote:
> Le 11/10/13 11:00 AM, Markus Unterwaditzer a écrit :
>> While it is a nice idea, i don't think this feature deserves its own
>> syntax.

To put it another way, we already have syntax support for testing: 
assert, which is sugar for conditional stateements, but with extra 
features; and functions, which are executed when called.

Like most suggested new keywords, 'where' is certain to by in use 
already as an identifier. So we need a really good reason, with no 
better alternative, to make it a keyword.

 >> [test_xxx functions]

> yes, that's what we all already do: tests in test_xxx functions.
 > And the adopted convention is to have the tests in dedicated
 > tests modules, which defeats the benefit of having
> real isolated unit tests just by the function code.

As others have noted, one big reason for the convention is that testing 
class methods usually requires big chunks of code that are better 
isolated in another file. However, the convention is not a rule, and for 
pure module-level functions that run in isolation, one is free to 
include tests in the doc string or just after. See example below.

> And even if we place the test function just besides the tested function,
> Python will not make any distinction : they are both just functions.

Functions are fine. Distinction is easily done by an obvious name 
convention.

> Having the ability to distinguish tests and regular code at the language
> level has benefits like the ability to ignore tests when you run the app in
> production etc.

Functions only run when called.

For my book, most example code consists of classical functions. For 
these, I am doing the following, adapted for your sum example. For 
didactic reasons, I like having the tests immediately follow the 
function code; the input-output pairs serve as testable documentation. 
(This code does not run at the moment as I am midstream in changing the 
test module.) The first and last statements are boilerplate that is part 
of a _template.py file.

----
from xploro.test import main, ftest

def sum_rec(seq):
   if seq:
     return seq[0] + sum_rec(seq[1:])
   else:
     return 0

def sum_for(seq):
   ret = 0
   for num in seq:
     ret += num
   return ret

def test_sum():
   ftest((sum_rec, sum_for), (([], 0), ([1], 1), ([1,2,3], 6),) )

if __name__ == '__main__':
   main()
----

ftest calls each function with each input of the input-output pairs and 
checks that the function output matches the output given.
main scans globals() for functions named 'test_xxx' and calls them.

Anyway, I prefer the above to the 'where' suggestion.

-- 
Terry Jan Reedy




More information about the Python-ideas mailing list