diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 01ef0077..96085e88 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -12,7 +12,7 @@ jobs: strategy: matrix: os: [ 'ubuntu-latest' ] # , 'windows-latest', 'macos-latest' ] - python_version: [ '3.10' ] + python_version: [ '3.9', '3.10', '3.11' ] runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v2 diff --git a/CMakeLists.txt b/CMakeLists.txt index 4d34aea9..9fd40977 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -64,7 +64,10 @@ if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME) set(PYTHON_LIBRARIES ${Python_LIBRARIES}) message("Apple - Using Python:${Python_VERSION_MAJOR} - Libraries:${PYTHON_LIBRARIES} - IncludeDirs: ${PYTHON_INCLUDE_DIR}") elseif(UNIX) - find_package(PythonLibs 3.9...3.11 REQUIRED) + find_package(Python 3.9...<3.12 COMPONENTS Interpreter Development REQUIRED) + set(Python_FIND_VIRTUALENV FIRST) # (require cmake >= v3.15 and this is the default) use the Python version configured by pyenv if available + set(PYTHON_LIBRARIES ${Python_LIBRARIES}) + set(PYTHON_INCLUDE_DIR ${Python_INCLUDE_DIRS}) find_package(SpiderMonkey REQUIRED) elseif(WIN32) find_package(PythonInterp 3.9...3.11 REQUIRED) diff --git a/src/IntType.cc b/src/IntType.cc index cb8cdb18..76fc67b2 100644 --- a/src/IntType.cc +++ b/src/IntType.cc @@ -58,14 +58,13 @@ IntType::IntType(JSContext *cx, JS::BigInt *bigint) { // If the native endianness is also little-endian, // we now have consecutive bytes of 8-bit "digits" in little-endian order const uint8_t *bytes = const_cast((uint8_t *)jsDigits); - if (jsDigitCount == 0) { - // Create a new object instead of reusing the object for int 0 - // see https://github.com/python/cpython/blob/3.9/Objects/longobject.c#L862 - // https://github.com/python/cpython/blob/3.9/Objects/longobject.c#L310 - pyObject = (PyObject *)_PyLong_New(0); - } else { - pyObject = _PyLong_FromByteArray(bytes, jsDigitCount * JS_DIGIT_BYTE, true, false); - } + PyObject *pyIntObj = _PyLong_FromByteArray(bytes, jsDigitCount * JS_DIGIT_BYTE, true, false); + + // Cast to a pythonmonkey.bigint to differentiate it from a normal Python int, + // allowing Py<->JS two-way BigInt conversion. + // We don't do `Py_SET_TYPE` because `_PyLong_FromByteArray` may cache and reuse objects for small ints + pyObject = PyObject_CallOneArg(PythonMonkey_BigInt, pyIntObj); // pyObject = pythonmonkey.bigint(pyIntObj) + Py_DECREF(pyIntObj); // Set the sign bit // see https://github.com/python/cpython/blob/3.9/Objects/longobject.c#L956 @@ -73,10 +72,6 @@ IntType::IntType(JSContext *cx, JS::BigInt *bigint) { ssize_t pyDigitCount = Py_SIZE(pyObject); Py_SET_SIZE(pyObject, -pyDigitCount); } - - // Cast to a pythonmonkey.bigint to differentiate it from a normal Python int, - // allowing Py<->JS two-way BigInt conversion - Py_SET_TYPE(pyObject, (PyTypeObject *)(PythonMonkey_BigInt)); } JS::BigInt *IntType::toJsBigInt(JSContext *cx) { @@ -144,4 +139,4 @@ void IntType::print(std::ostream &os) const { os << PyUnicode_AsUTF8(str); // https://pythonextensionpatterns.readthedocs.io/en/latest/refcount.html#new-references Py_DECREF(str); // free -} \ No newline at end of file +}