Skip to content

Commit 430723c

Browse files
committed
add a version info getter
1 parent 5993209 commit 430723c

File tree

7 files changed

+113
-3
lines changed

7 files changed

+113
-3
lines changed

.vscode/c_cpp_properties.json

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,15 @@
11
{
2+
"env": {
3+
"projectDefines": [
4+
"NAPI_EXPERIMENTAL",
5+
"NODE_ADDON_API_DISABLE_DEPRECATED",
6+
"NAPI_VERSION=6",
7+
"PYMPORT_VERSION_MAJOR=1",
8+
"PYMPORT_VERSION_MINOR=0",
9+
"PYMPORT_VERSION_PATCH=0",
10+
"PYMPORT_VERSION_SUFFIX=git"
11+
]
12+
},
213
"configurations": [
314
{
415
"name": "Linux",
@@ -7,6 +18,9 @@
718
"${workspaceFolder}/node_modules/node-addon-api",
819
"/usr/include/python3.8"
920
],
21+
"defines": [
22+
"${projectDefines}"
23+
],
1024
"compilerPath": "/usr/bin/g++",
1125
"cStandard": "c17",
1226
"cppStandard": "c++14"
@@ -18,6 +32,9 @@
1832
"C:/Program Files/Python310/include",
1933
"~/AppData/Local/node-gyp/Cache/16.10.0/include/node"
2034
],
35+
"defines": [
36+
"${projectDefines}"
37+
],
2138
"compilerPath": "cl.exe",
2239
"cStandard": "c17",
2340
"cppStandard": "c++14"

binding.gyp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,13 @@
2020
"<!@(node -p \"require('node-addon-api').include\")"
2121
],
2222
'defines': [
23-
'NAPI_EXPERIMENTAL'
23+
'NAPI_EXPERIMENTAL',
2424
'NODE_ADDON_API_DISABLE_DEPRECATED',
25-
'NAPI_VERSION=6'
25+
'NAPI_VERSION=6',
26+
'PYMPORT_VERSION_MAJOR=<!(node -e "console.log(require(\'./package.json\').version.split(\'.\')[0])")',
27+
'PYMPORT_VERSION_MINOR=<!(node -e "console.log(require(\'./package.json\').version.split(\'.\')[1])")',
28+
'PYMPORT_VERSION_PATCH=<!(node -e "console.log(require(\'./package.json\').version.split(\'-\')[0].split(\'.\')[2])")',
29+
'PYMPORT_VERSION_SUFFIX=<!(node -e "console.log(require(\'./package.json\').version.split(\'-\')[1])")'
2630
],
2731
'dependencies': ["<!(node -p \"require('node-addon-api').gyp\")"],
2832
'conditions': [

lib/index.d.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,3 +161,24 @@ export function pyval(
161161
globals?: PyObject | Record<string, any>,
162162
locals?: PyObject | Record<string, any>
163163
): PyObject;
164+
165+
export const version: {
166+
pymport: { major: number, minor: number, patch: number, suffix: string; },
167+
pythonLibrary: {
168+
builtin: boolean;
169+
major: number;
170+
minor: number;
171+
micro: number;
172+
release: number;
173+
serial: number;
174+
/**
175+
* Hex number
176+
*/
177+
version: string;
178+
};
179+
/**
180+
* Supported only on Python 3.11+
181+
*/
182+
pythonRuntime: null | string;
183+
pythonPath: string;
184+
};

src/main.cc

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,72 @@
11
#include <locale>
22
#include <codecvt>
33
#include <string>
4+
#include <iomanip>
45

56
#include "pymport.h"
67
#include "values.h"
78

89
using namespace Napi;
910
using namespace pymport;
1011

12+
#define STR(s) __STR(s)
13+
#define __STR(x) #x
14+
1115
size_t pymport::active_environments = 0;
1216
std::wstring builtin_python_path;
1317

18+
std::string to_hex(long number) {
19+
std::stringstream r;
20+
r << std::hex << number;
21+
return r.str();
22+
}
23+
24+
Value Version(const CallbackInfo &info) {
25+
Env env = info.Env();
26+
Object versionInfo = Object::New(env);
27+
28+
Object pymportVersion = Object::New(env);
29+
versionInfo.Set("pymport", pymportVersion);
30+
pymportVersion.Set("major", Number::New(env, PYMPORT_VERSION_MAJOR));
31+
pymportVersion.Set("minor", Number::New(env, PYMPORT_VERSION_MINOR));
32+
pymportVersion.Set("patch", Number::New(env, PYMPORT_VERSION_PATCH));
33+
pymportVersion.Set("suffix", String::New(env, STR(PYMPORT_VERSION_SUFFIX)));
34+
35+
#ifdef BUILTIN_PYTHON_PATH
36+
bool builtin = true;
37+
#else
38+
bool builtin = false;
39+
#endif
40+
Object pythonLibrary = Object::New(env);
41+
versionInfo.Set("pythonLibrary", pythonLibrary);
42+
pythonLibrary.Set("builtin", Boolean::New(env, builtin));
43+
pythonLibrary.Set("major", Number::New(env, PY_MAJOR_VERSION));
44+
pythonLibrary.Set("minor", Number::New(env, PY_MINOR_VERSION));
45+
pythonLibrary.Set("micro", Number::New(env, PY_MICRO_VERSION));
46+
pythonLibrary.Set("release", Number::New(env, PY_RELEASE_LEVEL));
47+
pythonLibrary.Set("serial", Number::New(env, PY_RELEASE_SERIAL));
48+
pythonLibrary.Set("version", String::New(env, to_hex(PY_VERSION_HEX)));
49+
50+
#if PY_MAJOR_VERSION > 3 || (PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 11)
51+
versionInfo.Set("pythonRuntime", String::New(env, to_hex(Py_Version())));
52+
#else
53+
versionInfo.Set("pythonRuntime", env.Null());
54+
#endif
55+
56+
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
57+
std::string pyHome = converter.to_bytes(Py_GetPythonHome());
58+
versionInfo.Set("pythonPath", String::New(env, pyHome.c_str()));
59+
60+
return versionInfo;
61+
}
62+
1463
Napi::Object Init(Env env, Object exports) {
1564
Function pyObjCons = PyObjectWrap::GetClass(env);
1665

1766
exports.Set("PyObject", pyObjCons);
1867
exports.Set("pymport", Function::New(env, PyObjectWrap::Import));
1968
exports.Set("pyval", Function::New(env, PyObjectWrap::Eval));
69+
exports.DefineProperty(PropertyDescriptor::Accessor<Version>("version", napi_enumerable));
2070

2171
auto context = new EnvContext();
2272
context->pyObj = new FunctionReference();

test/pymport.test.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,25 @@
1-
import { pymport } from 'pymport';
1+
import { pymport, version } from 'pymport';
22
import { assert } from 'chai';
33

4+
import pkg from '../package.json';
5+
46
describe('pymport', () => {
57
afterEach('gc', global.gc);
68

9+
it('version', () => {
10+
assert.strictEqual(version.pymport.major, +pkg.version.split('.')[0]);
11+
assert.strictEqual(version.pymport.minor, +pkg.version.split('.')[1]);
12+
assert.strictEqual(version.pymport.patch, +pkg.version.split('-')[0].split('.')[2]);
13+
assert.isBoolean(version.pythonLibrary.builtin);
14+
assert.isNumber(version.pythonLibrary.major);
15+
assert.isNumber(version.pythonLibrary.minor);
16+
assert.isNumber(version.pythonLibrary.micro);
17+
assert.isNumber(version.pythonLibrary.release);
18+
assert.isNumber(version.pythonLibrary.serial);
19+
assert.isString(version.pythonLibrary.version);
20+
assert.isString(version.pythonPath);
21+
});
22+
723
describe('numpy', () => {
824
it('basic pyimport', () => {
925
const np = pymport('numpy');

test/tsconfig.test.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
"strict": true,
55
"strictNullChecks": true,
66
"baseUrl": ".",
7+
"resolveJsonModule": true,
78
"paths": {
89
"@mapbox/node-pre-gyp": [
910
"./mapbox-node-pre-gyp"

tsconfig.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
"compilerOptions": {
33
"esModuleInterop": true,
44
"moduleResolution": "node",
5+
"resolveJsonModule": true,
56
"paths": {
67
"pymport": [
78
"."

0 commit comments

Comments
 (0)