PythonMonkey adalah mesin JavaScript Mozilla Spidermonkey yang tertanam di runtime Python, menggunakan mesin Python untuk menyediakan lingkungan host Javascript.
Kami menampilkan metode array dan objek JavaScript yang diimplementasikan pada daftar python dan kamus menggunakan CPYTHON C API, dan invers menggunakan Mozilla Punfox Spidermonkey Javascript C ++ API.
Proyek ini telah mencapai MVP pada September 2024. Ini sedang dalam pemeliharaan oleh distributif.
Kontribusi dan umpan balik eksternal dipersilakan dan didorong.
$ pip install pythonmonkey from pythonmonkey import eval as js_eval
js_eval ( "console.log" )( 'hello, world' )eval() dalam python yang menerima kode JS dan mengembalikan JS-> Python yang dipaksakan nilairequire fungsi, mengembalikan dikt ekspor modul yang dipaksaBaca ini jika Anda ingin membangun versi lokal.
Anda akan membutuhkan yang diinstal berikut (yang dapat dilakukan secara otomatis dengan menjalankan ./setup.sh ):
Jalankan poetry install . Perintah ini secara otomatis menyusun proyek dan menginstal proyek serta dependensi ke virtualEnv puisi. Jika Anda ingin membangun dokumen, atur variabel lingkungan BUILD_DOCS , seperti demikian: BUILD_DOCS=1 poetry install . PythonMonkey mendukung beberapa jenis build, yang dapat Anda bangun dengan mengatur variabel lingkungan BUILD_TYPE , seperti So: BUILD_TYPE=Debug poetry install . Tipe build adalah (tidak peka case):
Release : Simbol Dikupahkan, Optimalisasi Maksimum (Default)DRelease : Sama seperti Release , kecuali simbol tidak dilucutiDebug : optimisasi minimalSanitize : Sama seperti Debug , kecuali dengan addressanitizer diaktifkanProfile : Sama seperti Debug , kecuali profil diaktifkanNone : Jangan mengkompilasi (berguna jika Anda hanya ingin membangun dokumen) Jika Anda menggunakan vScode, Anda dapat menekan Ctrl + Shift + B untuk menjalankan tugas Build - kami memiliki file tasks.json yang dikonfigurasi untuk Anda.
poetry install --no-root --only=devpoetry run pytest ./tests/pythonpoetry run bash ./peter-jr ./tests/js/Untuk pengguna vScode, mirip dengan tugas build, kami memiliki tugas tes yang siap digunakan.
NPM (Node.js) diperlukan selama instalasi hanya untuk mengisi dependensi JS.
$ pip install pythonmonkey$ pip install --extra-index-url https://nightly.pythonmonkey.io/ --pre pythonmonkey pythonmonkey tersedia di puisi VirtualEnv setelah Anda menyusun proyek menggunakan puisi.
$ 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!'Atau, Anda dapat membuat paket yang dapat diinstal dengan berjalan
$ cd python/pminit && poetry build --format=sdist && cd - && mv -v python/pminit/dist/ * ./dist/
$ poetry build --format=wheel dan instal dengan pip install ./dist/* .
Menginstal pythonmonkey juga akan menginstal paket pminit sebagai ketergantungan. Namun, pip uninstall instalan paket tidak akan secara otomatis menghapus dependensinya.
Jika Anda ingin menghapus pythonmonkey dengan bersih dari sistem Anda, lakukan hal berikut:
$ pip uninstall pythonmonkey pminitpoetry run gdb python . Lihat Python Wiki: debuggingwithgdb Jika Anda menggunakan vScode, lebih nyaman untuk men-debug di debugger bawaan vScode. Cukup tekan F5 pada file Python terbuka di editor untuk memulai debugging - kami memiliki file launch.json yang dikonfigurasi untuk Anda.
Metode -metode ini diekspor dari modul PythonMonkey. Lihat Definisi dalam Python/PythonMonkey/PythonMonkey.pyi.
Evaluasi kode JavaScript. Semantik eval ini sangat mirip dengan eval yang digunakan dalam JavaScript; Ekspresi terakhir yang dievaluasi dalam string code digunakan sebagai nilai pengembalian fungsi ini. Untuk mengevaluasi code dalam mode ketat, ekspresi pertama harus menjadi string "use strict" .
Fungsi eval mendukung objek opsi yang dapat memengaruhi bagaimana kode JS dievaluasi dengan cara yang kuat. Mereka sebagian besar didasarkan pada CompileOptions spidermonkey. Kunci opsi yang didukung adalah:
filename : Atur nama file kode ini untuk keperluan menghasilkan jejak tumpukan dll.lineno : Atur offset nomor baris kode ini untuk keperluan menghasilkan jejak tumpukan dll.column : Atur Offset Nomor Kolom Kode ini untuk keperluan menghasilkan jejak tumpukan dll.mutedErrors : Jika diatur ke True , kesalahan evaluasi atau penolakan yang tidak ditangani diabaikan ("diredam"). False default.noScriptRval : Jika False , kembalikan nilai ekspresi terakhir dari skrip sebagai nilai hasil untuk penelepon. False default.selfHosting : Eksperimentalstrict : Mengevaluasi secara paksa dalam mode ketat ( "use strict" ). False default.module : Tunjukkan file adalah modul ecmascript (selalu kode mode yang ketat dan larang komentar HTML). False default.fromPythonFrame : Hasilkan setara dengan nama file, lineno, dan kolom berdasarkan lokasi panggilan Python untuk mengevaluasi. Hal ini memungkinkan untuk mengevaluasi literal string multiline Python dan menghasilkan jejak tumpukan dalam JS yang menunjuk kesalahan dalam file sumber Python. undefined dalam JavaScript; Jika Anda ingin mengembalikan fungsi, Anda harus mengevaluasi ekspresi: pythonmonkey . eval ( "myFunction() { return 123 }; myFunction" ) pythonmonkey . eval ( "(myFunction() { return 123 })" ) pythonmonkey . eval ( "(thing) => console.log('you said', thing)" )( "this string came from Python" ) Kembalikan ekspor modul CommonJS yang diidentifikasi oleh moduleIdentifier , menggunakan semantik CommonJS standar
require.js - modul javascript; Kode sumber menghiasi objek exports.py - modul Python; Kode sumber menghiasi dikt exports.json - modul json; Ekspor adalah hasil parsing teks JSON dalam fileDikt Python yang setara dengan objek Global ini dalam JavaScript.
Fungsi pabrik yang mengembalikan fungsi yang membutuhkan baru
Memuat dan mengevaluasi modul program (utama). Modul program harus ditulis dalam JavaScript. Modul program tidak diperlukan kecuali titik masuk utama program Anda ditulis dalam JavaScript.
Perawatan harus diambil untuk memastikan bahwa hanya satu modul program yang dijalankan per JS konteks.
Memeriksa code string dan mengembalikan false jika string mungkin menjadi pernyataan JS yang valid dengan penambahan lebih banyak baris. Ini digunakan secara internal oleh PMJ dan dapat sangat membantu untuk membangun JavaScript REPLS; Idenya adalah untuk mengumpulkan garis dalam buffer sampai isCompilableUnit benar, kemudian mengevaluasi seluruh buffer.
Mengembalikan fungsi Python yang memohon function dengan operator baru JS.
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
{}
>> > Ini adalah typeof operator JS, dibungkus dalam suatu fungsi sehingga dapat digunakan dengan mudah dari Python.
Semua kelas standar JS (array, fungsi, objek, tanggal ...) dan objek (GlobalThis, finalisasi registrasi ...) tersedia sebagai ekspor modul PythonMonkey. Ekspor ini dihasilkan dengan menyebutkan variabel global dalam konteks spidermonkey saat ini. Daftar saat ini adalah:
tidak ditentukan, boolean, json, tanggal, matematika, angka, string, regexp, kesalahan, internalerror, agregateError, evaleRror, rangeerror, referensiererror, sintakser, typeerror, urierror, arraybuffer, int8array, uint8array, int16array, uint166Array, uint32Array, int16array, uint166, uint1666Arl32Array, uint166aRay, uint1666Art32Array, uint1666 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, Finalisasi Registry, Array, GlobalThis
Lihat Definisi dalam Python/PythonMonkey/Global.D.TS. Termasuk:
consoleatobbtoasetTimeoutclearTimeout Subsistem CommonJS diaktifkan dengan memohon ekspor require atau createRequire dari Modul Pythonmonkey (Python).
requireexportsmodule__filename__dirnamepython.print - Fungsi Cetak Pythonpython.getenv - fungsi Python getENVpython.stdout - Objek dengan metode read dan write , yang membaca dan menulis ke stdoutpython.stderr - Objek dengan metode read dan write , yang membaca dan menulis ke Stderrpython.exec - Fungsi Python Execpython.eval - Fungsi Python Evalpython.exit - keluar melalui sys.exit (); Kode keluar adalah argumen fungsi atau python.exit.code .python.paths - Daftar Python Sys.Paths, terlihat di JS sebagai array Saat mengirim variabel dari Python ke JavaScript, PythonMonkey akan secara cerdas memaksa atau membungkus variabel Anda berdasarkan jenisnya. PythonMonkey akan berbagi toko backing (gunakan memori yang sama) untuk CTYPE, array yang diketik, dan string; Memindahkan tipe -tipe ini melintasi hambatan bahasa sangat cepat karena tidak ada penyalinan yang terlibat.
Catatan: Ada rencana dalam Python 3.12 (Pep 623) untuk mengubah representasi string internal sehingga setiap karakter dalam string menggunakan empat byte memori. Ini akan merusak transfer string cepat untuk PythonMonkey, karena bergantung pada tata letak memori yang sama di Python dan JavaScript. Sampai tulisan ini (Juli 2023), string ularin "klasik" masih berfungsi dalam rilis beta 3.12.
Di mana toko backing yang dibagikan tidak dimungkinkan, PythonMonkey akan secara otomatis memancarkan pembungkus yang menggunakan struktur data "nyata" sebagai otoritas nilai. Hanya intrinsik abadi yang disalin. Ini berarti bahwa jika Anda memperbarui objek di JavaScript, dikt yang sesuai dalam Python akan diperbarui, dll.
JavaScript array dan metode objek diimplementasikan pada daftar python dan kamus, dan sebaliknya.
| Jenis Python | Tipe JavaScript |
|---|---|
| Rangkaian | rangkaian |
| Bilangan bulat | nomor |
| Bool | Boolean |
| Fungsi | fungsi |
| Dikt | obyek |
| Daftar | Array |
| datetime | Objek tanggal |
| bisa ditunggu -tunggu | Janji |
| Kesalahan | Objek kesalahan |
| Penyangga | ArrayBuffer |
| Tipe JavaScript | Jenis Python |
|---|---|
| rangkaian | PythonMonkey.jsstringproxy (string) |
| nomor | Mengambang |
| Bigint | pythonmonkey.bigint (integer) |
| Boolean | Bool |
| fungsi | PythonMonkey.jsfunctionProxy |
| objek - kebanyakan | PythonMonkey.jsobjectProxy (DICT) |
| Objek - Tanggal | datetime |
| Objek - Array | PythonMonkey.jSarrayproxy (Daftar) |
| objek - janji | bisa ditunggu -tunggu |
| Objek - ArrayBuffer | Penyangga |
| Objek - Ketik Array | Penyangga |
| Objek - Kesalahan | Kesalahan |
Anda dapat memaksa angka dalam JavaScript untuk dipaksa sebagai bilangan bulat dengan melemparkannya ke Bigint:
function myFunction ( a , b ) {
const result = calculate ( a , b ) ;
return BigInt ( Math . floor ( result ) ) ;
} Objek pythonmonkey.bigint berfungsi seperti int di Python, tetapi akan dipaksa sebagai bigint di JavaScript:
import pythonmonkey
def fn myFunction ()
result = 5
return pythonmonkey . bigint ( result )Anda dapat menggunakan JavaScript IIFE untuk membuat ruang lingkup di mana Anda dapat menyuntikkan simbol Python:
globalThis . python . exit = pm . eval ( """'use strict';
(exit) => function pythonExitWrapper(exitCode) {
if (typeof exitCode === 'number')
exitCode = BigInt(Math.floor(exitCode));
exit(exitCode);
}
""" )( sys . exit ); Anda memerlukan loop acara untuk menggunakan setTimeout dan Promise <=> paksaan 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 ()) Shell JavaScript dasar, pmjs , dikirimkan dengan pythonmonkey. Shell ini dapat bertindak sebagai program JavaScript repl atau run; Secara konseptual mirip dengan shell node yang dikirimkan dengan node.js.
PMJS memulai subsistem CommonJS PythonMonkey, yang memungkinkannya menggunakan modul CommonJS, dengan semantik yang mirip dengan Node.js - misalnya Module.Paths, Memahami Package.json, Index.js, dan sebagainya. Lihat modul CTX untuk daftar lengkap fitur yang didukung.
Selain modul CommonJS yang ditulis dalam JavaScript, PythonMonkey mendukung modul CommonJS yang ditulis dalam Python. Cukup hiasi dikte bernama exports di dalam file dengan ekstensi .py , dan dapat dimuat dengan require() - baik dalam javascript atau python.
Modul program, atau modul utama, adalah modul khusus di CommonJS. Dalam modul program:
globalThisarguments dalam array yang memegang vektor argumen program Anda (argumen baris perintah) $ 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 () Jika Anda mengalami masalah dengan CommonJS memerlukan fungsi, atur variabel lingkungan DEBUG='ctx-module*' dan Anda dapat melihat nama file yang dicoba dimuat.
PythonMonkey memiliki debugger baris perintah JavaScript seperti GDB yang disebut PMDB , yang secara otomatis akan dipicu pada debugger; Pernyataan dan pengecualian yang tidak dibawa.
Untuk mengaktifkan PMDB , cukup hubungi from pythonmonkey.lib import pmdb; pmdb.enable() sebelum melakukan apa pun di PythonMonkey.
import pythonmonkey as pm
from pythonmonkey . lib import pmdb
pmdb . enable ()
pm . eval ( "..." ) Jalankan perintah help di PMDB untuk melihat perintah yang tersedia.
(pmdb) > help
List of commands:
• ...
• ... .help di repl--help--inspect memungkinkan PMDB , debugger baris perintah JavaScript seperti GDB-r dapat digunakan untuk memuat modul sebelum program Anda atau rept berjalan-e dapat digunakan evaluasi kode -misalnya menentukan variabel global -sebelum program Anda atau repl berjalan$1 , $2 , dll. $ 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'
>