Browse Source

refac: migrated to pyodide from pyscript

Timothy J. Baek 1 year ago
parent
commit
8f8ce26948
60 changed files with 254 additions and 188 deletions
  1. 7 4
      package-lock.json
  2. 1 1
      package.json
  3. 3 0
      pyodide.sh
  4. 0 8
      pyscript-mv.sh
  5. 0 20
      src/Untitled-1.js
  6. 0 8
      src/app.html
  7. 42 63
      src/lib/components/chat/Messages/CodeBlock.svelte
  8. 6 6
      src/lib/utils/index.ts
  9. 134 0
      static/pyodide/package.json
  10. 0 0
      static/pyodide/pyodide-lock.json
  11. 1 1
      static/pyodide/pyodide.asm.js
  12. BIN
      static/pyodide/pyodide.asm.wasm
  13. 60 57
      static/pyodide/pyodide.d.ts
  14. 0 0
      static/pyodide/pyodide.js
  15. 0 0
      static/pyodide/pyodide.js.map
  16. 0 0
      static/pyodide/pyodide.mjs
  17. 0 0
      static/pyodide/pyodide.mjs.map
  18. BIN
      static/pyodide/python_stdlib.zip
  19. 0 0
      static/pyscript/codemirror-Dr2Hgejs.js
  20. 0 0
      static/pyscript/codemirror-Dr2Hgejs.js.map
  21. 0 0
      static/pyscript/codemirror_commands-MgxtVkrD.js
  22. 0 0
      static/pyscript/codemirror_commands-MgxtVkrD.js.map
  23. 0 0
      static/pyscript/codemirror_lang-python-Cxoc-ydj.js
  24. 0 0
      static/pyscript/codemirror_lang-python-Cxoc-ydj.js.map
  25. 0 0
      static/pyscript/codemirror_language-_XiX6II0.js
  26. 0 0
      static/pyscript/codemirror_language-_XiX6II0.js.map
  27. 0 0
      static/pyscript/codemirror_state-BKbyfKsm.js
  28. 0 0
      static/pyscript/codemirror_state-BKbyfKsm.js.map
  29. 0 0
      static/pyscript/codemirror_view-C0PMO2z_.js
  30. 0 0
      static/pyscript/codemirror_view-C0PMO2z_.js.map
  31. 0 0
      static/pyscript/core-CPpjJT4b.js
  32. 0 0
      static/pyscript/core-CPpjJT4b.js.map
  33. 0 1
      static/pyscript/core.css
  34. 0 2
      static/pyscript/core.js
  35. 0 1
      static/pyscript/core.js.map
  36. 0 2
      static/pyscript/deprecations-manager-CQ0oxKrq.js
  37. 0 1
      static/pyscript/deprecations-manager-CQ0oxKrq.js.map
  38. 0 2
      static/pyscript/error-BfnovtqK.js
  39. 0 0
      static/pyscript/error-BfnovtqK.js.map
  40. 0 0
      static/pyscript/index-CTWZX_TW.js
  41. 0 0
      static/pyscript/index-CTWZX_TW.js.map
  42. 0 0
      static/pyscript/py-editor-CmqzUo2Z.js
  43. 0 0
      static/pyscript/py-editor-CmqzUo2Z.js.map
  44. 0 0
      static/pyscript/py-terminal-CgcHH2nx.js
  45. 0 0
      static/pyscript/py-terminal-CgcHH2nx.js.map
  46. 0 0
      static/pyscript/toml-CvAfdf9_.js
  47. 0 0
      static/pyscript/toml-CvAfdf9_.js.map
  48. 0 3
      static/pyscript/toml-DiUM0_qs.js
  49. 0 0
      static/pyscript/toml-DiUM0_qs.js.map
  50. 0 0
      static/pyscript/xterm-DqawCVsv.js
  51. 0 0
      static/pyscript/xterm-DqawCVsv.js.map
  52. 0 0
      static/pyscript/xterm-readline-D247p8vq.js
  53. 0 0
      static/pyscript/xterm-readline-D247p8vq.js.map
  54. 0 6
      static/pyscript/xterm.css
  55. 0 2
      static/pyscript/xterm_addon-fit--gyF3PcZ.js
  56. 0 0
      static/pyscript/xterm_addon-fit--gyF3PcZ.js.map
  57. 0 0
      static/pyscript/xterm_addon-web-links-Cnej-nJ6.js
  58. 0 0
      static/pyscript/xterm_addon-web-links-Cnej-nJ6.js.map
  59. 0 0
      static/pyscript/zip-D2yvzXKD.js
  60. 0 0
      static/pyscript/zip-D2yvzXKD.js.map

+ 7 - 4
package-lock.json

@@ -24,7 +24,7 @@
 				"js-sha256": "^0.10.1",
 				"js-sha256": "^0.10.1",
 				"katex": "^0.16.9",
 				"katex": "^0.16.9",
 				"marked": "^9.1.0",
 				"marked": "^9.1.0",
-				"pyodide": "^0.25.1",
+				"pyodide": "^0.26.0-alpha.4",
 				"svelte-sonner": "^0.3.19",
 				"svelte-sonner": "^0.3.19",
 				"tippy.js": "^6.3.7",
 				"tippy.js": "^6.3.7",
 				"uuid": "^9.0.1"
 				"uuid": "^9.0.1"
@@ -6277,12 +6277,15 @@
 			}
 			}
 		},
 		},
 		"node_modules/pyodide": {
 		"node_modules/pyodide": {
-			"version": "0.25.1",
-			"resolved": "https://registry.npmjs.org/pyodide/-/pyodide-0.25.1.tgz",
-			"integrity": "sha512-y0nJ/fLA3bxD2iZRzvVTbP2O+wp4Ewm2wThfV4HF0BytQ6hsoqTJFLNY4usLOcCVBrK8TTWqFqrmsVPzHe4rsw==",
+			"version": "0.26.0-alpha.4",
+			"resolved": "https://registry.npmjs.org/pyodide/-/pyodide-0.26.0-alpha.4.tgz",
+			"integrity": "sha512-Ixuczq99DwhQlE+Bt0RaS6Ln9MHSZOkbU6iN8azwaeorjHtr7ukaxh+FeTxViFrp2y+ITyKgmcobY+JnBPcULw==",
 			"dependencies": {
 			"dependencies": {
 				"base-64": "^1.0.0",
 				"base-64": "^1.0.0",
 				"ws": "^8.5.0"
 				"ws": "^8.5.0"
+			},
+			"engines": {
+				"node": ">=18.0.0"
 			}
 			}
 		},
 		},
 		"node_modules/qs": {
 		"node_modules/qs": {

+ 1 - 1
package.json

@@ -63,7 +63,7 @@
 		"js-sha256": "^0.10.1",
 		"js-sha256": "^0.10.1",
 		"katex": "^0.16.9",
 		"katex": "^0.16.9",
 		"marked": "^9.1.0",
 		"marked": "^9.1.0",
-		"pyodide": "^0.25.1",
+		"pyodide": "^0.26.0-alpha.4",
 		"svelte-sonner": "^0.3.19",
 		"svelte-sonner": "^0.3.19",
 		"tippy.js": "^6.3.7",
 		"tippy.js": "^6.3.7",
 		"uuid": "^9.0.1"
 		"uuid": "^9.0.1"

+ 3 - 0
pyodide.sh

@@ -0,0 +1,3 @@
+mkdir -p ./static/pyodide
+cp ./node_modules/pyodide/pyodide* ./static/pyodide/
+cp ./node_modules/pyodide/python_stdlib.zip ./static/pyodide/

+ 0 - 8
pyscript-mv.sh

@@ -1,8 +0,0 @@
-cp -R ./node_modules/@pyscript/core/dist ./static/pyscript
-
-# mkdir -p ./static/micropython
-# cp -R ./node_modules/@micropython/micropython-webassembly-pyscript/micropython.* ./static/micropython
-
-mkdir -p ./static/pyodide
-cp ./node_modules/pyodide/pyodide* ./static/pyodide/
-cp ./node_modules/pyodide/python_stdlib.zip ./static/pyodide/

+ 0 - 20
src/Untitled-1.js

@@ -1,20 +0,0 @@
-function execute(id, text) {
-	// pyscript
-	let div = document.createElement('div');
-	let html = `
-            <py-script type="mpy">
-${text}
-            </py-script>
-            `;
-	div.innerHTML = html;
-	const pyScript = div.firstElementChild;
-	try {
-		document.body.appendChild(pyScript);
-		setTimeout(() => {
-			document.body.removeChild(pyScript);
-		}, 0);
-	} catch (error) {
-		console.error('Python error:');
-		console.error(error);
-	}
-}

+ 0 - 8
src/app.html

@@ -13,9 +13,6 @@
 			href="/opensearch.xml"
 			href="/opensearch.xml"
 		/>
 		/>
 
 
-		<script type="module" src="/pyscript/core.js"></script>
-		<link rel="stylesheet" href="/pyscript/core.css" />
-
 		<script>
 		<script>
 			// On page load or when changing themes, best to add inline in `head` to avoid FOUC
 			// On page load or when changing themes, best to add inline in `head` to avoid FOUC
 			(() => {
 			(() => {
@@ -58,11 +55,6 @@
 		%sveltekit.head%
 		%sveltekit.head%
 	</head>
 	</head>
 	<body data-sveltekit-preload-data="hover">
 	<body data-sveltekit-preload-data="hover">
-		<py-config> interpreter = "/pyodide/pyodide.mjs" </py-config>
-
-		<script type="py">
-			print('pyscript:loaded')
-		</script>
 		<div style="display: contents">%sveltekit.body%</div>
 		<div style="display: contents">%sveltekit.body%</div>
 
 
 		<div
 		<div

+ 42 - 63
src/lib/components/chat/Messages/CodeBlock.svelte

@@ -2,6 +2,7 @@
 	import { copyToClipboard } from '$lib/utils';
 	import { copyToClipboard } from '$lib/utils';
 	import hljs from 'highlight.js';
 	import hljs from 'highlight.js';
 	import 'highlight.js/styles/github-dark.min.css';
 	import 'highlight.js/styles/github-dark.min.css';
+	import { loadPyodide } from 'pyodide';
 	import { tick } from 'svelte';
 	import { tick } from 'svelte';
 
 
 	export let id = '';
 	export let id = '';
@@ -10,6 +11,11 @@
 	export let code = '';
 	export let code = '';
 
 
 	let executed = false;
 	let executed = false;
+
+	let stdout = null;
+	let stderr = null;
+	let result = null;
+
 	let copied = false;
 	let copied = false;
 
 
 	const copyCode = async () => {
 	const copyCode = async () => {
@@ -131,72 +137,35 @@
 		return false;
 		return false;
 	};
 	};
 
 
-	const executePython = async (text) => {
+	const executePython = async (code) => {
 		executed = true;
 		executed = true;
 
 
-		await tick();
-		const outputDiv = document.getElementById(`code-output-${id}`);
+		let pyodide = await loadPyodide({
+			indexURL: '/pyodide/',
+			stderr: (text) => {
+				console.log('An error occured:', text);
+				if (stderr) {
+					stderr += `${text}\n`;
+				} else {
+					stderr = `${text}\n`;
+				}
+			},
+			stdout: (text) => {
+				console.log('Python output:', text);
+
+				if (stdout) {
+					stdout += `${text}\n`;
+				} else {
+					stdout = `${text}\n`;
+				}
+			}
+		});
 
 
-		if (outputDiv) {
-			outputDiv.innerText = 'Running...';
-		}
+		result = pyodide.runPython(code);
 
 
-		text = text
-			.split('\n')
-			.map((line, index) => (index === 0 ? line : '    ' + line))
-			.join('\n');
-
-		// pyscript
-		let div = document.createElement('div');
-		let html = `
-<py-script type="py" worker>
-import js
-import sys
-import io
-
-# Create a StringIO object to capture the output
-output_capture = io.StringIO()
-
-# Save the current standard output
-original_stdout = sys.stdout
-
-# Replace the standard output with the StringIO object
-sys.stdout = output_capture
-
-try:
-    ${text}
-except Exception as e:
-    # Capture any errors and write them to the output capture
-    print(f"Error: {e}", file=output_capture)
-
-# Restore the original standard output
-sys.stdout = original_stdout
-
-# Retrieve the captured output
-captured_output = "[NO OUTPUT]"
-captured_output = output_capture.getvalue()
-
-# Print the captured output
-print(captured_output)
-
-def display_message():
-    output_div = js.document.getElementById("code-output-${id}")
-    output_div.innerText = captured_output
-
-display_message()
-</py-script>`;
-
-		div.innerHTML = html;
-		const pyScript = div.firstElementChild;
-		try {
-			document.body.appendChild(pyScript);
-			setTimeout(() => {
-				document.body.removeChild(pyScript);
-			}, 0);
-		} catch (error) {
-			console.error('Python error:');
-			console.error(error);
-		}
+		console.log(result);
+		console.log(stderr);
+		console.log(stdout);
 	};
 	};
 
 
 	$: highlightedCode = code ? hljs.highlightAuto(code, hljs.getLanguage(lang)?.aliases).value : '';
 	$: highlightedCode = code ? hljs.highlightAuto(code, hljs.getLanguage(lang)?.aliases).value : '';
@@ -234,7 +203,17 @@ display_message()
 		{#if executed}
 		{#if executed}
 			<div class="bg-[#202123] text-white px-4 py-4 rounded-b-lg">
 			<div class="bg-[#202123] text-white px-4 py-4 rounded-b-lg">
 				<div class=" text-gray-500 text-xs mb-1">STDOUT/STDERR</div>
 				<div class=" text-gray-500 text-xs mb-1">STDOUT/STDERR</div>
-				<div id="code-output-{id}" class="text-sm" />
+				<div class="text-sm">
+					{#if stdout}
+						{stdout}
+					{:else if result}
+						{result}
+					{:else if stderr}
+						{stderr}
+					{:else}
+						Running...
+					{/if}
+				</div>
 			</div>
 			</div>
 		{/if}
 		{/if}
 	</div>
 	</div>

+ 6 - 6
src/lib/utils/index.ts

@@ -6,15 +6,15 @@ import { getLiteLLMModels } from '$lib/apis/litellm';
 
 
 export const getModels = async (token: string) => {
 export const getModels = async (token: string) => {
 	let models = await Promise.all([
 	let models = await Promise.all([
-		await getOllamaModels(token).catch((error) => {
+		getOllamaModels(token).catch((error) => {
 			console.log(error);
 			console.log(error);
 			return null;
 			return null;
 		}),
 		}),
-		await getOpenAIModels(token).catch((error) => {
-			console.log(error);
-			return null;
-		}),
-		await getLiteLLMModels(token).catch((error) => {
+		// getOpenAIModels(token).catch((error) => {
+		// 	console.log(error);
+		// 	return null;
+		// }),
+		getLiteLLMModels(token).catch((error) => {
 			console.log(error);
 			console.log(error);
 			return null;
 			return null;
 		})
 		})

+ 134 - 0
static/pyodide/package.json

@@ -0,0 +1,134 @@
+{
+  "name": "pyodide",
+  "version": "0.25.1",
+  "description": "The Pyodide JavaScript package",
+  "keywords": [
+    "python",
+    "webassembly"
+  ],
+  "homepage": "https://github.com/pyodide/pyodide",
+  "repository": {
+    "type": "git",
+    "url": "https://github.com/pyodide/pyodide"
+  },
+  "bugs": {
+    "url": "https://github.com/pyodide/pyodide/issues"
+  },
+  "license": "Apache-2.0",
+  "devDependencies": {
+    "@types/assert": "^1.5.6",
+    "@types/expect": "^24.3.0",
+    "@types/mocha": "^9.1.0",
+    "@types/node": "^20.8.4",
+    "@types/ws": "^8.5.3",
+    "chai": "^4.3.6",
+    "chai-as-promised": "^7.1.1",
+    "cross-env": "^7.0.3",
+    "dts-bundle-generator": "^8.1.1",
+    "error-stack-parser": "^2.1.4",
+    "esbuild": "^0.17.12",
+    "express": "^4.17.3",
+    "mocha": "^9.0.2",
+    "npm-run-all": "^4.1.5",
+    "nyc": "^15.1.0",
+    "prettier": "^2.2.1",
+    "ts-mocha": "^9.0.2",
+    "tsd": "^0.24.1",
+    "typedoc": "^0.25.1",
+    "typescript": "^4.6.4",
+    "wabt": "^1.0.32"
+  },
+  "main": "pyodide.js",
+  "exports": {
+    ".": {
+      "require": "./pyodide.js",
+      "import": "./pyodide.mjs",
+      "types": "./pyodide.d.ts"
+    },
+    "./ffi": {
+      "types": "./ffi.d.ts"
+    },
+    "./pyodide.asm.wasm": "./pyodide.asm.wasm",
+    "./pyodide.asm.js": "./pyodide.asm.js",
+    "./python_stdlib.zip": "./python_stdlib.zip",
+    "./pyodide.mjs": "./pyodide.mjs",
+    "./pyodide.js": "./pyodide.js",
+    "./package.json": "./package.json",
+    "./pyodide-lock.json": "./pyodide-lock.json"
+  },
+  "files": [
+    "pyodide.asm.js",
+    "pyodide.asm.wasm",
+    "python_stdlib.zip",
+    "pyodide.mjs",
+    "pyodide.js.map",
+    "pyodide.mjs.map",
+    "pyodide.d.ts",
+    "ffi.d.ts",
+    "pyodide-lock.json",
+    "console.html"
+  ],
+  "browser": {
+    "child_process": false,
+    "crypto": false,
+    "fs": false,
+    "fs/promises": false,
+    "path": false,
+    "url": false,
+    "vm": false,
+    "ws": false
+  },
+  "scripts": {
+    "build": "tsc --noEmit && node esbuild.config.mjs",
+    "test": "npm-run-all test:*",
+    "test:unit": "cross-env TEST_NODE=1 ts-mocha --node-option=experimental-loader=./test/loader.mjs --node-option=experimental-wasm-stack-switching -p tsconfig.test.json test/unit/**/*.test.*",
+    "test:node": "cross-env TEST_NODE=1 mocha test/integration/**/*.test.js",
+    "test:browser": "mocha test/integration/**/*.test.js",
+    "tsc": "tsc --noEmit",
+    "coverage": "cross-env TEST_NODE=1 npm-run-all coverage:*",
+    "coverage:build": "nyc npm run test:node"
+  },
+  "mocha": {
+    "bail": false,
+    "timeout": 30000,
+    "full-trace": true,
+    "inline-diffs": true,
+    "check-leaks": false,
+    "global": [
+      "pyodide",
+      "page",
+      "chai"
+    ]
+  },
+  "nyc": {
+    "reporter": [
+      "html",
+      "text-summary"
+    ],
+    "include": [
+      "*.ts"
+    ],
+    "all": true,
+    "clean": true,
+    "cache": false,
+    "instrument": false,
+    "checkCoverage": true,
+    "statements": 95,
+    "functions": 95,
+    "branches": 80,
+    "lines": 95
+  },
+  "tsd": {
+    "compilerOptions": {
+      "lib": [
+        "ES2017",
+        "DOM"
+      ]
+    }
+  },
+  "dependencies": {
+    "base-64": "^1.0.0",
+    "ws": "^8.5.0"
+  },
+  "types": "./pyodide.d.ts"
+}

File diff suppressed because it is too large
+ 0 - 0
static/pyodide/pyodide-lock.json


File diff suppressed because it is too large
+ 1 - 1
static/pyodide/pyodide.asm.js


BIN
static/pyodide/pyodide.asm.wasm


+ 60 - 57
static/pyodide/pyodide.d.ts

@@ -653,10 +653,36 @@ declare class PyCallableMethods {
 	 */
 	 */
 	call(thisArg: any, ...jsargs: any): any;
 	call(thisArg: any, ...jsargs: any): any;
 	/**
 	/**
-	 * Call the function with key word arguments. The last argument must be an
+	 * Call the function with keyword arguments. The last argument must be an
 	 * object with the keyword arguments.
 	 * object with the keyword arguments.
 	 */
 	 */
 	callKwargs(...jsargs: any): any;
 	callKwargs(...jsargs: any): any;
+	/**
+	 * Call the function in a "relaxed" manner. Any extra arguments will be
+	 * ignored. This matches the behavior of JavaScript functions more accurately.
+	 *
+	 * Any extra arguments will be ignored. This matches the behavior of
+	 * JavaScript functions more accurately. Missing arguments are **NOT** filled
+	 * with `None`. If too few arguments are passed, this will still raise a
+	 * TypeError.
+	 *
+	 * This uses :py:func:`pyodide.code.relaxed_call`.
+	 */
+	callRelaxed(...jsargs: any): any;
+	/**
+	 * Call the function with keyword arguments in a "relaxed" manner. The last
+	 * argument must be an object with the keyword arguments. Any extra arguments
+	 * will be ignored. This matches the behavior of JavaScript functions more
+	 * accurately.
+	 *
+	 * Missing arguments are **NOT** filled with `None`. If too few arguments are
+	 * passed, this will still raise a TypeError. Also, if the same argument is
+	 * passed as both a keyword argument and a positional argument, it will raise
+	 * an error.
+	 *
+	 * This uses :py:func:`pyodide.code.relaxed_call`.
+	 */
+	callKwargsRelaxed(...jsargs: any): any;
 	/**
 	/**
 	 * Call the function with stack switching enabled. Functions called this way
 	 * Call the function with stack switching enabled. Functions called this way
 	 * can use
 	 * can use
@@ -911,7 +937,7 @@ interface CanvasInterface {
 declare class PythonError extends Error {
 declare class PythonError extends Error {
 	/**
 	/**
 	 * The address of the error we are wrapping. We may later compare this
 	 * The address of the error we are wrapping. We may later compare this
-	 * against sys.last_value.
+	 * against sys.last_exc.
 	 * WARNING: we don't own a reference to this pointer, dereferencing it
 	 * WARNING: we don't own a reference to this pointer, dereferencing it
 	 * may be a use-after-free error!
 	 * may be a use-after-free error!
 	 * @private
 	 * @private
@@ -1128,36 +1154,6 @@ declare class PyodideAPI {
 		locals?: PyProxy;
 		locals?: PyProxy;
 		filename?: string;
 		filename?: string;
 	}): Promise<any>;
 	}): Promise<any>;
-	/**
-	 * Runs a Python code string like :js:func:`pyodide.runPython` but with stack
-	 * switching enabled. Code executed in this way can use
-	 * :py:meth:`PyodideFuture.syncify() <pyodide.webloop.PyodideFuture.syncify>`
-	 * to block until a :py:class:`~asyncio.Future` or :js:class:`Promise` is
-	 * resolved. Only works in runtimes with JS Promise Integration enabled.
-	 *
-	 * .. admonition:: Experimental
-	 *    :class: warning
-	 *
-	 *    This feature is not yet stable.
-	 *
-	 * @experimental
-	 * @param code The Python code to run
-	 * @param options
-	 * @param options.globals An optional Python dictionary to use as the globals.
-	 * Defaults to :js:attr:`pyodide.globals`.
-	 * @param options.locals An optional Python dictionary to use as the locals.
-	 *        Defaults to the same as ``globals``.
-	 * @param options.filename An optional string to use as the file name.
-	 *        Defaults to ``"<exec>"``. If a custom file name is given, the
-	 *        traceback for any exception that is thrown will show source lines
-	 *        (unless the given file name starts with ``<`` and ends with ``>``).
-	 * @returns The result of the Python code translated to JavaScript.
-	 */
-	static runPythonSyncifying(code: string, options?: {
-		globals?: PyProxy;
-		locals?: PyProxy;
-		filename?: string;
-	}): Promise<any>;
 	/**
 	/**
 	 * Registers the JavaScript object ``module`` as a JavaScript module named
 	 * Registers the JavaScript object ``module`` as a JavaScript module named
 	 * ``name``. This module can then be imported from Python using the standard
 	 * ``name``. This module can then be imported from Python using the standard
@@ -1232,30 +1228,25 @@ declare class PyodideAPI {
 	/**
 	/**
 	 * Imports a module and returns it.
 	 * Imports a module and returns it.
 	 *
 	 *
-	 * .. admonition:: Warning
-	 *    :class: warning
-	 *
-	 *    This function has a completely different behavior than the old removed pyimport function!
-	 *
-	 *    ``pyimport`` is roughly equivalent to:
-	 *
-	 *    .. code-block:: js
-	 *
-	 *      pyodide.runPython(`import ${pkgname}; ${pkgname}`);
-	 *
-	 *    except that the global namespace will not change.
-	 *
-	 *    Example:
-	 *
-	 *    .. code-block:: js
-	 *
-	 *      let sysmodule = pyodide.pyimport("sys");
-	 *      let recursionLimit = sysmodule.getrecursionlimit();
+	 * If `name` has no dot in it, then `pyimport(name)` is approximately
+	 * equivalent to:
+	 * ```js
+	 * pyodide.runPython(`import ${name}; ${name}`)
+	 * ```
+	 * except that `name` is not introduced into the Python global namespace. If
+	 * the name has one or more dots in it, say it is of the form `path.name`
+	 * where `name` has no dots but path may have zero or more dots. Then it is
+	 * approximately the same as:
+	 * ```js
+	 * pyodide.runPython(`from ${path} import ${name}; ${name}`);
+	 * ```
 	 *
 	 *
 	 * @param mod_name The name of the module to import
 	 * @param mod_name The name of the module to import
-	 * @returns A PyProxy for the imported module
+	 *
+	 * @example
+	 * pyodide.pyimport("math.comb")(4, 2) // returns 4 choose 2 = 6
 	 */
 	 */
-	static pyimport(mod_name: string): PyProxy;
+	static pyimport(mod_name: string): any;
 	/**
 	/**
 	 * Unpack an archive into a target directory.
 	 * Unpack an archive into a target directory.
 	 *
 	 *
@@ -1277,14 +1268,26 @@ declare class PyodideAPI {
 	}): void;
 	}): void;
 	/**
 	/**
 	 * Mounts a :js:class:`FileSystemDirectoryHandle` into the target directory.
 	 * Mounts a :js:class:`FileSystemDirectoryHandle` into the target directory.
+	 * Currently it's only possible to acquire a
+	 * :js:class:`FileSystemDirectoryHandle` in Chrome.
 	 *
 	 *
 	 * @param path The absolute path in the Emscripten file system to mount the
 	 * @param path The absolute path in the Emscripten file system to mount the
-	 * native directory. If the directory does not exist, it will be created. If it
-	 * does exist, it must be empty.
-	 * @param fileSystemHandle A handle returned by :js:func:`navigator.storage.getDirectory() <getDirectory>`
-	 * or :js:func:`window.showDirectoryPicker() <showDirectoryPicker>`.
+	 * native directory. If the directory does not exist, it will be created. If
+	 * it does exist, it must be empty.
+	 * @param fileSystemHandle A handle returned by
+	 * :js:func:`navigator.storage.getDirectory() <getDirectory>` or
+	 * :js:func:`window.showDirectoryPicker() <showDirectoryPicker>`.
 	 */
 	 */
 	static mountNativeFS(path: string, fileSystemHandle: FileSystemDirectoryHandle): Promise<NativeFS>;
 	static mountNativeFS(path: string, fileSystemHandle: FileSystemDirectoryHandle): Promise<NativeFS>;
+	/**
+	 * Mounts a host directory into Pyodide file system. Only works in node.
+	 *
+	 * @param emscriptenPath The absolute path in the Emscripten file system to
+	 * mount the native directory. If the directory does not exist, it will be
+	 * created. If it does exist, it must be empty.
+	 * @param hostPath The host path to mount. It must be a directory that exists.
+	 */
+	static mountNodeFS(emscriptenPath: string, hostPath: string): void;
 	/**
 	/**
 	 * Tell Pyodide about Comlink.
 	 * Tell Pyodide about Comlink.
 	 * Necessary to enable importing Comlink proxies into Python.
 	 * Necessary to enable importing Comlink proxies into Python.

File diff suppressed because it is too large
+ 0 - 0
static/pyodide/pyodide.js


File diff suppressed because it is too large
+ 0 - 0
static/pyodide/pyodide.js.map


File diff suppressed because it is too large
+ 0 - 0
static/pyodide/pyodide.mjs


File diff suppressed because it is too large
+ 0 - 0
static/pyodide/pyodide.mjs.map


BIN
static/pyodide/python_stdlib.zip


File diff suppressed because it is too large
+ 0 - 0
static/pyscript/codemirror-Dr2Hgejs.js


File diff suppressed because it is too large
+ 0 - 0
static/pyscript/codemirror-Dr2Hgejs.js.map


File diff suppressed because it is too large
+ 0 - 0
static/pyscript/codemirror_commands-MgxtVkrD.js


File diff suppressed because it is too large
+ 0 - 0
static/pyscript/codemirror_commands-MgxtVkrD.js.map


File diff suppressed because it is too large
+ 0 - 0
static/pyscript/codemirror_lang-python-Cxoc-ydj.js


File diff suppressed because it is too large
+ 0 - 0
static/pyscript/codemirror_lang-python-Cxoc-ydj.js.map


File diff suppressed because it is too large
+ 0 - 0
static/pyscript/codemirror_language-_XiX6II0.js


File diff suppressed because it is too large
+ 0 - 0
static/pyscript/codemirror_language-_XiX6II0.js.map


File diff suppressed because it is too large
+ 0 - 0
static/pyscript/codemirror_state-BKbyfKsm.js


File diff suppressed because it is too large
+ 0 - 0
static/pyscript/codemirror_state-BKbyfKsm.js.map


File diff suppressed because it is too large
+ 0 - 0
static/pyscript/codemirror_view-C0PMO2z_.js


File diff suppressed because it is too large
+ 0 - 0
static/pyscript/codemirror_view-C0PMO2z_.js.map


File diff suppressed because it is too large
+ 0 - 0
static/pyscript/core-CPpjJT4b.js


File diff suppressed because it is too large
+ 0 - 0
static/pyscript/core-CPpjJT4b.js.map


+ 0 - 1
static/pyscript/core.css

@@ -1 +0,0 @@
-mpy-config,mpy-script,py-config,py-script{display:none}.mpy-editor-box,.py-editor-box{padding:.5rem}.mpy-editor-input,.py-editor-input{position:relative}.mpy-editor-box:before,.py-editor-box:before{content:attr(data-env);display:block;font-size:x-small;text-align:end}.mpy-editor-output,.py-editor-output{white-space:pre}.mpy-editor-run-button,.py-editor-run-button{bottom:.5rem;opacity:0;position:absolute;right:.5rem;transition:opacity .25s;z-index:1}.mpy-editor-box:hover .mpy-editor-run-button,.mpy-editor-run-button:disabled,.mpy-editor-run-button:focus,.py-editor-box:hover .py-editor-run-button,.py-editor-run-button:disabled,.py-editor-run-button:focus{opacity:1}

+ 0 - 2
static/pyscript/core.js

@@ -1,2 +0,0 @@
-export{g as MPWorker,f as PyWorker,T as TYPES,h as config,e as hooks,o as offline_interpreter,b as optional,s as stdlib,i as whenDefined}from"./core-CPpjJT4b.js";
-//# sourceMappingURL=core.js.map

+ 0 - 1
static/pyscript/core.js.map

@@ -1 +0,0 @@
-{"version":3,"file":"core.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}

+ 0 - 2
static/pyscript/deprecations-manager-CQ0oxKrq.js

@@ -1,2 +0,0 @@
-import{e}from"./core-CPpjJT4b.js";import{notify as o}from"./error-BfnovtqK.js";function r(){const e=document.querySelectorAll("script");for(const o of e)s(o.src)}function s(e){/\/pyscript\.net\/latest/.test(e)&&o("Loading scripts from latest is deprecated and will be removed soon. Please use a specific version instead.")}e.main.onReady.add(r),e.main.onWorker.add(r);
-//# sourceMappingURL=deprecations-manager-CQ0oxKrq.js.map

+ 0 - 1
static/pyscript/deprecations-manager-CQ0oxKrq.js.map

@@ -1 +0,0 @@
-{"version":3,"file":"deprecations-manager-CQ0oxKrq.js","sources":["../src/plugins/deprecations-manager.js"],"sourcesContent":["// PyScript Derepcations Plugin\nimport { hooks } from \"../core.js\";\nimport { notify } from \"./error.js\";\n\n// react lazily on PyScript bootstrap\nhooks.main.onReady.add(checkDeprecations);\nhooks.main.onWorker.add(checkDeprecations);\n\n/**\n * Check that there are no scripts loading from pyscript.net/latest\n */\nfunction checkDeprecations() {\n    const scripts = document.querySelectorAll(\"script\");\n    for (const script of scripts) checkLoadingScriptsFromLatest(script.src);\n}\n\n/**\n * Check if src being loaded from pyscript.net/latest and display a notification if true\n * * @param {string} src\n */\nfunction checkLoadingScriptsFromLatest(src) {\n    if (/\\/pyscript\\.net\\/latest/.test(src)) {\n        notify(\n            \"Loading scripts from latest is deprecated and will be removed soon. Please use a specific version instead.\",\n        );\n    }\n}\n"],"names":["checkDeprecations","scripts","document","querySelectorAll","script","checkLoadingScriptsFromLatest","src","test","notify","hooks","main","onReady","add","onWorker"],"mappings":"+EAWA,SAASA,IACL,MAAMC,EAAUC,SAASC,iBAAiB,UAC1C,IAAK,MAAMC,KAAUH,EAASI,EAA8BD,EAAOE,IACvE,CAMA,SAASD,EAA8BC,GAC/B,0BAA0BC,KAAKD,IAC/BE,EACI,6GAGZ,CArBAC,EAAMC,KAAKC,QAAQC,IAAIZ,GACvBS,EAAMC,KAAKG,SAASD,IAAIZ"}

+ 0 - 2
static/pyscript/error-BfnovtqK.js

@@ -1,2 +0,0 @@
-import{e}from"./core-CPpjJT4b.js";function n(e){const n=document.createElement("div");n.className="py-error",n.textContent=e,n.style.cssText="\n    border: 1px solid red;\n    background: #ffdddd;\n    color: black;\n    font-family: courier, monospace;\n    white-space: pre;\n    overflow-x: auto;\n    padding: 8px;\n    margin-top: 8px;\n  ",document.body.append(n)}e.main.onReady.add((function o(r){e.main.onReady.delete(o);const{stderr:t}=r.io;r.io.stderr=(e,...o)=>(n(e.message||e),t(e,...o)),addEventListener("error",(({message:e})=>{e.startsWith("Uncaught PythonError")&&n(e)}))}));export{n as notify};
-//# sourceMappingURL=error-BfnovtqK.js.map

File diff suppressed because it is too large
+ 0 - 0
static/pyscript/error-BfnovtqK.js.map


File diff suppressed because it is too large
+ 0 - 0
static/pyscript/index-CTWZX_TW.js


File diff suppressed because it is too large
+ 0 - 0
static/pyscript/index-CTWZX_TW.js.map


File diff suppressed because it is too large
+ 0 - 0
static/pyscript/py-editor-CmqzUo2Z.js


File diff suppressed because it is too large
+ 0 - 0
static/pyscript/py-editor-CmqzUo2Z.js.map


File diff suppressed because it is too large
+ 0 - 0
static/pyscript/py-terminal-CgcHH2nx.js


File diff suppressed because it is too large
+ 0 - 0
static/pyscript/py-terminal-CgcHH2nx.js.map


File diff suppressed because it is too large
+ 0 - 0
static/pyscript/toml-CvAfdf9_.js


File diff suppressed because it is too large
+ 0 - 0
static/pyscript/toml-CvAfdf9_.js.map


+ 0 - 3
static/pyscript/toml-DiUM0_qs.js

@@ -1,3 +0,0 @@
-/*! (c) Andrea Giammarchi - ISC */
-const{isArray:e}=Array,{parse:r}=JSON,s=(e,{s:r})=>e.replace(/"s(\d+)"/g,((e,s)=>r[s])),t=(e,s)=>r(e.replace(/(\S+?)\s*=/g,'"$1":'),((e,r)=>"string"==typeof r?s[r[0]][r.slice(1)]:r)),p=(r,t,p,l)=>{for(let n=0,{length:a}=r,c=a-1;n<a;n++){const a=s(r[n],t);p=p[a]||(p[a]=l&&n===c?[]:{}),e(p)&&(n!==c&&p.length||p.push({}),p=p.at(-1))}return p},l=e=>{const[r,l]=((e,r,s)=>[e.replace(/(["'])(?:(?=(\\?))\2.)*?\1/g,(e=>`"s${r.push(e.slice(1,-1))-1}"`)).replace(/\d{2,}([:-]\d{2}){2}([ T:-][\dZ:-]+)?/g,(e=>`"d${s.push(new Date(e))-1}"`)).replace(/,\s*[\r\n]+/g,", ").replace(/\[\s*[\r\n]+/g,"[").replace(/[\r\n]+\s*]/g,"]"),{s:r,d:s}])(e,[],[]),n={};let a=n;for(let e of r.split(/[\r\n]+/))if((e=e.trim())&&!e.startsWith("#"))if(/^(\[+)(.*?)\]+/.test(e))a=p(RegExp.$2.trim().split("."),l,n,"["!==RegExp.$1);else if(/^(\S+?)\s*=([^#]+)/.test(e)){const{$1:e,$2:r}=RegExp;a[s(e,l)]=t(r.trim(),l)}return n};export{l as parse};
-//# sourceMappingURL=toml-DiUM0_qs.js.map

File diff suppressed because it is too large
+ 0 - 0
static/pyscript/toml-DiUM0_qs.js.map


File diff suppressed because it is too large
+ 0 - 0
static/pyscript/xterm-DqawCVsv.js


File diff suppressed because it is too large
+ 0 - 0
static/pyscript/xterm-DqawCVsv.js.map


File diff suppressed because it is too large
+ 0 - 0
static/pyscript/xterm-readline-D247p8vq.js


File diff suppressed because it is too large
+ 0 - 0
static/pyscript/xterm-readline-D247p8vq.js.map


File diff suppressed because it is too large
+ 0 - 6
static/pyscript/xterm.css


+ 0 - 2
static/pyscript/xterm_addon-fit--gyF3PcZ.js

@@ -1,2 +0,0 @@
-var e,t,r={exports:{}},s=r.exports=(e=t={},Object.defineProperty(e,"__esModule",{value:!0}),e.FitAddon=void 0,e.FitAddon=class{activate(e){this._terminal=e}dispose(){}fit(){const e=this.proposeDimensions();if(!e||!this._terminal||isNaN(e.cols)||isNaN(e.rows))return;const t=this._terminal._core;this._terminal.rows===e.rows&&this._terminal.cols===e.cols||(t._renderService.clear(),this._terminal.resize(e.cols,e.rows))}proposeDimensions(){if(!this._terminal)return;if(!this._terminal.element||!this._terminal.element.parentElement)return;const e=this._terminal._core,t=e._renderService.dimensions;if(0===t.css.cell.width||0===t.css.cell.height)return;const r=0===this._terminal.options.scrollback?0:e.viewport.scrollBarWidth,s=window.getComputedStyle(this._terminal.element.parentElement),i=parseInt(s.getPropertyValue("height")),o=Math.max(0,parseInt(s.getPropertyValue("width"))),n=window.getComputedStyle(this._terminal.element),l=i-(parseInt(n.getPropertyValue("padding-top"))+parseInt(n.getPropertyValue("padding-bottom"))),a=o-(parseInt(n.getPropertyValue("padding-right"))+parseInt(n.getPropertyValue("padding-left")))-r;return{cols:Math.max(2,Math.floor(a/t.css.cell.width)),rows:Math.max(1,Math.floor(l/t.css.cell.height))}}},t),i=r.exports.FitAddon,o=r.exports.__esModule;export{i as FitAddon,o as __esModule,s as default};
-//# sourceMappingURL=xterm_addon-fit--gyF3PcZ.js.map

File diff suppressed because it is too large
+ 0 - 0
static/pyscript/xterm_addon-fit--gyF3PcZ.js.map


File diff suppressed because it is too large
+ 0 - 0
static/pyscript/xterm_addon-web-links-Cnej-nJ6.js


File diff suppressed because it is too large
+ 0 - 0
static/pyscript/xterm_addon-web-links-Cnej-nJ6.js.map


File diff suppressed because it is too large
+ 0 - 0
static/pyscript/zip-D2yvzXKD.js


File diff suppressed because it is too large
+ 0 - 0
static/pyscript/zip-D2yvzXKD.js.map


Some files were not shown because too many files changed in this diff