Giter VIP home page Giter VIP logo

Comments (13)

maxfischer2781 avatar maxfischer2781 commented on June 8, 2024 8

assert definitely has its place, so warning for every occurrence seems misleading. The entire point of assertions is that they can be switched off. So one actually should use them similar to how @gaul describes it: Have some costly checks that can be disabled in production.

However, -O implies the assertion machinery is switched off. Entirely. That means two things:

  1. Explicitly raising AssertionError defeats the purpose of assert being optional. That means the suggestion of B011 encourages misuse of assertions.
  2. Explicitly catching AssertionError leads to different -O-behaviour at a distance. It is a better indication of misusing assertions.

A better replacement for assert False is raise NotImplementedError, since it usually indicates a dead code path.
However, I would rather suggest to flag except AssertionError, perhaps flag raise AssertionError as well. They indicate that assertions are misused for control flow, which they are not suitable for.

from flake8-bugbear.

neutrinoceros avatar neutrinoceros commented on June 8, 2024 5

Came here to report basically the same problem. I see this is more controversial than I expected.
Would it be acceptable to have an opinionated version of this warning (B911?) that would flag all assertions outside of tests functions and classes, assuming those are all named with test as a case-insensitive prefix ?

from flake8-bugbear.

gaul avatar gaul commented on June 8, 2024 3

In my code base I have expensive assert sanity checks on data structures which python -O will remove in production. It has check_true, check_not_none, etc. helper functions for preconditions that do not use assert. Thus some of the assert are valid for this code base but assert false should always be replaced with raise AssertionError.

I modeled this check after a similar one in Java error-prone which might explain my motivation more clearly:

http://errorprone.info/bugpattern/AssertFalse

from flake8-bugbear.

DylanYoung avatar DylanYoung commented on June 8, 2024 2

I like the check (because there is never a need to assert False that I can see), but can certainly get behind modifying the advice ("replace this with by raising an appropriate exception"). What that appropriate exception is seems to be beyond the scope of a tool like this since it's highly dependent on the code and the exception hierarchy in use.

from flake8-bugbear.

gaul avatar gaul commented on June 8, 2024 1

I authored this check and would like to understand your concern. I have not seen a use of assert False where the author somehow wanted to disable it via python -O. Could you point me at an example? I also do not understand how the message misleads readers since it only flags for assert False and not for other assert call sites.

from flake8-bugbear.

rpdelaney avatar rpdelaney commented on June 8, 2024 1

Maybe this isn't in perfect alignment with the OP, but I'm curious why we only flag assert False and not all assertions. I only recently learned that using assert to detect a failure mode is an antipattern, and had to remove various assertions for this reason. If bugbear had told me sooner, I might not have put them in to begin with.

from flake8-bugbear.

rpdelaney avatar rpdelaney commented on June 8, 2024 1

I dunno. If you print a warning, then people who understand not to do it can disable the warning. If you don't print the warning, then people don't know they need it.

from flake8-bugbear.

gimbo avatar gimbo commented on June 8, 2024 1

Thanks, @maxfischer2781 ; I was using assert False in some tests I hadn't written yet (and marking them as xfail), and then hit B011, which led me to this page, and your reminder that raise NotImplementedError() is a better approach in that case.

from flake8-bugbear.

tobixx avatar tobixx commented on June 8, 2024 1

My 2c: I also landed here because I was looking for how to disable this check within our test suite - which uses pytest runner - where using assert is exactly the right way to go (https://docs.pytest.org/en/7.2.x/how-to/assert.html#assert)

from flake8-bugbear.

scop avatar scop commented on June 8, 2024

Yeah, @rpdelaney's comment is a variant of the problem, although slightly unrelated in the sense that the advice given by this check is quite likely the best possible fix for that case: using AssertionError() would not in my opinion very rarely if ever be an appropriate way to signal failure, there are likely better exception types for that depending on case.

But I'll try to elaborate. So, the current implementation asks to use AssertionError instead of using assert False. The reason it gives for that is that those asserts get removed by -O. But that reason is valid for (well it isn't actually a valid reason IMO, but applies similarly to) all asserts, not just assert False. So, to make the check consistent and not misleading, all asserts should be flagged. But that would not be a good thing to do, because using asserts is a valid pattern, when used properly. Hence I don't think this check is fixable.

from flake8-bugbear.

scop avatar scop commented on June 8, 2024

Sure, but the warning needs to be valid in some scenarios on its own. If this lead you to avoid using asserts to signal failure, that I think was a coincidence, and thus should not count in this check's favor.

Quite bluntly, as it stands here, people who understand this thing will turn it off, and those who don't are subject to make misinformed changes and develop bad practices.

from flake8-bugbear.

rpdelaney avatar rpdelaney commented on June 8, 2024

If this lead you to avoid using asserts to signal failure, that I think was a coincidence, and thus should not count in this check's favor.

It certainly didn't -- I didn't use bugbear until very recently. But if I had been using it, and there had been a warning for all assertions, then I would have learned about this antipattern sooner. That's what I'm saying. I think I agree that it's bad to warn only for assert False, but it would be better to warn for all assertions than none.

from flake8-bugbear.

DylanYoung avatar DylanYoung commented on June 8, 2024

I also like the idea of catching places where AssertionError is caught, but it should be a separate check and disabled by default (it's valid in many cases: e.g. a unit test runner that runs other unit tests and gathers up the errors).

from flake8-bugbear.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.