##// END OF EJS Templates
check: check modules in hgdemandimport...
Siddharth Agarwal -
r32421:778dc37c default
parent child Browse files
Show More
@@ -1,95 +1,96 b''
1 1 #!/usr/bin/env python
2 2 #
3 3 # check-py3-compat - check Python 3 compatibility of Mercurial files
4 4 #
5 5 # Copyright 2015 Gregory Szorc <gregory.szorc@gmail.com>
6 6 #
7 7 # This software may be used and distributed according to the terms of the
8 8 # GNU General Public License version 2 or any later version.
9 9
10 10 from __future__ import absolute_import, print_function
11 11
12 12 import ast
13 13 import importlib
14 14 import os
15 15 import sys
16 16 import traceback
17 17
18 18 def check_compat_py2(f):
19 19 """Check Python 3 compatibility for a file with Python 2"""
20 20 with open(f, 'rb') as fh:
21 21 content = fh.read()
22 22 root = ast.parse(content)
23 23
24 24 # Ignore empty files.
25 25 if not root.body:
26 26 return
27 27
28 28 futures = set()
29 29 haveprint = False
30 30 for node in ast.walk(root):
31 31 if isinstance(node, ast.ImportFrom):
32 32 if node.module == '__future__':
33 33 futures |= set(n.name for n in node.names)
34 34 elif isinstance(node, ast.Print):
35 35 haveprint = True
36 36
37 37 if 'absolute_import' not in futures:
38 38 print('%s not using absolute_import' % f)
39 39 if haveprint and 'print_function' not in futures:
40 40 print('%s requires print_function' % f)
41 41
42 42 def check_compat_py3(f):
43 43 """Check Python 3 compatibility of a file with Python 3."""
44 44 with open(f, 'rb') as fh:
45 45 content = fh.read()
46 46
47 47 try:
48 48 ast.parse(content)
49 49 except SyntaxError as e:
50 50 print('%s: invalid syntax: %s' % (f, e))
51 51 return
52 52
53 53 # Try to import the module.
54 # For now we only support mercurial.* and hgext.* modules because figuring
55 # out module paths for things not in a package can be confusing.
56 if f.startswith(('hgext/', 'mercurial/')) and not f.endswith('__init__.py'):
54 # For now we only support modules in packages because figuring out module
55 # paths for things not in a package can be confusing.
56 if (f.startswith(('hgdemandimport/', 'hgext/', 'mercurial/'))
57 and not f.endswith('__init__.py')):
57 58 assert f.endswith('.py')
58 59 name = f.replace('/', '.')[:-3]
59 60 try:
60 61 importlib.import_module(name)
61 62 except Exception as e:
62 63 exc_type, exc_value, tb = sys.exc_info()
63 64 # We walk the stack and ignore frames from our custom importer,
64 65 # import mechanisms, and stdlib modules. This kinda/sorta
65 66 # emulates CPython behavior in import.c while also attempting
66 67 # to pin blame on a Mercurial file.
67 68 for frame in reversed(traceback.extract_tb(tb)):
68 69 if frame.name == '_call_with_frames_removed':
69 70 continue
70 71 if 'importlib' in frame.filename:
71 72 continue
72 73 if 'mercurial/__init__.py' in frame.filename:
73 74 continue
74 75 if frame.filename.startswith(sys.prefix):
75 76 continue
76 77 break
77 78
78 79 if frame.filename:
79 80 filename = os.path.basename(frame.filename)
80 81 print('%s: error importing: <%s> %s (error at %s:%d)' % (
81 82 f, type(e).__name__, e, filename, frame.lineno))
82 83 else:
83 84 print('%s: error importing module: <%s> %s (line %d)' % (
84 85 f, type(e).__name__, e, frame.lineno))
85 86
86 87 if __name__ == '__main__':
87 88 if sys.version_info[0] == 2:
88 89 fn = check_compat_py2
89 90 else:
90 91 fn = check_compat_py3
91 92
92 93 for f in sys.argv[1:]:
93 94 fn(f)
94 95
95 96 sys.exit(0)
@@ -1,28 +1,28 b''
1 1 #require test-repo
2 2
3 3 $ . "$TESTDIR/helpers-testrepo.sh"
4 4
5 5 $ cat <<'EOF' > scanhelptopics.py
6 6 > from __future__ import absolute_import, print_function
7 7 > import re
8 8 > import sys
9 9 > if sys.platform == "win32":
10 10 > import os, msvcrt
11 11 > msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
12 12 > topics = set()
13 13 > topicre = re.compile(r':hg:`help ([a-z0-9\-.]+)`')
14 14 > for fname in sys.argv:
15 15 > with open(fname) as f:
16 16 > topics.update(m.group(1) for m in topicre.finditer(f.read()))
17 17 > for s in sorted(topics):
18 18 > print(s)
19 19 > EOF
20 20
21 21 $ cd "$TESTDIR"/..
22 22
23 23 Check if ":hg:`help TOPIC`" is valid:
24 24 (use "xargs -n1 -t" to see which help commands are executed)
25 25
26 $ hg files 'glob:{hgext,mercurial}/**/*.py' | sed 's|\\|/|g' \
26 $ hg files 'glob:{hgdemandimport,hgext,mercurial}/**/*.py' | sed 's|\\|/|g' \
27 27 > | xargs python "$TESTTMP/scanhelptopics.py" \
28 28 > | xargs -n1 hg help > /dev/null
@@ -1,19 +1,19 b''
1 1 #require test-repo pylint hg10
2 2
3 3 Run pylint for known rules we care about.
4 4 -----------------------------------------
5 5
6 6 There should be no recorded failures; fix the codebase before introducing a
7 7 new check.
8 8
9 9 Current checks:
10 10 - W0102: no mutable default argument
11 11
12 12 $ touch $TESTTMP/fakerc
13 13 $ pylint --rcfile=$TESTTMP/fakerc --disable=all \
14 14 > --enable=W0102 --reports=no \
15 > mercurial hgext hgext3rd
15 > mercurial hgdemandimport hgext hgext3rd
16 16 (?)
17 17 ------------------------------------ (?)
18 18 Your code has been rated at 10.00/10 (?)
19 19 (?)
General Comments 0
You need to be logged in to leave comments. Login now