New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Don't use assert in the library code when an exception would be better #5090
Comments
This is easy to fix. Basically, each assertion should be negated using the rules of http://en.wikipedia.org/wiki/De_Morgan%27s_Law , i.e., change
to
And also, you might as well add a raises() test to the relevant test file, if you can reproduce the exception (I have done this for the matrices, which is 846af4a by the way, and can be reviewed). Labels: EasyToFix NeedsReview Original comment: http://code.google.com/p/sympy/issues/detail?id=1991#c1 |
Sometimes the assert is there because that is an assumption at that point in the code that you want the reader to be made aware of. They are like road signs that help keep you oriented...not that you couldn't look at a map and figure out where you were, but in the limited amount of lines to a screen (and finite "where am I" memory) they also provide a nanny-ish role. e.g. in the ode module there is a portion where perhaps you think that there should only be one solution and you act on that belief. I would just like to put "assert len(sol) == 1" and proceed with confidence. I maybe can't (in my limited imagination) think of a case where there would be more solutions but if, for some reason there are I want someone to make the code len(sol) > 1 compliant. "Today" I don't want to have to think up imaginative names for errors that probably won't exist. I am happy enough to know that I alerted someone -- like a zone of red on a tachometer -- that there is a pending problem. I once looked at some personal code of Tim Peters and it was loaded with assertions. He writes some pretty slick stuff. I asked what that was for and he taught me about the assertion. I'm not saying there isn't a place for a good error message. I am just saying that sometimes it isn't a user error as much as a logical error that the assertion protects against. Original comment: http://code.google.com/p/sympy/issues/detail?id=1991#c2 |
So maybe they do have their place. I just got through removing all assertions from matrix.py (see the above cited commit), because it had things like
when there was even a custom NonSquareMatrixError already made. So those obviously should have been
Here's the problem with having assertions in code like that. If you are writing general purpose code, say something that calls on an arbitrary matrix the .inv() method, which only works if the matrix is square. You then see that it sometimes fails with AssertionError, so you write your code as
But except AssertionError will catch all AssertionError's that that code block happens to raise, and in this case, will mask them with NotImplementedError, which no longer looks like a bug. You really only wanted the try block to catch the case where the matrix inversion failed because it was not square, so it's much better to have Matrix.inv() raise NonSquareMatrixError and for your code to catch that. I remember making a change like this in solve() last year (cf781bc). I was forced to have "except AssertionError, ValueError, NotImplementedError:" in my code, where I really only wanted "except NotImplementedError:". Keeping those other ones would have masked other errors in the code that raised those exceptions. So I think you should only use assertions where the code should unequivocally stop because some assertion that has to be true for the algorithm to be correct no longer is. In other words, if the assertion does fail, it's not because of bad input, but because there is some unexpected bug in my code, which if I ever see this error I will need to go in and fix, or special case with a more descriptive exception. So maybe the issue title should be "Don't use assert in the library code when a better exception can be used instead," i.e., ValueError, TypeError, NotImplementedError, etc. And even if the assertion does belong, it should be given an error message, which can be done by adding a string to the end of the line:
Original comment: http://code.google.com/p/sympy/issues/detail?id=1991#c3 |
Original comment: http://code.google.com/p/sympy/issues/detail?id=1991#c4 |
Original comment: http://code.google.com/p/sympy/issues/detail?id=1991#c5 |
Original comment: http://code.google.com/p/sympy/issues/detail?id=1991#c6 |
I want to apply for GSOC 2014 and I am interested in solving this bug. Although I am still a little bit confused as to where assert is necessary and where it has to be replaced with a raise exception construct. Original comment: http://code.google.com/p/sympy/issues/detail?id=1991#c7 |
Original comment: http://code.google.com/p/sympy/issues/detail?id=1991#c8 |
Here's a useful guide on when assert should and should not be used. https://mail.python.org/pipermail/python-list/2013-November/660401.html Original comment: http://code.google.com/p/sympy/issues/detail?id=1991#c9 |
I addressed this issue and I have went through the entire code base and removed asserts wherever necessary.Please refer to this: #2655 Original comment: http://code.google.com/p/sympy/issues/detail?id=1991#c10 |
PR #2655 was merged. Does any work still need to be done here? |
The command from the top shows some asserts for me, although I don't know how many of them are valid. I saw at least one that isn't:
|
@asmeurer I have changed |
Replaced assert with exception, issue #5090
Replaced some asserts in non-test code with exceptions (#5090)
Hi, @ethandeguire and I have begun looking into this issue. We are new contributors to open source. Has any new work been done on this issue/are there any guidelines we should be aware of in fixing this? We were planning of just expanding on the work that others have done in replacing some asserts with exceptions in files where it is still necessary |
Replaced assertion with raising a TypeError in core/backend.py when matrix M is not an instance of Matrix or Immutable Matrix. Does not create accompanying core/tests/test_backend.py. Issue: sympy#5090
Replaced assertion with raising a TypeError in core/backend.py when matrix M is not an instance of Matrix or Immutable Matrix. Does not create accompanying core/tests/test_backend.py. Issue: sympy#5090
Hello, I am working on this issue and I just wanted to add a note about finding these potentially unwanted assert statements: Modified command to find offending line, and print their file and line number, excluding documentation and test files (.rst, .md) Or to find all files with an offending assert: |
I think this wasn't supposed to be automatically closed. |
Basically, you should rewrite it to use an if construct and a proper exception (ValueError, TypeError, NotImplementedError, or a special error for the module are the usual suspects).
Will show most offending lines. I have already fixed matrices.py in my integration3 branch.
Original issue for #5090: http://code.google.com/p/sympy/issues/detail?id=1991
Original author: https://code.google.com/u/asmeurer@gmail.com/
Original owner: https://code.google.com/u/asmeurer@gmail.com/
The text was updated successfully, but these errors were encountered: