astral-sh / ruff

An extremely fast Python linter and code formatter, written in Rust.

Home Page:https://docs.astral.sh/ruff

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

flag `print` in `assert` message

janosh opened this issue · comments

i've come across code like this a few times, leading me to believe a lint rule to catch this makes sense

assert 1 == 2, print("probably didn't mean to print this")
>>> AssertionError: None

the developer very likely wanted the print message to become the error message but of course the error message is None instead, print's return value

I thought there was a rule for this but I don't see one. This makes sense to me.

Seeing that this could be a fairly straight forward condition to check against, I would like to have a go at this as Ruff Rule 030.

I wonder if we have to support all variations of print calls, such as:

U00A0 = "\u00a0"
assert False, print("Unreachable due to", condition, f", ask {maintainer} for advice", sep=U00A0)

I can potentially do a FStringValue::concatenated as:

assert False, "Unreachable due to" f"{U00A0}" f"{condition}" f"{U00A0}" f", ask {maintainer} for advice"

But honestly it does not make very readable code.

Any advice would be welcomed.

EDIT

Looks like I can support the above case with just a FStringValue::single. I'll put up a PR tomorrow.

I wonder if it makes sense to phrase this rule more generally. Overall, it is probably incorrect if anything that returns None is passed as the assertion message. But implementing this would likely require type inference.

With type inference this rule could become a nice-to-have: since the return type of print already violates the type of the expression, the only thing that this rule will provide is a nicer error message instead of "str is expected but found NoneType".

Added by @denwong47 in #11981. Thank you, great contribution!