From 35998a0314d4660ccbf1341eb5c55d72236570de Mon Sep 17 00:00:00 2001 From: Jason Rhinelander Date: Sat, 20 May 2017 20:34:51 -0400 Subject: [PATCH] Define both __div__ and __truediv__ for Python 2 Python 2 requires both `__div__` and `__truediv__` (and variants) for compatibility with both regular Python 2 and Python 2 under `from __future__ import division`. Without both, division fails in one or the other case. --- include/pybind11/operators.h | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/include/pybind11/operators.h b/include/pybind11/operators.h index d054d9f97..562987b86 100644 --- a/include/pybind11/operators.h +++ b/include/pybind11/operators.h @@ -13,6 +13,9 @@ #if defined(__clang__) && !defined(__INTEL_COMPILER) # pragma clang diagnostic ignored "-Wunsequenced" // multiple unsequenced modifications to 'self' (when using def(py::self OP Type())) +#elif defined(_MSC_VER) +# pragma warning(push) +# pragma warning(disable: 4127) // warning C4127: Conditional expression is constant #endif NAMESPACE_BEGIN(pybind11) @@ -54,6 +57,11 @@ template struct op_ { using R_type = conditional_t::value, Base, R>; using op = op_impl; cl.def(op::name(), &op::execute, is_operator(), extra...); + #if PY_MAJOR_VERSION < 3 + if (id == op_truediv || id == op_itruediv) + cl.def(id == op_itruediv ? "__idiv__" : ot == op_l ? "__div__" : "__rdiv__", + &op::execute, is_operator(), extra...); + #endif } template void execute_cast(Class &cl, const Extra&... extra) const { using Base = typename Class::type; @@ -61,6 +69,11 @@ template struct op_ { using R_type = conditional_t::value, Base, R>; using op = op_impl; cl.def(op::name(), &op::execute_cast, is_operator(), extra...); + #if PY_MAJOR_VERSION < 3 + if (id == op_truediv || id == op_itruediv) + cl.def(id == op_itruediv ? "__idiv__" : ot == op_l ? "__div__" : "__rdiv__", + &op::execute, is_operator(), extra...); + #endif } }; @@ -108,11 +121,7 @@ inline op_ op(const self_t &) { PYBIND11_BINARY_OPERATOR(sub, rsub, operator-, l - r) PYBIND11_BINARY_OPERATOR(add, radd, operator+, l + r) PYBIND11_BINARY_OPERATOR(mul, rmul, operator*, l * r) -#if PY_MAJOR_VERSION >= 3 PYBIND11_BINARY_OPERATOR(truediv, rtruediv, operator/, l / r) -#else -PYBIND11_BINARY_OPERATOR(div, rdiv, operator/, l / r) -#endif PYBIND11_BINARY_OPERATOR(mod, rmod, operator%, l % r) PYBIND11_BINARY_OPERATOR(lshift, rlshift, operator<<, l << r) PYBIND11_BINARY_OPERATOR(rshift, rrshift, operator>>, l >> r) @@ -129,11 +138,7 @@ PYBIND11_BINARY_OPERATOR(le, ge, operator<=, l <= r) PYBIND11_INPLACE_OPERATOR(iadd, operator+=, l += r) PYBIND11_INPLACE_OPERATOR(isub, operator-=, l -= r) PYBIND11_INPLACE_OPERATOR(imul, operator*=, l *= r) -#if PY_MAJOR_VERSION >= 3 PYBIND11_INPLACE_OPERATOR(itruediv, operator/=, l /= r) -#else -PYBIND11_INPLACE_OPERATOR(idiv, operator/=, l /= r) -#endif PYBIND11_INPLACE_OPERATOR(imod, operator%=, l %= r) PYBIND11_INPLACE_OPERATOR(ilshift, operator<<=, l <<= r) PYBIND11_INPLACE_OPERATOR(irshift, operator>>=, l >>= r) @@ -156,3 +161,7 @@ NAMESPACE_END(detail) using detail::self; NAMESPACE_END(pybind11) + +#if defined(_MSC_VER) +# pragma warning(pop) +#endif