Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 54ac832

Browse files
committed
#14490, #14491: add 'sundry'-style import tests for Tools/scripts.
This patch changes a few of the scripts to have __name__=='__main__' clauses so that they are importable without running. Also fixes the syntax errors revealed by the tests.
1 parent b604630 commit 54ac832

7 files changed

Lines changed: 132 additions & 86 deletions

File tree

Lib/test/test_tools.py

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
"""
66

77
import os
8+
import sys
89
import unittest
910
import sysconfig
1011
from test import support
@@ -17,10 +18,11 @@
1718

1819
srcdir = sysconfig.get_config_var('projectbase')
1920
basepath = os.path.join(os.getcwd(), srcdir, 'Tools')
21+
scriptsdir = os.path.join(basepath, 'scripts')
2022

2123

2224
class ReindentTests(unittest.TestCase):
23-
script = os.path.join(basepath, 'scripts', 'reindent.py')
25+
script = os.path.join(scriptsdir, 'reindent.py')
2426

2527
def test_noargs(self):
2628
assert_python_ok(self.script)
@@ -31,8 +33,47 @@ def test_help(self):
3133
self.assertGreater(err, b'')
3234

3335

36+
class TestSundryScripts(unittest.TestCase):
37+
# At least make sure the rest don't have syntax errors. When tests are
38+
# added for a script it should be added to the whitelist below.
39+
40+
# scripts that have independent tests.
41+
whitelist = ['reindent.py']
42+
# scripts that can't be imported without running
43+
blacklist = ['make_ctype.py']
44+
# scripts that use windows-only modules
45+
windows_only = ['win_add2path.py']
46+
# blacklisted for other reasons
47+
other = ['analyze_dxp.py']
48+
49+
skiplist = blacklist + whitelist + windows_only + other
50+
51+
def setUp(self):
52+
cm = support.DirsOnSysPath(scriptsdir)
53+
cm.__enter__()
54+
self.addCleanup(cm.__exit__)
55+
56+
def test_sundry(self):
57+
for fn in os.listdir(scriptsdir):
58+
if fn.endswith('.py') and fn not in self.skiplist:
59+
__import__(fn[:-3])
60+
61+
@unittest.skipIf(sys.platform != "win32", "Windows-only test")
62+
def test_sundry_windows(self):
63+
for fn in self.windows_only:
64+
__import__(fn[:-3])
65+
66+
def test_analyze_dxp_import(self):
67+
if hasattr(sys, 'getdxp'):
68+
import analyze_dxp
69+
else:
70+
with self.assertRaises(RuntimeError):
71+
import analyze_dxp
72+
73+
3474
def test_main():
35-
support.run_unittest(ReindentTests)
75+
support.run_unittest(*[obj for obj in globals().values()
76+
if isinstance(obj, type)])
3677

3778

3879
if __name__ == '__main__':

Tools/scripts/abitype.py

Lines changed: 45 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -3,34 +3,6 @@
33
# Usage: abitype.py < old_code > new_code
44
import re, sys
55

6-
############ Simplistic C scanner ##################################
7-
tokenizer = re.compile(
8-
r"(?P<preproc>#.*\n)"
9-
r"|(?P<comment>/\*.*?\*/)"
10-
r"|(?P<ident>[a-zA-Z_][a-zA-Z0-9_]*)"
11-
r"|(?P<ws>[ \t\n]+)"
12-
r"|(?P<other>.)",
13-
re.MULTILINE)
14-
15-
tokens = []
16-
source = sys.stdin.read()
17-
pos = 0
18-
while pos != len(source):
19-
m = tokenizer.match(source, pos)
20-
tokens.append([m.lastgroup, m.group()])
21-
pos += len(tokens[-1][1])
22-
if tokens[-1][0] == 'preproc':
23-
# continuation lines are considered
24-
# only in preprocess statements
25-
while tokens[-1][1].endswith('\\\n'):
26-
nl = source.find('\n', pos)
27-
if nl == -1:
28-
line = source[pos:]
29-
else:
30-
line = source[pos:nl+1]
31-
tokens[-1][1] += line
32-
pos += len(line)
33-
346
###### Replacement of PyTypeObject static instances ##############
357

368
# classify each token, giving it a one-letter code:
@@ -79,7 +51,7 @@ def get_fields(start, real_end):
7951
while tokens[pos][0] in ('ws', 'comment'):
8052
pos += 1
8153
if tokens[pos][1] != 'PyVarObject_HEAD_INIT':
82-
raise Exception, '%s has no PyVarObject_HEAD_INIT' % name
54+
raise Exception('%s has no PyVarObject_HEAD_INIT' % name)
8355
while tokens[pos][1] != ')':
8456
pos += 1
8557
pos += 1
@@ -183,18 +155,48 @@ def make_slots(name, fields):
183155
return '\n'.join(res)
184156

185157

186-
# Main loop: replace all static PyTypeObjects until
187-
# there are none left.
188-
while 1:
189-
c = classify()
190-
m = re.search('(SW)?TWIW?=W?{.*?};', c)
191-
if not m:
192-
break
193-
start = m.start()
194-
end = m.end()
195-
name, fields = get_fields(start, m)
196-
tokens[start:end] = [('',make_slots(name, fields))]
158+
if __name__ == '__main__':
159+
160+
############ Simplistic C scanner ##################################
161+
tokenizer = re.compile(
162+
r"(?P<preproc>#.*\n)"
163+
r"|(?P<comment>/\*.*?\*/)"
164+
r"|(?P<ident>[a-zA-Z_][a-zA-Z0-9_]*)"
165+
r"|(?P<ws>[ \t\n]+)"
166+
r"|(?P<other>.)",
167+
re.MULTILINE)
168+
169+
tokens = []
170+
source = sys.stdin.read()
171+
pos = 0
172+
while pos != len(source):
173+
m = tokenizer.match(source, pos)
174+
tokens.append([m.lastgroup, m.group()])
175+
pos += len(tokens[-1][1])
176+
if tokens[-1][0] == 'preproc':
177+
# continuation lines are considered
178+
# only in preprocess statements
179+
while tokens[-1][1].endswith('\\\n'):
180+
nl = source.find('\n', pos)
181+
if nl == -1:
182+
line = source[pos:]
183+
else:
184+
line = source[pos:nl+1]
185+
tokens[-1][1] += line
186+
pos += len(line)
187+
188+
# Main loop: replace all static PyTypeObjects until
189+
# there are none left.
190+
while 1:
191+
c = classify()
192+
m = re.search('(SW)?TWIW?=W?{.*?};', c)
193+
if not m:
194+
break
195+
start = m.start()
196+
end = m.end()
197+
name, fields = get_fields(start, m)
198+
tokens[start:end] = [('',make_slots(name, fields))]
197199

198-
# Output result to stdout
199-
for t, v in tokens:
200-
sys.stdout.write(v)
200+
# Output result to stdout
201+
for t, v in tokens:
202+
sys.stdout.write(v)

Tools/scripts/find_recursionlimit.py

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -106,14 +106,16 @@ def check_limit(n, test_func_name):
106106
else:
107107
print("Yikes!")
108108

109-
limit = 1000
110-
while 1:
111-
check_limit(limit, "test_recurse")
112-
check_limit(limit, "test_add")
113-
check_limit(limit, "test_repr")
114-
check_limit(limit, "test_init")
115-
check_limit(limit, "test_getattr")
116-
check_limit(limit, "test_getitem")
117-
check_limit(limit, "test_cpickle")
118-
print("Limit of %d is fine" % limit)
119-
limit = limit + 100
109+
if __name__ == '__main__':
110+
111+
limit = 1000
112+
while 1:
113+
check_limit(limit, "test_recurse")
114+
check_limit(limit, "test_add")
115+
check_limit(limit, "test_repr")
116+
check_limit(limit, "test_init")
117+
check_limit(limit, "test_getattr")
118+
check_limit(limit, "test_getitem")
119+
check_limit(limit, "test_cpickle")
120+
print("Limit of %d is fine" % limit)
121+
limit = limit + 100

Tools/scripts/findnocoding.py

Lines changed: 28 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -76,29 +76,31 @@ def needs_declaration(fullpath):
7676
-c: recognize Python source files trying to compile them
7777
-d: debug output""" % sys.argv[0]
7878

79-
try:
80-
opts, args = getopt.getopt(sys.argv[1:], 'cd')
81-
except getopt.error as msg:
82-
print(msg, file=sys.stderr)
83-
print(usage, file=sys.stderr)
84-
sys.exit(1)
85-
86-
is_python = pysource.looks_like_python
87-
debug = False
88-
89-
for o, a in opts:
90-
if o == '-c':
91-
is_python = pysource.can_be_compiled
92-
elif o == '-d':
93-
debug = True
94-
95-
if not args:
96-
print(usage, file=sys.stderr)
97-
sys.exit(1)
98-
99-
for fullpath in pysource.walk_python_files(args, is_python):
100-
if debug:
101-
print("Testing for coding: %s" % fullpath)
102-
result = needs_declaration(fullpath)
103-
if result:
104-
print(fullpath)
79+
if __name__ == '__main__':
80+
81+
try:
82+
opts, args = getopt.getopt(sys.argv[1:], 'cd')
83+
except getopt.error as msg:
84+
print(msg, file=sys.stderr)
85+
print(usage, file=sys.stderr)
86+
sys.exit(1)
87+
88+
is_python = pysource.looks_like_python
89+
debug = False
90+
91+
for o, a in opts:
92+
if o == '-c':
93+
is_python = pysource.can_be_compiled
94+
elif o == '-d':
95+
debug = True
96+
97+
if not args:
98+
print(usage, file=sys.stderr)
99+
sys.exit(1)
100+
101+
for fullpath in pysource.walk_python_files(args, is_python):
102+
if debug:
103+
print("Testing for coding: %s" % fullpath)
104+
result = needs_declaration(fullpath)
105+
if result:
106+
print(fullpath)

Tools/scripts/fixcid.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,7 @@ def addsubst(substfile):
292292
if not words: continue
293293
if len(words) == 3 and words[0] == 'struct':
294294
words[:2] = [words[0] + ' ' + words[1]]
295-
elif len(words) <> 2:
295+
elif len(words) != 2:
296296
err(substfile + '%s:%r: warning: bad line: %r' % (substfile, lineno, line))
297297
continue
298298
if Reverse:

Tools/scripts/md5sum.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
import sys
2121
import os
2222
import getopt
23-
import md5
23+
from hashlib import md5
2424

2525
def sum(*files):
2626
sts = 0

Tools/scripts/parseentities.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
1414
"""
1515
import re,sys
16-
import TextTools
1716

1817
entityRE = re.compile('<!ENTITY +(\w+) +CDATA +"([^"]+)" +-- +((?:.|\n)+?) *-->')
1918

@@ -45,7 +44,7 @@ def writefile(f,defs):
4544
charcode = repr(charcode)
4645
else:
4746
charcode = repr(charcode)
48-
comment = TextTools.collapse(comment)
47+
comment = ' '.join(comment.split())
4948
f.write(" '%s':\t%s, \t# %s\n" % (name,charcode,comment))
5049
f.write('\n}\n')
5150

0 commit comments

Comments
 (0)