Browse by type
PythonMonkey is a Mozilla SpiderMonkey JavaScript engine embedded into the Python Runtime, using the Python engine to provide the Javascript host environment.
We feature JavaScript Array and Object methods implemented on Python List and Dictionaries using the cPython C API, and the inverse using the Mozilla Firefox Spidermonkey JavaScript C++ API.
This project has reached MVP as of September 2024. It is under maintenance by Distributive.
External contributions and feedback are welcome and encouraged.
$ pip install pythonmonkey
from pythonmonkey import eval as js_eval
js_eval("console.log")('hello, world')
eval() function in Python which accepts JS code and returns JS->Python coerced valuesrequire function, returns a coerced dict of module exportsRead this if you want to build a local version.
You will need the following installed (which can be done automatically by running ./setup.sh):
Run poetry install. This command automatically compiles the project and installs the project as well as dependencies into the poetry virtualenv. If you would like to build the docs, set the BUILD_DOCS environment variable, like so: BUILD_DOCS=1 poetry install.
PythonMonkey supports multiple build types, which you can build by setting the BUILD_TYPE environment variable, like so: BUILD_TYPE=Debug poetry install. The build types are (case-insensitive):
Release: stripped symbols, maximum optimizations (default)DRelease: same as Release, except symbols are not strippedDebug: minimal optimizationsSanitize: same as Debug, except with AddressSanitizer enabledProfile: same as Debug, except profiling is enabled None: don't compile (useful if you only want to build the docs)If you are using VSCode, you can just press Ctrl + Shift + B to run build task - We have the tasks.json file configured for you.
poetry install --no-root --only=devpoetry run pytest ./tests/pythonpoetry run bash ./peter-jr ./tests/js/For VSCode users, similar to the Build Task, we have a Test Task ready to use.
npm (Node.js) is required during installation only to populate the JS dependencies.
$ pip install pythonmonkey
$ pip install --extra-index-url https://nightly.pythonmonkey.io/ --pre pythonmonkey
pythonmonkey is available in the poetry virtualenv once you compiled the project using poetry.
$ poetry run python
Python 3.10.6 (main, Nov 14 2022, 16:10:14) [GCC 11.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import pythonmonkey as pm
>>> hello = pm.eval("() => {return 'Hello from Spidermonkey!'}")
>>> hello()
'Hello from Spidermonkey!'
Alternatively, you can build installable packages by running
$ cd python/pminit && poetry build --format=sdist && cd - && mv -v python/pminit/dist/* ./dist/
$ poetry build --format=wheel
and install them by pip install ./dist/*.
Installing pythonmonkey will also install the pminit package as a dependency. However, pip uninstalling a package won't automatically remove its dependencies.
If you want to cleanly remove pythonmonkey from your system, do the following:
$ pip uninstall pythonmonkey pminit
poetry run gdb python.
See Python Wiki: DebuggingWithGdbIf you are using VSCode, it's more convenient to debug in VSCode's built-in debugger. Simply press F5 on an open Python file in the editor to start debugging - We have the launch.json file configured for you.
These methods are exported from the pythonmonkey module. See definitions in python/pythonmonkey/pythonmonkey.pyi.
Evaluate JavaScript code. The semantics of this eval are very similar to the eval used in JavaScript;
the last expression evaluated in the code string is used as the return value of this function. To
evaluate code in strict mode, the first expression should be the string "use strict".
The eval function supports an options object that can affect how JS code is evaluated in powerful ways.
They are largely based on SpiderMonkey's CompileOptions. The supported option keys are:
- filename: set the filename of this code for the purposes of generating stack traces etc.
- lineno: set the line number offset of this code for the purposes of generating stack traces etc.
- column: set the column number offset of this code for the purposes of generating stack traces etc.
- mutedErrors: if set to True, eval errors or unhandled rejections are ignored ("muted"). Default False.
- noScriptRval: if False, return the last expression value of the script as the result value to the caller. Default False.
- selfHosting: experimental
- strict: forcibly evaluate in strict mode ("use strict"). Default False.
- module: indicate the file is an ECMAScript module (always strict mode code and disallow HTML comments). Default False.
- fromPythonFrame: generate the equivalent of filename, lineno, and column based on the location of
the Python call to eval. This makes it possible to evaluate Python multiline string literals and
generate stack traces in JS pointing to the error in the Python source file.
undefined in JavaScript; if you want to return a function, you must
evaluate an expression:
python
pythonmonkey.eval("myFunction() { return 123 }; myFunction")
or
python
pythonmonkey.eval("(myFunction() { return 123 })")python
pythonmonkey.eval("(thing) => console.log('you said', thing)")("this string came from Python")Return the exports of a CommonJS module identified by moduleIdentifier, using standard CommonJS
semantics
- modules are singletons and will never be loaded or evaluated more than once
- moduleIdentifier is relative to the Python file invoking require
- moduleIdentifier should not include a file extension
- moduleIdentifiers which do not begin with ./, ../, or / are resolved by search require.path
and module.paths.
- Modules are evaluated immediately after loading
- Modules are not loaded until they are required
- The following extensions are supported:
* .js - JavaScript module; source code decorates exports object
* .py - Python module; source code decorates exports dict
* .json - JSON module; exports are the result of parsing the JSON text in the file
A Python Dict which is equivalent to the globalThis object in JavaScript.
Factory function which returns a new require function - filename: the pathname of the module that this require function could be used for - extraPaths: [optional] a list of extra paths to search to resolve non-relative and non-absolute module identifiers - isMain: [optional] True if the require function is being created for a main module
Load and evaluate a program (main) module. Program modules must be written in JavaScript. Program modules are not necessary unless the main entry point of your program is written in JavaScript. - filename: the location of the JavaScript source code - argv: the program's argument vector - extraPaths: [optional] a list of extra paths to search to resolve non-relative and non-absolute module identifiers
Care should be taken to ensure that only one program module is run per JS context.
Examines the string code and returns False if the string might become a valid JS statement with
the addition of more lines. This is used internally by pmjs and can be very helpful for building
JavaScript REPLs; the idea is to accumulate lines in a buffer until isCompilableUnit is true, then
evaluate the entire buffer.
Returns a Python function which invokes function with the JS new operator.
import pythonmonkey as pm
>>> pm.eval("class MyClass { constructor() { console.log('ran ctor') }}")
>>> MyClass = pm.eval("MyClass")
>>> MyClass()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
pythonmonkey.SpiderMonkeyError: TypeError: class constructors must be invoked with 'new'
>>> MyClassCtor = pm.new(MyClass)
>>> MyClassCtor()
ran ctor
{}
>>>
This is the JS typeof operator, wrapped in a function so that it can be used easily from Python.
All of the JS Standard Classes (Array, Function, Object, Date...) and objects (globalThis, FinalizationRegistry...) are available as exports of the pythonmonkey module. These exports are generated by enumerating the global variable in the current SpiderMonkey context. The current list is:
undefined, Boolean, JSON, Date, Math, Number, String, RegExp, Error, InternalError, AggregateError, EvalError, RangeError, ReferenceError, SyntaxError, TypeError, URIError, ArrayBuffer, Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array, Float32Array, Float64Array, Uint8ClampedArray, BigInt64Array, BigUint64Array, BigInt, Proxy, WeakMap, Map, Set, DataView, Symbol, Intl, Reflect, WeakSet, Promise, WebAssembly, WeakRef, Iterator, AsyncIterator, NaN, Infinity, isNaN, isFinite, parseFloat, parseInt, escape, unescape, decodeURI, encodeURI, decodeURIComponent, encodeURIComponent, Function, Object, debuggerGlobal, FinalizationRegistry, Array, globalThis
See definitions in [python/pythonmonkey/global.d.ts](h
$ claude mcp add PythonMonkey \
-- python -m otcore.mcp_server <graph>