[New-bugs-announce] [issue33217] x in enum.Flag() is True when x is no Flag

Dutcho report at bugs.python.org
Tue Apr 3 16:16:12 EDT 2018


New submission from Dutcho <dutcho at ziggo.nl>:

While `Flag() in Flag()` and `Flag() | Flag()` result in the expected outcomes, e.g. `str() in Flag()` unexpectedly returns `True`, whereas `Flag() | str()` as expected raises a TypeError.
    >>> import enum
    >>> ABC = enum.Flag('ABC', 'a, b, c')
    >>> ac = ABC.a | ABC.c
    >>> def test():
    ...     for x in (*ABC, 'test'):
    ...         print(x, end=' ')
    ...         try:
    ...             print(x in ac, end=' ')
    ...         except TypeError as e:
    ...             print(e, end=' ')
    ...         try:
    ...             print(x | ac)
    ...         except TypeError as e:
    ...             print(e)
    >>> test()
    ABC.a True ABC.c|a
    ABC.b False ABC.c|b|a
    ABC.c True ABC.c|a
    test True unsupported operand type(s) for |: 'str' and 'ABC'

Likely cause is modelling of Flag.__contains__ after Flag.__and__ etc., which is incorrect as __contains__ doesn't have a reflected version like __and__ etc. have. The returned `NotImplemented` is therefore not handled by the interpreter, although it is converted to bool to satisfy __contains__ return type.

This can be fixed by redefinition of Flag.__contains__ to raise TypeError:
    >>> def __contains__(self, other):
    ...     if not isinstance(other, self.__class__):
    ...         raise TypeError(f"unsupported operand type(s) for 'in': "
    ...                         f"{type(other).__qualname__!r} and {type(self).__qualname__!r}")
    ...     return other & self == other
    >>> enum.Flag.__contains__ = __contains__
    >>> test()
    ABC.a True ABC.c|a
    ABC.b False ABC.c|b|a
    ABC.c True ABC.c|a
    test unsupported operand type(s) for 'in': 'str' and 'ABC' unsupported operand type(s) for |: 'str' and 'ABC'

----------
components: Library (Lib)
messages: 314890
nosy: Dutcho
priority: normal
severity: normal
status: open
title: x in enum.Flag() is True when x is no Flag
type: behavior
versions: Python 3.6

_______________________________________
Python tracker <report at bugs.python.org>
<https://bugs.python.org/issue33217>
_______________________________________


More information about the New-bugs-announce mailing list