@@ -155,23 +155,23 @@ class object_api : public pyobject_tag {
155
155
object operator -() const ;
156
156
object operator ~() const ;
157
157
object operator +(object_api const &other) const ;
158
- object operator +=(object_api const &other) const ;
158
+ object operator +=(object_api const &other);
159
159
object operator -(object_api const &other) const ;
160
- object operator -=(object_api const &other) const ;
160
+ object operator -=(object_api const &other);
161
161
object operator *(object_api const &other) const ;
162
- object operator *=(object_api const &other) const ;
162
+ object operator *=(object_api const &other);
163
163
object operator /(object_api const &other) const ;
164
- object operator /=(object_api const &other) const ;
164
+ object operator /=(object_api const &other);
165
165
object operator |(object_api const &other) const ;
166
- object operator |=(object_api const &other) const ;
166
+ object operator |=(object_api const &other);
167
167
object operator &(object_api const &other) const ;
168
- object operator &=(object_api const &other) const ;
168
+ object operator &=(object_api const &other);
169
169
object operator ^(object_api const &other) const ;
170
- object operator ^=(object_api const &other) const ;
170
+ object operator ^=(object_api const &other);
171
171
object operator <<(object_api const &other) const ;
172
- object operator <<=(object_api const &other) const ;
172
+ object operator <<=(object_api const &other);
173
173
object operator >>(object_api const &other) const ;
174
- object operator >>=(object_api const &other) const ;
174
+ object operator >>=(object_api const &other);
175
175
176
176
PYBIND11_DEPRECATED (" Use py::str(obj) instead" )
177
177
pybind11::str str () const ;
@@ -334,12 +334,15 @@ class object : public handle {
334
334
}
335
335
336
336
object &operator =(const object &other) {
337
- other.inc_ref ();
338
- // Use temporary variable to ensure `*this` remains valid while
339
- // `Py_XDECREF` executes, in case `*this` is accessible from Python.
340
- handle temp (m_ptr);
341
- m_ptr = other.m_ptr ;
342
- temp.dec_ref ();
337
+ // Skip inc_ref and dec_ref if both objects are the same
338
+ if (!this ->is (other)) {
339
+ other.inc_ref ();
340
+ // Use temporary variable to ensure `*this` remains valid while
341
+ // `Py_XDECREF` executes, in case `*this` is accessible from Python.
342
+ handle temp (m_ptr);
343
+ m_ptr = other.m_ptr ;
344
+ temp.dec_ref ();
345
+ }
343
346
return *this ;
344
347
}
345
348
@@ -353,6 +356,20 @@ class object : public handle {
353
356
return *this ;
354
357
}
355
358
359
+ #define PYBIND11_INPLACE_OP (iop ) \
360
+ object iop (object_api const &other) { return operator =(handle::iop (other)); }
361
+
362
+ PYBIND11_INPLACE_OP (operator +=)
363
+ PYBIND11_INPLACE_OP (operator -=)
364
+ PYBIND11_INPLACE_OP (operator *=)
365
+ PYBIND11_INPLACE_OP (operator /=)
366
+ PYBIND11_INPLACE_OP (operator |=)
367
+ PYBIND11_INPLACE_OP (operator &=)
368
+ PYBIND11_INPLACE_OP (operator ^=)
369
+ PYBIND11_INPLACE_OP (operator <<=)
370
+ PYBIND11_INPLACE_OP (operator >>=)
371
+ #undef PYBIND11_INPLACE_OP
372
+
356
373
// Calling cast() on an object lvalue just copies (via handle::cast)
357
374
template <typename T>
358
375
T cast () const &;
@@ -2364,26 +2381,35 @@ bool object_api<D>::rich_compare(object_api const &other, int value) const {
2364
2381
return result; \
2365
2382
}
2366
2383
2384
+ #define PYBIND11_MATH_OPERATOR_BINARY_INPLACE (iop, fn ) \
2385
+ template <typename D> \
2386
+ object object_api<D>::iop(object_api const &other) { \
2387
+ object result = reinterpret_steal<object>(fn (derived ().ptr (), other.derived ().ptr ())); \
2388
+ if (!result.ptr ()) \
2389
+ throw error_already_set (); \
2390
+ return result; \
2391
+ }
2392
+
2367
2393
PYBIND11_MATH_OPERATOR_UNARY (operator ~, PyNumber_Invert)
2368
2394
PYBIND11_MATH_OPERATOR_UNARY(operator -, PyNumber_Negative)
2369
2395
PYBIND11_MATH_OPERATOR_BINARY(operator +, PyNumber_Add)
2370
- PYBIND11_MATH_OPERATOR_BINARY (operator +=, PyNumber_InPlaceAdd)
2396
+ PYBIND11_MATH_OPERATOR_BINARY_INPLACE (operator +=, PyNumber_InPlaceAdd)
2371
2397
PYBIND11_MATH_OPERATOR_BINARY(operator -, PyNumber_Subtract)
2372
- PYBIND11_MATH_OPERATOR_BINARY (operator -=, PyNumber_InPlaceSubtract)
2398
+ PYBIND11_MATH_OPERATOR_BINARY_INPLACE (operator -=, PyNumber_InPlaceSubtract)
2373
2399
PYBIND11_MATH_OPERATOR_BINARY(operator *, PyNumber_Multiply)
2374
- PYBIND11_MATH_OPERATOR_BINARY (operator *=, PyNumber_InPlaceMultiply)
2400
+ PYBIND11_MATH_OPERATOR_BINARY_INPLACE (operator *=, PyNumber_InPlaceMultiply)
2375
2401
PYBIND11_MATH_OPERATOR_BINARY(operator /, PyNumber_TrueDivide)
2376
- PYBIND11_MATH_OPERATOR_BINARY (operator /=, PyNumber_InPlaceTrueDivide)
2402
+ PYBIND11_MATH_OPERATOR_BINARY_INPLACE (operator /=, PyNumber_InPlaceTrueDivide)
2377
2403
PYBIND11_MATH_OPERATOR_BINARY(operator |, PyNumber_Or)
2378
- PYBIND11_MATH_OPERATOR_BINARY (operator |=, PyNumber_InPlaceOr)
2404
+ PYBIND11_MATH_OPERATOR_BINARY_INPLACE (operator |=, PyNumber_InPlaceOr)
2379
2405
PYBIND11_MATH_OPERATOR_BINARY(operator &, PyNumber_And)
2380
- PYBIND11_MATH_OPERATOR_BINARY (operator &=, PyNumber_InPlaceAnd)
2406
+ PYBIND11_MATH_OPERATOR_BINARY_INPLACE (operator &=, PyNumber_InPlaceAnd)
2381
2407
PYBIND11_MATH_OPERATOR_BINARY(operator ^, PyNumber_Xor)
2382
- PYBIND11_MATH_OPERATOR_BINARY (operator ^=, PyNumber_InPlaceXor)
2408
+ PYBIND11_MATH_OPERATOR_BINARY_INPLACE (operator ^=, PyNumber_InPlaceXor)
2383
2409
PYBIND11_MATH_OPERATOR_BINARY(operator <<, PyNumber_Lshift)
2384
- PYBIND11_MATH_OPERATOR_BINARY (operator <<=, PyNumber_InPlaceLshift)
2410
+ PYBIND11_MATH_OPERATOR_BINARY_INPLACE (operator <<=, PyNumber_InPlaceLshift)
2385
2411
PYBIND11_MATH_OPERATOR_BINARY(operator >>, PyNumber_Rshift)
2386
- PYBIND11_MATH_OPERATOR_BINARY (operator >>=, PyNumber_InPlaceRshift)
2412
+ PYBIND11_MATH_OPERATOR_BINARY_INPLACE (operator >>=, PyNumber_InPlaceRshift)
2387
2413
2388
2414
#undef PYBIND11_MATH_OPERATOR_UNARY
2389
2415
#undef PYBIND11_MATH_OPERATOR_BINARY
0 commit comments