Skip to content

Multiple binary | operation in a single statement failed with "E1131: unsupported operand type(s) for | (unsupported-binary-operation)" #7381

@Wayonb

Description

@Wayonb

Bug description

If I am trying to OR more than two flags, pylint 2.15.0 fails with "E1131: unsupported operand type(s) for | (unsupported-binary-operation)". This worked with pylint 2.14.1

	class MosaicFlags(Flag):
		NONE = 0
		SUPPLY_MUTABLE = 1
		TRANSFERABLE = 2
		RESTRICTABLE = 4
		REVOKABLE = 8

value = MosaicFlags.SUPPLY_MUTABLE | MosaicFlags.RESTRICTABLE | MosaicFlags.REVOKABLE

Configuration

No response

Command used

python3 -m pylint --rcfile .pylintrc --load-plugins pylint_quotes

Pylint output

************* Module tests.test_RuleBasedTransactionFactory
tests/test_RuleBasedTransactionFactory.py:148:3: E1131: unsupported operand type(s) for | (unsupported-binary-operation)
tests/test_RuleBasedTransactionFactory.py:164:10: E1131: unsupported operand type(s) for | (unsupported-binary-operation)

Expected behavior

Expected no errors

Pylint version

pylint 2.15.0
Python 3.8.10

OS / Environment

Ubuntu 20.04

Additional dependencies

isort==5.10.1
pycodestyle==2.9.1
pylint==2.15.0
pylint-quotes==0.2.3

Activity

added
Needs triage 📥Just created, needs acknowledgment, triage, and proper labelling
on Aug 29, 2022
RemiCardona

RemiCardona commented on Aug 30, 2022

@RemiCardona
Contributor

Same issue when using Django's "Q objects" https://docs.djangoproject.com/en/3.1/topics/db/queries/#complex-lookups-with-q

2 Q objects |-ed or &-ed together is fine, 3 or more breaks pylint. We're getting hundreds of errors as Q objects are a fairly common sight in Django projects.

mbyrnepr2

mbyrnepr2 commented on Aug 30, 2022

@mbyrnepr2
Member

Thanks for the report. I can't reproduce this one myself:

(venv310) Marks-MacBook-Air-2:programming markbyrne$ pip freeze |grep pylint
pylint==2.15.0
pylint-quotes==0.2.3
(venv310) Marks-MacBook-Air-2:programming markbyrne$ pylint --version
pylint 2.15.0
astroid 2.12.5
Python 3.10.4 (v3.10.4:9d38120e33, Mar 23 2022, 17:29:05) [Clang 13.0.0 (clang-1300.0.29.30)]
(venv310) Marks-MacBook-Air-2:programming markbyrne$ cat example.py 
'''test'''

from enum import Flag

class MosaicFlags(Flag):
    """test"""
    NONE = 0
    SUPPLY_MUTABLE = 1
    TRANSFERABLE = 2
    RESTRICTABLE = 4
    REVOKABLE = 8

value = MosaicFlags.SUPPLY_MUTABLE | MosaicFlags.RESTRICTABLE | MosaicFlags.REVOKABLE
print(value)
(venv310) Marks-MacBook-Air-2:programming markbyrne$ pylint example.py --load-plugins pylint_quotes
************* Module programming.p
p.py:1:0: C4003: Invalid docstring quote ''', should be """ (invalid-docstring-quote)

------------------------------------------------------------------
Your code has been rated at 8.89/10 (previous run: 8.89/10, +0.00)
added
Needs reproduction 🔍Need a way to reproduce it locally on a maintainer's machine
and removed
Needs triage 📥Just created, needs acknowledgment, triage, and proper labelling
on Aug 30, 2022
Wayonb

Wayonb commented on Aug 30, 2022

@Wayonb
Author

Hi @mbyrnepr2, Thanks for taking a look. Sorry, I didnt actually try the sample code.
I was able to repo with the sample below.

pylint example.py --load-plugins pylint_quotes

from enum import Flag


class Module:
    """module"""

    class TestFlags(Flag):
        """test flags"""
        TEST_NONE = 0
        TEST_SUPPLY_MUTABLE = 1
        TEST_TRANSFERABLE = 2
        TEST_RESTRICTABLE = 4
        TEST_REVOKABLE = 8


class TestClass():
    """test class"""

    @staticmethod
    def _assert_flags_parser(value, expected):
        """assert"""
        pass

    def test_flags_parser_can_handle_multiple_string_flags(self):
        """test flags"""
        self._assert_flags_parser(
            'supply_mutable restrictable revokable',
            Module.TestFlags.TEST_SUPPLY_MUTABLE | Module.TestFlags.TEST_RESTRICTABLE | Module.TestFlags.TEST_REVOKABLE)

    @staticmethod
    def test_flags_parser_passes_non_parsed_values_as_is():
        """test parser"""
        value = Module.TestFlags.TEST_SUPPLY_MUTABLE | Module.TestFlags.TEST_RESTRICTABLE | Module.TestFlags.TEST_REVOKABLE
        print(value)
SamyCookie

SamyCookie commented on Aug 30, 2022

@SamyCookie

if you want a shorter example without enum dependency you can reproduce this false positive bug with this:

class BinaryOperator:
    """ only make useless binary operations
    """
    def __or__(self, whatever):
        return 42
operators = [ BinaryOperator(), BinaryOperator() ]
def _fn(idx: int=0):
    print(operators[0] | operators[1])  # NO unsupported-binary-operation issue
    print(operators[idx] | operators[1])  # OUPS unsupported-binary-operation issue
_fn(0)
added
False Positive 🦟A message is emitted but nothing is wrong with the code
and removed
Needs reproduction 🔍Need a way to reproduce it locally on a maintainer's machine
on Aug 30, 2022
mbyrnepr2

mbyrnepr2 commented on Aug 30, 2022

@mbyrnepr2
Member

Thanks for the examples.

@Wayonb you're right - something between 2.14.1 & 2.15.0 has led to this false positive. Note it happens only for Python versions below 3.10 because of this logic: https://github.com/PyCQA/pylint/blob/main/pylint/checkers/typecheck.py#L1879-L1880

added
Needs PRThis issue is accepted, sufficiently specified and now needs an implementation
on Aug 30, 2022
RemiCardona

RemiCardona commented on Sep 8, 2022

@RemiCardona
Contributor

Is there any chance for part or all of the new type checker code to be reverted until the issue is fixed?

Thanks

23 remaining items

Loading
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

    False Positive 🦟A message is emitted but nothing is wrong with the codeNeeds PRThis issue is accepted, sufficiently specified and now needs an implementationRegression

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @RemiCardona@fechnert@belm0@SamyCookie@Pierre-Sassoulas

        Issue actions

          Multiple binary | operation in a single statement failed with "E1131: unsupported operand type(s) for | (unsupported-binary-operation)" · Issue #7381 · pylint-dev/pylint