Pythonmonkey ist eine Mozilla Spidermonkey JavaScript -Engine, die in die Python -Laufzeit eingebettet ist und die Python -Engine verwendet, um die JavaScript -Hostumgebung bereitzustellen.
Wir bieten JavaScript -Array und Objektmethoden, die auf Python -Liste und Wörterbüchern mit der CPython C -API implementiert sind, und das Inverse unter Verwendung der Mozilla Firefox Spidermonkey JavaScript C ++ API.
Dieses Projekt hat MVP ab September 2024 erreicht. Es wird von Verteilungsverteilung gewartet.
Externe Beiträge und Feedback sind willkommen und gefördert.
$ pip install pythonmonkey from pythonmonkey import eval as js_eval
js_eval ( "console.log" )( 'hello, world' )eval() in Python, die JS-Code akzeptiert und JS-> Python-Zwangswerte zurückgibtrequire Funktion, gibt ein erzwungenes Diktieren der Modulexporte zurückLesen Sie dies, wenn Sie eine lokale Version erstellen möchten.
Sie benötigen die folgenden Installationen (die automatisch durch Ausführen durchgeführt werden kann ./setup.sh ):
poetry install . Dieser Befehl kompiliert das Projekt automatisch und installiert das Projekt sowie Abhängigkeiten in das Poesie Virtualenv. Wenn Sie die Dokumente erstellen möchten, setzen Sie die Umgebungsvariable BUILD_DOCS wie SO: BUILD_DOCS=1 poetry install . Pythonmonkey unterstützt mehrere Build -Typen, die Sie erstellen können, indem Sie die Umgebungsvariable BUILD_TYPE wie SO einstellen: BUILD_TYPE=Debug poetry install . Die Build-Typen sind (Fall-unempfindlich):
Release : Strippierte Symbole, maximale Optimierungen (Standard)DRelease : Gleich wie Release , außer dass Symbole nicht abgezogen werdenDebug : Minimale OptimierungenSanitize : Wie Debug , außer bei aktiviertem AdressanitizerProfile : Gleich wie Debug , außer dass die Profilerstellung aktiviert istNone : Nicht kompilieren (nützlich, wenn Sie nur die Dokumente erstellen möchten) Wenn Sie VSCODE verwenden, können Sie einfach Strg + Shift + B drücken, um die Build -Aufgabe auszuführen. Wir haben die für Sie konfigurierte tasks.json -Datei.
poetry install --no-root --only=devpoetry run pytest ./tests/pythonpoetry run bash ./peter-jr ./tests/js/Für VSCODE -Benutzer, ähnlich wie bei der Build -Aufgabe, können wir eine Testaufgabe verwenden.
NPM (NODE.JS) ist während der Installation nur erforderlich, um die JS -Abhängigkeiten zu bevölkern.
$ pip install pythonmonkey$ pip install --extra-index-url https://nightly.pythonmonkey.io/ --pre pythonmonkey pythonmonkey ist im Poesie Virtualenv erhältlich, sobald Sie das Projekt mit Poesie zusammengestellt haben.
$ 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!'Alternativ können Sie installierbare Pakete durch Ausführen erstellen
$ cd python/pminit && poetry build --format=sdist && cd - && mv -v python/pminit/dist/ * ./dist/
$ poetry build --format=wheel und installieren Sie sie per pip install ./dist/* .
Durch die Installation pythonmonkey wird auch das pminit -Paket als Abhängigkeit installiert. pip uninstall , entfernt seine Abhängigkeiten jedoch nicht automatisch.
Wenn Sie pythonmonkey sauber aus Ihrem System entfernen möchten, machen Sie Folgendes:
$ pip uninstall pythonmonkey pminitpoetry run gdb python . Siehe Python Wiki: Debugging mit Wenn Sie VSCODE verwenden, ist es bequemer, im integrierten Debugger von VSCODE zu debuggen. Drücken Sie einfach F5 in einer offenen Python -Datei im Editor, um das Debugging zu starten. Wir haben die Datei launch.json für Sie konfiguriert.
Diese Methoden werden aus dem Pythonmonkey -Modul exportiert. Siehe Definitionen in Python/Pythonmonkey/Pythonmonkey.pyi.
Bewerten Sie den JavaScript -Code. Die Semantik dieser Bewertung ist der in JavaScript verwendeten Bewertung sehr ähnlich. Der letzte Ausdruck, der in der code bewertet wird, wird als Rückgabewert dieser Funktion verwendet. Um code im strengen Modus zu bewerten, sollte der erste Ausdruck die Zeichenfolge "use strict" sein.
Die EV -Funktion unterstützt ein Optionsobjekt, das sich auf leistungsstarke Weise auswirken kann, wie JS -Code bewertet wird. Sie basieren größtenteils auf Spidermonkeys CompileOptions . Die unterstützten Optionsschlüssel sind:
filename : Legen Sie den Dateinamen dieses Codes fest, um Stapelspuren usw. zu generieren.lineno : Legen Sie den Zeilennummer -Versatz dieses Codes ein, um Stapelspuren usw. zu generieren.column : Setzen Sie den Spaltennummernversatz dieses Codes, um Stapelspuren usw. zu generieren.mutedErrors : Wenn sie auf True gesetzt werden, werden Fehler oder ungehandelte Ablehnungen ignoriert ("gedämpft"). Standard False .noScriptRval : Wenn False , geben Sie den letzten Ausdruckswert des Skripts als Ergebniswert an den Anrufer zurück. Standard False .selfHosting : Experimentellstrict : im strengen Modus gewaltsam bewerten ( "use strict" ). Standard False .module : Geben Sie an, dass die Datei ein ECMascript -Modul ist (immer strenger Moduscode und nicht zu HTML -Kommentaren). Standard False .fromPythonFrame : Generieren Sie das Äquivalent von Dateinamen, Leineno und Spalte basierend auf dem Ort des Python -Aufrufs an eval. Dies ermöglicht es, Python Multiline String -Literale zu bewerten und Stapelspuren in JS zu generieren, die auf den Fehler in der Python -Quelldatei hinweisen. undefined bewertet werden; Wenn Sie eine Funktion zurückgeben möchten, müssen Sie einen Ausdruck bewerten: pythonmonkey . eval ( "myFunction() { return 123 }; myFunction" ) pythonmonkey . eval ( "(myFunction() { return 123 })" ) pythonmonkey . eval ( "(thing) => console.log('you said', thing)" )( "this string came from Python" ) Geben Sie die Exporte eines von moduleIdentifier identifizierten CommonJS -Moduls unter Verwendung der Standard -CommonJS -Semantik zurück
require.js - JavaScript -Modul; Quellcode dekoriert das exports.py - Python -Modul; Quellcode dekoriert exports DICT.json - JSON -Modul; Exporte sind das Ergebnis des Parsens des JSON -Textes in der DateiEin Python -Diktat, das dem globalen Objekt in JavaScript entspricht.
Fabrikfunktion, die eine neue Erforderungsfunktion zurückgibt
Laden und bewerten Sie ein Programm (Haupt-) Modul. Programmmodule müssen in JavaScript geschrieben werden. Programmmodule sind nicht erforderlich, es sei denn, der Haupteintrittspunkt Ihres Programms ist in JavaScript geschrieben.
Es sollte darauf geachtet werden, dass nur ein Programmmodul pro JS -Kontext ausgeführt wird.
Untersucht den String code und gibt FALSE zurück, wenn die Zeichenfolge eine gültige JS -Anweisung mit mehr Zeilen wird. Dies wird intern von PMJs verwendet und kann sehr hilfreich sein, um JavaScript -Repls zu erstellen. Die Idee ist, Linien in einem Puffer zu sammeln, bis IscompilableUnit wahr ist und dann den gesamten Puffer bewertet.
Gibt eine Python -Funktion zurück, die function mit dem JS New Operator aufruft.
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
{}
>> > Dies ist der JS typeof -Operator, der in eine Funktion eingewickelt ist, damit er leicht von Python verwendet werden kann.
Alle JS -Standardklassen (Array, Funktion, Objekt, Datum ...) und Objekte (Globalthis, Finalization Registry ...) sind als Exporte des Pythonmonkey -Moduls verfügbar. Diese Exporte werden durch Aufzählen der globalen Variablen im aktuellen Spidermonkey -Kontext generiert. Die aktuelle Liste lautet:
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, Funktion, Objekt, Debuggerglobal, Abschlussregistrierung, Array, Globalthis
Siehe Definitionen in Python/Pythonmonkey/global.d.ts. Einschließlich:
consoleatobbtoasetTimeoutclearTimeout Das CommonJS -Subsystem wird aktiviert, indem die require oder createRequire -Exporte des (Python) Pythonmonkey -Moduls aufgerufen werden.
requireexportsmodule__filename__dirnamepython.print - Die Python -Druckfunktionpython.getenv - Die Python Getenv -Funktionpython.stdout - Ein Objekt mit read und write , die Lesen und Schreiben an stdoutpython.stderr - Ein Objekt mit read und write , die Lesen und Schreiben an Stderrpython.exec - Die Python Exec -Funktionpython.eval - Die Python -Evalfunktionpython.exit - beenden über sys.exit (); Der Exit -Code ist das Funktionsargument oder python.exit.code .python.paths - Die Liste der Python -Sys.Paths, die in JS als Array sichtbar ist Wenn Pythonmonkey Variablen von Python in JavaScript senden, zwingt sie Ihre Variablen intelligent auf ihrem Typ. Pythonmonkey teilen Backing -Stores (verwenden Sie denselben Speicher) für CTypes, typisierte Arrays und Saiten. Das Bewegen dieser Typen über die Sprachbarriere ist extrem schnell, da kein Kopieren beteiligt ist.
Hinweis: In Python 3.12 (PEP 623) gibt es Pläne, die interne String -Darstellung so zu ändern, dass jedes Zeichen in der Zeichenfolge vier Speicherbytes verwendet. Dadurch werden schnelle Stringtransfers für Pythonmonkey gebrochen, da es sich auf das Speicherlayout in Python und JavaScript beruht. Zum jetzigen Schreiben (Juli 2023) funktioniert "klassische" Python -Saiten noch in den 3.12 Beta -Veröffentlichungen.
Wenn der gemeinsame Backing -Store nicht möglich ist, wird Pythonmonkey automatisch Wrapper abgibt, die die "reale" Datenstruktur als Wertberechnung verwenden. Es werden nur unveränderliche Intrinsiks kopiert. Dies bedeutet, dass beim Aktualisieren eines Objekts in JavaScript das entsprechende Diktat in Python aktualisiert wird usw.
JavaScript-Array und Objektmethoden werden in Python-Liste und Wörterbüchern sowie umgekehrt implementiert.
| Python -Typ | JavaScript -Typ |
|---|---|
| Saite | Saite |
| Ganze Zahl | Nummer |
| Bool | boolean |
| Funktion | Funktion |
| DICT | Objekt |
| Liste | Array |
| datetime | Datum Objekt |
| wartbar | Versprechen |
| Fehler | Fehlerobjekt |
| Puffer | ArrayBuffer |
| JavaScript -Typ | Python -Typ |
|---|---|
| Saite | pythonmonkey.jsstringProxy (String) |
| Nummer | Schweben |
| Bigint | pythonmonkey.bigint (Ganzzahl) |
| boolean | Bool |
| Funktion | pythonmonkey.jsfunctionProxy |
| Objekt - die meisten | Pythonmonkey.jsobjectProxy (Diktat) |
| Objekt - Datum | datetime |
| Objekt - Array | pythonmonkey.jsarrayproxy (Liste) |
| Objekt - Versprechen | wartbar |
| Objekt - ArrayBuffer | Puffer |
| Objekt - Typ Arrays Type | Puffer |
| Objekt - Fehler | Fehler |
Sie können eine Zahl in JavaScript erzwingen, dass sie als Ganzzahl gezwungen werden, indem Sie sie an Bigint übertragen:
function myFunction ( a , b ) {
const result = calculate ( a , b ) ;
return BigInt ( Math . floor ( result ) ) ;
} Das pythonmonkey.bigint -Objekt funktioniert wie ein int in Python, wird aber als Bigint in JavaScript gezwungen:
import pythonmonkey
def fn myFunction ()
result = 5
return pythonmonkey . bigint ( result )Sie können ein JavaScript -IIfe verwenden, um einen Bereich zu erstellen, in dem Sie Python -Symbole injizieren können:
globalThis . python . exit = pm . eval ( """'use strict';
(exit) => function pythonExitWrapper(exitCode) {
if (typeof exitCode === 'number')
exitCode = BigInt(Math.floor(exitCode));
exit(exitCode);
}
""" )( sys . exit ); Sie benötigen eine Event-Schleife, um setTimeout zu verwenden, und Promise awaitable
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 ()) Eine grundlegende JavaScript -Shell, pmjs , Schiffe mit Pythonmonkey. Diese Shell kann als Reply oder JavaScript -Programme ausführen. Es ähnelt konzeptionell der node , die mit Node.js.
PMJS startet das CommonJS -Subsystem von Pythonmonkey, mit dem es CommonJS -Module verwenden kann, mit Semantik, die Node.js - z. Eine vollständige Liste der unterstützten Funktionen finden Sie im CTX-Modul.
Neben CommonJS -Modulen, die in JavaScript geschrieben wurden, unterstützt Pythonmonkey CommonJS -Module, die in Python geschrieben wurden. Dekorieren Sie einfach einen dikten namens exports in einer Datei mit einer .py -Erweiterung und kann durch require() in JavaScript oder Python geladen werden.
Das Programmmodul oder das Hauptmodul ist ein spezielles Modul in CommonJs. In einem Programmmodul:
globalThisarguments in einem Array, das den Argumentvektor Ihres Programms enthält (Befehlszeilenargumente) $ echo " console.log('hello world') " > my-program.js
$ pmjs my-program.js
hello world
$ // 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' ) } ` # date-lib.py - require("./date-lib")
from datetime import date # You can use Python libraries.
exports [ 'today' ] = date . today () Wenn Sie Probleme mit dem CommonJS benötigen, um Funktion zu erfordern, setzen Sie die Umgebungsvariablen DEBUG='ctx-module*' und Sie können die Dateinamen sehen, die sie laden möchten.
Pythonmonkey verfügt über einen integrierten GDB-ähnlichen JavaScript-Befehlszeilen-Debugger namens PMDB , der bei debugger; Aussagen und ungewöhnliche Ausnahmen.
Um PMDB zu aktivieren, rufen Sie einfach from pythonmonkey.lib import pmdb; pmdb.enable() Bevor Sie etwas auf Pythonmonkey machen.
import pythonmonkey as pm
from pythonmonkey . lib import pmdb
pmdb . enable ()
pm . eval ( "..." ) help -Befehl in PMDB ausführen, um verfügbare Befehle anzuzeigen.
(pmdb) > help
List of commands:
• ...
• ... .help -Menü in der Wiederholung--help--inspect ermöglicht PMDB , einen GDB-ähnlichen JavaScript-Befehlszeilen-Debugger-r kann verwendet werden, um ein Modul vor Ihrem Programm zu laden oder die REP -Ausführungen-e kann verwendet werden$1 , $2 usw. speichern. $ 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'
>