Skip to content

Commit

Permalink
Fix CLIF tests for Python 3.12
Browse files Browse the repository at this point in the history
No changes in CLIF itself, only in tests. Makes tests pass with both 3.11 and 3.12 (tested with `--define=PYTYPE=FALSE --config=python_next`).

List of changes:
- assertRegex instead of deprecated assertRegexpMatches
- list instead of tuple as a test object, as in 3.12 refcount for tuples changes to 2**32-1
- for the previous change, make SwapDoesNotIncrement logic explicit instead of implicitly relying on tuples refcount

PiperOrigin-RevId: 648360071
  • Loading branch information
CLIF Team authored and Ralf W. Grosse-Kunstleve committed Aug 27, 2024
1 parent 9636eb3 commit 8ad1c33
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 14 deletions.
31 changes: 18 additions & 13 deletions clif/python/pyobj_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
// limitations under the License.

#include "clif/python/pyobj.h"
#include <Python.h>
#include "gtest/gtest.h"

namespace clif {
Expand All @@ -34,7 +35,7 @@ TEST_F(PyObjectTest, NullCtor) {
}

TEST_F(PyObjectTest, Equality) {
PyObject* obj = PyTuple_New(0);
PyObject* obj = PyList_New(0);
py::Object a(obj);
EXPECT_EQ(a, obj);
EXPECT_NE(a, nullptr);
Expand All @@ -46,7 +47,7 @@ TEST_F(PyObjectTest, Equality) {
}

TEST_F(PyObjectTest, CtorAndDtorManageRefcount) {
PyObject* obj = PyTuple_New(0);
PyObject* obj = PyList_New(0);
int initial_ref_count = Py_REFCNT(obj);

{
Expand All @@ -58,7 +59,7 @@ TEST_F(PyObjectTest, CtorAndDtorManageRefcount) {
}

TEST_F(PyObjectTest, CopyCtorIncrements) {
PyObject* obj = PyTuple_New(0);
PyObject* obj = PyList_New(0);
int initial_ref_count = Py_REFCNT(obj);

{
Expand All @@ -77,7 +78,7 @@ TEST_F(PyObjectTest, CopyCtorIncrements) {
}

TEST_F(PyObjectTest, CopyIncrements) {
PyObject* obj = PyTuple_New(0);
PyObject* obj = PyList_New(0);
int initial_ref_count = Py_REFCNT(obj);

{
Expand All @@ -97,7 +98,7 @@ TEST_F(PyObjectTest, CopyIncrements) {
}

TEST_F(PyObjectTest, MoveCtorDoesNotIncrement) {
PyObject* obj = PyTuple_New(0);
PyObject* obj = PyList_New(0);
int initial_ref_count = Py_REFCNT(obj);

{
Expand All @@ -114,7 +115,7 @@ TEST_F(PyObjectTest, MoveCtorDoesNotIncrement) {
}

TEST_F(PyObjectTest, MoveDoesNotIncrement) {
PyObject* obj = PyTuple_New(0);
PyObject* obj = PyList_New(0);
int initial_ref_count = Py_REFCNT(obj);

{
Expand All @@ -132,32 +133,36 @@ TEST_F(PyObjectTest, MoveDoesNotIncrement) {
}

TEST_F(PyObjectTest, SwapDoesNotIncrement) {
PyObject* obj1 = PyTuple_New(0);
PyObject* obj1 = PyList_New(0);
PyObject* obj2 = PyList_New(0);
int initial_ref_count1 = Py_REFCNT(obj1);
int initial_ref_count2 = Py_REFCNT(obj2);
ASSERT_NE(initial_ref_count1, initial_ref_count2);
EXPECT_EQ(initial_ref_count1, initial_ref_count2);
// Make refcount different to test swapping.
Py_INCREF(obj2);
EXPECT_NE(Py_REFCNT(obj1), Py_REFCNT(obj2));

py::Object scoped1(obj1);
py::Object scoped2(obj2);
EXPECT_EQ(initial_ref_count1 + 1, Py_REFCNT(obj1));
EXPECT_EQ(initial_ref_count2 + 1, Py_REFCNT(obj2));
EXPECT_EQ(initial_ref_count2 + 2, Py_REFCNT(obj2));

using std::swap; // go/using-std-swap
swap(scoped1, scoped2);
EXPECT_EQ(scoped2, obj1);
EXPECT_EQ(scoped1, obj2);
EXPECT_EQ(initial_ref_count1 + 1, Py_REFCNT(obj1));
EXPECT_EQ(initial_ref_count2 + 1, Py_REFCNT(obj2));
EXPECT_EQ(initial_ref_count2 + 2, Py_REFCNT(obj2));

Py_DECREF(obj1);
Py_DECREF(obj2);
Py_DECREF(obj2);
EXPECT_GT(Py_REFCNT(obj1), 0);
EXPECT_GT(Py_REFCNT(obj2), 0);
}

TEST_F(PyObjectTest, ReleaseDoesNotDescrement) {
PyObject* obj = PyTuple_New(0);
PyObject* obj = PyList_New(0);
int initial_ref_count = Py_REFCNT(obj);

py::Object scoped(obj);
Expand All @@ -171,7 +176,7 @@ TEST_F(PyObjectTest, ReleaseDoesNotDescrement) {
}

TEST_F(PyObjectTest, CopyDoesNotLeakOldValue) {
PyObject* obj = PyTuple_New(0);
PyObject* obj = PyList_New(0);
int initial_ref_count = Py_REFCNT(obj);

py::Object scoped(obj);
Expand All @@ -181,7 +186,7 @@ TEST_F(PyObjectTest, CopyDoesNotLeakOldValue) {
}

TEST_F(PyObjectTest, AssignFromPyDoesNotLeakOldValue) {
PyObject* obj = PyTuple_New(0);
PyObject* obj = PyList_New(0);
int initial_ref_count = Py_REFCNT(obj);

py::Object scoped(obj);
Expand Down
2 changes: 1 addition & 1 deletion clif/testing/python/top_level_pass_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
class TopLevelPassTest(absltest.TestCase):

def testEmptyModule(self):
self.assertRegexpMatches( # pylint: disable=deprecated-method
self.assertRegex(
top_level_pass.__doc__,
'CLIF-generated module for .*top_level_pass.clif')
self.assertIn(top_level_pass.__pyclif_codegen_mode__, ('c_api', 'pybind11'))
Expand Down

0 comments on commit 8ad1c33

Please sign in to comment.