Node.js library that enables seamless integration of Python libraries into JavaScript applications
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Advanced type conversion capabilities between Python and JavaScript, including specialized typed array handling, buffer protocol support, and proxified alternatives.
Convert between Python array.array objects and JavaScript TypedArrays with automatic type mapping.
/**
* Get the JavaScript TypedArray constructor for a Python array.array object
* @param array - Python array.array PyObject
* @returns TypedArray constructor (Uint8Array, Float32Array, etc.)
*/
function getJSType(array: PyObject): TypedArrayConstructor;
/**
* Get the Python array.array type code for a JavaScript TypedArray
* @param array - JavaScript TypedArray
* @returns Python array type code string ('b', 'i', 'f', etc.)
*/
function getPythonType(array: TypedArray): string;
/**
* Convert Python array.array to JavaScript TypedArray (contents copied)
* @param array - Python array.array PyObject
* @returns Corresponding JavaScript TypedArray
*/
function toTypedArray(array: PyObject): TypedArray;
/**
* Convert JavaScript TypedArray to Python array.array (contents copied)
* @param array - JavaScript TypedArray
* @returns Python array.array PyObject
*/
function toPythonArray(array: TypedArray): PyObject;Usage Examples:
import { toTypedArray, toPythonArray, getJSType, getPythonType } from 'pymport/array';
// Create Python array
const array_module = pymport('array');
const pyArray = array_module.get('array').call('f', [1.1, 2.2, 3.3, 4.4]);
// Convert to JavaScript TypedArray
const jsArray = toTypedArray(pyArray);
console.log(jsArray); // Float32Array [1.1, 2.2, 3.3, 4.4]
console.log(jsArray.constructor.name); // "Float32Array"
// Get type information
const JSType = getJSType(pyArray);
console.log(JSType.name); // "Float32Array"
// Convert JavaScript TypedArray to Python
const uint32Array = new Uint32Array([1, 2, 3, 4]);
const pyArray2 = toPythonArray(uint32Array);
console.log(getPythonType(uint32Array)); // "I" (unsigned int)
// Type mappings:
// 'b' → Int8Array
// 'B' → Uint8Array
// 'h' → Int16Array
// 'H' → Uint16Array
// 'i' → Int32Array
// 'I' → Uint32Array
// 'l' → Int32Array or BigInt64Array (platform dependent)
// 'L' → Uint32Array or BigUint64Array (platform dependent)
// 'q' → BigInt64Array
// 'Q' → BigUint64Array
// 'f' → Float32Array
// 'd' → Float64ArrayExecute Python expressions with full context control for dynamic code execution.
/**
* Evaluate Python code with optional global and local contexts
* @param code - Python expression string (not statements)
* @param globals - Global context (PyObject dict or JS object)
* @param locals - Local context (PyObject dict or JS object)
* @returns PyObject result of the evaluation
*/
function pyval(
code: string,
globals?: PyObject | Record<string, any>,
locals?: PyObject | Record<string, any>
): PyObject;Usage Examples:
import { pyval, pymport } from 'pymport';
// Basic mathematical expressions
const result1 = pyval('2 ** 10');
console.log(result1.toJS()); // 1024
const result2 = pyval('abs(-42) + max([1, 5, 3])');
console.log(result2.toJS()); // 47
// Using imported modules
const np = pymport('numpy');
const globals = { np, x: [1, 2, 3, 4, 5] };
const array_result = pyval('np.array(x) * 2', globals);
console.log(array_result.toJS()); // [2, 4, 6, 8, 10]
// Complex expressions with local variables
const math = pymport('math');
const context = {
math,
radius: 5
};
const area = pyval('math.pi * radius ** 2', context);
console.log(area.toJS()); // ~78.54
// String operations
const text_result = pyval('"hello".upper() + " " + "world".title()');
console.log(text_result.toJS()); // "HELLO World"Use proxified versions of core pymport functions that automatically return proxified objects.
/**
* Proxified PyObject class that creates proxified objects
*/
const PyObject: typeof rawPyObject & any;
/**
* Proxified pymport function that returns proxified modules
* @param mod - Python module name
* @returns Proxified Python module
*/
const pymport: (mod: string) => any;
/**
* Proxified pyval function that returns proxified results
* @param code - Python expression string
* @param globals - Global context
* @param locals - Local context
* @returns Proxified PyObject result
*/
function pyval(
code: string,
globals?: typeof PyObject | Record<string, any>,
locals?: typeof PyObject | Record<string, any>
): any;Usage Examples:
// Import proxified versions
import { pymport, pyval, PyObject } from 'pymport/proxified';
// All results are automatically proxified
const np = pymport('numpy'); // Already proxified
const array = np.arange(12).reshape(3, 4); // Natural syntax
const sum = array.sum(); // No .get() needed
// Proxified pyval
const result = pyval('list(range(5))'); // Returns proxified list
console.log(result[2]); // Access like JS array: 2
// Proxified object creation
const pyList = PyObject.list([1, 2, 3]);
console.log(pyList.append); // Direct method access
pyList.append(4); // Natural method callHandle Python objects that implement the buffer protocol (bytes, bytearray, memoryview) with automatic Buffer conversion.
// From PyObject.toJS() conversion options
interface ConversionOptions {
/**
* Maximum recursion depth for nested objects
* undefined = unlimited depth
*/
depth?: number;
/**
* Whether to convert buffer protocol objects to Node.js Buffers
* true = convert to Buffer (default)
* false = keep as PyObject
*/
buffer?: boolean;
}Usage Examples:
// Python bytes/bytearray to Buffer conversion
const pyBytes = PyObject.bytes(Buffer.from('Hello'));
const pyBytearray = PyObject.bytearray(Buffer.from('World'));
// Automatic Buffer conversion (default)
const buffer1 = pyBytes.toJS(); // Node.js Buffer
const buffer2 = pyBytearray.toJS(); // Node.js Buffer
// Keep as PyObject
const pyObj1 = pyBytes.toJS({ buffer: false }); // Still PyObject
const pyObj2 = pyBytearray.toJS({ buffer: false }); // Still PyObject
// Memory view handling
const originalBuffer = Buffer.from('Shared Memory');
const memView = PyObject.memoryview(originalBuffer);
// Memoryview references original buffer
const sharedBuffer = memView.toJS();
originalBuffer[0] = 65; // Modify original
console.log(sharedBuffer[0]); // 65 (reflects change)Handle complex nested structures with configurable conversion depth.
Usage Examples:
const np = proxify(pymport('numpy'));
// Create complex nested structure
const nested = {
arrays: [
np.array([1, 2, 3]),
np.array([[4, 5], [6, 7]])
],
metadata: {
shape: np.array([2, 2]),
dtype: np.float64
}
};
const pyNested = PyObject.fromJS(nested);
// Full conversion (unlimited depth)
const fullJS = pyNested.toJS();
console.log(fullJS.arrays[0]); // [1, 2, 3] (JS array)
// Shallow conversion (depth=1)
const shallow = pyNested.toJS({ depth: 1 });
console.log(shallow.arrays[0].toJS); // Still PyObject (function exists)
// Intermediate depth
const intermediate = pyNested.toJS({ depth: 2 });
console.log(intermediate.arrays); // JS array
console.log(intermediate.arrays[0].toJS); // Still PyObjectType conversion errors include full Python traceback information.
Usage Examples:
try {
// This will fail - can't convert incompatible types
const badConversion = pyval('object()').toJS();
} catch (error) {
if (error.pythonTrace) {
console.log('Python Error Type:', error.pythonType.toString());
console.log('Python Value:', error.pythonValue.toString());
console.log('Python Traceback:', error.pythonTrace.toString());
}
}
try {
// Invalid Python syntax
const invalid = pyval('2 +'); // Incomplete expression
} catch (error) {
console.log('Syntax Error:', error.message);
}Complete type definitions for the array conversion module:
type TypedArray = Uint8Array | Int8Array | Uint16Array | Int16Array |
Uint32Array | Int32Array | BigUint64Array | BigInt64Array |
Float32Array | Float64Array;
type TypedArrayConstructor =
typeof Uint8Array | typeof Int8Array | typeof Uint16Array | typeof Int16Array |
typeof Uint32Array | typeof Int32Array | typeof BigUint64Array | typeof BigInt64Array |
typeof Float32Array | typeof Float64Array;
interface ConversionOptions {
depth?: number;
buffer?: boolean;
}Install with Tessl CLI
npx tessl i tessl/npm-pymport