comparison contrib/check-py3-compat.py @ 28584:d69172ddfdca

tests: try to import modules with Python 3 All of mercurial.* is now using absolute_import. Most of mercurial.* is able to ast parse with Python 3. The next big hurdle is being able to import modules using Python 3. This patch adds testing of hgext.* and mercurial.* module imports in Python 3. As the new test output shows, most modules can't import under Python 3. However, many of the failures are due to a common problem in a highly imported module (e.g. the bytes vs str issue in node.py).
author Gregory Szorc <gregory.szorc@gmail.com>
date Sat, 12 Mar 2016 14:05:23 -0800
parents 260ce2eed951
children 1c22400db72d
comparison
equal deleted inserted replaced
28583:260ce2eed951 28584:d69172ddfdca
8 # GNU General Public License version 2 or any later version. 8 # GNU General Public License version 2 or any later version.
9 9
10 from __future__ import absolute_import, print_function 10 from __future__ import absolute_import, print_function
11 11
12 import ast 12 import ast
13 import imp
14 import os
13 import sys 15 import sys
16 import traceback
14 17
15 def check_compat_py2(f): 18 def check_compat_py2(f):
16 """Check Python 3 compatibility for a file with Python 2""" 19 """Check Python 3 compatibility for a file with Python 2"""
17 with open(f, 'rb') as fh: 20 with open(f, 'rb') as fh:
18 content = fh.read() 21 content = fh.read()
45 ast.parse(content) 48 ast.parse(content)
46 except SyntaxError as e: 49 except SyntaxError as e:
47 print('%s: invalid syntax: %s' % (f, e)) 50 print('%s: invalid syntax: %s' % (f, e))
48 return 51 return
49 52
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'):
57 assert f.endswith('.py')
58 name = f.replace('/', '.')[:-3]
59 with open(f, 'r') as fh:
60 try:
61 imp.load_module(name, fh, '', ('py', 'r', imp.PY_SOURCE))
62 except Exception as e:
63 exc_type, exc_value, tb = sys.exc_info()
64 frame = traceback.extract_tb(tb)[-1]
65
66 if frame.filename:
67 filename = os.path.basename(frame.filename)
68 print('%s: error importing: <%s> %s (error at %s:%d)' % (
69 f, type(e).__name__, e, filename, frame.lineno))
70 else:
71 print('%s: error importing module: <%s> %s (line %d)' % (
72 f, type(e).__name__, e, frame.lineno))
73
50 if __name__ == '__main__': 74 if __name__ == '__main__':
51 if sys.version_info[0] == 2: 75 if sys.version_info[0] == 2:
52 fn = check_compat_py2 76 fn = check_compat_py2
53 else: 77 else:
54 fn = check_compat_py3 78 fn = check_compat_py3