PythonMonkeyは、Pythonエンジンを使用してJavaScriptホスト環境を提供するPythonランタイムに埋め込まれたMozilla Spidermonkey JavaScriptエンジンです。
cpython c apiを使用してPythonリストに実装されたJavaScriptアレイとオブジェクトメソッドと、Mozilla firefox spidermonkey JavaScript C ++ APIを使用して逆数を備えています。
このプロジェクトは、2024年9月現在、MVPに達しました。分配によりメンテナンスを受けています。
外部の貢献とフィードバックは歓迎され、奨励されています。
$ pip install pythonmonkey from pythonmonkey import eval as js_eval
js_eval ( "console.log" )( 'hello, world' )eval()関数を実装しますrequire 、モジュールのエクスポートの強制されたDICTを返しますローカルバージョンを作成する場合は、これをお読みください。
次のインストールが必要です( ./setup.shを実行して自動的に実行できます):
poetry installを実行します。このコマンドは、プロジェクトを自動的にコンパイルし、プロジェクトと依存関係を詩Virtualenvにインストールします。ドキュメントを構築する場合は、 BUILD_DOCS環境変数BUILD_DOCS=1 poetry install設定します。 PythonMonkeyは複数のビルドタイプをサポートしています。これは、 BUILD_TYPE=Debug poetry installなど、 BUILD_TYPE環境変数を設定することでビルドできます。ビルドタイプは(ケース非感受性)です。
Release :剥がれたシンボル、最大の最適化(デフォルト)DRelease :シンボルが剥がれていないことを除いて、 Releaseと同じDebug :最小限の最適化Sanitize : Debugと同じですが、アドレスサンタイザーが有効になっている場合を除きますProfile :プロファイリングが有効になっていることを除いて、 Debugと同じNone :コンパイルしないでください(ドキュメントのみを作成する場合は便利です) VSCodeを使用している場合は、 Ctrl + Shift + Bを押してビルドタスクを実行するだけですtasks.jsonファイルが設定されています。
poetry install --no-root --only=devpoetry run pytest ./tests/pythonpoetry run bash ./peter-jr ./tests/js/VSCODEユーザーの場合、ビルドタスクと同様に、使用可能なテストタスクがあります。
NPM(node.js)は、JS依存関係を埋めるためにのみインストール中に必要です。
$ pip install pythonmonkey$ pip install --extra-index-url https://nightly.pythonmonkey.io/ --pre pythonmonkeypythonmonkey 、詩を使用してプロジェクトをコンパイルしたら、Poetry Virtualenvで入手できます。
$ 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!'または、実行してインストール可能なパッケージを構築できます
$ cd python/pminit && poetry build --format=sdist && cd - && mv -v python/pminit/dist/ * ./dist/
$ poetry build --format=wheel pip install ./dist/*でインストールします。
pythonmonkeyインストールは、 pminitパッケージも依存関係としてインストールします。ただし、パッケージをpip uninstall 、自動的に依存関係を削除しません。
システムからpythonmonkeyをきれいに削除したい場合は、次のことを行います。
$ pip uninstall pythonmonkey pminitpoetry run gdb python 。 python wiki:Debuggingwithgdbを参照してくださいVSCODEを使用している場合、VSCODEの組み込みデバッガーでデバッグする方が便利です。エディターの開いたPython launch.jsonでF5を押してデバッグを開始するだけです。Launch.JSONファイルが設定されています。
これらの方法は、PythonMonkeyモジュールからエクスポートされます。 python/pythonmonkey/pythonmonkey.pyiの定義を参照してください。
JavaScriptコードを評価します。この評価のセマンティクスは、JavaScriptで使用される評価と非常に似ています。 code文字列で評価された最後の式は、この関数の戻り値として使用されます。 Strictモードでcodeを評価するには、最初の式は文字列"use strict"でなければなりません。
評価関数は、JSコードが強力な方法で評価される方法に影響を与える可能性のあるオプションオブジェクトをサポートします。それらは主にSpidermonkeyのCompileOptionsに基づいています。サポートされているオプションキーは次のとおりです。
filename :スタックトレースなどを生成する目的で、このコードのファイル名を設定します。lineno :スタックトレースなどを生成する目的で、このコードのライン番号オフセットを設定します。column :スタックトレースなどを生成する目的で、このコードの列番号オフセットを設定します。mutedErrors : Trueに設定されている場合、評価エラーまたは未処理の拒否は無視されます(「Muted」)。デフォルトのFalse 。noScriptRval : Falseの場合、結果値としてスクリプトの最後の式値を呼び出し元に返します。デフォルトのFalse 。selfHosting :実験strict :厳密なモードで強制的に評価します( "use strict" )。デフォルトのFalse 。module :ファイルがECMAScriptモジュールであることを示します(常に厳密なモードコードとHTMLコメントを許可しません)。デフォルトのFalse 。fromPythonFrame :Pythonコールの場所に基づいて、Filename、Lineno、および列に相当するものを生成します。これにより、Python Multiline Stringリテラルを評価し、Pythonソースファイルのエラーを指してJSでスタックトレースを生成することができます。 undefinedとして評価されます。関数を返したい場合は、式を評価する必要があります。 pythonmonkey . eval ( "myFunction() { return 123 }; myFunction" ) pythonmonkey . eval ( "(myFunction() { return 123 })" ) pythonmonkey . eval ( "(thing) => console.log('you said', thing)" )( "this string came from Python" )標準CommonJSセマンティクスを使用して、 moduleIdentifierによって識別されたCommonJSモジュールのエクスポートを返します
require.js -JavaScriptモジュール。ソースコードはexportsオブジェクトを飾ります.py -pythonモジュール;ソースコードはexports DICTを飾ります.json -JSONモジュール;エクスポートは、ファイル内のJSONテキストを解析した結果ですJavaScriptのグローバルオブジェクトに相当するPython Dict。
新しい要求関数を返す工場関数
プログラム(メイン)モジュールをロードして評価します。プログラムモジュールは、JavaScriptに記述する必要があります。プログラムのメインエントリポイントがJavaScriptに記述されていない限り、プログラムモジュールは必要ありません。
JSコンテキストごとに1つのプログラムモジュールのみが実行されるように注意する必要があります。
文字列codeを調べ、文字列がより多くの行を追加して有効なJSステートメントになる可能性がある場合、falseを返します。これはPMJSによって内部的に使用されており、JavaScript REPLを構築するのに非常に役立ちます。アイデアは、IsCompilableUnitがTrueになるまでバッファーにラインを蓄積し、バッファー全体を評価することです。
JS Newオペレーターとのfunctionを呼び出すPython関数を返します。
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
{}
>> >これは、Pythonから簡単に使用できるように機能に包まれたJS typeofオペレーターです。
すべてのJS標準クラス(配列、関数、オブジェクト、日付...)およびオブジェクト(GlobalThis、FinalizationRegistry ...)は、PythonMonkeyモジュールのエクスポートとして利用できます。これらのエクスポートは、現在のSpidermonkeyコンテキストでグローバル変数を列挙することにより生成されます。現在のリストは次のとおりです。
未定義、ブール、JSON、日付、数学、数値、文字列、regexp、エラー、内部エラー、アグリゲートエラー、evalError、raighenerror、referenceerror、syntaxerror、typeerror、urieror、arraybuffer、int8array、uint8array、int16array、uint16array、int32array、uint32arreay、uint32array、uint32array、 float64array、uint8clampedarray、bigint64array、biguint64array、bigint、proxy、weakmap、map、set、dataview、symbol、intl、refter、weakset、promise、webassembly、weakref、iterator、yearator、aynciterator、nan、nan、infinity、decape、usefloat、usefloat、usefloat、usefloat、usefloat、usefloat、 encodeuri、decodeuricoponent、encodeuricoponent、function、object、debuggerglobal、finalizationregistry、array、global this
python/pythonmonkey/global.d.tsの定義を参照してください。含む:
consoleatobbtoasetTimeoutclearTimeoutCommonJSサブシステムは、(python)pythonmonkeyモジュールのrequireまたはcreateRequireエクスポートを呼び出すことによりアクティブになります。
requireexportsmodule__filename__dirnamepython.print python印刷機能python.getenv -Python getEnv関数python.stdout stdoutにreadとwriteの読み取りと書き込みのオブジェクトpython.stderr stderrに読み書きした方法をreadとwrite方法を備えたオブジェクトpython.exec python exec関数python.eval python eval関数python.exit sys.exit()経由で終了します。 exitコードは、関数引数またはpython.exit.codeです。python.paths -python sys.pathsリスト。 PythonからJavaScriptに変数を送信すると、PythonMonkeyはそのタイプに基づいて変数をインテリジェントに強制またはラップします。 PythonMonkeyは、CTYPE、タイプ付き配列、文字列のバッキングストア(同じメモリを使用)を共有します。コピーが関係していないため、これらのタイプを言語の壁に移動するのは非常に高速です。
注: Python 3.12(PEP 623)には、文字列内のすべての文字が4バイトのメモリを使用するように、内部文字列表現を変更する計画があります。これにより、PythonMonkeyの高速文字列転送が壊れます。これは、PythonとJavaScriptで同じであるメモリレイアウトに依存しているためです。この執筆時点(2023年7月)の時点で、「クラシック」Python文字列は3.12ベータリリースでまだ機能しています。
共有されたバッキングストアが不可能な場合、PythonMonkeyは、「実際の」データ構造を価値のある権限として使用するラッパーを自動的に放出します。不変の内因性のみがコピーされます。これは、JavaScriptでオブジェクトを更新すると、Pythonの対応するDICTが更新されることを意味します。
JavaScriptアレイとオブジェクトメソッドは、Pythonリストと辞書に実装されており、その逆も同様です。
| Pythonタイプ | JavaScriptタイプ |
|---|---|
| 弦 | 弦 |
| 整数 | 番号 |
| ブール | ブール |
| 関数 | 関数 |
| dict | 物体 |
| リスト | 配列 |
| DateTime | 日付オブジェクト |
| お待ちの | 約束 |
| エラー | エラーオブジェクト |
| バッファ | arraybuffer |
| JavaScriptタイプ | Pythonタイプ |
|---|---|
| 弦 | pythonmonkey.jsstringproxy(string) |
| 番号 | フロート |
| bigint | pythonmonkey.bigint(整数) |
| ブール | ブール |
| 関数 | pythonmonkey.jsfunctionproxy |
| オブジェクト - ほとんど | pythonmonkey.jsobjectproxy(dict) |
| オブジェクト - 日付 | DateTime |
| オブジェクト - 配列 | pythonmonkey.jsarrayproxy(リスト) |
| オブジェクト - 約束 | お待ちの |
| オブジェクト-ArrayBuffer | バッファ |
| オブジェクト - タイプ配列 | バッファ |
| オブジェクト - エラー | エラー |
JavaScriptの数字を強制的に整数として強制することができます。
function myFunction ( a , b ) {
const result = calculate ( a , b ) ;
return BigInt ( Math . floor ( result ) ) ;
} pythonmonkey.bigintオブジェクトはpythonのintのように機能しますが、JavascriptのBigintとして強制されます。
import pythonmonkey
def fn myFunction ()
result = 5
return pythonmonkey . bigint ( result )JavaScript Iifeを使用して、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 );setTimeoutと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 ())基本的なJavaScriptシェル、 pmjs 、PythonMonkeyを搭載しています。このシェルは、REPLとして機能するか、JavaScriptプログラムを実行できます。概念的には、node.jsに出荷されるnodeシェルに似ています。
PMJSは、node.jsに似たセマンティクスを使用して、pythonmonkeyのcommonjsサブシステムを開始します。これにより、commonjsモジュールを使用できます。サポートされている機能の完全なリストについては、CTX-Moduleを参照してください。
JavaScriptで記述されたCommonJSモジュールに加えて、PythonMonkeyはPythonで記述されたCommonJSモジュールをサポートしています。 .py拡張機能を備えたファイル内のexportsという名前のdictを飾るだけで、javascriptまたはpythonのいずれかでrequire()でロードできます。
プログラムモジュール、またはメインモジュールは、CommonJSの特別なモジュールです。プログラムモジュール:
globalThisのプロパティですarguments変数(コマンドライン引数) $ 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 () commonjs requent機能に問題がある場合、環境変数DEBUG='ctx-module*'を設定し、ロードしようとしているファイル名を見ることができます。
PythonMonkeyには、 PMDBと呼ばれるGDBのようなJavaScriptコマンドラインデバッガーが組み込まれており、 debugger;声明と猛攻撃の例外。
PMDBを有効にするには、 from pythonmonkey.lib import pmdb; pmdb.enable() pythonmonkeyで何かをする前に、 from pythonmonkey.lib import pmdb; pmdb.enable() 。
import pythonmonkey as pm
from pythonmonkey . lib import pmdb
pmdb . enable ()
pm . eval ( "..." ) PMDBでhelpコマンドを実行して、利用可能なコマンドを表示します。
(pmdb) > help
List of commands:
• ...
• ... .helpメニューがあります--helpコマンドラインオプションがあります--inspectオプションは、GDBのようなJavaScriptコマンドラインデバッガーであるPMDBを有効にします-rオプションは、プログラムまたはREPLが実行される前にモジュールをロードするために使用できます-eオプションは、プログラムまたはREPLが実行される前に、コードを使用することができます - グローバル変数を定義する例:$1 、 $2などという名前の変数に保存できます。 $ 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'
>