[Python-ideas] [Brainstorm] Testing with Documented ABCs

James Lu jamtlu at gmail.com
Sat Dec 8 16:27:13 EST 2018


> Interesting. In the thread you linked on DBC, it seemed like Steve
D'Aprano and David Mertz (and possibly others) were put off by the
verbosity and noisiness of the decorator-based solution you provided with
icontract (though I think there are ways to streamline that solution). It
seems like syntactic support could offer a more concise and less noisy
implementation.

Btw, it would be relatively easy to create a parser for Python. Python
doesn't have any crazy grammar constructs like the lexer hack
<https://en.wikipedia.org/wiki/The_lexer_hack> AFAIK. I'm imagining using
Bison:
1. convert python's grammar (
https://github.com/python/cpython/blob/master/Lib/lib2to3/Grammar.txt) to
Bison format.
2. write a lexer to parse tokens and convert indentation to indent/dedent
tokens.
3. extend the grammar however you want it. Call these custom AST nodes
"contract nodes."
4. create a simple AST, really an annotated parse tree. I think we can use
a simple one that's a bunch of nested lists:

["for_stmt", "for i in range(10):",
[
 ["exprlist", "i", [ ... ]],
 ["testlist", "range(10)", [ ... ]]
]]
# ["node_type", "<source code>", <grammar nodes contained inside the for
stmt>]

The AST can be made more detailed on an as-needed basis.
5. traverse the AST, and "rewrite" the the AST by pasting traditional
python AST nodes where contract nodes are.

This example from the Babel handbook may help if you have trouble
understanding what this step means.
https://github.com/jamiebuilds/babel-handbook/blob/master/translations/en/plugin-handbook.md#toc-writing-your-first-babel-plugin


6. turn the AST back into python source. Since we're storing the source
code from the beginning, this should be fairly easy. (Bison lets your lexer
tell the parser the line and column numbers of each token.)

---

I made a joke language with Bison once, it's really flexible and
well-suited for this kind of task. This 6-step p
Tip: I found Bison's C++ mode too complicated, so I used it in C mode with
the C++ Standard Library and C++ references enabled.

---
I'm interested, what contract-related functionality do you think Python's
existing syntax is inadequate for? You could look into using with
statements and a python program that takes the AST and snips
contract-related with statements to produce optimized code, though I
suppose that's one step below the custom-parser method.

On Wed, Nov 28, 2018 at 3:29 PM Abe Dillon <abedillon at gmail.com> wrote:

> [Marko Ristin-Kaufmann]
>>
>> Have you looked at the recent discussions regarding design-by-contract on
>> this list
>
>
> I tried to read through them all before posting, but I may have missed
> some of the forks. There was a lot of good discussion!
>
> [Marko Ristin-Kaufmann]
>
>> You might want to have a look at static checking techniques such as
>> abstract interpretation. I hope to be able to work on such a tool for
>> Python in some two years from now. We can stay in touch if you are
>> interested.
>
>
> I'll look into that! I'm very interested!
>
> [Marko Ristin-Kaufmann]
>
>> Re decorators: to my own surprise, using decorators in a larger code base
>> is completely practical including the  readability and maintenance of the
>> code. It's neither that ugly nor problematic as it might seem at first look.
>
>
> Interesting. In the thread you linked on DBC, it seemed like Steve
> D'Aprano and David Mertz (and possibly others) were put off by the
> verbosity and noisiness of the decorator-based solution you provided with
> icontract (though I think there are ways to streamline that solution). It
> seems like syntactic support could offer a more concise and less noisy
> implementation.
>
> One thing that I can get on a soap-box about is the benefit putting the
> most relevant information to the reader in the order of top to bottom and
> left to right whenever possible. I've written many posts about this. I
> think a lot of Python syntax gets this right. It would have been easy to
> follow the same order as for-loops when designing comprehensions, but
> expressions allow you some freedom to order things differently, so now
> comprehensions read:
>
> squares = ...
> # squares is
>
> squares = [...
> # squares is a list
>
> squares = [number*number...
> # squares is a list of num squared
>
> squares = [number*number for num in numbers]
> # squares is a list of num squared 'from' numbers
>
> I think decorators sort-of break this rule because they can put a lot of
> less important information (like, that a function is logged or timed)
> before more important information (like the function's name, signature,
> doc-string, etc...). It's not a huge deal because they tend to be
> de-emphasized by my IDE and there typically aren't dozens of them on each
> function, but I definitely prefer Eiffel's syntax
> <https://www.eiffel.com/values/design-by-contract/introduction/> over
> decorators for that reason.
>
> I understand that syntax changes have an very high bar for very good
> reasons. Hillel Wayne's PyCon talk got me thinking that we might be close
> enough to a really great solution to a wide variety of testing problems
> that it might justify some new syntax or perhaps someone has an idea that
> wouldn't require new syntax that I didn't think of.
>
> [Marko Ristin-Kaufmann]
>
>> Some of the aspects we still haven't figured out are: how to approach
>> multi-threading (locking around the whole function with an additional
>> decorator?) and granularity of contract switches (right now we use
>> always/optimized, production/non-optimized and teating/slow, but it seems
>> that a larger system requires finer categories).
>
>
> Yeah... I don't know anything about testing concurrent or parallel code.
>
> On Wed, Nov 28, 2018 at 1:12 AM Marko Ristin-Kaufmann <
> marko.ristin at gmail.com> wrote:
>
>> Hi Abe,
>>
>> I've been pulling a lot of ideas from the recent discussion on design by
>>> contract (DBC), the elegance and drawbacks
>>> <https://bemusement.org/doctests-arent-code> of doctests
>>> <https://docs.python.org/3/library/doctest.html>, and the amazing talk
>>> <https://www.youtube.com/watch?v=MYucYon2-lk> given by Hillel Wayne at
>>> this year's PyCon entitled "Beyond Unit Tests: Taking your Tests to the
>>> Next Level".
>>>
>>
>> Have you looked at the recent discussions regarding design-by-contract on
>> this list (
>> https://groups.google.com/forum/m/#!topic/python-ideas/JtMgpSyODTU
>> and the following forked threads)?
>>
>> You might want to have a look at static checking techniques such as
>> abstract interpretation. I hope to be able to work on such a tool for
>> Python in some two years from now. We can stay in touch if you are
>> interested.
>>
>> Re decorators: to my own surprise, using decorators in a larger code base
>> is completely practical including the  readability and maintenance of the
>> code. It's neither that ugly nor problematic as it might seem at first look.
>>
>> We use our https://github.com/Parquery/icontract at the company. Most of
>> the design choices come from practical issues we faced -- so you might want
>> to read the doc even if you don't plant to use the library.
>>
>> Some of the aspects we still haven't figured out are: how to approach
>> multi-threading (locking around the whole function with an additional
>> decorator?) and granularity of contract switches (right now we use
>> always/optimized, production/non-optimized and teating/slow, but it seems
>> that a larger system requires finer categories).
>>
>> Cheers Marko
>>
>>
>>
>> _______________________________________________
> Python-ideas mailing list
> Python-ideas at python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20181208/cd5f3340/attachment.html>


More information about the Python-ideas mailing list