[Python-ideas] Raise exception if (not) true

spir denis.spir at gmail.com
Fri Feb 21 18:42:41 CET 2014


On 02/21/2014 07:11 AM, Andrew Barnert wrote:
> On Feb 20, 2014, at 18:23, spir <denis.spir at gmail.com> wrote:
>
>> On 02/20/2014 10:28 PM, Steven D'Aprano wrote:
>>> On Thu, Feb 20, 2014 at 09:44:57PM +0100, spir wrote:
>>>
>>>>> But I would like to be able to add an error type to assertions (in addition
>>>>> to the optional message). This is particularly useful for people (like me)
>>>>> who systematically check func inputs (for client debugging comfort), using
>>>>> assert's.
>>> Then your code is systematically broken, and badly so.
>>
>> Why do you speak _that_ negatively? (or should I say: _that_ violently?) And this, maybe not _that_ logically? Do you own the (copy)rights on proper usage of assert's?
>>
>>> All anyone needs
>>> to do to disable your checking is pass -O to the Python interpreter.
>>>
>>> assert is not a short-cut for lazy programmers to avoid having to write
>>> an explicit "if cond: raise SomethingAppropriate(message)". Assertions
>>> have specific uses. You should read this post I made last November:
>>>
>>> https://mail.python.org/pipermail/python-list/2013-November/660401.html
>>
>> I think you are wrong, at least in this very case. Assert's for me are a debugging tool (or maybe more generally a tool for improving reliability). Such checks help finding errors and correcting them (thank to hopefully clear error messages), with a higher chance these corrections happen before "too late", meaning before users pay for our bugs. What else is the proper usage of assertions?
>>
>> If not checked on function input, either with assert's or an if-raise combination, execution will break anyway, just later (later in time, and slightly further in code), because some input variable's value or type is wrong. Assert's placed that way are not strictly necessary (it's like duck typing: you don't need to check), instead they're a helpful tool for all users of your "service".
>>
>>     def average (numbers):
>>         n = len(numbers)
>>         assert n != 0, "Cannot compute average of 'zero number'.", ValueError
>>         return sum(numbers) / n
>
> I think you're actually suffering from the confusion you accused Steven of. His post explains the difference between internal preconditions and external value checks. Then difference has nothing to do with the form of the function, but with how it's used.
>
> If average is only called by your own code with your own values, so you know it can never be called with an empty list unless there's a bug somewhere, then you're asserting a precondition, which is exactly what asserts are for--but in that case this should be an AssertionError, not a ValueError.
>
> If average is part of an external API, or is called with user data, so you're testing for something that could fail because of user error rather than a bug in your code, then this is a perfect case for a ValueError--but it's not an assertion, it's an error check.
>
> The fact that assertions happen to work by exception handling doesn't mean you should ignore the difference between them.

side-note: from wikipedia 
[https://en.wikipedia.org/wiki/Assertion_%28software_development%29]:

Assertions during the development cycle

During the development cycle, the programmer will typically run the program with 
assertions enabled. When an assertion failure occurs, the programmer is 
immediately notified of the problem. Many assertion implementations will also 
halt the program's execution: this is useful, since if the program continued to 
run after an assertion violation occurred, it might corrupt its state and make 
the cause of the problem more difficult to locate. Using the information 
provided by the assertion failure (such as the location of the failure and 
perhaps a stack trace, or even the full program state if the environment 
supports core dumps or if the program is running in a debugger), the programmer 
can usually fix the problem. Thus assertions provide a very powerful tool in 
debugging.

This is what I do. Note that whether assertion instructions were written by the 
client developper (who gets assertion errors) or by the author of a tool used 
for this project, does not change anything: in both cases, the client is 
properly notified of his/her errors.
In fact, there is no other border between internal and external components 
(modules, libs...) than a purely practical one. Semantically, it makes no sense 
(for me). The very same component can be written for a given project and 
distributed together with the rest, or written by someone else and installed 
apart. What is important is _coherence_ (or meaningfulness); this is what 
assertions check.

d


More information about the Python-ideas mailing list