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 -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at
https://mail.python.org/archives/list/[email protected]/message/VZTK7JXF6MUTW3A5LVSB452VDLWWAI24/
Code of Conduct: http://python.org/psf/codeofconduct/