{"id":16259752,"url":"https://github.com/distributive-network/pythonmonkey","last_synced_at":"2025-05-15T15:07:13.755Z","repository":{"id":89201199,"uuid":"538570824","full_name":"Distributive-Network/PythonMonkey","owner":"Distributive-Network","description":"A Mozilla SpiderMonkey JavaScript engine embedded into the Python VM, using the Python engine to provide the JS host environment.","archived":false,"fork":false,"pushed_at":"2025-04-07T20:50:09.000Z","size":8294,"stargazers_count":895,"open_issues_count":43,"forks_count":42,"subscribers_count":11,"default_branch":"main","last_synced_at":"2025-05-13T01:06:20.305Z","etag":null,"topics":["cpp","javascript","python","pythonmonkey","spidermonkey"],"latest_commit_sha":null,"homepage":"https://pythonmonkey.io","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Distributive-Network.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2022-09-19T15:32:19.000Z","updated_at":"2025-05-12T16:32:22.000Z","dependencies_parsed_at":"2024-01-04T00:52:41.342Z","dependency_job_id":"e1b5c624-7c70-4bbe-b7ea-20da9e0b6773","html_url":"https://github.com/Distributive-Network/PythonMonkey","commit_stats":null,"previous_names":[],"tags_count":15,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Distributive-Network%2FPythonMonkey","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Distributive-Network%2FPythonMonkey/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Distributive-Network%2FPythonMonkey/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Distributive-Network%2FPythonMonkey/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Distributive-Network","download_url":"https://codeload.github.com/Distributive-Network/PythonMonkey/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254364270,"owners_count":22058878,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cpp","javascript","python","pythonmonkey","spidermonkey"],"created_at":"2024-10-10T16:04:49.471Z","updated_at":"2025-05-15T15:07:08.746Z","avatar_url":"https://github.com/Distributive-Network.png","language":"C++","readme":"# PythonMonkey\n\n[![Test and Publish Suite](https://github.com/Distributive-Network/PythonMonkey/actions/workflows/test-and-publish.yaml/badge.svg)](https://github.com/Distributive-Network/PythonMonkey/actions/workflows/test-and-publish.yaml)\n\n## About\n[PythonMonkey](https://pythonmonkey.io) is a Mozilla [SpiderMonkey](https://firefox-source-docs.mozilla.org/js/index.html) JavaScript engine embedded into the Python Runtime,\nusing the Python engine to provide the Javascript host environment.\n\nWe 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.\n\nThis project has reached MVP as of September 2024. It is under maintenance by [Distributive](https://distributive.network/).\n\nExternal contributions and feedback are welcome and encouraged.\n\n### tl;dr\n```bash\n$ pip install pythonmonkey\n```\n```python\nfrom pythonmonkey import eval as js_eval\n\njs_eval(\"console.log\")('hello, world')\n```\n\n### Goals\n- **Fast** and memory-efficient\n- Make writing code in either JS or Python a developer preference\n- Use JavaScript libraries from Python\n- Use Python libraries from JavaScript\n- The same process runs both JavaScript and Python VirtualMachines - no serialization, pipes, etc\n- Python Lists and Dicts behave as Javacript Arrays and Objects, and vice-versa, fully adapting to the given context.\n\n### Data Interchange\n- Strings share immutable backing stores whenever possible (when allocating engine choses UCS-2 or Latin-1 internal string representation) to keep memory consumption under control, and to make it possible to move very large strings between JavaScript and Python library code without memory-copy overhead.\n- TypedArrays share mutable backing stores.\n- JS objects are represented by Python dicts through a Dict subclass for optimal compatibility. Similarly for JS arrays and Python lists.\n- JS Date objects are represented by Python datetime.datetime objects\n- Intrinsics (boolean, number, null, undefined) are passed by value\n- JS Functions are automatically wrapped so that they behave like Python functions, and vice-versa\n- Python Lists are represented by JS true arrays and support all Array methods through a JS API Proxy. Similarly for Python Dicts and JS objects.\n\n### Roadmap\n- [done] JS instrinsics coerce to Python intrinsics\n- [done] JS strings coerce to Python strings\n- [done] JS objects coerce to Python dicts [own-properties only]\n- [done] JS functions coerce to Python function wrappers\n- [done] JS exceptions propagate to Python\n- [done] Implement `eval()` function in Python which accepts JS code and returns JS-\u003ePython coerced values\n- [done] NodeJS+NPM-compatible CommonJS module system\n- [done] Python strings coerce to JS strings\n- [done] Python intrinsics coerce to JS intrinsics\n- [done] Python dicts coerce to JS objects\n- [done] Python `require` function, returns a coerced dict of module exports\n- [done] Python functions coerce to JS function wrappers\n- [done] CommonJS module system .py loader, loads Python modules for use by JS\n- [done] Python host environment supplies event loop, including EventEmitter, setTimeout, etc.\n- [done] Python host environment supplies XMLHttpRequest\n- [done] Python TypedArrays coerce to JS TypeArrays\n- [done] JS TypedArrays coerce to Python TypeArrays\n- [done] Python lists coerce to JS Arrays\n- [done] JS arrays coerce to Python lists\n- [90%] PythonMonkey can run the dcp-client npm package from Distributive.\n\n## Build Instructions\n\nRead this if you want to build a local version.\n\n1. You will need the following installed (which can be done automatically by running `./setup.sh`):\n    - bash\n    - cmake\n    - Doxygen 1.9 series (if you want to build the docs)\n    - graphviz  (if you want to build the docs)\n    - llvm\n    - rust\n    - python3.8 or later with header files (python3-dev)\n    - spidermonkey latest from mozilla-central\n    - npm (nodejs)\n    - [Poetry](https://python-poetry.org/docs/#installation)\n    - [poetry-dynamic-versioning](https://github.com/mtkennerly/poetry-dynamic-versioning)\n\n2. 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`.\nPythonMonkey 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):\n- `Release`: stripped symbols, maximum optimizations (default)\n- `DRelease`: same as `Release`, except symbols are not stripped\n- `Debug`: minimal optimizations\n- `Sanitize`: same as `Debug`, except with [AddressSanitizer](https://github.com/google/sanitizers/wiki/AddressSanitizer) enabled\n- `Profile`: same as `Debug`, except profiling is enabled \n- `None`: don't compile (useful if you only want to build the docs)\n\nIf you are using VSCode, you can just press \u003ckbd\u003eCtrl\u003c/kbd\u003e + \u003ckbd\u003eShift\u003c/kbd\u003e + \u003ckbd\u003eB\u003c/kbd\u003e to [run build task](https://code.visualstudio.com/docs/editor/tasks#_custom-tasks) - We have [the `tasks.json` file configured for you](.vscode/tasks.json).\n\n## Running tests\n1. Compile the project\n2. Install development dependencies: `poetry install --no-root --only=dev`\n3. From the root directory, run `poetry run pytest ./tests/python`\n4. From the root directory, run `poetry run bash ./peter-jr ./tests/js/`\n\nFor VSCode users, similar to the Build Task, we have a Test Task ready to use.\n\n## Using the library\n\n\u003e npm (Node.js) is required **during installation only** to populate the JS dependencies.\n\n### Install from [PyPI](https://pypi.org/project/pythonmonkey/)\n\n```bash\n$ pip install pythonmonkey\n```\n\n### Install the [nightly build](https://nightly.pythonmonkey.io/)\n\n```bash\n$ pip install --extra-index-url https://nightly.pythonmonkey.io/ --pre pythonmonkey\n```\n\n### Use local version\n\n`pythonmonkey` is available in the poetry virtualenv once you compiled the project using poetry.\n\n```bash\n$ poetry run python\n```\n```py\nPython 3.10.6 (main, Nov 14 2022, 16:10:14) [GCC 11.3.0] on linux\nType \"help\", \"copyright\", \"credits\" or \"license\" for more information.\n\u003e\u003e\u003e import pythonmonkey as pm\n\u003e\u003e\u003e hello = pm.eval(\"() =\u003e {return 'Hello from Spidermonkey!'}\")\n\u003e\u003e\u003e hello()\n'Hello from Spidermonkey!'\n```\n\nAlternatively, you can build installable packages by running\n```bash\n$ cd python/pminit \u0026\u0026 poetry build --format=sdist \u0026\u0026 cd - \u0026\u0026 mv -v python/pminit/dist/* ./dist/\n$ poetry build --format=wheel\n```\nand install them by `pip install ./dist/*`.\n\n## Uninstallation\n\nInstalling `pythonmonkey` will also install the `pminit` package as a dependency. However, `pip uninstall`ing a package won't automatically remove its dependencies.  \nIf you want to cleanly remove `pythonmonkey` from your system, do the following:\n\n```bash\n$ pip uninstall pythonmonkey pminit\n```\n\n## Debugging Steps\n\n1. [build the project locally](#build-instructions)\n2. To use gdb, run `poetry run gdb python`.\nSee [Python Wiki: DebuggingWithGdb](https://wiki.python.org/moin/DebuggingWithGdb)\n\nIf you are using VSCode, it's more convenient to debug in [VSCode's built-in debugger](https://code.visualstudio.com/docs/editor/debugging). Simply press \u003ckbd\u003eF5\u003c/kbd\u003e on an open Python file in the editor to start debugging - We have [the `launch.json` file configured for you](https://github.com/Distributive-Network/PythonMonkey/blob/main/.vscode/launch.json).\n\n## Examples\n\n* [examples/](https://github.com/Distributive-Network/PythonMonkey/tree/main/examples)\n* https://github.com/Distributive-Network/PythonMonkey-examples\n* https://github.com/Distributive-Network/PythonMonkey-Crypto-JS-Fullstack-Example\n\n## Official API\nThese methods are exported from the pythonmonkey module. See definitions in [python/pythonmonkey/pythonmonkey.pyi](https://github.com/Distributive-Network/PythonMonkey/blob/main/python/pythonmonkey/pythonmonkey.pyi).\n\n### eval(code, options)\nEvaluate JavaScript code. The semantics of this eval are very similar to the eval used in JavaScript;\nthe last expression evaluated in the `code` string is used as the return value of this function. To\nevaluate `code` in strict mode, the first expression should be the string `\"use strict\"`.\n\n#### options\nThe eval function supports an options object that can affect how JS code is evaluated in powerful ways.\nThey are largely based on SpiderMonkey's `CompileOptions`. The supported option keys are:\n- `filename`: set the filename of this code for the purposes of generating stack traces etc.\n- `lineno`: set the line number offset of this code for the purposes of generating stack traces etc.\n- `column`: set the column number offset of this code for the purposes of generating stack traces etc.\n- `mutedErrors`: if set to `True`, eval errors or unhandled rejections are ignored (\"muted\"). Default `False`.\n- `noScriptRval`: if `False`, return the last expression value of the script as the result value to the caller. Default `False`.\n- `selfHosting`: *experimental*\n- `strict`: forcibly evaluate in strict mode (`\"use strict\"`). Default `False`.\n- `module`: indicate the file is an ECMAScript module (always strict mode code and disallow HTML comments). Default `False`.\n- `fromPythonFrame`: generate the equivalent of filename, lineno, and column based on the location of\n  the Python call to eval. This makes it possible to evaluate Python multiline string literals and\n  generate stack traces in JS pointing to the error in the Python source file.\n\n#### tricks\n- function literals evaluate as `undefined` in JavaScript; if you want to return a function, you must\n  evaluate an expression:\n  ```python\n  pythonmonkey.eval(\"myFunction() { return 123 }; myFunction\")\n  ```\n  or\n  ```python\n  pythonmonkey.eval(\"(myFunction() { return 123 })\")\n  ```\n- function expressions are a great way to build JS IIFEs that accept Python arguments\n  ```python\n  pythonmonkey.eval(\"(thing) =\u003e console.log('you said', thing)\")(\"this string came from Python\")\n  ```\n\n### require(moduleIdentifier)\nReturn the exports of a CommonJS module identified by `moduleIdentifier`, using standard CommonJS\nsemantics\n - modules are singletons and will never be loaded or evaluated more than once\n - moduleIdentifier is relative to the Python file invoking `require`\n - moduleIdentifier should not include a file extension\n - moduleIdentifiers which do not begin with ./, ../, or / are resolved by search require.path\n   and module.paths.\n - Modules are evaluated immediately after loading\n - Modules are not loaded until they are required\n - The following extensions are supported:\n  * `.js` - JavaScript module; source code decorates `exports` object\n  * `.py` - Python module; source code decorates `exports` dict\n  * `.json` - JSON module; exports are the result of parsing the JSON text in the file\n\n### globalThis\nA Python Dict which is equivalent to the globalThis object in JavaScript.\n\n### createRequire(filename, extraPaths, isMain)\nFactory function which returns a new require function\n- filename: the pathname of the module that this require function could be used for\n- extraPaths: [optional] a list of extra paths to search to resolve non-relative and non-absolute module identifiers\n- isMain: [optional] True if the require function is being created for a main module\n\n### runProgramModule(filename, argv, extraPaths)\nLoad and evaluate a program (main) module. Program modules must be written in JavaScript. Program modules are not\nnecessary unless the main entry point of your program is written in JavaScript.\n- filename: the location of the JavaScript source code\n- argv: the program's argument vector\n- extraPaths: [optional] a list of extra paths to search to resolve non-relative and non-absolute module identifiers\n\nCare should be taken to ensure that only one program module is run per JS context.\n\n### isCompilableUnit(code)\nExamines the string `code` and returns False if the string might become a valid JS statement with\nthe addition of more lines. This is used internally by pmjs and can be very helpful for building\nJavaScript REPLs; the idea is to accumulate lines in a buffer until isCompilableUnit is true, then\nevaluate the entire buffer.\n\n### new(function)\nReturns a Python function which invokes `function` with the JS new operator.\n```python\nimport pythonmonkey as pm\n\n\u003e\u003e\u003e pm.eval(\"class MyClass { constructor() { console.log('ran ctor') }}\")\n\u003e\u003e\u003e MyClass = pm.eval(\"MyClass\")\n\u003e\u003e\u003e MyClass()\nTraceback (most recent call last):\n  File \"\u003cstdin\u003e\", line 1, in \u003cmodule\u003e\npythonmonkey.SpiderMonkeyError: TypeError: class constructors must be invoked with 'new'\n\n\u003e\u003e\u003e MyClassCtor = pm.new(MyClass)\n\u003e\u003e\u003e MyClassCtor()\nran ctor\n{}\n\u003e\u003e\u003e\n```\n\n### typeof(value)\nThis is the JS `typeof` operator, wrapped in a function so that it can be used easily from Python.\n\n### Standard Classes and Globals\nAll of the JS Standard Classes (Array, Function, Object, Date...) and objects (globalThis,\nFinalizationRegistry...) are available as exports of the pythonmonkey module. These exports are\ngenerated by enumerating the global variable in the current SpiderMonkey context. The current list is:\n\u003cblockquote\u003eundefined, 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\u003c/blockquote\u003e\n\n## Built-In Functions\n\nSee definitions in [python/pythonmonkey/global.d.ts](https://github.com/Distributive-Network/PythonMonkey/blob/main/python/pythonmonkey/global.d.ts).\nIncluding:\n\n- `console`\n- `atob`\n- `btoa`\n- `setTimeout`\n- `clearTimeout`\n\n### CommonJS Subsystem Additions\nThe CommonJS subsystem is activated by invoking the `require` or `createRequire` exports of the (Python)\npythonmonkey module.\n\n- `require`\n- `exports`\n- `module`\n- `__filename`\n- `__dirname`\n- `python.print`  - the Python print function\n- `python.getenv` - the Python getenv function\n- `python.stdout` - an object with `read` and `write` methods, which read and write to stdout\n- `python.stderr` - an object with `read` and `write` methods, which read and write to stderr\n- `python.exec`   - the Python exec function\n- `python.eval`   - the Python eval function\n- `python.exit`   - exit via sys.exit(); the exit code is the function argument or `python.exit.code`.\n- `python.paths`  - the Python sys.paths list, visible in JS as an Array\n\n## Type Transfer (Coercion / Wrapping)\nWhen sending variables from Python into JavaScript, PythonMonkey will intelligently coerce or wrap your\nvariables based on their type. PythonMonkey will share backing stores (use the same memory) for ctypes,\ntyped arrays, and strings; moving these types across the language barrier is extremely fast because\nthere is no copying involved.\n\n*Note:* There are plans in Python 3.12 (PEP 623) to change the internal string representation so that\n        every character in the string uses four bytes of memory. This will break fast string transfers\n        for PythonMonkey, as it relies on the memory layout being the same in Python and JavaScript. As\n        of this writing (July 2023), \"classic\" Python strings still work in the 3.12 beta releases.\n\nWhere shared backing store is not possible, PythonMonkey will automatically emit wrappers that use\nthe \"real\" data structure as its value authority. Only immutable intrinsics are copied. This means\nthat if you update an object in JavaScript, the corresponding Dict in Python will be updated, etc.\n\nJavaScript Array and Object methods are implemented on Python List and Dictionaries, and vice-versa.\n\n| Python Type | JavaScript Type |\n|:------------|:----------------|\n| String      | string\n| Integer     | number\n| Bool        | boolean\n| Function    | function\n| Dict        | object\n| List        | Array\n| datetime    | Date object\n| awaitable   | Promise\n| Error       | Error object\n| Buffer      | ArrayBuffer\n\n| JavaScript Type      | Python Type     |\n|:---------------------|:----------------|\n| string               | pythonmonkey.JSStringProxy (String)\n| number               | Float\n| bigint               | pythonmonkey.bigint (Integer)\n| boolean              | Bool\n| function             | pythonmonkey.JSFunctionProxy || pythonmonkey.JSMethodProxy (Function || Method)\n| object - most        | pythonmonkey.JSObjectProxy (Dict)\n| object - Date        | datetime\n| object - Array       | pythonmonkey.JSArrayProxy (List)\n| object - Promise     | awaitable\n| object - ArrayBuffer | Buffer\n| object - type arrays | Buffer\n| object - Error       | Error\n\n## Tricks\n### Integer Type Coercion\nYou can force a number in JavaScript to be coerced as an integer by casting it to BigInt:\n```javascript\nfunction myFunction(a, b) {\n  const result = calculate(a, b);\n  return BigInt(Math.floor(result));\n}\n```\n\nThe `pythonmonkey.bigint` object works like an int in Python, but it will be coerced as a BigInt in JavaScript:\n```python\nimport pythonmonkey\n\ndef fn myFunction()\n  result = 5\n  return pythonmonkey.bigint(result)\n```\n\n### Symbol injection via cross-language IIFE\nYou can use a JavaScript IIFE to create a scope in which you can inject Python symbols:\n```python\nglobalThis.python.exit = pm.eval(\"\"\"'use strict';\n(exit) =\u003e function pythonExitWrapper(exitCode) {\n  if (typeof exitCode === 'number')\n    exitCode = BigInt(Math.floor(exitCode));\n  exit(exitCode);\n}\n\"\"\")(sys.exit);\n```\n\n### Run Python event-loop\n\nYou need an event-loop running to use `setTimeout` and `Promise`\u003c=\u003e`awaitable` coercion.\n\n```python\nimport asyncio\n\nasync def async_fn():\n  await pm.eval(\"\"\"\n    new Promise((resolve) =\u003e setTimeout((...args) =\u003e {\n        console.log(args);\n        resolve();\n      }, 1000, 42, \"abc\")\n    )\n  \"\"\")\n  await pm.eval(\"async (x) =\u003e await x\")(asyncio.sleep(0.5))\n\nasyncio.run(async_fn())\n```\n\n# pmjs\nA basic JavaScript shell, `pmjs`, ships with PythonMonkey. This shell can act as a REPL or run\nJavaScript programs; it is conceptually similar to the `node` shell which ships with Node.js.\n\n## Modules\nPmjs starts PythonMonkey's CommonJS subsystem, which allow it to use CommonJS modules, with semantics\nthat are similar to Node.js - e.g. searching module.paths, understanding package.json, index.js, and\nso on. See the [ctx-module](https://www.npmjs.com/package/ctx-module) for a full list of supported\nfeatures.\n\nIn addition to CommonJS modules written in JavaScript, PythonMonkey supports CommonJS modules written\nin Python. Simply decorate a Dict named `exports` inside a file with a `.py` extension, and it can be\nloaded by `require()` -- in either JavaScript or Python.\n\n### Program Module\nThe program module, or main module, is a special module in CommonJS. In a program module:\n - variables defined in the outermost scope are properties of `globalThis`\n - returning from the outermost scope is a syntax error\n - the `arguments` variable in an Array which holds your program's argument vector\n   (command-line arguments)\n\n```console\n$ echo \"console.log('hello world')\" \u003e my-program.js\n$ pmjs my-program.js\nhello world\n$\n```\n\n### CommonJS Module: JavaScript language\n```js\n// date-lib.js - require(\"./date-lib\")\nconst d = new Date();\nexports.today = `${d.getFullYear()}-${String(d.getMonth()).padStart(2,'0')}-${String(d.getDay()).padStart(2,'0')}`\n```\n\n### CommonJS Module: Python language\n```python\n# date-lib.py - require(\"./date-lib\")\nfrom datetime import date # You can use Python libraries.\nexports['today'] = date.today()\n```\n\n# Troubleshooting Tips\n\n## CommonJS (require)\nIf you are having trouble with the CommonJS require function, set environment variable `DEBUG='ctx-module*'` and you can see the filenames it tries to load.\n\n## pmdb\n\nPythonMonkey has a built-in gdb-like JavaScript command-line debugger called **pmdb**, which would be automatically triggered on `debugger;` statements and uncaught exceptions.\n\nTo enable **pmdb**, simply call `from pythonmonkey.lib import pmdb; pmdb.enable()` before doing anything on PythonMonkey.\n\n```py\nimport pythonmonkey as pm\nfrom pythonmonkey.lib import pmdb\n\npmdb.enable()\n\npm.eval(\"...\")\n```\n\nRun `help` command in **pmdb** to see available commands.\n\n```console\n(pmdb) \u003e help\nList of commands:\n• ...\n• ...\n```\n\n## pmjs\n- there is a `.help` menu in the REPL\n- there is a `--help` command-line option\n- the `--inspect` option enables **pmdb**, a gdb-like JavaScript command-line debugger\n- the `-r` option can be used to load a module before your program or the REPL runs\n- the `-e` option can be used evaluate code -- e.g. define global variables -- before your program or the REPL runs\n- The REPL can evaluate Python expressions, storing them in variables named `$1`, `$2`, etc.\n\n```console\n$ pmjs\n\nWelcome to PythonMonkey v1.0.0.\nType \".help\" for more information.\n\u003e .python import sys\n\u003e .python sys.path\n$1 = { '0': '/home/wes/git/pythonmonkey2',\n  '1': '/usr/lib/python310.zip',\n  '2': '/usr/lib/python3.10',\n  '3': '/usr/lib/python3.10/lib-dynload',\n  '4': '/home/wes/.cache/pypoetry/virtualenvs/pythonmonkey-StuBmUri-py3.10/lib/python3.10/site-packages',\n  '5': '/home/wes/git/pythonmonkey2/python' }\n\u003e $1[3]\n'/usr/lib/python3.10/lib-dynload'\n\u003e\n```\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdistributive-network%2Fpythonmonkey","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdistributive-network%2Fpythonmonkey","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdistributive-network%2Fpythonmonkey/lists"}