Pythonmonkey는 Python 엔진을 사용하여 JavaScript 호스트 환경을 제공하는 Python 런타임에 포함 된 Mozilla Spidermonkey JavaScript 엔진입니다.
CPYTHON C API를 사용하여 Python List 및 사전에서 구현 된 JavaScript Array 및 Object Methods와 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 실행하십시오. 이 명령은 프로젝트를 자동으로 컴파일하고 프로젝트를 설치하고 Poetry Virtualenv에 의존성을 설치합니다. 문서를 구축하려면 다음과 같은 BUILD_DOCS 환경 변수를 설정하십시오. BUILD_DOCS=1 poetry install . Pythonmonkey는 여러 빌드 유형을 지원하며, BUILD_TYPE 환경 변수를 설정하여 BUILD_TYPE=Debug poetry install 와 같이 빌드 할 수 있습니다. 빌드 유형은 (CASE-Insensitive)입니다.
Release : 스트리핑 기호, 최대 최적화 (기본값)DRelease : 기호가 벗겨지지 않은 경우를 제외하고 Release 와 동일합니다.Debug : 최소 최적화Sanitize : 주소 사료 활성화를 제외하고 Debug 와 동일합니다.Profile : 프로파일 링이 활성화 된 것을 제외하고 Debug 와 동일None : 컴파일하지 마십시오 (문서를 구축하려는 경우 유용합니다) VScode를 사용하는 경우 Ctrl + Shift + B를 눌러 빌드 작업을 실행할 수 있습니다. tasks.json 파일을 구성했습니다.
poetry install --no-root --only=devpoetry run pytest ./tests/python 실행하십시오poetry run bash ./peter-jr ./tests/js/빌드 작업과 유사한 VSCODE 사용자의 경우 사용할 준비가 된 테스트 작업이 있습니다.
JS 종속성을 채우기 위해서만 설치하는 동안 npm (node.js)이 필요합니다.
$ pip install pythonmonkey$ pip install --extra-index-url https://nightly.pythonmonkey.io/ --pre pythonmonkey pythonmonkey 시를 사용하여 프로젝트를 편집하면 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 파일에서 F5를 눌러 디버깅을 시작합니다. launch.json 파일이 구성되어 있습니다.
이 방법은 Pythonmonkey 모듈에서 내보내집니다. Python/Pythonmonkey/Pythonmonkey.pyi의 정의를 참조하십시오.
JavaScript 코드를 평가합니다. 이 평가의 의미론은 JavaScript에 사용 된 평가와 매우 유사합니다. code 문자열에서 평가 된 마지막 표현식은이 함수의 리턴 값으로 사용됩니다. 엄격한 모드에서 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 Call의 위치에 따라 파일 이름, 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 Semantics를 사용하여 moduleIdentifier 에서 식별 한 CommonJS 모듈의 내보내기를 반환합니다.
require 호출하는 Python 파일과 관련이 있습니다.js -JavaScript 모듈; 소스 코드는 exports 객체를 장식합니다.py 파이썬 모듈; 소스 코드는 exports DICT를 장식합니다.json -JSON 모듈; 내보내기는 파일에서 JSON 텍스트를 구문 분석 한 결과입니다.JavaScript의 global this 객체와 동일한 Python Dict.
새로운 요구 기능을 반환하는 공장 기능
프로그램 (메인) 모듈을로드하고 평가합니다. 프로그램 모듈은 JavaScript로 작성해야합니다. 프로그램의 주요 진입 점이 JavaScript로 작성되지 않는 한 프로그램 모듈이 필요하지 않습니다.
JS 컨텍스트에 따라 하나의 프로그램 모듈 만 실행되도록주의를 기울여야합니다.
문자열 code 검사하고 문자열이 더 많은 선이 추가 된 유효한 JS 문이 될 수 있으면 False를 반환합니다. 이것은 PMJ에 의해 내부적으로 사용되며 JavaScript Repls를 구축하는 데 매우 도움이 될 수 있습니다. 아이디어는 iscompilableUnit이 사실이 될 때까지 버퍼에 라인을 축적 한 다음 전체 버퍼를 평가하는 것입니다.
JS 새 연산자와 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
{}
>> > 이것은 JS typeof 연산자이며, 함수로 싸서 파이썬에서 쉽게 사용할 수 있습니다.
모든 JS 표준 클래스 (배열, 기능, 객체, 날짜 ...) 및 객체 (GlobalThis, FinalizationRegistry ...)는 Pythonmonkey 모듈의 내보내기로 제공됩니다. 이러한 수출은 현재 SpiderMonkey 컨텍스트에서 전역 변수를 열거하여 생성됩니다. 현재 목록은 다음과 같습니다.
정의, 부울, 부울, JSON, 날짜, 수학, 번호, 문자열, regexp, 오류, 내부 테러, 골재 거부자, 평가 테러, 레인지 서러, 참조 오류, syntaxerror, typeerror, urierror, arraybuffer, int8array, uint8array, int16array, uint16array, int32Array, flate32Array, flate32Array, flate32Array, uint8clampedarray, bigint64array, biguint64array, bigint, proxy, weakmap, map, set, set, dataview, intl, 반사, 약점, 약속, webassembly, webicref, iterator, asynciterator, nan, Infinity, isnan, isfinite, parsefloat, parseint, unscode, decodeuri,, decodeuri. decodeUricomponent, EncodeUricomponent, 함수, 객체, 디버거 글로벌, 최종화 레스트리, 배열, GlobalThis
Python/Pythonmonkey/Global.d.ts의 정의를 참조하십시오. 포함:
consoleatobbtoasetTimeoutclearTimeout CommonJS 서브 시스템은 (Python) Pythonmonkey 모듈의 require 또는 createRequire 수출을 호출하여 활성화됩니다.
requireexportsmodule__filename__dirnamepython.print 파이썬 인쇄 기능python.getenv 파이썬 getenv 함수python.stdout read 및 write 방법이있는 개체, stdout에 읽고 쓰는 객체python.stderr read 및 write 방법이있는 개체, Stderr에 읽고 쓰는 객체python.exec Python exec 기능python.eval 파이썬 평가 기능python.exit sys.exit ()를 통해 종료; 종료 코드는 함수 인수 또는 python.exit.code 입니다.python.paths Python sys.paths 목록, JS에서 배열로 보입니다. Python에서 JavaScript로 변수를 보낼 때 Pythonmonkey는 유형에 따라 변수를 지능적으로 강요하거나 랩핑합니다. Pythonmonkey는 CTYPES, 유형 어레이 및 문자열의 백업 스토어 (동일한 메모리 사용)를 공유합니다. 복사가 없기 때문에 이러한 유형을 언어 장벽으로 이동하는 것은 매우 빠릅니다.
참고 : Python 3.12 (PEP 623)에는 내부 문자열 표현을 변경하여 문자열의 모든 문자가 4 바이트의 메모리를 사용하도록 계획이 있습니다. Pythonmonkey의 빠른 문자열 전송이 파괴됩니다. Python 및 JavaScript에서 메모리 레이아웃에 동일하게 의존하기 때문입니다. 이 글을 쓰는 시점 (2023 년 7 월)에서 "클래식"파이썬 문자열은 여전히 3.12 베타 릴리스에서 작동합니다.
공유 백업 스토어가 불가능한 경우, Pythonmonkey는 "실제"데이터 구조를 가치 기관으로 사용하는 포장지를 자동으로 방출합니다. 불변의 고부인 만 복사됩니다. 즉, JavaScript로 객체를 업데이트하면 Python의 해당 DICT가 업데이트됩니다.
JavaScript 배열 및 객체 방법은 Python List 및 Dictionaries에서 구현되며 그 반대도 마찬가지입니다.
| 파이썬 유형 | 자바 스크립트 유형 |
|---|---|
| 끈 | 끈 |
| 정수 | 숫자 |
| 부 | 부울 |
| 기능 | 기능 |
| DITT | 물체 |
| 목록 | 정렬 |
| DateTime | 날짜 개체 |
| 기다릴 수 있습니다 | 약속하다 |
| 오류 | 오류 객체 |
| 완충기 | Arraybuffer |
| 자바 스크립트 유형 | 파이썬 유형 |
|---|---|
| 끈 | pythonmonkey.jsstringproxy (String) |
| 숫자 | 뜨다 |
| 큰 | Pythonmonkey.bigint (정수) |
| 부울 | 부 |
| 기능 | pythonmonkey.jsfunctionproxy |
| 객체 - 대부분 | pythonmonkey.jsobjectproxy (dict) |
| 객체 - 날짜 | DateTime |
| 객체 - 배열 | pythonmonkey.jsarrayproxy (목록) |
| 대상 - 약속 | 기다릴 수 있습니다 |
| 객체 - Arraybuffer | 완충기 |
| 객체 - 유형 배열 | 완충기 |
| 객체 - 오류 | 오류 |
Bigint에 캐스팅하여 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 사용하려면 이벤트 루프가 필요하고 <=> awaitable 강요를 Promise .
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와 함께 배송됩니다. 이 쉘은 대체 또는 실행 자바 스크립트 프로그램 역할을 할 수 있습니다. Node.js와 함께 배송하는 node 쉘과 개념적으로 유사합니다.
PMJS는 Pythonmonkey의 CommonJS 서브 시스템을 시작하여 Node.js와 유사한 시맨틱과 함께 CommonJS 모듈을 사용할 수 있습니다. 지원되는 기능의 전체 목록은 CTX 모듈을 참조하십시오.
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에 문제가있는 경우 기능이 필요한 경우 환경 변수 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 옵션은 프로그램 또는 대체가 실행되기 전에 코드 평가 (예 : 글로벌 변수 정의)를 사용할 수 있습니다.$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'
>