### Install PythonMonkey Source: https://github.com/distributive-network/pythonmonkey/blob/main/README.md Install the PythonMonkey package using pip. This is the initial step to begin using the library. ```bash pip install pythonmonkey ``` -------------------------------- ### Build PythonMonkey Documentation Source: https://github.com/distributive-network/pythonmonkey/blob/main/README.md Builds the project documentation. Set the BUILD_DOCS environment variable to '1' before running 'poetry install'. ```bash BUILD_DOCS=1 poetry install ``` -------------------------------- ### Install PythonMonkey Nightly Build Source: https://github.com/distributive-network/pythonmonkey/blob/main/README.md Install the latest pre-release version of PythonMonkey from the nightly build index. Use the `--pre` flag for pre-release versions. ```bash pip install --extra-index-url https://nightly.pythonmonkey.io/ --pre pythonmonkey ``` -------------------------------- ### Install PythonMonkey Source: https://context7.com/distributive-network/pythonmonkey/llms.txt Install PythonMonkey using pip. Requires npm during installation. ```bash pip install pythonmonkey ``` ```bash # Install the nightly build pip install --extra-index-url https://nightly.pythonmonkey.io/ --pre pythonmonkey ``` -------------------------------- ### Build PythonMonkey (Default Release) Source: https://github.com/distributive-network/pythonmonkey/blob/main/README.md Installs the project and its dependencies. By default, it builds in 'Release' mode with maximum optimizations and stripped symbols. ```bash poetry install ``` -------------------------------- ### Show PythonMonkey Version Source: https://context7.com/distributive-network/pythonmonkey/llms.txt Use the `--version` flag to display the installed PythonMonkey version. ```bash pmjs --version ``` -------------------------------- ### CMake Code Formatting Example Source: https://github.com/distributive-network/pythonmonkey/blob/main/C++styleguide.md Illustrates CMake code formatting, showing how to split commands and conditions across multiple lines while maintaining indentation and brace alignment. Suitable for complex CMake scripts. ```cmake if( CONDITION AND ( ANOTHER_CONDITION OR POSSIBLY_ANOTHER_CONDITION ) ) add_custom_target("${PROJECT_NAME}-check" ALL COMMAND "${CMAKE_CTEST_COMMAND}" "." "--build-config" "$" "--output-on-failure" "--schedule-random" WORKING_DIRECTORY "${PROJECT_BINARY_DIR}" VERBATIM ) endif() ``` -------------------------------- ### Build Installable Python Packages Source: https://github.com/distributive-network/pythonmonkey/blob/main/README.md Commands to build source distribution (sdist) and wheel packages for PythonMonkey. These packages can then be installed using pip. ```bash cd python/pminit && poetry build --format=sdist && cd - && mv -v python/pminit/dist/* ./dist/ poetry build --format=wheel ``` -------------------------------- ### C++ Code Formatting Example Source: https://github.com/distributive-network/pythonmonkey/blob/main/C++styleguide.md Demonstrates C++ code formatting rules, including indentation, brace placement, and line splitting for conditions and loops. Adheres to 2-space indentation and 80-character line limits. ```cpp if ( condition && ( anotherCondition || possiblyAnotherCondition ) ) { do { ++index; } while (index < total); } else { return false; } ``` -------------------------------- ### Aggregate Initialization with Designated Initializers in C++ Source: https://github.com/distributive-network/pythonmonkey/blob/main/C++styleguide.md Provides an example of C-style aggregate initialization for structs using designated initializers. This allows for explicit member assignment by name. ```cpp { .thisMember = theValue, .thisOtherMember = theOtherValue }; ``` -------------------------------- ### Run PythonMonkey Tests Source: https://github.com/distributive-network/pythonmonkey/blob/main/README.md Installs development dependencies and runs Python tests using pytest. Ensure the project is compiled first. ```bash poetry install --no-root --only=dev poetry run pytest ./tests/python ``` -------------------------------- ### Multi-Configuration Build Type Setup Source: https://github.com/distributive-network/pythonmonkey/blob/main/CMakeLists.txt Configures the CMAKE_CONFIGURATION_TYPES for multi-configuration generators, allowing selection of build types like Profile, Sanitize, Debug, DRelease, and Release. Compile flags are appended based on the selected configuration. ```cmake if(GENERATOR_IS_MULTI_CONFIG) set(CMAKE_CONFIGURATION_TYPES "Profile;Sanitize;Debug;DRelease;Release;None" CACHE STRING "" FORCE) string(APPEND COMPILE_FLAGS "$<$:${PROFILE_FLAGS}> $<$:${SANITIZE_FLAGS}> $<$:${DEBUG_FLAGS}> $<$:${DRELEASE_FLAGS}> $<$:${RELEASE_FLAGS}>") else() set_property(CACHE PM_BUILD_TYPE PROPERTY HELPSTRING "Choose the type of build") set_property(CACHE PM_BUILD_TYPE PROPERTY STRINGS "Profile;Sanitize;Debug;DRelease;Release;None") if(PM_BUILD_TYPE STREQUAL "Profile") list(APPEND COMPILE_FLAGS "${PROFILE_FLAGS}") elseif(PM_BUILD_TYPE STREQUAL "Sanitize") list(APPEND COMPILE_FLAGS "${SANITIZE_FLAGS}") elseif(PM_BUILD_TYPE STREQUAL "Debug") list(APPEND COMPILE_FLAGS "${DEBUG_FLAGS}") elseif(PM_BUILD_TYPE STREQUAL "DRelease") list(APPEND COMPILE_FLAGS "${DRELEASE_FLAGS}") elseif(PM_BUILD_TYPE STREQUAL "None") message("PM_BUILD_TYPE is None. Not compiling.") else() #Release build message("PM_BUILD_TYPE not detected or invalid value, defaulting to Release build.") set(PM_BUILD_TYPE Release CACHE STRING "" FORCE) list(APPEND COMPILE_FLAGS "${RELEASE_FLAGS}") endif() message("PythonMonkey build type is: ${PM_BUILD_TYPE}") list(JOIN COMPILE_FLAGS " " COMPILE_FLAGS) endif() ``` -------------------------------- ### Set Minimum CMake Version Source: https://github.com/distributive-network/pythonmonkey/blob/main/CMakeLists.txt Specifies the minimum required version of CMake for this project. Ensure your CMake installation meets this requirement. ```cmake cmake_minimum_required(VERSION 3.25) ``` -------------------------------- ### Handle uncaught JS Promise rejections gracefully Source: https://context7.com/distributive-network/pythonmonkey/llms.txt Set an exception handler for the event loop to gracefully manage uncaught JavaScript Promise rejections. This example demonstrates setting a custom exception handler and evaluating JavaScript code that uses Promises. ```python import pythonmonkey as pm import asyncio async def safe_main(): loop = asyncio.get_running_loop() loop.set_exception_handler(pm.simpleUncaughtExceptionHandler) pm.eval(""" async function fetchData() { const xhr = new XMLHttpRequest(); xhr.open('GET', 'https://httpbin.org/get'); await new Promise((res, rej) => { xhr.onload = res; xhr.onerror = rej; xhr.send(); }); return xhr.responseText; } fetchData().then(console.log); """) await pm.wait() asyncio.run(safe_main()) ``` -------------------------------- ### Using pmjs: JavaScript shell and REPL Source: https://context7.com/distributive-network/pythonmonkey/llms.txt Demonstrates various ways to use the `pmjs` command-line tool, including running JS files, interactive REPL, inline evaluation, pre-loading modules, and enabling the debugger. ```bash # Run a JS program file pmjs my-program.js arg1 arg2 # Interactive REPL pmjs # Evaluate an inline expression pmjs -e "console.log('hello from pmjs')" # Print the result of an expression pmjs -p "2 ** 32" # Preload a module before entering REPL pmjs -r lodash # Enable pmdb debugger pmjs --inspect my-program.js ``` -------------------------------- ### Variable Initialization with Brace Initialization in C++ Source: https://github.com/distributive-network/pythonmonkey/blob/main/C++styleguide.md Illustrates variable initialization using brace syntax. This is an alternative to function-like constructor initialization. ```cpp Type /*modifiers*/ /*qualifiers*/ theVariable{…}; ``` -------------------------------- ### CommonJS Module in JavaScript Source: https://github.com/distributive-network/pythonmonkey/blob/main/README.md Example of a CommonJS module written in JavaScript (`date-lib.js`). It exports the current date formatted as YYYY-MM-DD. ```js // date-lib.js - require("./date-lib") const d = new Date(); exports.today = `${d.getFullYear()}-${String(d.getMonth()).padStart(2,'0')}-${String(d.getDay()).padStart(2,'0')}` ``` -------------------------------- ### Execute JavaScript Program with pmjs Source: https://github.com/distributive-network/pythonmonkey/blob/main/README.md Shows how to run a simple JavaScript file using the `pmjs` shell. The output 'hello world' is printed to the console. ```console $ echo "console.log('hello world')" > my-program.js $ pmjs my-program.js hello world $ ``` -------------------------------- ### Project Configuration Source: https://github.com/distributive-network/pythonmonkey/blob/main/CMakeLists.txt Configures the main project settings, including its name, version, description, and the primary language used (CXX). ```cmake project("PythonMonkey" VERSION ${PYTHONMONKEY_VERSION} DESCRIPTION "A tool for Javascript-Python interoperability." LANGUAGES "CXX" ) ``` -------------------------------- ### Build PythonMonkey with Profiling Enabled Source: https://github.com/distributive-network/pythonmonkey/blob/main/README.md Builds the project with profiling enabled, useful for performance analysis. Set the BUILD_TYPE environment variable to 'Profile'. ```bash BUILD_TYPE=Profile poetry install ``` -------------------------------- ### CommonJS Module in Python Source: https://github.com/distributive-network/pythonmonkey/blob/main/README.md Example of a CommonJS module written in Python (`date-lib.py`). It imports the `date` object from the `datetime` module and exports today's date. ```python # date-lib.py - require("./date-lib") from datetime import date # You can use Python libraries. exports['today'] = date.today() ``` -------------------------------- ### Evaluate JavaScript with pm.eval Source: https://context7.com/distributive-network/pythonmonkey/llms.txt Evaluate JavaScript code strings and get results coerced to Python types. Supports options for controlling evaluation context and error handling. ```python import pythonmonkey as pm # Basic expression evaluation result = pm.eval("1 + 2") print(result) # 3.0 ``` ```python # Return a JS function and call it from Python greet = pm.eval("(name) => `Hello, ${name}!`") print(greet("world")) # Hello, world! ``` ```python # Pass a Python dict to JS — it is seen as an object data = {"x": 10, "y": 20} total = pm.eval("(obj) => obj.x + obj.y")(data) print(total) # 30.0 ``` ```python # Strict mode evaluation pm.eval("'use strict'; x = 1") # raises SpiderMonkeyError: ReferenceError ``` ```python # With options: set filename for stack traces add = pm.eval("(a, b) => a + b", {"filename": "math-helpers.js", "lineno": 1}) print(add(3, 4)) # 7.0 ``` ```python # noScriptRval: suppress return value (useful for statements/declarations) pm.eval("var x = 42; var y = 99;", {"noScriptRval": True}) ``` ```python # mutedErrors: silently ignore eval errors and unhandled rejections pm.eval("throw new Error('silent')", {"mutedErrors": True}) # no exception raised ``` ```python # fromPythonFrame: map JS stack traces back to Python source location result = pm.eval("( a, b ) => a * b ", {"fromPythonFrame": True})(6, 7) print(result) # 42.0 ``` ```python # IIFE pattern — inject Python values into a JS scope import sys pm.eval("(paths) => { globalThis._pyPaths = paths; }")(sys.path) ``` -------------------------------- ### Variable Initialization with Explicit Constructor in C++ Source: https://github.com/distributive-network/pythonmonkey/blob/main/C++styleguide.md Demonstrates initializing a variable using explicit (function-like) constructor syntax. This is used when type inference is not applicable or desired. ```cpp Type /*modifiers*/ /*qualifiers*/ theVariable(…); ``` -------------------------------- ### Variable Initialization with Type Inference in C++ Source: https://github.com/distributive-network/pythonmonkey/blob/main/C++styleguide.md Shows how to initialize a variable using 'auto' when the type can be inferred from the assigned value. This promotes concise code. ```cpp auto /*modifiers*/ /*qualifiers*/ theVariable = theValue; ``` -------------------------------- ### Member Initializer List - Brace Initialization in C++ Source: https://github.com/distributive-network/pythonmonkey/blob/main/C++styleguide.md Demonstrates initializing a data member in a constructor's initializer list using brace syntax. This is an alternative to function-like initialization. ```cpp theMember{…} ``` -------------------------------- ### JS `typeof` Operator Source: https://context7.com/distributive-network/pythonmonkey/llms.txt Apply the JavaScript `typeof` operator to any value using `pm.typeof` and get the type string. This is particularly useful for differentiating JavaScript's `null`, `undefined`, functions, and objects, which can be ambiguous when translated to Python. ```python import pythonmonkey as pm print(pm.typeof(42.0)) # "number" print(pm.typeof("hello")) # "string" print(pm.typeof(True)) # "boolean" print(pm.typeof(pm.eval("undefined"))) # "undefined" print(pm.typeof(pm.null)) # "object" (JS quirk: typeof null === "object") print(pm.typeof(pm.eval("() => {}"))) # "function" print(pm.typeof({})) # "object" print(pm.typeof(pm.eval("Symbol()") )) # "symbol" # Practical: guard against calling non-functions js_val = pm.eval("Math.random") if pm.typeof(js_val) == "function": print(js_val()) # e.g. 0.7341... ``` -------------------------------- ### runProgramModule(filename, argv, extraPaths) Source: https://github.com/distributive-network/pythonmonkey/blob/main/README.md Loads and evaluates a JavaScript program (main) module. ```APIDOC ## runProgramModule(filename, argv, extraPaths) ### Description Load and evaluate a program (main) module. Program modules must be written in JavaScript. This is typically used when the main entry point of your program is in JavaScript. ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **filename** (string) - Required - The location of the JavaScript source code for the program module. - **argv** (list[string]) - Required - The program's argument vector, similar to `sys.argv` in Python. - **extraPaths** (list[string]) - Optional - A list of extra paths to search for resolving non-relative and non-absolute module identifiers. ### Request Example ```python import pythonmonkey as pm # Run a JavaScript program with arguments pm.runProgramModule('my_program.js', ['--input', 'data.txt'], ['/path/to/node_modules']) ``` ### Response #### Success Response (200) This function typically does not return a value directly but executes the JavaScript program. ``` -------------------------------- ### Build PythonMonkey with AddressSanitizer Source: https://github.com/distributive-network/pythonmonkey/blob/main/README.md Builds the project with AddressSanitizer enabled for memory error detection. Set the BUILD_TYPE environment variable to 'Sanitize'. ```bash BUILD_TYPE=Sanitize poetry install ``` -------------------------------- ### Doxygen Documentation Build Option Source: https://github.com/distributive-network/pythonmonkey/blob/main/CMakeLists.txt Configures an option to build documentation using Doxygen. If the option is enabled and Doxygen is found, it adds the documentation subdirectory. Otherwise, it prints a message indicating that docs are not being built. ```cmake # Add doxygen if this is the main app option(BUILD_DOCS "Build documentation" OFF) if(BUILD_DOCS) find_package(Doxygen) if(Doxygen_FOUND) add_subdirectory(cmake/docs) else() message(STATUS "Doxygen not found. Not building docs.") endif() endif() ``` -------------------------------- ### pm.runProgramModule(filename, argv, extraPaths) Source: https://context7.com/distributive-network/pythonmonkey/llms.txt Loads and evaluates a JavaScript program module. This is useful when the main entry point of your application is written in JavaScript, allowing outermost scope variables to become globalThis properties and providing arguments to the script. ```APIDOC ## `pm.runProgramModule(filename, argv, extraPaths)` — Run a JS program module Loads and evaluates a JavaScript program (main) module. In a program module, outermost scope variables become `globalThis` properties, and `arguments` holds the argument vector. Use this when the main entry point of your application is written in JavaScript. ```python import pythonmonkey as pm import asyncio import sys # my-app.js: # const path = require('path'); # console.log('Running:', arguments[0]); # console.log('Args:', arguments.slice(1)); async def run(): pm.runProgramModule( './my-app.js', argv=['my-app.js', '--verbose', 'input.txt'], extraPaths=['/opt/app/lib'] ) await pm.wait() # block until all async work completes asyncio.run(run()) # Output: # Running: my-app.js # Args: ['--verbose', 'input.txt'] ``` ``` -------------------------------- ### createRequire(filename, extraPaths, isMain) Source: https://github.com/distributive-network/pythonmonkey/blob/main/README.md Factory function that returns a new `require` function. ```APIDOC ## createRequire(filename, extraPaths, isMain) ### Description Factory function which returns a new require function, allowing for custom module resolution. ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **filename** (string) - Required - The pathname of the module for which this require function is being created. - **extraPaths** (list[string]) - Optional - A list of extra paths to search for resolving module identifiers. - **isMain** (boolean) - Optional - `True` if this require function is being created for a main module. ### Request Example ```python import pythonmonkey as pm # Create a require function for a specific file with extra paths custom_require = pm.createRequire('/path/to/module.js', extraPaths=['/extra/modules']) module_exports = custom_require('some_module') ``` ### Response #### Success Response (200) - **require_function** (function) - A new require function with custom resolution paths. ``` -------------------------------- ### Define Project Version Source: https://github.com/distributive-network/pythonmonkey/blob/main/CMakeLists.txt Sets the project version, intended to be dynamically updated by poetry-dynamic-versioning. It also includes a regex match to ensure the version format is correct. ```cmake set(PYTHONMONKEY_VERSION "0") # to be automatically set by poetry-dynamic-versioning string(REGEX MATCH ^[0-9]+\.[0-9]+\.[0-9]+ PYTHONMONKEY_VERSION ${PYTHONMONKEY_VERSION}) # the version number can only contain integers ``` -------------------------------- ### Uninstall PythonMonkey and Dependencies Source: https://github.com/distributive-network/pythonmonkey/blob/main/README.md Command to remove PythonMonkey and its associated package 'pminit' from your system. This ensures a clean uninstallation. ```bash pip uninstall pythonmonkey pminit ``` -------------------------------- ### Pointer and Reference Expressions in C++ Source: https://github.com/distributive-network/pythonmonkey/blob/main/C++styleguide.md Illustrates correct formatting for pointer and reference operations, including dereferencing, address-of, member access, and arrow operator. No spaces are used around the operators. ```cpp x = *p; ``` ```cpp p = &x; ``` ```cpp x = r.y; ``` ```cpp x = r->y; ``` -------------------------------- ### pmdb Debugger Help Command Source: https://github.com/distributive-network/pythonmonkey/blob/main/README.md Displays the available commands within the `pmdb` JavaScript debugger. Type `help` in the `pmdb` prompt to see this list. ```console (pmdb) > help List of commands: • ... • ... ``` -------------------------------- ### Set C++ Standards and Find Files Source: https://github.com/distributive-network/pythonmonkey/blob/main/CMakeLists.txt Configures the C++ standard to C++20, enforces its usage, disables extensions, and enables generation of compile commands. It also finds all header and source files recursively within the include and src directories, respectively. ```cmake set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) set(CMAKE_EXPORT_COMPILE_COMMANDS ON) file (GLOB_RECURSE HEADER_FILES "include/*.hh") # Find all header files in the include directory and below file (GLOB_RECURSE SOURCE_FILES "src/*.cc") # Find all C++ files in the src directory and below include_directories(${CMAKE_CURRENT_LIST_DIR}) ``` -------------------------------- ### Using pm.bigint for JS BigInt (full precision) Source: https://context7.com/distributive-network/pythonmonkey/llms.txt Demonstrates how to use pm.bigint to represent JavaScript BigInt values, ensuring full precision for large numbers in calculations. ```python big = pm.bigint(9007199254740993) result = pm.eval("(n) => typeof n")(big) print(result) # "bigint" precise = pm.eval("(n) => n + 1n")(big) print(precise) # 9007199254740994 (exact) print(type(precise)) # # Factorial computed in JS BigInt, returned to Python factorial = pm.eval(""" (function factorial(n) { if (n <= 1n) return 1n; return n * factorial(n - 1n); }) """) print(factorial(pm.bigint(20))) # 2432902008176640000 ``` -------------------------------- ### Run Python Event Loop with JavaScript Promises Source: https://github.com/distributive-network/pythonmonkey/blob/main/README.md Demonstrates running a Python event loop using `asyncio` and interacting with JavaScript Promises via `pm.eval`. This allows for `setTimeout` and `Promise` to `awaitable` coercion. ```python import asyncio async def async_fn(): await pm.eval(""" new Promise((resolve) => setTimeout((...args) => { console.log(args); resolve(); }, 1000, 42, "abc") ) "" ") await pm.eval("async (x) => await x")(asyncio.sleep(0.5)) asyncio.run(async_fn()) ``` -------------------------------- ### Build PythonMonkey with Debug Symbols Source: https://github.com/distributive-network/pythonmonkey/blob/main/README.md Builds the project with debug symbols enabled, useful for debugging. Set the BUILD_TYPE environment variable to 'Debug'. ```bash BUILD_TYPE=Debug poetry install ``` -------------------------------- ### C++ Namespace and Macro Naming Convention Source: https://github.com/distributive-network/pythonmonkey/blob/main/C++styleguide.md Demonstrates a naming convention for C++ namespaces, structs, macros, and functions, including header guards. This pattern helps emulate namespaces in C and macros, ensuring clarity and preventing naming conflicts. ```cpp #if !defined(DCP_NamespaceName_StructName_) #define DCP_NamespaceName_StructName_ #define DCP_NamespaceName_StructName_macroName(argumentName) !(argumentName) #define DCP_NamespaceName_StructName_definitionName 42 namespace DCP::NamespaceName { struct StructName { int functionName(int argumentName) { int variableName = argumentName; return variableName; } int memberName; }; } #endif ``` -------------------------------- ### pm.createRequire(filename, extraPaths, isMain) Source: https://context7.com/distributive-network/pythonmonkey/llms.txt Creates a `require` function scoped to a specific file location, useful when the caller's file path cannot be inferred from the call stack. ```APIDOC ## pm.createRequire(filename, extraPaths, isMain) — Create a scoped require function Factory that returns a `require` function scoped to a specific file location. Essential when the caller's file path cannot be inferred from the call stack (e.g., inside generated code, lambdas, or wrappers). Equivalent to Node.js `node:module.createRequire()`. ```python import pythonmonkey as pm import os # Create a require scoped to the current file require = pm.createRequire(__file__) # Resolve modules relative to this file utils = require('./utils') print(utils['VERSION']) ``` ``` -------------------------------- ### C++ Class Copyability and Movability Source: https://github.com/distributive-network/pythonmonkey/blob/main/C++styleguide.md Demonstrates how to explicitly define copyable, move-only, and non-copyable/non-movable semantics for C++ structs. Use these patterns to clearly communicate a class's intended usage. ```cpp struct Copyable { Copyable(Copyable const &other) = default; Copyable &operator=(Copyable const &other) = default; // The implicit move operations are suppressed by the declarations above. // You may explicitly declare move operations to support efficient moves. }; struct MoveOnly { MoveOnly(MoveOnly &&other) = default; MoveOnly &operator=(MoveOnly &&other) = default; // The copy operations are implicitly deleted, but you can // spell that out explicitly if you want: MoveOnly(MoveOnly const &) = delete; MoveOnly &operator=(MoveOnly const &) = delete; }; struct NotCopyableOrMovable { // Not copyable or movable NotCopyableOrMovable(NotCopyableOrMovable const &) = delete; NotCopyableOrMovable &operator=(NotCopyableOrMovable const &) = delete; // The move operations are implicitly disabled, but you can // spell that out explicitly if you want: NotCopyableOrMovable(NotCopyableOrMovable &&) = delete; NotCopyableOrMovable& operator=(NotCopyableOrMovable &&) = delete; }; ``` -------------------------------- ### Run JavaScript Tests with PythonMonkey Source: https://github.com/distributive-network/pythonmonkey/blob/main/README.md Executes JavaScript tests using a bash script. Ensure the project is compiled first. ```bash poetry run bash ./peter-jr ./tests/js/ ``` -------------------------------- ### Member Initializer List - Explicit Constructor in C++ Source: https://github.com/distributive-network/pythonmonkey/blob/main/C++styleguide.md Shows the syntax for initializing a data member within a constructor's initializer list using explicit (function-like) syntax. Members must be initialized in declaration order. ```cpp theMember(…) ``` -------------------------------- ### Using pm.null for JS null singleton Source: https://context7.com/distributive-network/pythonmonkey/llms.txt Illustrates the use of pm.null to represent JavaScript's null value, distinguishing it from Python's None (which maps to JS undefined). ```python import pythonmonkey as pm # JS null vs undefined print(pm.eval("null === null")) # True print(pm.eval("(v) => v === null")(pm.null)) # True print(pm.eval("(v) => v === null")(None)) # False (None → undefined) # Practical: passing null to a JS function that checks for it js_fn = pm.eval("(x) => x === null ? 'got null' : 'got something else'") print(js_fn(pm.null)) # got null print(js_fn(None)) # got something else print(pm.typeof(pm.null)) # object (classic JS typeof null quirk) ``` -------------------------------- ### Fetch Content Module Source: https://github.com/distributive-network/pythonmonkey/blob/main/CMakeLists.txt Includes the FetchContent module, which is commonly used for managing external dependencies in CMake projects. ```cmake include(FetchContent) ``` -------------------------------- ### Create Scoped Require with pm.createRequire Source: https://context7.com/distributive-network/pythonmonkey/llms.txt Create a require function scoped to a specific file location, useful when the call stack cannot infer the caller's path. Equivalent to Node.js `node:module.createRequire()`. ```python import pythonmonkey as pm import os # Create a require scoped to the current file require = pm.createRequire(__file__) # Resolve modules relative to this file utils = require('./utils') print(utils['VERSION']) ``` -------------------------------- ### Create Require with Extra Paths Source: https://context7.com/distributive-network/pythonmonkey/llms.txt Use `createRequire` to establish a require function that includes additional directories for module resolution. This is useful for shared libraries or custom module structures. ```python import pythonmonkey as pm import os # Create a require with extra search paths extra_paths = ['/opt/myapp/js-libs', os.path.expanduser('~/node_modules')] require_with_extras = pm.createRequire(__file__, extra_paths) my_lib = require_with_extras('my-shared-lib') # Create a program (main) module require — sets globalThis.require, module, exports main_require = pm.createRequire( os.path.abspath('./main.js'), extraPaths=False, isMain=True ) # Now globalThis.require is available to all JS code result = main_require('./startup') ``` -------------------------------- ### Check JavaScript REPL completeness with pm.isCompilableUnit Source: https://context7.com/distributive-network/pythonmonkey/llms.txt Use `pm.isCompilableUnit(code)` to determine if a JavaScript string is syntactically complete or requires more input. This is useful for building interactive REPLs. It returns `True` for complete statements and `False` for incomplete ones. ```python import pythonmonkey as pm # Complete statements print(pm.isCompilableUnit("1 + 2")) # True print(pm.isCompilableUnit("function f() {}")) # True print(pm.isCompilableUnit("")) # True # Incomplete statements — need more input print(pm.isCompilableUnit("function f() {")) # False print(pm.isCompilableUnit("if (true) {")) # False print(pm.isCompilableUnit("(1 +")) # False ``` ```python import sys import pythonmonkey as pm buffer = "" while True: try: line = input("... " if buffer else "> ") except EOFError: break buffer += ("\n" if buffer else "") + line if pm.isCompilableUnit(buffer): try: result = pm.eval(buffer) if result is not None: print(repr(result)) except Exception as e: print(f"Error: {e}") buffer = "" ``` -------------------------------- ### Evaluate JavaScript Code with PythonMonkey Source: https://github.com/distributive-network/pythonmonkey/blob/main/README.md Demonstrates how to use the `eval` function to execute JavaScript code within a Python environment. The last expression evaluated in the JavaScript code string is returned. ```python import pythonmonkey as pm hello = pm.eval("() => {return 'Hello from Spidermonkey!'}") hello() ``` -------------------------------- ### pmjs REPL Python Expression Evaluation Source: https://github.com/distributive-network/pythonmonkey/blob/main/README.md Demonstrates using the `pmjs` REPL to evaluate Python expressions. Python expressions can be evaluated and stored in variables like `$1`, `$2`, etc. ```console $ pmjs Welcome to PythonMonkey v1.0.0. Type ".help" for more information. > .python import sys > .python sys.path $1 = { '0': '/home/wes/git/pythonmonkey2', '1': '/usr/lib/python310.zip', '2': '/usr/lib/python3.10', '3': '/usr/lib/python3.10/lib-dynload', '4': '/home/wes/.cache/pypoetry/virtualenvs/pythonmonkey-StuBmUri-py3.10/lib/python3.10/site-packages', '5': '/home/wes/git/pythonmonkey2/python' } > $1[3] '/usr/lib/python3.10/lib-dynload' > ``` -------------------------------- ### Instantiate JavaScript Classes with 'new' Source: https://github.com/distributive-network/pythonmonkey/blob/main/README.md Use the pm.new function to create a Python callable that invokes a JavaScript constructor with the 'new' operator. This is necessary for instantiating JavaScript classes. ```python import pythonmonkey as pm >>> pm.eval("class MyClass { constructor() { console.log('ran ctor') }}") >>> MyClass = pm.eval("MyClass") >>> MyClass() Traceback (most recent call last): File "", line 1, in pythonmonkey.SpiderMonkeyError: TypeError: class constructors must be invoked with 'new' >>> MyClassCtor = pm.new(MyClass) >>> MyClassCtor() ran ctor {} ``` -------------------------------- ### Enable pmdb Debugger in Python Source: https://github.com/distributive-network/pythonmonkey/blob/main/README.md Instructions on how to enable the built-in `pmdb` JavaScript debugger within a Python script. This debugger is triggered by `debugger;` statements and uncaught exceptions. ```python import pythonmonkey as pm from pythonmonkey.lib import pmdb pmdb.enable() pm.eval("...") ``` -------------------------------- ### require(moduleIdentifier) Source: https://github.com/distributive-network/pythonmonkey/blob/main/README.md Returns the exports of a CommonJS module identified by `moduleIdentifier`. ```APIDOC ## require(moduleIdentifier) ### Description Returns the exports of a CommonJS module identified by `moduleIdentifier`, using standard CommonJS semantics. ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **moduleIdentifier** (string) - Required - The identifier of the module to load. Relative to the Python file invoking `require`. Should not include a file extension. Modules not starting with './', '../', or '/' are resolved via `require.path` and `module.paths`. ### Request Example ```python import pythonmonkey as pm # Assuming 'my-module.js' exists and exports a function my_module = pm.require('my-module') my_module.someFunction() ``` ### Response #### Success Response (200) - **exports** (object) - The exports object of the required module. ``` -------------------------------- ### Run JS Program Module Source: https://context7.com/distributive-network/pythonmonkey/llms.txt Execute a JavaScript program module using `runProgramModule`. This function loads and evaluates a JS file, making outermost scope variables global and providing arguments to the script. Use this for JS applications where the entry point is JavaScript. ```python import pythonmonkey as pm import asyncio import sys # my-app.js: # const path = require('path'); # console.log('Running:', arguments[0]); # console.log('Args:', arguments.slice(1)); async def run(): pm.runProgramModule( './my-app.js', argv=['my-app.js', '--verbose', 'input.txt'], extraPaths=['/opt/app/lib'] ) await pm.wait() # block until all async work completes asyncio.run(run()) # Output: # Running: my-app.js # Args: ['--verbose', 'input.txt'] ``` -------------------------------- ### Apply Compile Flags and Find Dependencies Source: https://github.com/distributive-network/pythonmonkey/blob/main/CMakeLists.txt Applies the determined compile flags to CMAKE_CXX_FLAGS and sets up the module path. It then finds and configures Python and SpiderMonkey, including platform-specific adjustments for dependency discovery. ```cmake if(NOT PM_BUILD_TYPE STREQUAL "None") SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${COMPILE_FLAGS}") set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/modules) if(APPLE) find_package(Python 3.8 COMPONENTS Interpreter Development REQUIRED) find_package(SpiderMonkey REQUIRED) set(PYTHON_MAJOR $ENV{Python_VERSION_MAJOR}) set(PYTHON_MINOR $ENV{Python_VERSION_MINOR}) set(PYTHONLIBS_VERSION_STRING ${Python_VERSION}) set(PYTHON_INCLUDE_DIR ${Python_INCLUDE_DIRS}) set(PYTHON_LIBRARIES ${Python_LIBRARIES}) elseif(UNIX) find_package(Python 3.8 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(Python 3.8 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) endif() message("${CMAKE_SYSTEM_NAME} - Using Python:${Python_VERSION} - Libraries:${Python_LIBRARIES} - IncludeDirs: ${Python_INCLUDE_DIRS}") include_directories(${Python_INCLUDE_DIRS}) include_directories(${SPIDERMONKEY_INCLUDE_DIR}) # Add compiled folder directories add_subdirectory(src) endif(NOT PM_BUILD_TYPE STREQUAL "None") ``` -------------------------------- ### pm.require(moduleIdentifier) Source: https://context7.com/distributive-network/pythonmonkey/llms.txt Loads a CommonJS module, returning its exports. Supports JavaScript, Python, and JSON modules, as well as npm packages. Modules are cached after the first load. ```APIDOC ## pm.require(moduleIdentifier) — Load a CommonJS module Returns the `exports` of a CommonJS module. Supports `.js`, `.py`, and `.json` file extensions. Modules are singletons — loaded and evaluated only once. Relative identifiers are resolved relative to the calling Python file. Non-relative identifiers are resolved via `require.path` and `module.paths`. ```python import pythonmonkey as pm # Load a JS module (./math-utils.js) # math-utils.js: # exports.add = (a, b) => a + b; # exports.square = (x) => x * x; math = pm.require('./math-utils') print(math['add'](3, 4)) # 7.0 print(math['square'](5)) # 25.0 # Load a Python module as a CommonJS module (./string-utils.py) # string-utils.py: # exports['shout'] = lambda s: s.upper() + '!' string_utils = pm.require('./string-utils') print(string_utils['shout']('hello')) # HELLO! # Load a JSON module # config.json: { "host": "localhost", "port": 8080 } config = pm.require('./config') print(config['host']) # localhost print(config['port']) # 8080.0 # Load an npm package (resolved via node_modules) lodash = pm.require('lodash') chunked = lodash['chunk']([1, 2, 3, 4, 5], 2) print(list(chunked)) # [[1, 2], [3, 4], [5]] ``` ``` -------------------------------- ### Load CommonJS Modules with pm.require Source: https://context7.com/distributive-network/pythonmonkey/llms.txt Load CommonJS modules, supporting .js, .py, and .json extensions. Modules are singletons and resolved relative to the calling Python file or via require.path. ```python import pythonmonkey as pm # Load a JS module (./math-utils.js) # math-utils.js: # exports.add = (a, b) => a + b; # exports.square = (x) => x * x; math = pm.require('./math-utils') print(math['add'](3, 4)) # 7.0 print(math['square'](5)) # 25.0 ``` ```python # Load a Python module as a CommonJS module (./string-utils.py) # string-utils.py: # exports['shout'] = lambda s: s.upper() + '!' string_utils = pm.require('./string-utils') print(string_utils['shout']('hello')) # HELLO! ``` ```python # Load a JSON module # config.json: { "host": "localhost", "port": 8080 } config = pm.require('./config') print(config['host']) # localhost print(config['port']) # 8080.0 ``` ```python # Load an npm package (resolved via node_modules) lodash = pm.require('lodash') chunked = lodash['chunk']([1, 2, 3, 4, 5], 2) print(list(chunked)) # [[1, 2], [3, 4], [5]] ``` -------------------------------- ### Enabling and using the pmdb JavaScript debugger Source: https://context7.com/distributive-network/pythonmonkey/llms.txt Activates the built-in `pmdb` JavaScript debugger, which can be triggered by `debugger;` statements or uncaught exceptions, offering interactive debugging capabilities. ```python import pythonmonkey as pm from pythonmonkey.lib import pmdb # Enable pmdb before running any JS pmdb.enable() # pmdb activates when a `debugger;` statement is hit pm.eval(""" function add(a, b) { debugger; # <-- pmdb drops into interactive mode here return a + b; } add(3, 4); """) # pmdb session example: # (pmdb) > l # function add(a, b) { # ^ # (pmdb) > p a # 3 # (pmdb) > p b # 4 # (pmdb) > b 4 <- set breakpoint on line 4 # (pmdb) > n <- step next # (pmdb) > bt <- print backtrace # (pmdb) > c <- continue # (pmdb) > q <- quit / force exit ``` -------------------------------- ### globalThis Source: https://github.com/distributive-network/pythonmonkey/blob/main/README.md A Python dictionary equivalent to the JavaScript `globalThis` object. ```APIDOC ## globalThis ### Description A Python Dict which is equivalent to the globalThis object in JavaScript. ### Usage Access properties and methods of the global JavaScript environment directly through this dictionary. ### Example ```python import pythonmonkey as pm # Access a global JavaScript variable console_log = pm.globalThis['console']['log'] console_log('Hello from Python via globalThis!') ``` ### Response #### Success Response (200) - **globalThis** (dict) - A dictionary representing the JavaScript global scope. ``` -------------------------------- ### pm.isCompilableUnit(code) Source: https://context7.com/distributive-network/pythonmonkey/llms.txt Checks if a given JavaScript string is syntactically complete and can be evaluated, or if it requires more input. This is useful for building interactive JavaScript REPLs. ```APIDOC ## `pm.isCompilableUnit(code)` — REPL completeness check Returns `False` if the JavaScript string might become valid with more input (i.e., is syntactically incomplete). Used to build JavaScript REPLs that accumulate lines until a complete statement is ready for evaluation. ```python import pythonmonkey as pm # Complete statements print(pm.isCompilableUnit("1 + 2")) # True print(pm.isCompilableUnit("function f() {}")) # True print(pm.isCompilableUnit("")) # True # Incomplete statements — need more input print(pm.isCompilableUnit("function f() {")) # False print(pm.isCompilableUnit("if (true) {")) # False print(pm.isCompilableUnit("(1 +")) # False # Build a simple JS REPL import sys buffer = "" while True: try: line = input("... " if buffer else "> ") except EOFError: break buffer += ("\n" if buffer else "") + line if pm.isCompilableUnit(buffer): try: result = pm.eval(buffer) if result is not None: print(repr(result)) except Exception as e: print(f"Error: {e}") buffer = "" ``` ``` -------------------------------- ### pm.new(ctor) Source: https://context7.com/distributive-network/pythonmonkey/llms.txt Invokes a JavaScript constructor with the `new` operator semantics. This wrapper is necessary because calling JS class constructors directly from Python raises a `SpiderMonkeyError`. ```APIDOC ## `pm.new(ctor)` — Invoke a JS constructor with `new` Wraps a JavaScript class constructor so it can be called from Python using the `new` operator semantics. Without this, calling a JS class constructor directly from Python raises a `SpiderMonkeyError` because classes must be invoked with `new`. ```python import pythonmonkey as pm # Define a JS class pm.eval(""" class Point { constructor(x, y) { this.x = x; this.y = y; } toString() { return `Point(${this.x}, ${this.y})`; } } """) Point = pm.eval("Point") PointCtor = pm.new(Point) p = PointCtor(3, 4) print(p['x']) # 3.0 print(p['y']) # 4.0 print(pm.eval("(p) => p.toString() ")(p)) # Point(3, 4) # pm.new also accepts a JS expression string DateCtor = pm.new("Date") now = DateCtor() # creates a new JS Date object (coerced to Python datetime) print(type(now)) # # Using with built-in JS constructors MapCtor = pm.new(pm.eval("Map")) m = MapCtor() pm.eval("(m) => m.set('key', 42)")(m) print(pm.eval("(m) => m.get('key')")(m)) # 42.0 ``` ``` -------------------------------- ### isCompilableUnit(code) Source: https://github.com/distributive-network/pythonmonkey/blob/main/README.md Examines JavaScript code to determine if it can be compiled as a complete unit. ```APIDOC ## isCompilableUnit(code) ### Description Examines the string `code` and returns `False` if the string might become a valid JS statement with the addition of more lines. This is useful for building JavaScript REPLs where lines are accumulated until this function returns `True`. ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **code** (string) - Required - The JavaScript code string to examine. ### Request Example ```python import pythonmonkey as pm # Check if a code snippet is a complete unit print(pm.isCompilableUnit('var x = 1;')) # True print(pm.isCompilableUnit('function foo() {')) # False ``` ### Response #### Success Response (200) - **compilable** (boolean) - `True` if the code is a complete compilable unit, `False` otherwise. ``` -------------------------------- ### pm.globalThis Source: https://context7.com/distributive-network/pythonmonkey/llms.txt Provides access to the JavaScript `globalThis` object as a Python dictionary-like object (`JSObjectProxy`). Allows reading and writing global JavaScript variables and accessing standard JS globals. ```APIDOC ## `pm.globalThis` — The JS global object A Python `dict` (specifically a `JSObjectProxy`) that is the JavaScript `globalThis` object. Reading and writing this dict directly reads and writes JavaScript global variables. All JS standard classes and globals are accessible through it. ```python import pythonmonkey as pm # Read a JS global print(pm.globalThis['Math']['PI']) # 3.141592653589793 print(pm.globalThis['undefined']) # None (JS undefined) # Set a global variable accessible to all subsequent JS evaluations pm.globalThis['MY_APP_VERSION'] = "2.1.0" print(pm.eval("MY_APP_VERSION")) # 2.1.0 # Access standard globals directly from the module (also exported) print(pm.Math['sqrt'](16.0)) # 4.0 print(pm.JSON['stringify']({"a": 1})) # '{"a":1}' # Use globalThis to inject Python callbacks into JS def on_event(event_name, data): print(f"[Python] Event: {event_name}, data: {data}") pm.globalThis['onEvent'] = on_event pm.eval("onEvent('click', { x: 100, y: 200 })") # [Python] Event: click, data: {'x': 100.0, 'y': 200.0} ``` ``` -------------------------------- ### Loading Python modules as CommonJS in JavaScript Source: https://context7.com/distributive-network/pythonmonkey/llms.txt Enables using Python files as CommonJS modules in JavaScript by exporting Python variables and functions via the `exports` dictionary. ```python # math_helpers.py (loaded by JS as require('./math_helpers')) import math exports['PI'] = math.pi exports['sqrt'] = math.sqrt exports['hypot'] = math.hypot exports['factorial'] = math.factorial ``` ```javascript // app.js (run via pmjs or pm.runProgramModule) const { PI, sqrt, hypot, factorial } = require('./math_helpers'); console.log(PI); // 3.141592653589793 console.log(sqrt(2)); // 1.4142135623730951 console.log(hypot(3, 4)); // 5.0 console.log(factorial(10)); // 3628800 ``` ```python # Driving the whole thing from Python import pythonmonkey as pm import asyncio async def main(): pm.runProgramModule('./app.js', ['app.js']) await pm.wait() asyncio.run(main()) ``` -------------------------------- ### PythonMonkey Interactive Console Source: https://context7.com/distributive-network/pythonmonkey/llms.txt Interact with PythonMonkey using its command-line interface. You can execute JavaScript expressions, import Python modules, and run Python code directly. ```console $ pmjs Welcome to PythonMonkey v1.0.0. Type ".help" for more information. > 2 + 2 4 > .python import sys > .python sys.version $1 = '3.10.12 (main, ...' > $1.split(' ')[0] '3.10.12' > const greet = (name) => `Hello, ${name}!` undefined > greet('world') 'Hello, world!' > .exit ```