[Python-ideas] Why is design-by-contracts not widely adopted?

Steven D'Aprano steve at pearwood.info
Sat Sep 29 00:06:24 EDT 2018


On Sat, Sep 29, 2018 at 12:30:45PM +1200, Greg Ewing wrote:
> Chris Angelico wrote:
> >But as a part of the
> >function's declared intent, it's fine to have a postcondition of "the
> >directory will be empty" even though something could drop a file into
> >it.
> 
> If you only intend the contract to serve as documentation,
> I suppose that's okay, but it means you can't turn on runtime
> checking of contracts, otherwise your program could suffer
> spurious failures.

If your code can cope with a particular file system state ("directory 
isn't empty") then you don't need to specify it as a precondition. If it 
can't cope, then it isn't a spurious failure, its a real failure. You 
either get an error when the condition is checked, up front, or you get 
an error in the middle of processing the directory.

Of course for many things (especially file system operations) you need 
to be prepared to handle I/O errors *even if the precondition passed*. 
So what? That hasn't changed, and nobody said that contracts were a cure 
for Time Of Check To Time Of Use bugs.

Contracts are a tool to help developers write better code, not a magic 
wand. You still need to write your code in a way which isn't vulnerable 
to TOCTTOU failures, contracts or not.

Anticipating an objection: why bother with the precondition check if the 
code has to handle an error anyway?

Because it is better to get an upfront error than an error halfway 
through processing. In general you get a better, more informative error 
message, closer to the place where it matters, if you fail fast.

Yes yes yes, in theory you might have a precondition requirement which 
would fail up front but resolve itself before it matters:

    directory not empty
    start running your program
    precondition check fails
    ... later
    directory is emptied by another process
    your program actually needs to use the empty directory

but do you really think it is good practice to design your code on the 
basis of that? Better to write your code conservatively: if the 
directory isn't empty up front, don't hope it will empty itself, fail 
fast, but be prepared to handle the error case as well.


-- 
Steve


More information about the Python-ideas mailing list