Skip to content

Commit

Permalink
Add (failing) tests for issue PyO3#1064
Browse files Browse the repository at this point in the history
  • Loading branch information
mvaled committed Aug 3, 2020
1 parent a877300 commit 76d8738
Showing 1 changed file with 129 additions and 0 deletions.
129 changes: 129 additions & 0 deletions tests/test_arithmetics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -423,3 +423,132 @@ fn rich_comparisons_python_3_type_error() {
py_expect_exception!(py, c2, "c2 >= 1", PyTypeError);
py_expect_exception!(py, c2, "1 >= c2", PyTypeError);
}

// Checks that binary operations for which the arguments don't match the
// required type, return NotImplemented.
mod return_not_implemented {
use super::*;

#[pyclass]
struct RichComparisonToSelf {}

#[pyproto]
impl<'p> PyObjectProtocol<'p> for RichComparisonToSelf {
fn __repr__(&self) -> &'static str {
"RC_Self"
}

fn __richcmp__(&self, other: PyRef<'p, Self>, _op: CompareOp) -> PyObject {
other.py().None()
}
}

fn test_dunder(operator: &str) {
let gil = Python::acquire_gil();
let py = gil.python();
let c2 = PyCell::new(py, RichComparisonToSelf {}).unwrap();
py_run!(
py,
c2,
&format!(
"\
class Other:
def __eq__(self, other):
return True
__ne__ = __lt__ = __le__ = __gt__ = __ge__ = __eq__
def __radd__(self, other):
return self
__rand__ = __ror__ = __rxor__ = __radd__
__rsub__ = __rmul__ = __rtruediv__ = __rfloordiv__ = __rpow__ = __radd__
__rmatmul__ = __rlshift__ = __rrshift__ = __rmod__ = __rdivmod__ = __radd__
c2 {} Other()",
operator
)
);
py_expect_exception!(
py,
c2,
&format!("class Other: pass; c2 {} Other()", operator),
PyTypeError
);
}

macro_rules! not_implemented_test {
($dunder: ident, $operator: literal) => {
#[test]
fn $dunder() {
test_dunder($operator)
}
};

[$( ($dunder: ident, $operator: literal) ),*] => {
$(not_implemented_test!{$dunder, $operator})*
};

[$( ($dunder: ident, $operator: literal) ),* ,] => {
$(not_implemented_test!{$dunder, $operator})*
};

}

mod richcmp {
use super::*;

not_implemented_test![
(eq, "=="),
(ne, "!="),
(lt, "<"),
(le, "<="),
(gt, ">"),
(ge, ">="),
];
}

#[cfg(feature = "remove-this-when-implemented")]
mod reversed {
use super::*;

// The pyclass returns NotImplemented, so the other object gets is
// reversed dunder method called.
not_implemented_test![
(rand, "&"),
(ror, "|"),
(rxor, "^"),
(radd, "+"),
(rsub, "-"),
(rmul, "*"),
(rmatmul, "@"),
(rtruediv, "/"),
(rfloordiv, "//"),
(rmod, "%"),
(rpow, "**"),
(rlshift, "<<"),
(rshift, ">>"),
];
}

#[cfg(feature = "remove-this-when-implemented")]
mod inplace {
use super::*;

// The pyclass returns NotImplemented for the in-place operator, so the
// other object gets is reversed dunder method called.
not_implemented_test![
(rand, "&="),
(ror, "|="),
(rxor, "^="),
(radd, "+="),
(rsub, "-="),
(rmul, "*="),
(rmatmul, "@="),
(rtruediv, "/="),
(rfloordiv, "//="),
(rmod, "%="),
(rpow, "**="),
(rlshift, "<<="),
(rshift, ">>="),
];
}
}

0 comments on commit 76d8738

Please sign in to comment.