Skip to content

Wrong ternary suggested #5200

Closed
Closed
@sami-evangelista

Description

@sami-evangelista

Bug description

# pylint: disable=missing-module-docstring,invalid-name

a = True
b = False
c = True
x = (a and b) or c
print(x)  #  x == True
print(b if a else c)  #  ternary suggested == False

Configuration

No response

Command used

pylint test.py

Pylint output

************* Module test
test.py:6:0: R1706: Consider using ternary (b if a else c) (consider-using-ternary)

Expected behavior

Success.

Pylint version

pylint 2.11.1
astroid 2.8.0
Python 3.9.7 (default, Aug 30 2021, 00:00:00) 
[GCC 11.2.1 20210728 (Red Hat 11.2.1-1)]

OS / Environment

Fedora 34

Additional dependencies

No response

Activity

added
False Positive 🦟A message is emitted but nothing is wrong with the code
and removed
Needs triage 📥Just created, needs acknowledgment, triage, and proper labelling
on Oct 22, 2021
areveny

areveny commented on Oct 28, 2021

@areveny
Contributor

This is a continuation of #1559 and #2058 which concern the message consider-using-ternary and the behavior on statements like a and b or c where b might be False.

#1559 made the check emit simplify-boolean-expression if b is falsey, suggesting simplifying to c.

#2058 tries to infer the value of b if it is an expression. However, I think the logic is a bit faulty.

        if inferred_truth_value in (None, astroid.Uninferable):
            truth_boolean_value = True
        else:
            truth_boolean_value = truth_value.bool_value()

        if truth_boolean_value is False:
            message = 'simplify-boolean-expression'
            suggestion = false_value.as_string()
        else:
            message = 'consider-using-ternary'
            suggestion = '{truth} if {cond} else {false}'.format(
                truth=truth_value.as_string(),
                cond=cond.as_string(),
                false=false_value.as_string()
            )

If truth_value is any variable, then truth_boolean_value.bool_value() is Uninferable. This means we always suggest consider-using-ternary unless truth_value is a falsey literal. The integration test on this ticket only tests the case where truth_value is truthy, and even then it doesn't suggest consider-using-ternary because truth_boolean_value is True, but because it is Uninferable.

My fix is to change truth_boolean_value = truth_value.bool_value() to truth_boolean_value = inferred_truth_value.bool_value(). I think this was the original intention. This will try to infer the boolean value of b, and sees that it is False, and suggests simplify-boolean-expression instead.

added this to the 2.12.0 milestone on Oct 29, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Bug 🪲False Positive 🦟A message is emitted but nothing is wrong with the code

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

      Participants

      @sami-evangelista@Pierre-Sassoulas@areveny

      Issue actions

        Wrong ternary suggested · Issue #5200 · pylint-dev/pylint