| 107 | sys.version_info < (3, 15), reason="opaque PyObject requires Python 3.15+" |
| 108 | ) |
| 109 | def test_limited_opaque(install_temp): |
| 110 | import limited_api_opaque |
| 111 | |
| 112 | import numpy as np |
| 113 | arr = np.ones((200, 200)) |
| 114 | assert limited_api_opaque.nonzero(arr) == 200 * 200 |
| 115 | |
| 116 | # Test PyArray_ITER_NEXT / PyArray_ITER_DATA / PyArray_ITER_NOTDONE |
| 117 | arr = np.arange(12.0).reshape(3, 4) |
| 118 | assert limited_api_opaque.iter_next(arr) == 66.0 |
| 119 | |
| 120 | # Test PyArray_ITER_GOTO1D |
| 121 | assert limited_api_opaque.iter_goto1d(arr, 5) == 5.0 |
| 122 | assert limited_api_opaque.iter_goto1d(arr, -1) == 11.0 |
| 123 | |
| 124 | # Test PyArray_ITER_RESET |
| 125 | assert limited_api_opaque.iter_reset(arr) == 66.0 |
| 126 | |
| 127 | # Test PyArray_MultiIter_NEXT / RESET / DATA with broadcasting |
| 128 | a = np.arange(3.0).reshape(3, 1) # shape (3, 1) |
| 129 | b = np.arange(4.0).reshape(1, 4) # shape (1, 4) |
| 130 | # Each broadcast element is a[i] + b[j], total sum: |
| 131 | expected = float(np.sum(a + b)) |
| 132 | assert limited_api_opaque.multi_iter_next(a, b) == expected |
| 133 | |
| 134 | # Test PyArray_ITER_GOTO |
| 135 | arr = np.arange(12.0).reshape(3, 4) |
| 136 | assert limited_api_opaque.iter_goto(arr, (1, 2)) == 6.0 |
| 137 | assert limited_api_opaque.iter_goto(arr, (2, 3)) == 11.0 |
| 138 | |
| 139 | # Test PyArray_MultiIter_GOTO |
| 140 | a = np.arange(3.0).reshape(3, 1) |
| 141 | b = np.arange(4.0).reshape(1, 4) |
| 142 | va, vb = limited_api_opaque.multi_iter_goto(a, b, (1, 2)) |
| 143 | assert va == 1.0 and vb == 2.0 |
| 144 | |
| 145 | # Test PyArray_MultiIter_GOTO1D |
| 146 | # flat index 6 in (3,4) broadcast → row 1, col 2 |
| 147 | va, vb = limited_api_opaque.multi_iter_goto1d(a, b, 6) |
| 148 | assert va == 1.0 and vb == 2.0 |
| 149 | |
| 150 | # Test PyArray_MultiIter_NEXTi |
| 151 | a = np.arange(6.0).reshape(2, 3) |
| 152 | b = np.zeros((2, 3)) |
| 153 | # Advance iter 0 by 3 steps → flat index 3 → value 3.0 |
| 154 | assert limited_api_opaque.multi_iter_nexti(a, b, 3) == 3.0 |