Skip to content

Commit 09b5b37

Browse files
authored
Merge pull request #139 from Distributive-Network/Xmader/fix/readline-windows
Make pmjs & peter-jr work on Windows
2 parents 42e617a + 3691cac commit 09b5b37

14 files changed

+43
-16
lines changed

.github/workflows/test-and-publish.yaml

-2
Original file line numberDiff line numberDiff line change
@@ -159,8 +159,6 @@ jobs:
159159
poetry run python -m pip install --force-reinstall --verbose ./dist/*
160160
poetry run python -m pytest tests/python
161161
- name: Run JS tests (peter-jr)
162-
if: ${{ runner.os != 'Windows' }} # Python on Windows doesn't have the readline library
163-
# FIXME: on macOS we must make sure to use the GNU version of wc and realpath
164162
run: |
165163
poetry run bash ./peter-jr ./tests/js/
166164
sdist:

poetry.lock

+12-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

+1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ include = [
2828

2929
[tool.poetry.dependencies]
3030
python = "^3.8"
31+
pyreadline3 = "^3.4.1"
3132
pminit = { version = "*", allow-prereleases = true }
3233

3334

python/pythonmonkey/cli/pmjs.py

+9-6
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,17 @@
33
# @author Wes Garland, [email protected]
44
# @date June 2023
55

6-
import sys, os, readline, signal, getopt
6+
import sys, os, signal, getopt
7+
try:
8+
import readline # Unix
9+
except ImportError:
10+
import pyreadline3 as readline # Windows
711
import pythonmonkey as pm
812
globalThis = pm.eval("globalThis")
913
evalOpts = { 'filename': __file__, 'fromPythonFrame': True, 'strict': False } # type: pm.EvalOptions
1014

1115
if (os.getenv('PMJS_PATH')):
12-
requirePath = list(map(os.path.abspath, os.getenv('PMJS_PATH').split(':')))
16+
requirePath = list(map(os.path.abspath, os.getenv('PMJS_PATH').split(',')))
1317
else:
1418
requirePath = False;
1519

@@ -108,7 +112,7 @@
108112
* like that which is also a valid compilation unit with parens, then if that is a syntax error,
109113
* we re-evaluate without the parens.
110114
*/
111-
if (/^\\s*\{.*[^;\\s]\\s*$/.test(statement))
115+
if (/^\\s*\\{.*[^;\\s]\\s*$/.test(statement))
112116
{
113117
const testStatement = `(${statement})`;
114118
if (globalThis.python.pythonMonkey.isCompilableUnit(testStatement))
@@ -195,8 +199,7 @@ def sigint_handler(signum, frame):
195199

196200
got_sigint = got_sigint + 1
197201
if (got_sigint > 1):
198-
sys.stdout.write("\n")
199-
quit()
202+
raise EOFError
200203

201204
if (inner_loop != True):
202205
if (got_sigint == 1 and len(readline.get_line_buffer()) == readline_skip_chars):
@@ -304,7 +307,7 @@ def initGlobalThis():
304307

305308
require = pm.createRequire(os.path.abspath(os.getcwd() + '/__pmjs_virtual__'), requirePath)
306309
globalThis.require = require
307-
globalInitModule = require(os.path.dirname(__file__) + "/../lib/pmjs/global-init") # module load has side-effects
310+
globalInitModule = require(os.path.realpath(os.path.dirname(__file__) + "/../lib/pmjs/global-init")) # module load has side-effects
308311
argvBuilder = globalInitModule.makeArgvBuilder()
309312
for arg in sys.argv:
310313
argvBuilder(arg); # list=>Array not working yet

python/pythonmonkey/require.py

+11-5
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
# @date May 2023
2424
#
2525

26-
import sys, os
26+
import sys, os, io
2727
from typing import Union, Dict, Literal, List
2828
import importlib
2929
import importlib.util
@@ -43,6 +43,12 @@
4343
)
4444
evalOpts = { 'filename': __file__, 'fromPythonFrame': True } # type: pm.EvalOptions
4545

46+
# Force to use UTF-8 encoding
47+
# Windows may use other encodings / code pages that have many characters missing/unrepresentable
48+
# Error: Python UnicodeEncodeError: 'charmap' codec can't encode characters in position xx-xx: character maps to <undefined>
49+
sys.stdout.reconfigure(encoding='utf-8')
50+
sys.stderr.reconfigure(encoding='utf-8')
51+
4652
# Add some python functions to the global python object for code in this file to use.
4753
globalThis = pm.eval("globalThis;", evalOpts)
4854
pm.eval("globalThis.python = { pythonMonkey: {}, stdout: {}, stderr: {} }", evalOpts);
@@ -60,8 +66,7 @@
6066
globalThis.python.eval = eval
6167
globalThis.python.exec = exec
6268
globalThis.python.getenv = os.getenv
63-
globalThis.python.paths = ':'.join(sys.path)
64-
pm.eval("python.paths = python.paths.split(':');", evalOpts); # fix when pm supports arrays
69+
globalThis.python.paths = sys.path
6570

6671
globalThis.python.exit = pm.eval("""'use strict';
6772
(exit) => function pythonExitWrapper(exitCode) {
@@ -269,6 +274,7 @@ def _createRequireInner(*args):
269274
*/
270275
function createRequire(filename, bootstrap_broken, extraPaths, isMain)
271276
{
277+
filename = filename.split('\\\\').join('/');
272278
const bootstrap = globalThis.bootstrap; /** @bug PM-65 */
273279
const CtxModule = bootstrap.modules['ctx-module'].CtxModule;
274280
const moduleCache = globalThis.require?.cache || {};
@@ -283,7 +289,7 @@ def _createRequireInner(*args):
283289
284290
const module = new CtxModule(globalThis, filename, moduleCache);
285291
moduleCache[filename] = module;
286-
for (let path of python.paths)
292+
for (let path of Array.from(python.paths))
287293
module.paths.push(path + '/node_modules');
288294
module.require.path.push(python.pythonMonkey.dir + '/builtin_modules');
289295
module.require.path.push(python.pythonMonkey.nodeModules);
@@ -300,7 +306,7 @@ def _createRequireInner(*args):
300306
}
301307
302308
if (extraPaths)
303-
module.require.path.splice(module.require.path.length, 0, ...(extraPaths.split(':')));
309+
module.require.path.splice(module.require.path.length, 0, ...(extraPaths.split(',')));
304310
305311
return module.require;
306312
})""", evalOpts)(*args)

tests/js/commonjs-modules.bash

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ runTest()
2020
echo -n "${testName}: "
2121

2222
PMJS_PATH="`pwd`" pmjs -e 'print=python.print' program.js\
23+
| tr -d '\r'\
2324
| while read word rest
2425
do
2526
case "$word" in

tests/js/console-stdio.bash

+2
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ cd `dirname "$0"` || panic "could not change to test directory"
2222
-e 'console.debug("stdout")' \
2323
-e 'console.info("stdout")' \
2424
< /dev/null \
25+
| tr -d '\r' \
2526
| grep -c '^stdout$' \
2627
| while read qty
2728
do
@@ -34,6 +35,7 @@ cd `dirname "$0"` || panic "could not change to test directory"
3435
-e 'console.error("stderr")' \
3536
-e 'console.warn("stderr")' \
3637
< /dev/null 2>&1 \
38+
| tr -d '\r' \
3739
| grep -c '^stderr$' \
3840
| while read qty
3941
do

tests/js/pmjs-eopt.bash

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ panic()
1818
cd `dirname "$0"` || panic "could not change to test directory"
1919

2020
"${PMJS:-pmjs}" -e 'console.log("OKAY")' < /dev/null |\
21+
tr -d '\r' |\
2122
while read keyword rest
2223
do
2324
case "$keyword" in

tests/js/pmjs-global-arguments.bash

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ cd `dirname "$0"` || panic "could not change to test directory"
2020

2121
argc=0
2222
"${PMJS:-pmjs}" program.js abc easy as one two three |\
23+
tr -d '\r' |\
2324
while read keyword rest
2425
do
2526
case "$keyword" in

tests/js/pmjs-interactive-smoke.bash

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ a;
3030
b(${rnd});
3131
EOF
3232
)\
33-
| cat -u | while read prompt keyword rest
33+
| cat -u | tr -d '\r' | while read prompt keyword rest
3434
do
3535
case "$keyword" in
3636
"...")

tests/js/pmjs-popt.bash

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ panic()
1818
cd `dirname "$0"` || panic "could not change to test directory"
1919

2020
"${PMJS:-pmjs}" -p '"OKAY"' < /dev/null |\
21+
tr -d '\r' |\
2122
while read keyword rest
2223
do
2324
case "$keyword" in

tests/js/pmjs-require-cache.bash

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ cd `dirname "$0"` || panic "could not change to test directory"
2020

2121
loaded=0
2222
"${PMJS:-pmjs}" -r ./modules/print-load -r ./modules/print-load program.js |\
23+
tr -d '\r' |\
2324
while read keyword rest
2425
do
2526
case "$keyword" in

tests/js/pmjs-ropt.bash

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ panic()
1818
cd `dirname "$0"` || panic "could not change to test directory"
1919

2020
"${PMJS:-pmjs}" -r ./modules/print-load < /dev/null |\
21+
tr -d '\r' |\
2122
while read keyword rest
2223
do
2324
case "$keyword" in

tests/js/typeofs.simple

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
'use strict';
1010

1111
const throughJS = x => x;
12-
const throughBoth = python.eval('(lambda x: throughJS(x))', { throughJS });
12+
const throughBoth = python.eval('(lambda func: lambda x: func(x))')(throughJS);
1313

1414
function check(jsval, expected)
1515
{

0 commit comments

Comments
 (0)