Skip to content

bitwise complement missing after enum rewrite? #1907

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
loriab opened this issue Sep 3, 2019 · 1 comment
Closed

bitwise complement missing after enum rewrite? #1907

loriab opened this issue Sep 3, 2019 · 1 comment

Comments

@loriab
Copy link
Contributor

loriab commented Sep 3, 2019

Issue description

Once upon a time, adding py::arithmetic() to an enum class defined the bitwise complement operator (aka ~, aka __invert__). It looks like that went away in #1511. Was this intentional or a regression? If the former, please just close. I included a code snippet that reactivates the operator downstream, in case others run across the problem.

Reproducible example code

If one adds an invert line (~m.Flags.Write) to the test_enum.py test case (to an enum with arithmetic enabled, it throws an error

========================================================= FAILURES ==========================================================
___________________________________________________ test_binary_operators ___________________________________________________

    def test_binary_operators():
        assert int(m.Flags.Read) == 4
        assert int(m.Flags.Write) == 2
        assert int(m.Flags.Execute) == 1
        assert int(m.Flags.Read | m.Flags.Write | m.Flags.Execute) == 7
        assert int(m.Flags.Read | m.Flags.Write) == 6
        assert int(m.Flags.Read | m.Flags.Execute) == 5
        assert int(m.Flags.Write | m.Flags.Execute) == 3
        assert int(m.Flags.Write | 1) == 3
>       ~m.Flags.Write
E       TypeError: bad operand type for unary ~: 'pybind11_tests.enums.Flags'

test_enum.py:143: TypeError

User code solution

In case anyone needs this capability, this is a fix for your own code. (The def must be after the export_values.)

    py::enum_<efp_term>(m, "efp_term", py::arithmetic(), "Flags to specify EFP energy terms")
        .value("EFP_TERM_ELEC", EFP_TERM_ELEC, "EFP/EFP electrostatics.")
        .value("EFP_TERM_POL", EFP_TERM_POL, "EFP/EFP polarization.")
     ...
        .export_values()
        .def("__invert__", [](efp_term& value) { return ~value; });
@wjakob
Copy link
Member

wjakob commented Sep 4, 2019

Hi @loriab,

this is a regression. Would you be willing to create PR that adds the __invert__ operator to the enum_base class.

Best,
Wenzel

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants