Hi Cameron,

Just a word of caution: I made a mistake and badly designed interface to icontract. It will change in the near future from:

@post(lambda arg1, arg2, result: arg1 < result < arg2)

most probably to:

@ensures(lambda P:  P.arg1 < result < P.arg2)

This avoids any name conflicts with "result" if it's in the arguments and also many conflicts with web frameworks which frequently use "post". We will also add snapshotting before the function execution:
@snapshot(lambda P, var2: set(arg2))
@ensures(lambda O, P: P.arg1 < result and result in O.var2)

so that postcondition can deal with state transitions. There are also some other approaches in discussion.

The library name will also need to change. When I started developing it, I was not aware of Java icontract library. It will be probably renamed to "pcontract" or any other suggested better name :)

Please see the github issues for more details and current discussions: https://github.com/Parquery/icontract/issues

On Sun, 30 Sep 2018 at 06:44, Cameron Simpson <cs@cskk.id.au> wrote:
On 30Sep2018 12:17, Chris Angelico <rosuav@gmail.com> wrote:
>At the moment, I'm seeing decorator-based contracts as a clunky
>version of unit tests. We already have "inline unit testing" - it's
>called doctest - and I haven't seen anything pinned down as "hey, this
>is what it'd take to make contracts more viable". Certainly nothing
>that couldn't be done as a third-party package. But I'm still open to
>being swayed on that point.

Decorator based contracts are very little like clunky unit tests to me. I'm
basing my opinion on the icontracts pip package, which I'm going to start
using.

In case you've been looking at something different, it provides a small number
of decorators including @pre(test-function) and @post(test-function) and the
class invariant decorator @inv, with good error messages for violations.

They are _functionally_ like putting assertions in your code at the start and
end of your functions, but have some advantages:

- they're exposed, not buried inside the function, where they're easy to see
  and can be considered as contracts

- they run on _every_ function call, not just during your testing, and get
  turned off just like assertions do: when you run Python with the -O
  (optimise) option. (There's some more tuning available too.)

- the assertions make qualitative statements about the object/parameter state
  in the form "the state is consistent if these things apply";
  tests tend to say "here's a situation, do these things and examine these
  results". You need to invent the situations and the results, rather than
  making general statements about the purpose and functional semantics of the
  class.

They're different to both unit tests _and_ doctests because they get exercised
during normal code execution. Both unit tests and doctests run _only_ during
your test phase, with only whatever test scenarios you have devised.

The difficulty with unit tests and doctests (both of which I use) and also
integration tests is making something small enough to run but big/wide enough
to cover all the relevant cases. They _do not_ run against all your real world
data. It can be quite hard to apply them to your real world data.

Also, all the @pre/@post/@inv stuff will run _during_ your unit tests and
doctests as well, so they get included in your test regime for free.

I've got a few classes which have a selftest method whose purpose is to confirm
correctness of the instance state, and I call that from a few methods at start
and end, particularly those for which unit tests have been hard to write or I
know are inadequately covered (and probably never will be because devising a
sufficient test case is impractical, especially for hard to envisage corner
cases).

The icontracts module will be very helpful to me here: I can pull out the
self-test function as the class invariant, and make a bunch of @pre/@post
assertions corresponding the the method semantic definition.

The flip side of this is that there's no case for language changes in what I
say above: the decorators look pretty good to my eye.

Cheers,
Cameron Simpson <cs@cskk.id.au>
_______________________________________________
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/