WiseLibs / better-sqlite3

The fastest and simplest library for SQLite3 in Node.js.
MIT License
5.23k stars 390 forks source link

Unable to install when using Python 3.12.2 | ModuleNotFoundError: No module named 'distutils' #1154

Closed travislaynewilson closed 4 months ago

travislaynewilson commented 4 months ago

Python: 3.12.2 installed.

I'm attempting to do a clean install into my Electron app in VSCode using the following command: npm install better-sqlite3 --save

The install fails with the following stack:

npm ERR! code 1
npm ERR! path G:\Current\[REDACTED]\Repositories\ci-transfer\src\ui\node_modules\better-sqlite3
npm ERR! command failed
npm ERR! command C:\Windows\system32\cmd.exe /d /s /c C:\Users\[REDACTED]\AppData\Local\Temp\install-a3e7fb70.cmd
npm ERR! prebuild-install warn install No prebuilt binaries found (target=16.17.0 runtime=node arch=x64 libc= platform=win32)
npm ERR! gyp info it worked if it ends with ok
npm ERR! gyp info using node-gyp@8.4.1
npm ERR! gyp info using node@16.17.0 | win32 | x64
npm ERR! gyp info find Python using Python version 3.12.2 found at "C:\Python312\python.exe"
npm ERR! gyp info find VS using VS2019 (16.11.34601.136) found at:
npm ERR! gyp info find VS "C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools"
npm ERR! gyp info find VS run with --verbose for detailed information
npm ERR! gyp info spawn C:\Python312\python.exe
npm ERR! gyp info spawn args [
npm ERR! gyp info spawn args   'G:\\Current\\[REDACTED]\\Repositories\\ci-transfer\\src\\ui\\node_modules\\node-gyp\\gyp\\gyp_main.py',
npm ERR! gyp info spawn args   'binding.gyp',
npm ERR! gyp info spawn args   '-f',
npm ERR! gyp info spawn args   'msvs',
npm ERR! gyp info spawn args   '-I',
npm ERR! gyp info spawn args   'G:\\Current\\[REDACTED]\\Repositories\\ci-transfer\\src\\ui\\node_modules\\better-sqlite3\\build\\config.gypi',
npm ERR! gyp info spawn args   '-I',
npm ERR! gyp info spawn args   'G:\\Current\\[REDACTED]\\Repositories\\ci-transfer\\src\\ui\\node_modules\\node-gyp\\addon.gypi',
npm ERR! gyp info spawn args   '-I',
npm ERR! gyp info spawn args   'C:\\Users\\[REDACTED]\\AppData\\Local\\node-gyp\\Cache\\16.17.0\\include\\node\\common.gypi',
npm ERR! gyp info spawn args   '-Dlibrary=shared_library',
npm ERR! gyp info spawn args   '-Dvisibility=default',
npm ERR! gyp info spawn args   '-Dnode_root_dir=C:\\Users\\[REDACTED]\\AppData\\Local\\node-gyp\\Cache\\16.17.0',
npm ERR! gyp info spawn args   '-Dnode_gyp_dir=G:\\Current\\[REDACTED]\\Repositories\\ci-transfer\\src\\ui\\node_modules\\node-gyp',
npm ERR! gyp info spawn args   '-Dnode_lib_file=C:\\\\Users\\\\[REDACTED]\\\\AppData\\\\Local\\\\node-gyp\\\\Cache\\\\16.17.0\\\\<(target_arch)\\\\node.lib',
npm ERR! gyp info spawn args   '-Dmodule_root_dir=G:\\Current\\[REDACTED]\\Repositories\\ci-transfer\\src\\ui\\node_modules\\better-sqlite3',
npm ERR! gyp info spawn args   '-Dnode_engine=v8',
npm ERR! gyp info spawn args   '--depth=.',
npm ERR! gyp info spawn args   '--no-parallel',
npm ERR! gyp info spawn args   '--generator-output',
npm ERR! gyp info spawn args   'G:\\Current\\[REDACTED]\\Repositories\\ci-transfer\\src\\ui\\node_modules\\better-sqlite3\\build',
npm ERR! gyp info spawn args   '-Goutput_dir=.'
npm ERR! gyp info spawn args ]
npm ERR! Traceback (most recent call last):
npm ERR!   File "G:\Current\[REDACTED]\Repositories\ci-transfer\src\ui\node_modules\node-gyp\gyp\gyp_main.py", line 42, in <module>
npm ERR!     import gyp  # noqa: E402
npm ERR!     ^^^^^^^^^^
npm ERR!   File "G:\Current\[REDACTED]\Repositories\ci-transfer\src\ui\node_modules\node-gyp\gyp\pylib\gyp\__init__.py", line 9, in <module>
npm ERR!     import gyp.input
npm ERR!   File "G:\Current\[REDACTED]\Repositories\ci-transfer\src\ui\node_modules\node-gyp\gyp\pylib\gyp\input.py", line 19, in <module>
npm ERR!     from distutils.version import StrictVersion
npm ERR! ModuleNotFoundError: No module named 'distutils'
npm ERR! gyp ERR! configure error
npm ERR! gyp ERR! stack Error: `gyp` failed with exit code: 1
npm ERR! gyp ERR! stack     at ChildProcess.onCpExit (G:\Current\[REDACTED]\Repositories\ci-transfer\src\ui\node_modules\node-gyp\lib\configure.js:259:16)
npm ERR! gyp ERR! stack     at ChildProcess.emit (node:events:513:28)
npm ERR! gyp ERR! stack     at Process.ChildProcess._handle.onexit (node:internal/child_process:291:12)
npm ERR! gyp ERR! System Windows_NT 10.0.22631
npm ERR! gyp ERR! command "C:\\Program Files\\nodejs\\node.exe" "G:\\Current\\[REDACTED]\\Repositories\\ci-transfer\\src\\ui\\node_modules\\node-gyp\\bin\\node-gyp.js" "rebuild" "--release"
npm ERR! gyp ERR! cwd G:\Current\[REDACTED]\Repositories\ci-transfer\src\ui\node_modules\better-sqlite3
npm ERR! gyp ERR! node -v v16.17.0
npm ERR! gyp ERR! node-gyp -v v8.4.1
npm ERR! gyp ERR! not ok

According to my research, distutils is no longer supported/exported in Python 3.12.

neoxpert commented 4 months ago

better-sqlite3 itself is not using Python or any Python dependencies but does rely on node-gyp in order to build the native library in case no prebuilt binary is available.

As NodeJS 16 has reached its end of life 5 months ago, it is not covered with prebuilt binaries anymore. If you do not want to deal with setting up a proper build environment, which would also require a more up to date version of node-gyp, the easiest way would be to update the used NodeJS version to a recent LTS release in order to make use of the available prebuilt binaries. Otherwise you might try to update the global version of node-gyp to the latest release which already contains adjustments to work with Python 3.12 https://github.com/nodejs/gyp-next/pull/214.

mceachen commented 4 months ago

Recent versions of Python dropped bundling distutils by default, and broke a ton of software in the process.

If your setup can't be upgraded to one of the (100+!) prebuilt os/architecture/node combinations of better-sqlite3, try running

pip install setuptools
npm install better-sqlite3 --save

See more here: https://github.com/nodejs/node-gyp/issues/2915