Skip to content

Commit bcfcbf3

Browse files
committed
refactor: add shim for PyObject_CallOneArg
1 parent 3f7f722 commit bcfcbf3

File tree

4 files changed

+18
-12
lines changed

4 files changed

+18
-12
lines changed

include/pyshim.hh

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,4 +118,14 @@ static inline void _Py_SET_SIZE(PyVarObject *ob, Py_ssize_t size) {
118118
#define Py_SET_SIZE(ob, size) _Py_SET_SIZE((PyVarObject *)(ob), size)
119119
#endif
120120

121+
/**
122+
* @brief Shim for `PyObject_CallOneArg`.
123+
* `PyObject_CallOneArg` is not available in Python < 3.9
124+
*/
125+
#if PY_VERSION_HEX < 0x03090000 // Python version is less than 3.9
126+
inline PyObject *PyObject_CallOneArg(PyObject *func, PyObject *arg) {
127+
return PyObject_CallFunction(func, "O", arg);
128+
}
129+
#endif
130+
121131
#endif // #ifndef PythonMonkey_py_version_shim_

src/ExceptionType.cc

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@
1919
#include <jsapi.h>
2020
#include <js/Exception.h>
2121

22+
#include <Python.h>
2223
#include <frameobject.h>
24+
#include "include/pyshim.hh"
2325

2426

2527
PyObject *ExceptionType::getPyObject(JSContext *cx, JS::HandleObject error) {
@@ -29,11 +31,7 @@ PyObject *ExceptionType::getPyObject(JSContext *cx, JS::HandleObject error) {
2931
PyObject *errStr = getExceptionString(cx, JS::ExceptionStack(cx, errValue, errStack), true);
3032

3133
// Construct a new SpiderMonkeyError python object
32-
#if PY_VERSION_HEX >= 0x03090000
3334
PyObject *pyObject = PyObject_CallOneArg(SpiderMonkeyError, errStr); // _PyErr_CreateException, https://github.com/python/cpython/blob/3.9/Python/errors.c#L100
34-
#else
35-
PyObject *pyObject = PyObject_CallFunction(SpiderMonkeyError, "O", errStr); // PyObject_CallOneArg is not available in Python < 3.9
36-
#endif
3735
Py_XDECREF(errStr);
3836

3937
// Preserve the original JS Error object as the Python Exception's `jsError` attribute for lossless two-way conversion

src/IntType.cc

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@
1414
#include <jsapi.h>
1515
#include <js/BigInt.h>
1616

17+
#include <Python.h>
18+
#include "include/pyshim.hh"
19+
1720
#include <vector>
1821

1922
#define SIGN_BIT_MASK 0b1000 // https://hg.mozilla.org/releases/mozilla-esr102/file/tip/js/src/vm/BigIntType.h#l40
@@ -98,11 +101,7 @@ PyObject *IntType::getPyObject(JSContext *cx, JS::BigInt *bigint) {
98101
// Cast to a pythonmonkey.bigint to differentiate it from a normal Python int,
99102
// allowing Py<->JS two-way BigInt conversion.
100103
// We don't do `Py_SET_TYPE` because `_PyLong_FromByteArray` may cache and reuse objects for small ints
101-
#if PY_VERSION_HEX >= 0x03090000
102104
PyObject *pyObject = PyObject_CallOneArg(getPythonMonkeyBigInt(), pyIntObj); // pyObject = pythonmonkey.bigint(pyIntObj)
103-
#else
104-
PyObject *pyObject = PyObject_CallFunction(getPythonMonkeyBigInt(), "O", pyIntObj); // PyObject_CallOneArg is not available in Python < 3.9
105-
#endif
106105
Py_DECREF(pyIntObj);
107106

108107
// Set the sign bit

src/PromiseType.cc

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@
1919
#include <jsfriendapi.h>
2020
#include <js/Promise.h>
2121

22+
#include <Python.h>
23+
#include "include/pyshim.hh"
24+
2225
// slot ids to access the python object in JS callbacks
2326
#define PY_FUTURE_OBJ_SLOT 0
2427
#define PROMISE_OBJ_SLOT 1
@@ -38,11 +41,7 @@ static bool onResolvedCb(JSContext *cx, unsigned argc, JS::Value *vp) {
3841
if (state == JS::PromiseState::Rejected && !PyExceptionInstance_Check(result)) {
3942
// Wrap the result object into a SpiderMonkeyError object
4043
// because only *Exception objects can be thrown in Python `raise` statement and alike
41-
#if PY_VERSION_HEX >= 0x03090000
4244
PyObject *wrapped = PyObject_CallOneArg(SpiderMonkeyError, result); // wrapped = SpiderMonkeyError(result)
43-
#else
44-
PyObject *wrapped = PyObject_CallFunction(SpiderMonkeyError, "O", result); // PyObject_CallOneArg is not available in Python < 3.9
45-
#endif
4645
// Preserve the original JS value as the `jsError` attribute for lossless conversion back
4746
PyObject *originalJsErrCapsule = DictType::getPyObject(cx, resultArg);
4847
PyObject_SetAttrString(wrapped, "jsError", originalJsErrCapsule);

0 commit comments

Comments
 (0)