Skip to main content

Seamless interop between Python and JavaScript.

Project description

PythonMonkey

Test and Publish Suite

About

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.

tl;dr

$ pip install pythonmonkey
from pythonmonkey import eval as js_eval

js_eval("console.log")('hello, world')

Goals

  • Fast and memory-efficient
  • Make writing code in either JS or Python a developer preference
  • Use JavaScript libraries from Python
  • Use Python libraries from JavaScript
  • The same process runs both JavaScript and Python VirtualMachines - no serialization, pipes, etc
  • Python Lists and Dicts behave as Javacript Arrays and Objects, and vice-versa, fully adapting to the given context.

Data Interchange

  • 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.
  • TypedArrays share mutable backing stores.
  • JS objects are represented by Python dicts through a Dict subclass for optimal compatibility. Similarly for JS arrays and Python lists.
  • JS Date objects are represented by Python datetime.datetime objects
  • Intrinsics (boolean, number, null, undefined) are passed by value
  • JS Functions are automatically wrapped so that they behave like Python functions, and vice-versa
  • 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.

Roadmap

  • [done] JS instrinsics coerce to Python intrinsics
  • [done] JS strings coerce to Python strings
  • [done] JS objects coerce to Python dicts [own-properties only]
  • [done] JS functions coerce to Python function wrappers
  • [done] JS exceptions propagate to Python
  • [done] Implement eval() function in Python which accepts JS code and returns JS->Python coerced values
  • [done] NodeJS+NPM-compatible CommonJS module system
  • [done] Python strings coerce to JS strings
  • [done] Python intrinsics coerce to JS intrinsics
  • [done] Python dicts coerce to JS objects
  • [done] Python require function, returns a coerced dict of module exports
  • [done] Python functions coerce to JS function wrappers
  • [done] CommonJS module system .py loader, loads Python modules for use by JS
  • [done] Python host environment supplies event loop, including EventEmitter, setTimeout, etc.
  • [done] Python host environment supplies XMLHttpRequest
  • [done] Python TypedArrays coerce to JS TypeArrays
  • [done] JS TypedArrays coerce to Python TypeArrays
  • [done] Python lists coerce to JS Arrays
  • [done] JS arrays coerce to Python lists
  • [90%] PythonMonkey can run the dcp-client npm package from Distributive.

Build Instructions

Read this if you want to build a local version.

  1. You will need the following installed (which can be done automatically by running ./setup.sh):

    • bash
    • cmake
    • Doxygen 1.9 series (if you want to build the docs)
    • graphviz (if you want to build the docs)
    • llvm
    • rust
    • python3.8 or later with header files (python3-dev)
    • spidermonkey latest from mozilla-central
    • npm (nodejs)
    • Poetry
    • poetry-dynamic-versioning
  2. 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 stripped
  • Debug: minimal optimizations
  • Sanitize: same as Debug, except with AddressSanitizer enabled
  • Profile: 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.

Running tests

  1. Compile the project
  2. Install development dependencies: poetry install --no-root --only=dev
  3. From the root directory, run poetry run pytest ./tests/python
  4. From the root directory, run poetry run bash ./peter-jr ./tests/js/

For VSCode users, similar to the Build Task, we have a Test Task ready to use.

Using the library

npm (Node.js) is required during installation only to populate the JS dependencies.

Install from PyPI

$ pip install pythonmonkey

Install the nightly build

$ pip install --extra-index-url https://nightly.pythonmonkey.io/ --pre pythonmonkey

Use local version

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/*.

Uninstallation

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

Debugging Steps

  1. build the project locally
  2. To use gdb, run poetry run gdb python. See Python Wiki: DebuggingWithGdb

If 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.

Examples

Official API

These methods are exported from the pythonmonkey module. See definitions in python/pythonmonkey/pythonmonkey.pyi.

eval(code, options)

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".

options

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.

tricks

  • function literals evaluate as undefined in JavaScript; if you want to return a function, you must evaluate an expression:
    pythonmonkey.eval("myFunction() { return 123 }; myFunction")
    
    or
    pythonmonkey.eval("(myFunction() { return 123 })")
    
  • function expressions are a great way to build JS IIFEs that accept Python arguments
    pythonmonkey.eval("(thing) => console.log('you said', thing)")("this string came from Python")
    

require(moduleIdentifier)

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

globalThis

A Python Dict which is equivalent to the globalThis object in JavaScript.

createRequire(filename, extraPaths, isMain)

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

runProgramModule(filename, argv, extraPaths)

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.

isCompilableUnit(code)

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.

new(function)

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
{}
>>>

typeof(value)

This is the JS typeof operator, wrapped in a function so that it can be used easily from Python.

Standard Classes and Globals

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

Built-In Functions

See definitions in python/pythonmonkey/global.d.ts. Including:

  • console
  • atob
  • btoa
  • setTimeout
  • clearTimeout

CommonJS Subsystem Additions

The CommonJS subsystem is activated by invoking the require or createRequire exports of the (Python) pythonmonkey module.

  • require
  • exports
  • module
  • __filename
  • __dirname
  • python.print - the Python print function
  • python.getenv - the Python getenv function
  • python.stdout - an object with read and write methods, which read and write to stdout
  • python.stderr - an object with read and write methods, which read and write to stderr
  • python.exec - the Python exec function
  • python.eval - the Python eval function
  • python.exit - exit via sys.exit(); the exit code is the function argument or python.exit.code.
  • python.paths - the Python sys.paths list, visible in JS as an Array

Type Transfer (Coercion / Wrapping)

When sending variables from Python into JavaScript, PythonMonkey will intelligently coerce or wrap your variables based on their type. PythonMonkey will share backing stores (use the same memory) for ctypes, typed arrays, and strings; moving these types across the language barrier is extremely fast because there is no copying involved.

Note: There are plans in Python 3.12 (PEP 623) to change the internal string representation so that every character in the string uses four bytes of memory. This will break fast string transfers for PythonMonkey, as it relies on the memory layout being the same in Python and JavaScript. As of this writing (July 2023), "classic" Python strings still work in the 3.12 beta releases.

Where shared backing store is not possible, PythonMonkey will automatically emit wrappers that use the "real" data structure as its value authority. Only immutable intrinsics are copied. This means that if you update an object in JavaScript, the corresponding Dict in Python will be updated, etc.

JavaScript Array and Object methods are implemented on Python List and Dictionaries, and vice-versa.

Python Type JavaScript Type
String string
Integer number
Bool boolean
Function function
Dict object
List Array
datetime Date object
awaitable Promise
Error Error object
Buffer ArrayBuffer
JavaScript Type Python Type
string pythonmonkey.JSStringProxy (String)
number Float
bigint pythonmonkey.bigint (Integer)
boolean Bool
function pythonmonkey.JSFunctionProxy
object - most pythonmonkey.JSObjectProxy (Dict)
object - Date datetime
object - Array pythonmonkey.JSArrayProxy (List)
object - Promise awaitable
object - ArrayBuffer Buffer
object - type arrays Buffer
object - Error Error

Tricks

Integer Type Coercion

You can force a number in JavaScript to be coerced as an integer by casting it to BigInt:

function myFunction(a, b) {
  const result = calculate(a, b);
  return BigInt(Math.floor(result));
}

The pythonmonkey.bigint object works like an int in Python, but it will be coerced as a BigInt in JavaScript:

import pythonmonkey

def fn myFunction()
  result = 5
  return pythonmonkey.bigint(result)

Symbol injection via cross-language IIFE

You can use a JavaScript IIFE to create a scope in which you can inject Python symbols:

globalThis.python.exit = pm.eval("""'use strict';
(exit) => function pythonExitWrapper(exitCode) {
  if (typeof exitCode === 'number')
    exitCode = BigInt(Math.floor(exitCode));
  exit(exitCode);
}
""")(sys.exit);

Run Python event-loop

You need an event-loop running to use setTimeout and Promise<=>awaitable coercion.

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())

pmjs

A basic JavaScript shell, pmjs, ships with PythonMonkey. This shell can act as a REPL or run JavaScript programs; it is conceptually similar to the node shell which ships with Node.js.

Modules

Pmjs starts PythonMonkey's CommonJS subsystem, which allow it to use CommonJS modules, with semantics that are similar to Node.js - e.g. searching module.paths, understanding package.json, index.js, and so on. See the ctx-module for a full list of supported features.

In addition to CommonJS modules written in JavaScript, PythonMonkey supports CommonJS modules written in Python. Simply decorate a Dict named exports inside a file with a .py extension, and it can be loaded by require() -- in either JavaScript or Python.

Program Module

The program module, or main module, is a special module in CommonJS. In a program module:

  • variables defined in the outermost scope are properties of globalThis
  • returning from the outermost scope is a syntax error
  • the arguments variable in an Array which holds your program's argument vector (command-line arguments)
$ echo "console.log('hello world')" > my-program.js
$ pmjs my-program.js
hello world
$

CommonJS Module: JavaScript language

// 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')}`

CommonJS Module: Python language

# date-lib.py - require("./date-lib")
from datetime import date # You can use Python libraries.
exports['today'] = date.today()

Troubleshooting Tips

CommonJS (require)

If 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.

pmdb

PythonMonkey has a built-in gdb-like JavaScript command-line debugger called pmdb, which would be automatically triggered on debugger; statements and uncaught exceptions.

To enable pmdb, simply call from pythonmonkey.lib import pmdb; pmdb.enable() before doing anything on PythonMonkey.

import pythonmonkey as pm
from pythonmonkey.lib import pmdb

pmdb.enable()

pm.eval("...")

Run help command in pmdb to see available commands.

(pmdb) > help
List of commands:
• ...
• ...

pmjs

  • there is a .help menu in the REPL
  • there is a --help command-line option
  • the --inspect option enables pmdb, a gdb-like JavaScript command-line debugger
  • the -r option can be used to load a module before your program or the REPL runs
  • the -e option can be used evaluate code -- e.g. define global variables -- before your program or the REPL runs
  • The REPL can evaluate Python expressions, storing them in variables named $1, $2, etc.
$ 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'
>

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pythonmonkey_fork-1.3.0.tar.gz (307.7 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

pythonmonkey_fork-1.3.0-cp314-cp314-win_amd64.whl (13.4 MB view details)

Uploaded CPython 3.14Windows x86-64

pythonmonkey_fork-1.3.0-cp314-cp314-manylinux_2_31_x86_64.whl (22.3 MB view details)

Uploaded CPython 3.14manylinux: glibc 2.31+ x86-64

pythonmonkey_fork-1.3.0-cp314-cp314-manylinux_2_31_aarch64.whl (22.2 MB view details)

Uploaded CPython 3.14manylinux: glibc 2.31+ ARM64

pythonmonkey_fork-1.3.0-cp314-cp314-macosx_11_0_x86_64.whl (15.4 MB view details)

Uploaded CPython 3.14macOS 11.0+ x86-64

pythonmonkey_fork-1.3.0-cp314-cp314-macosx_11_0_arm64.whl (14.8 MB view details)

Uploaded CPython 3.14macOS 11.0+ ARM64

pythonmonkey_fork-1.3.0-cp313-cp313-win_amd64.whl (13.0 MB view details)

Uploaded CPython 3.13Windows x86-64

pythonmonkey_fork-1.3.0-cp313-cp313-manylinux_2_31_x86_64.whl (22.3 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.31+ x86-64

pythonmonkey_fork-1.3.0-cp313-cp313-manylinux_2_31_aarch64.whl (22.2 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.31+ ARM64

pythonmonkey_fork-1.3.0-cp313-cp313-macosx_11_0_x86_64.whl (15.4 MB view details)

Uploaded CPython 3.13macOS 11.0+ x86-64

pythonmonkey_fork-1.3.0-cp313-cp313-macosx_11_0_arm64.whl (14.8 MB view details)

Uploaded CPython 3.13macOS 11.0+ ARM64

pythonmonkey_fork-1.3.0-cp312-cp312-win_amd64.whl (13.0 MB view details)

Uploaded CPython 3.12Windows x86-64

pythonmonkey_fork-1.3.0-cp312-cp312-manylinux_2_31_x86_64.whl (22.4 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.31+ x86-64

pythonmonkey_fork-1.3.0-cp312-cp312-manylinux_2_31_aarch64.whl (22.2 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.31+ ARM64

pythonmonkey_fork-1.3.0-cp312-cp312-macosx_11_0_x86_64.whl (15.4 MB view details)

Uploaded CPython 3.12macOS 11.0+ x86-64

pythonmonkey_fork-1.3.0-cp312-cp312-macosx_11_0_arm64.whl (14.8 MB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

pythonmonkey_fork-1.3.0-cp311-cp311-win_amd64.whl (13.0 MB view details)

Uploaded CPython 3.11Windows x86-64

pythonmonkey_fork-1.3.0-cp311-cp311-manylinux_2_31_x86_64.whl (22.4 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.31+ x86-64

pythonmonkey_fork-1.3.0-cp311-cp311-manylinux_2_31_aarch64.whl (22.2 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.31+ ARM64

pythonmonkey_fork-1.3.0-cp311-cp311-macosx_11_0_x86_64.whl (15.4 MB view details)

Uploaded CPython 3.11macOS 11.0+ x86-64

pythonmonkey_fork-1.3.0-cp311-cp311-macosx_11_0_arm64.whl (14.8 MB view details)

Uploaded CPython 3.11macOS 11.0+ ARM64

pythonmonkey_fork-1.3.0-cp310-cp310-win_amd64.whl (13.0 MB view details)

Uploaded CPython 3.10Windows x86-64

pythonmonkey_fork-1.3.0-cp310-cp310-manylinux_2_31_x86_64.whl (22.3 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.31+ x86-64

pythonmonkey_fork-1.3.0-cp310-cp310-manylinux_2_31_aarch64.whl (22.2 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.31+ ARM64

pythonmonkey_fork-1.3.0-cp310-cp310-macosx_11_0_x86_64.whl (15.4 MB view details)

Uploaded CPython 3.10macOS 11.0+ x86-64

pythonmonkey_fork-1.3.0-cp310-cp310-macosx_11_0_arm64.whl (14.8 MB view details)

Uploaded CPython 3.10macOS 11.0+ ARM64

pythonmonkey_fork-1.3.0-cp39-cp39-win_amd64.whl (13.0 MB view details)

Uploaded CPython 3.9Windows x86-64

pythonmonkey_fork-1.3.0-cp39-cp39-manylinux_2_31_x86_64.whl (22.3 MB view details)

Uploaded CPython 3.9manylinux: glibc 2.31+ x86-64

pythonmonkey_fork-1.3.0-cp39-cp39-manylinux_2_31_aarch64.whl (22.2 MB view details)

Uploaded CPython 3.9manylinux: glibc 2.31+ ARM64

pythonmonkey_fork-1.3.0-cp39-cp39-macosx_11_0_x86_64.whl (15.4 MB view details)

Uploaded CPython 3.9macOS 11.0+ x86-64

pythonmonkey_fork-1.3.0-cp39-cp39-macosx_11_0_arm64.whl (14.8 MB view details)

Uploaded CPython 3.9macOS 11.0+ ARM64

pythonmonkey_fork-1.3.0-cp38-cp38-win_amd64.whl (13.0 MB view details)

Uploaded CPython 3.8Windows x86-64

pythonmonkey_fork-1.3.0-cp38-cp38-manylinux_2_31_x86_64.whl (22.3 MB view details)

Uploaded CPython 3.8manylinux: glibc 2.31+ x86-64

pythonmonkey_fork-1.3.0-cp38-cp38-manylinux_2_31_aarch64.whl (22.2 MB view details)

Uploaded CPython 3.8manylinux: glibc 2.31+ ARM64

pythonmonkey_fork-1.3.0-cp38-cp38-macosx_11_0_x86_64.whl (15.4 MB view details)

Uploaded CPython 3.8macOS 11.0+ x86-64

pythonmonkey_fork-1.3.0-cp38-cp38-macosx_11_0_arm64.whl (14.8 MB view details)

Uploaded CPython 3.8macOS 11.0+ ARM64

File details

Details for the file pythonmonkey_fork-1.3.0.tar.gz.

File metadata

  • Download URL: pythonmonkey_fork-1.3.0.tar.gz
  • Upload date:
  • Size: 307.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.9.7

File hashes

Hashes for pythonmonkey_fork-1.3.0.tar.gz
Algorithm Hash digest
SHA256 4265c4aa62e00a36e39da30db74e8722385cab92498ee759a6ef95693a4b0a8a
MD5 e8023bacf23a7955a077ce3132898698
BLAKE2b-256 e76c7abb87ca436bd90277025d05e4928fa8aa420653d830cdeda8c429cc20fc

See more details on using hashes here.

File details

Details for the file pythonmonkey_fork-1.3.0-cp314-cp314-win_amd64.whl.

File metadata

File hashes

Hashes for pythonmonkey_fork-1.3.0-cp314-cp314-win_amd64.whl
Algorithm Hash digest
SHA256 81cc567ca3dae18f209996a0d3a8dedde75b146f21cc744a3153925a2780a863
MD5 9476156dcfbf0a3cc1a91c6202b56914
BLAKE2b-256 e00d06aa4ace3e0816a77f56454084c54865645f7412b0493c3b1927e7cb3566

See more details on using hashes here.

File details

Details for the file pythonmonkey_fork-1.3.0-cp314-cp314-manylinux_2_31_x86_64.whl.

File metadata

File hashes

Hashes for pythonmonkey_fork-1.3.0-cp314-cp314-manylinux_2_31_x86_64.whl
Algorithm Hash digest
SHA256 afe1b8916902793949eadc293257a89a981a306dcd84e71527791dc7508ba6d2
MD5 0410424de86cfeb5ea196e42bac8e523
BLAKE2b-256 45654e069971e7819a15ba4d059b2e112a46861f77b45379cd73d1603e1d4d38

See more details on using hashes here.

File details

Details for the file pythonmonkey_fork-1.3.0-cp314-cp314-manylinux_2_31_aarch64.whl.

File metadata

File hashes

Hashes for pythonmonkey_fork-1.3.0-cp314-cp314-manylinux_2_31_aarch64.whl
Algorithm Hash digest
SHA256 83e7837dc4742b5f3e231ebd91646590a14a412343e89c6696b99cd8dc2cf588
MD5 0d64948242dbc816940f1ab313d823a3
BLAKE2b-256 4f7a8cc700305138c9a4d0b10d3ac25836d14c00bb533f4d10a441e10b9e85d3

See more details on using hashes here.

File details

Details for the file pythonmonkey_fork-1.3.0-cp314-cp314-macosx_11_0_x86_64.whl.

File metadata

File hashes

Hashes for pythonmonkey_fork-1.3.0-cp314-cp314-macosx_11_0_x86_64.whl
Algorithm Hash digest
SHA256 53ab8856bf4a983b61486a6a82c34a5ba9470afded51dc061d13c9ccb8355e95
MD5 5e97ec765313b849d38ff7bc0eb9d14a
BLAKE2b-256 e6ca557582fd08e54476531e37d9e6676d77a8e5aa5886417fbd9dd11a8b53bb

See more details on using hashes here.

File details

Details for the file pythonmonkey_fork-1.3.0-cp314-cp314-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for pythonmonkey_fork-1.3.0-cp314-cp314-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 2a332d895209a072b3796e4400e89a5f3a5f22680ff0bb61ad1a5b26e5d83c22
MD5 96b4d4e7804942aaeb789ece96950226
BLAKE2b-256 96d4efa36302fa90ed4211d7390d1decd2159c5ce1b0b26d781d3dff3afb982d

See more details on using hashes here.

File details

Details for the file pythonmonkey_fork-1.3.0-cp313-cp313-win_amd64.whl.

File metadata

File hashes

Hashes for pythonmonkey_fork-1.3.0-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 c2b049ee4999ee6b00f70d6130c27e2ff06d397f12776f15614a0859c5c8f759
MD5 08dcd556216e163e1a0327793d8c6eb1
BLAKE2b-256 8f0de7c40501846a6d03fc594232203bf6b8c199f36dfcf7ab05d5e8605601e8

See more details on using hashes here.

File details

Details for the file pythonmonkey_fork-1.3.0-cp313-cp313-manylinux_2_31_x86_64.whl.

File metadata

File hashes

Hashes for pythonmonkey_fork-1.3.0-cp313-cp313-manylinux_2_31_x86_64.whl
Algorithm Hash digest
SHA256 22cff167ddb7d2be35f3f6f511b31db321f3030d5b6b8b85801b8c92c5d628d9
MD5 918eede5e099a6037d0b9d1dbbe07064
BLAKE2b-256 23a1ca9a93b0a3707c1253e8c7ec4b750608edc0bb63a984cdcf265597edf02d

See more details on using hashes here.

File details

Details for the file pythonmonkey_fork-1.3.0-cp313-cp313-manylinux_2_31_aarch64.whl.

File metadata

File hashes

Hashes for pythonmonkey_fork-1.3.0-cp313-cp313-manylinux_2_31_aarch64.whl
Algorithm Hash digest
SHA256 bb084b429563008c11487a3a577343a2c16fa70fbc1ba15f3aaece606dd107e3
MD5 d232797fc1e832571ec19e43e847fead
BLAKE2b-256 e11ab340ef2dd10780a4b614e1b4ff1326f9473d33663db2c00577098a93142c

See more details on using hashes here.

File details

Details for the file pythonmonkey_fork-1.3.0-cp313-cp313-macosx_11_0_x86_64.whl.

File metadata

File hashes

Hashes for pythonmonkey_fork-1.3.0-cp313-cp313-macosx_11_0_x86_64.whl
Algorithm Hash digest
SHA256 a771a2df9d252a635c5d33731783aaeecd56e18b49421408a01f18eed2842312
MD5 784513ff94db3bd11bede395db383eaf
BLAKE2b-256 7ba5c6b8310219b5435a82f8dbd447ca96fdb0ef3cbf1195ce31d0d28dbd8aa5

See more details on using hashes here.

File details

Details for the file pythonmonkey_fork-1.3.0-cp313-cp313-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for pythonmonkey_fork-1.3.0-cp313-cp313-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 8e548a3691b5723f8ffbebcad5efa0da3e88d3fa48ee5638138107ee7b3da191
MD5 b40afcede9959d1af66ac5167cadf03f
BLAKE2b-256 aeff3bd9a158a09e9e7f89c2b6a57b6ceb3a90f09a1b18d78a74d630470e87e1

See more details on using hashes here.

File details

Details for the file pythonmonkey_fork-1.3.0-cp312-cp312-win_amd64.whl.

File metadata

File hashes

Hashes for pythonmonkey_fork-1.3.0-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 8aae21b7f8d4ad109f95dab233a434f06d5a15e38f7dddd08cc954699b192cee
MD5 0ea481cbfe76860baaf788b73afe8f5f
BLAKE2b-256 aa0929dadc887543948dfc67d93888ca26b062e75d154644f7c89879c57f84ef

See more details on using hashes here.

File details

Details for the file pythonmonkey_fork-1.3.0-cp312-cp312-manylinux_2_31_x86_64.whl.

File metadata

File hashes

Hashes for pythonmonkey_fork-1.3.0-cp312-cp312-manylinux_2_31_x86_64.whl
Algorithm Hash digest
SHA256 2d7c2c52671d7ea4b120f3e7aee621d1ebfd9ec6c352bb6a6bb7dbebb83a3f31
MD5 5d3ac7ed943b6e38835f58baa37c161c
BLAKE2b-256 3ecc2e3bf1fbe4f6cf5ae70ccb98f57f141db16888afd452826067e3c8ff49d7

See more details on using hashes here.

File details

Details for the file pythonmonkey_fork-1.3.0-cp312-cp312-manylinux_2_31_aarch64.whl.

File metadata

File hashes

Hashes for pythonmonkey_fork-1.3.0-cp312-cp312-manylinux_2_31_aarch64.whl
Algorithm Hash digest
SHA256 a02ab2e25ca7807192b1a4e32179f08a52d9f7437027578e0087e991fc537da0
MD5 a4c783e5d6d20a29f27068bbbd399226
BLAKE2b-256 570cd1fbfb6b1331836d2f68a6ecc3714aabd3392c76f2c56dff87b2f3253422

See more details on using hashes here.

File details

Details for the file pythonmonkey_fork-1.3.0-cp312-cp312-macosx_11_0_x86_64.whl.

File metadata

File hashes

Hashes for pythonmonkey_fork-1.3.0-cp312-cp312-macosx_11_0_x86_64.whl
Algorithm Hash digest
SHA256 7448800940c0bddacfc29fb9e582a3e46cd97b5b5b791691061171df558e354c
MD5 64dd9d7bab7df1d68104da569c9cbf1a
BLAKE2b-256 62f68c0ab6fe36142492ba16b5ccec8ef54ee5919de1e30e2da0165c295fa74e

See more details on using hashes here.

File details

Details for the file pythonmonkey_fork-1.3.0-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for pythonmonkey_fork-1.3.0-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 dd266c1a37df7977a627ca228fd96768cc993c8c5b20ef264d78d6d55e3ea24c
MD5 652858200fb011a0b36b00a90d729f9d
BLAKE2b-256 3e04141d2dfe0f4d40e6dcded46026767adc06bb4c11d16d90ef88d8425ebf6d

See more details on using hashes here.

File details

Details for the file pythonmonkey_fork-1.3.0-cp311-cp311-win_amd64.whl.

File metadata

File hashes

Hashes for pythonmonkey_fork-1.3.0-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 c909d73f7940980a1d427197cace24191eff5ab4eb2c1a7a79aa3bfe616a21c1
MD5 ce0057f263129af380e0bf6e6e9ca99a
BLAKE2b-256 692085cfd5232c1bf8555fcb2f4de52bea2885a1273840e8ab6ce4d791733c2e

See more details on using hashes here.

File details

Details for the file pythonmonkey_fork-1.3.0-cp311-cp311-manylinux_2_31_x86_64.whl.

File metadata

File hashes

Hashes for pythonmonkey_fork-1.3.0-cp311-cp311-manylinux_2_31_x86_64.whl
Algorithm Hash digest
SHA256 555a30b33bae803ea6959f6ef9ae738c90879a943ed9d15b78bac1059a95f789
MD5 12afd98dd9e8790c0a8da20eb04d3dba
BLAKE2b-256 100e69cdf9ba30d2f41182e9e8425b672d9c5db4d6661ffa2153dd30ea99e51b

See more details on using hashes here.

File details

Details for the file pythonmonkey_fork-1.3.0-cp311-cp311-manylinux_2_31_aarch64.whl.

File metadata

File hashes

Hashes for pythonmonkey_fork-1.3.0-cp311-cp311-manylinux_2_31_aarch64.whl
Algorithm Hash digest
SHA256 1c133801bb70a4a5f5581079a1d58e02f287dc3f64842c29c7848d44205787b2
MD5 d0f7422f267e3347605cc89d33352f3a
BLAKE2b-256 308979e0a62d804a1688f02fdf3073f232030a3f26a4f4ff9b3f5e2b11598cd7

See more details on using hashes here.

File details

Details for the file pythonmonkey_fork-1.3.0-cp311-cp311-macosx_11_0_x86_64.whl.

File metadata

File hashes

Hashes for pythonmonkey_fork-1.3.0-cp311-cp311-macosx_11_0_x86_64.whl
Algorithm Hash digest
SHA256 e1f70074b63166ee1ebcb9e1fdcf181927be5b53086fedfd16bc8876061b1e9e
MD5 634f765ce6512ce844e560020f789887
BLAKE2b-256 eb6031cc5ba9f3917a6222af4f43efd55215b86a76fbcfdc2e25f3c01ca30fd3

See more details on using hashes here.

File details

Details for the file pythonmonkey_fork-1.3.0-cp311-cp311-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for pythonmonkey_fork-1.3.0-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 37c595b2b745ff776549f71f0b9297b41630dd8bc6efc023fd38a51136317c58
MD5 8a895b2855ea689584505052a0cb55f9
BLAKE2b-256 528194ee3a38e51d76a0516d5babd5f6fd7a83d03c1409741b31a8b9ac1ed0eb

See more details on using hashes here.

File details

Details for the file pythonmonkey_fork-1.3.0-cp310-cp310-win_amd64.whl.

File metadata

File hashes

Hashes for pythonmonkey_fork-1.3.0-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 eb8d4e3523553e48a0c336a9ced307f78580cc56ef567c1e743b6c0333d34cdb
MD5 eee83db638cb74789580102e03ffee82
BLAKE2b-256 e4c7b6397d27c63bbd5a5080d26c8004e1680be0cf1db3490168a9bae5d361a6

See more details on using hashes here.

File details

Details for the file pythonmonkey_fork-1.3.0-cp310-cp310-manylinux_2_31_x86_64.whl.

File metadata

File hashes

Hashes for pythonmonkey_fork-1.3.0-cp310-cp310-manylinux_2_31_x86_64.whl
Algorithm Hash digest
SHA256 a8879bef321fa150ab536af029424c05be6fdb90eacea11a1538aa1113fcd318
MD5 d8cb2cdf3875c6b1288547871ad4df66
BLAKE2b-256 85279cff88520f5f96eab1260eb42152c3f84fda738d4e4ed43da42137c6fcaa

See more details on using hashes here.

File details

Details for the file pythonmonkey_fork-1.3.0-cp310-cp310-manylinux_2_31_aarch64.whl.

File metadata

File hashes

Hashes for pythonmonkey_fork-1.3.0-cp310-cp310-manylinux_2_31_aarch64.whl
Algorithm Hash digest
SHA256 f734f627b43def87a91eaa1247242ecd29b971766f3b305b11afba689cbe9b0a
MD5 6e3d3f5793883ad1926cff5c3bca168b
BLAKE2b-256 c7bd58cd13f7306560ba8ad897e052846b41728a0c3fe9b069ff2f1444de7843

See more details on using hashes here.

File details

Details for the file pythonmonkey_fork-1.3.0-cp310-cp310-macosx_11_0_x86_64.whl.

File metadata

File hashes

Hashes for pythonmonkey_fork-1.3.0-cp310-cp310-macosx_11_0_x86_64.whl
Algorithm Hash digest
SHA256 91f3b1ad26fa4fe5da68297399cbef5e36055be8c339c7e1f022efef4abab55d
MD5 7965165661593c79ba51efdb5d0c9403
BLAKE2b-256 b2610eeb9f1b91d95fc06d2943f785adab5d1d25f65b9b42594ad09cc4d88ec0

See more details on using hashes here.

File details

Details for the file pythonmonkey_fork-1.3.0-cp310-cp310-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for pythonmonkey_fork-1.3.0-cp310-cp310-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 64c1027915cbd36a241292bce2eaf898fca4983b0862a4d3068c0e1deda4261e
MD5 937253965108293a36494f654c82b749
BLAKE2b-256 a86b032fbe5e08c1b54b299ccfff1eb27da662e5968e047e41cbb209430bcf87

See more details on using hashes here.

File details

Details for the file pythonmonkey_fork-1.3.0-cp39-cp39-win_amd64.whl.

File metadata

File hashes

Hashes for pythonmonkey_fork-1.3.0-cp39-cp39-win_amd64.whl
Algorithm Hash digest
SHA256 d6d64a0969fc4f51c33edf8c6221a7e7f14b63f92821a91c73b3eac4b6190400
MD5 8b44808e21b11c153a57ceeb24d536ef
BLAKE2b-256 6abe4855f57fa7d78faa9d4f1863bb02bf1ca59659f550325abc2f4eb6bb422c

See more details on using hashes here.

File details

Details for the file pythonmonkey_fork-1.3.0-cp39-cp39-manylinux_2_31_x86_64.whl.

File metadata

File hashes

Hashes for pythonmonkey_fork-1.3.0-cp39-cp39-manylinux_2_31_x86_64.whl
Algorithm Hash digest
SHA256 59bf9190fc4dde7b60888a1bc120f7aaca1b070da3f0ab6748cd00bd99853e7a
MD5 a8b26fda62c12bb584f4c9bb350149d8
BLAKE2b-256 8b2dd08d6d3cf649b578e93e91987491148033d50b38eedc4a2f2cdcb55d486a

See more details on using hashes here.

File details

Details for the file pythonmonkey_fork-1.3.0-cp39-cp39-manylinux_2_31_aarch64.whl.

File metadata

File hashes

Hashes for pythonmonkey_fork-1.3.0-cp39-cp39-manylinux_2_31_aarch64.whl
Algorithm Hash digest
SHA256 4d361738f712fc65c367130f6d0be455ee171d0e982e59a767d5b3d6640d0113
MD5 83f5b5eaced6c934bca76a809ee2d63b
BLAKE2b-256 df4703e3145a41a0ab6a599820c9eed5bdaa12150bebd2df590e3e0ddfeac6dc

See more details on using hashes here.

File details

Details for the file pythonmonkey_fork-1.3.0-cp39-cp39-macosx_11_0_x86_64.whl.

File metadata

File hashes

Hashes for pythonmonkey_fork-1.3.0-cp39-cp39-macosx_11_0_x86_64.whl
Algorithm Hash digest
SHA256 79a9b4c9ba987b1424fc3c3e35633bd09d6c3c238bac19881869a1f647f4d2b5
MD5 097fe083f7e53528b9f1e8c996f51d97
BLAKE2b-256 221bfb6d6f90c246ed9255ec19372a338cf16723562b4dff25149b6c210bb939

See more details on using hashes here.

File details

Details for the file pythonmonkey_fork-1.3.0-cp39-cp39-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for pythonmonkey_fork-1.3.0-cp39-cp39-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 c13a20a763c49f948cbed4e032d58ffc0a5aa06ad4d1b0b9bf9e0fb0d8ffa39f
MD5 6c64bcce374b948a89acbe5f4235d0ff
BLAKE2b-256 c0eed20e647cbc42edcb02429353da98635488300ca5cf14b8961e8fd87905d2

See more details on using hashes here.

File details

Details for the file pythonmonkey_fork-1.3.0-cp38-cp38-win_amd64.whl.

File metadata

File hashes

Hashes for pythonmonkey_fork-1.3.0-cp38-cp38-win_amd64.whl
Algorithm Hash digest
SHA256 268a91c23f723b373d2e69a0456eaaa11081c2f13a8f7c038dc111dc392badf3
MD5 871ab40ded395a412d3c5c76e0507613
BLAKE2b-256 777f6bed51500573410170d65cb29bd8e42fd7893ae485cfc64ef3d06ee8f00f

See more details on using hashes here.

File details

Details for the file pythonmonkey_fork-1.3.0-cp38-cp38-manylinux_2_31_x86_64.whl.

File metadata

File hashes

Hashes for pythonmonkey_fork-1.3.0-cp38-cp38-manylinux_2_31_x86_64.whl
Algorithm Hash digest
SHA256 175b549d7b1e48ab59549a67c2dc209f93232b94095a208303c52c89e4dcbdff
MD5 bdd39d4ad62aae6212171ecab26268e5
BLAKE2b-256 e20f30b65c985cca1229b018e9054615d6e1f438e950a29f200f46afa6d0c583

See more details on using hashes here.

File details

Details for the file pythonmonkey_fork-1.3.0-cp38-cp38-manylinux_2_31_aarch64.whl.

File metadata

File hashes

Hashes for pythonmonkey_fork-1.3.0-cp38-cp38-manylinux_2_31_aarch64.whl
Algorithm Hash digest
SHA256 aaef8772d7d0ac39470b6d34c04c18a90ea7520d90ddc32c13d06aab1dd619c5
MD5 51ba1e3b5364e303241dafebe0728cf7
BLAKE2b-256 a874f67817d83dd68ce70e069c4a725c30c07d675e688e47e6c6e0cafea8db12

See more details on using hashes here.

File details

Details for the file pythonmonkey_fork-1.3.0-cp38-cp38-macosx_11_0_x86_64.whl.

File metadata

File hashes

Hashes for pythonmonkey_fork-1.3.0-cp38-cp38-macosx_11_0_x86_64.whl
Algorithm Hash digest
SHA256 71c98736dbdf8fd74d393b8013b1778bcea377f84ec96e03033ef6b7a5d7149c
MD5 22b664d868d4cd3a33770f9ee243cab0
BLAKE2b-256 b2d3bfe068fbd0f4d0c8c84e7700847d7e16ca098348e2ebec0af7ff0325a5d6

See more details on using hashes here.

File details

Details for the file pythonmonkey_fork-1.3.0-cp38-cp38-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for pythonmonkey_fork-1.3.0-cp38-cp38-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 cc5cfcc712edd8e4b9f3185eb0df6f67f2b9eadd7112d709a2ff10d4efafd57a
MD5 4b50fedd708e7e17b23e43dbf877b4a9
BLAKE2b-256 4223194c7c2e8d9791e1fff2869d882e217b2921c99e23ff3e1975d8670c48b3

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page