On Fri, Sep 10, 2021 at 06:48:42PM -0400, Juancarlo Añez wrote:

> I agree that assertions can be and are abused.
> 
> And I'm not too interested in DBC, nor in preconditions, nor in contracts.

In your first post you said:

[quote]
This is in the context of "Design by contrast" (DBC) as a useful 
companion to "Test-driven development" and other forms of external 
tests.
[/quote]

I presume the "contrast" was a typo for contract.


> I'd like to make it easy to assert invariants and postconditions 

Invariants and postconditions **are** contracts. Both are part of DBC.

It seems very odd that you are taking only two thirds of DBC. Why do 
you think that preconditions are not important?


> over critical pieces of code to guard against failures caused by:
> 
>    - bugs in the design or the implementation
>    - third party software violating its contracts
>    - the environment

You just said you're not interested in contracts. Now you say you want 
to enforce third-party software's contracts.

The first item you give (bugs in design or implementation) is part of 
DBC.

The second is not something you can enforce. You don't know what, if 
any, contracts a third-party library may be enforcing internally. The 
only thing you can even *attempt* to enforce is the third-party 
external API, but you don't need anything more than a bare assert for 
that.

You can use assert as it is to validate your arguments that you pass to 
libraries:

    assert isinstance(count, int) and count > 0
    result = some_library.func(count)

so no change needed there. To verify that the third-party library is 
returning what it promises to return can also be done with assert:

    assert result is not None and hasattr(result, 'spam')


> Why target *assert*? Because invariants are clearer when the expected
> condition is what's asserted.

That's arguable.

If all you want is to be able to flip the sense of a test without using 
`not`, then it sounds like you need an "unless" keyword:


    unless condition:
        # block
        raise MyError(msg)


That avoids abusing assert for things that aren't assertions.

But adding a new keyword just so you don't have to write `not` seems 
like a high cost for a low benefit. Although now that we have soft 
keywords, the cost is somewhat less.


> Why specify an ExceptionType? Although in theory an assertion should never
> fail, reality is that they will fail,

If your assertions are regularly failing in production, then either your 
application is full of bugs and you put it into production too soon, or 
you are misusing assert by using it for things which aren't assertions.

In any case, you don't need to raise different exception types in order 
to assess the failure. You need to know *where* the failure occurred.


> and it's useful for outer layers of a
> software system to be able to assess the severity of a failure to know
> which actions are appropriate.
> 
>    - HALT
>    - preserve major state and HALT
>    - rollback and halt
>    - retry
>    - ...

The first three are what I would call "exit gracefully" (if possible, 
but if an error is so severe you can't exit gracefully, then all you can 
do is exit).

If an error can be resolved by retrying, then it is not an assertion 
that was violated. You cannot *assert* that (e.g.) a web server will 
respond with the expected amount of data, or that a user will input 
exactly 'Y' or 'N' at the prompt.


-- 
Steve
_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/VZTK7JXF6MUTW3A5LVSB452VDLWWAI24/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to