Skip to content

Commit ea8ce4f

Browse files
authored
run-tests.py works properly with python3 (#1285)
Fixes #1180 and #1181.
1 parent 168ba91 commit ea8ce4f

File tree

4 files changed

+52
-30
lines changed

4 files changed

+52
-30
lines changed

.gitattributes

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,10 @@ demo/libwabt.js binary
1414
demo/third_party/codemirror/codemirror.css binary
1515
demo/third_party/codemirror/codemirror.js binary
1616

17-
# Mark this test as binary so git doesn't change the line endings, since this
18-
# test is testing \r\n.
17+
# Mark these tests as binary so git doesn't change the line endings:
1918
test/parse/bad-crlf.txt binary
19+
test/parse/bad-string-eof.txt binary
20+
test/regress/regress-31.txt binary
2021

2122
# Highlight tests like .wast files when displayed on GitHub.
2223
test/**/*.txt linguist-language=WebAssembly

.github/workflows/build.yml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,16 @@ jobs:
99
strategy:
1010
matrix:
1111
os: [ubuntu-16.04, macos-latest, windows-latest]
12+
python: [2.7, '3.x']
13+
exclude:
14+
- os: macos-latest
15+
python: '3.x'
16+
- os: windows-latest
17+
python: '3.x'
1218
steps:
1319
- uses: actions/setup-python@v1
1420
with:
15-
python-version: '2.7'
21+
python-version: ${{ matrix.python }}
1622
- uses: actions/checkout@v1
1723
with:
1824
submodules: true

test/run-spec-wasm2c.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -95,13 +95,14 @@ def MangleTypes(types):
9595

9696

9797
def MangleName(s):
98-
result = 'Z_'
99-
for c in s.encode('utf-8'):
100-
# NOTE(binji): Z is not allowed.
101-
if c in '_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXY0123456789':
102-
result += c
103-
else:
104-
result += 'Z%02X' % ord(c)
98+
def Mangle(match):
99+
s = match.group(0)
100+
c = ord(s) if isinstance(s, str) else s[0] # Python2 vs Python3
101+
return b'Z%02X' % c
102+
103+
# NOTE(binji): Z is not allowed.
104+
pattern = b'([^_a-zA-Y0-9])'
105+
result = 'Z_' + re.sub(pattern, Mangle, s.encode('utf-8')).decode('utf-8')
105106
return result
106107

107108

test/run-tests.py

Lines changed: 34 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -162,8 +162,11 @@ def Indent(s, spaces):
162162

163163

164164
def DiffLines(expected, actual):
165-
expected_lines = [line for line in expected.splitlines() if line]
166-
actual_lines = [line for line in actual.splitlines() if line]
165+
def Decode(s):
166+
return s.decode('utf-8', 'replace')
167+
168+
expected_lines = [Decode(line) for line in expected.splitlines() if line]
169+
actual_lines = [Decode(line) for line in actual.splitlines() if line]
167170
return list(
168171
difflib.unified_diff(expected_lines, actual_lines, fromfile='expected',
169172
tofile='actual', lineterm=''))
@@ -268,7 +271,7 @@ def KillProcess(timeout=True):
268271
process = subprocess.Popen(self.args, cwd=cwd, env=env,
269272
stdout=None if console_out else subprocess.PIPE,
270273
stderr=None if console_out else subprocess.PIPE,
271-
universal_newlines=True, **kwargs)
274+
**kwargs)
272275
timer = threading.Timer(timeout, KillProcess)
273276
try:
274277
timer.start()
@@ -315,8 +318,8 @@ class TestResult(object):
315318

316319
def __init__(self):
317320
self.results = []
318-
self.stdout = ''
319-
self.stderr = ''
321+
self.stdout = b''
322+
self.stderr = b''
320323
self.duration = 0
321324

322325
def GetLastCommand(self):
@@ -479,7 +482,8 @@ def Parse(self, filename):
479482
self.filename = filename
480483

481484
test_path = os.path.join(REPO_ROOT_DIR, filename)
482-
with open(test_path) as f:
485+
# Read/write as binary because spec tests may have invalid UTF-8 codes.
486+
with open(test_path, 'rb') as f:
483487
state = 'header'
484488
empty = True
485489
header_lines = []
@@ -488,19 +492,29 @@ def Parse(self, filename):
488492
stderr_lines = []
489493
for line in f.readlines():
490494
empty = False
491-
m = re.match(r'\s*\(;; (STDOUT|STDERR) ;;;$', line)
495+
m = re.match(b'\\s*\\(;; (STDOUT|STDERR) ;;;$', line.strip())
492496
if m:
493-
directive = m.group(1)
497+
directive = m.group(1).decode('utf-8')
494498
if directive == 'STDERR':
495499
state = 'stderr'
496500
continue
497501
elif directive == 'STDOUT':
498502
state = 'stdout'
499503
continue
500504
else:
501-
m = re.match(r'\s*;;;(.*)$', line)
505+
m = re.match(b'\\s*;;;(.*)$', line)
502506
if m:
503-
directive = m.group(1).strip()
507+
# The matched string has type bytes, but in python2
508+
# that is the same as str. In python3 that needs to be
509+
# decoded first. If we decode the string in python2 the
510+
# result is a unicode string, which doesn't work
511+
# everywhere (as used in a subprocess environment, for
512+
# example).
513+
if sys.version_info.major == 3:
514+
directive = m.group(1).decode('utf-8').strip()
515+
else:
516+
directive = m.group(1).strip()
517+
504518
if state == 'header':
505519
key, value = directive.split(':', 1)
506520
key = key.strip()
@@ -517,7 +531,7 @@ def Parse(self, filename):
517531
state = 'input'
518532

519533
if state == 'header':
520-
header_lines.append(line)
534+
header_lines.append(line.decode('utf-8'))
521535
if state == 'input':
522536
if self.input_filename:
523537
raise Error('Can\'t have STDIN_FILE and input')
@@ -530,9 +544,9 @@ def Parse(self, filename):
530544
raise Error('empty test file')
531545

532546
self.header = ''.join(header_lines)
533-
self.input_ = ''.join(input_lines)
534-
self.expected_stdout = ''.join(stdout_lines)
535-
self.expected_stderr = ''.join(stderr_lines)
547+
self.input_ = b''.join(input_lines)
548+
self.expected_stdout = b''.join(stdout_lines)
549+
self.expected_stderr = b''.join(stderr_lines)
536550

537551
if not self.cmds:
538552
raise Error('test has no commands')
@@ -555,23 +569,23 @@ def CreateInputFile(self):
555569
else:
556570
# add an empty line for each header line so the line numbers match
557571
gen_input_file.write(('\n' * self.header.count('\n')).encode('ascii'))
558-
gen_input_file.write(self.input_.encode('ascii'))
572+
gen_input_file.write(self.input_)
559573
gen_input_file.flush()
560574
return gen_input_file.name
561575

562576
def Rebase(self, stdout, stderr):
563577
test_path = os.path.join(REPO_ROOT_DIR, self.filename)
564578
with open(test_path, 'wb') as f:
565-
f.write(self.header)
579+
f.write(self.header.encode('ascii'))
566580
f.write(self.input_)
567581
if stderr:
568-
f.write('(;; STDERR ;;;\n')
582+
f.write(b'(;; STDERR ;;;\n')
569583
f.write(stderr)
570-
f.write(';;; STDERR ;;)\n')
584+
f.write(b';;; STDERR ;;)\n')
571585
if stdout:
572-
f.write('(;; STDOUT ;;;\n')
586+
f.write(b'(;; STDOUT ;;;\n')
573587
f.write(stdout)
574-
f.write(';;; STDOUT ;;)\n')
588+
f.write(b';;; STDOUT ;;)\n')
575589

576590
def Diff(self, stdout, stderr):
577591
msg = ''

0 commit comments

Comments
 (0)