[Python-ideas] Contracts in python -- a report & next steps

Stephen J. Turnbull turnbull.stephen.fw at u.tsukuba.ac.jp
Wed Oct 24 22:40:35 EDT 2018


Chris Barker via Python-ideas writes:
 > On Wed, Oct 24, 2018 at 12:57 AM, Chris Angelico <rosuav at gmail.com> wrote:
 > 
 > > For the sake of those of us who REALLY don't feel like diving back
 > > into the extensive threads on this subject, can you please summarize
 > > the benefits of having this in the stdlib rather than as a third-party
 > > library?

 > That being said -- this is analogous to why PEP 484 -- Type Hints was
 > adopted, even though the syntax changes in Python had long been adopted to
 > enable it.

This is historically imprecise, though: function annotations were
adopted with an eye to some form of optional typing.

 > After all, PEP 484 didn't get rollling until Guido got interested
 > in MyPy.

I don't know how much effort Guido put into type hinting himself until
the run-up to PEP 484.  But he has said that type hinting was the
intended use case all along, and he wasn't very sympathetic to
arguments that people had found other uses that conflicted.  That
said, stub files could serve that purpose (with the stub overriding
inline annotations, and a flag to mypy to not check the inlines).

 > That is: the IF folks are going to use DbC in Python, the community
 > is MUCH better off if everyone does it in the same way.

I don't think that's true for icontracts (note, I'm being specific to
the implementation here!) in the same way as for type hints, though.
Type hints are part of the syntax (even though analyzed by a separate
program).  You would really need pragmas (function by function, maybe
even argument by argument) flags to allow use of multiple
type-checkers.  Python never liked pragmas at all (this could change
with Guido's retirement as BDFL, but of course we're all here because
to a great degree we like Guido's taste in such things).

With decorator-based contracts, however, you have a function wrapped
by code generated by a decorator.  It's transparent to the compiler.
I just don't see Marko's "dependency hell" being that big a problem.

Consider receiving a binary module "contraction" using icontracts.
Your project uses bfcontracts (b for banana, f for flavor), also
implemented as a set of decorators.  As far as I can see, to use bf
contracts at top level, all you need to do is

    import icontracts
    icontracts.verify_contracts = True

    # Note: no further mention of icontracts below.
    import bfcontracts
    import contraction
    class inherited(iparent):

        @bfcontracts.require(additional_contract)
        def recontract(old_arg_1, ...):
            return contraction.iparent.recontract(old_arg_1, ...)

This would be annoying, but not impossible.  You can't weaken the
contracts for iparent.recontract as far as I can see in a decorator-
based contract library.  I haven't thought about it, but with a little
bit of trickery it might even be possible in the simple case above to
do

        @bfcontracts.require(additional_contract)
        @bfcontracts.call_with_inherited_contracts(recontract)
        def recontract(old_arg_1, ...):
            pass

It's true that you can't replace the implementation of recontract()
(ie, without calling contractions.iparent.recontract) and preserve the
contracts automatically.  This means that contract implementations
will have to know something about how other implementations (that do
inherit contracts on interfaces rather than function/method
implementation) store such contracts.  This certainly would be worth
standardizing with a dunder attribute or something like that.

 > And the way to make that happen is to put it in the stdlib.

True, but

 > However, I'm not sure it's anywhere near time to actually do that -- before
 > we get there, there needs to be a pretty good community of folks using
 > icontract (or maybe something else?) and ideally some interest from a core
 > developer or two.

+1

 > Is the stdlib being fully typhinted since PEP 484 was added? a quick scan
 > of the PEP didn't seem to mention it at all.

There was discussion about stub hint files for the stdlib, but I
believe it's being implemented outside of the stdlib.  Sorry, don't
have time to check.


-- 
Associate Professor              Division of Policy and Planning Science
http://turnbull.sk.tsukuba.ac.jp/     Faculty of Systems and Information
Email: turnbull at sk.tsukuba.ac.jp                   University of Tsukuba
Tel: 029-853-5175                 Tennodai 1-1-1, Tsukuba 305-8573 JAPAN


More information about the Python-ideas mailing list