##// END OF EJS Templates
debian: add missing python-docutils dependency
debian: add missing python-docutils dependency

File last commit:

r28584:d69172dd default
r28983:cbb21826 stable
Show More
check-py3-compat.py
83 lines | 2.6 KiB | text/x-python | PythonLexer
/ contrib / check-py3-compat.py
Gregory Szorc
tests: add test for Python 3 compatibility...
r27279 #!/usr/bin/env python
#
# check-py3-compat - check Python 3 compatibility of Mercurial files
#
# Copyright 2015 Gregory Szorc <gregory.szorc@gmail.com>
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
from __future__ import absolute_import, print_function
import ast
Gregory Szorc
tests: try to import modules with Python 3...
r28584 import imp
import os
Gregory Szorc
tests: add test for Python 3 compatibility...
r27279 import sys
Gregory Szorc
tests: try to import modules with Python 3...
r28584 import traceback
Gregory Szorc
tests: add test for Python 3 compatibility...
r27279
Gregory Szorc
tests: perform an ast parse with Python 3...
r28583 def check_compat_py2(f):
"""Check Python 3 compatibility for a file with Python 2"""
Gregory Szorc
tests: add test for Python 3 compatibility...
r27279 with open(f, 'rb') as fh:
content = fh.read()
Yuya Nishihara
test: make check-py3-compat.py ignore empty code more reliably...
r28475 root = ast.parse(content)
Gregory Szorc
tests: add test for Python 3 compatibility...
r27279
Gregory Szorc
contrib: ignore empty files in check-py3-compat.py
r27331 # Ignore empty files.
Yuya Nishihara
test: make check-py3-compat.py ignore empty code more reliably...
r28475 if not root.body:
Gregory Szorc
contrib: ignore empty files in check-py3-compat.py
r27331 return
Gregory Szorc
tests: add test for Python 3 compatibility...
r27279 futures = set()
haveprint = False
for node in ast.walk(root):
if isinstance(node, ast.ImportFrom):
if node.module == '__future__':
futures |= set(n.name for n in node.names)
elif isinstance(node, ast.Print):
haveprint = True
if 'absolute_import' not in futures:
print('%s not using absolute_import' % f)
if haveprint and 'print_function' not in futures:
print('%s requires print_function' % f)
Gregory Szorc
tests: perform an ast parse with Python 3...
r28583 def check_compat_py3(f):
"""Check Python 3 compatibility of a file with Python 3."""
with open(f, 'rb') as fh:
content = fh.read()
try:
ast.parse(content)
except SyntaxError as e:
print('%s: invalid syntax: %s' % (f, e))
return
Gregory Szorc
tests: try to import modules with Python 3...
r28584 # Try to import the module.
# For now we only support mercurial.* and hgext.* modules because figuring
# out module paths for things not in a package can be confusing.
if f.startswith(('hgext/', 'mercurial/')) and not f.endswith('__init__.py'):
assert f.endswith('.py')
name = f.replace('/', '.')[:-3]
with open(f, 'r') as fh:
try:
imp.load_module(name, fh, '', ('py', 'r', imp.PY_SOURCE))
except Exception as e:
exc_type, exc_value, tb = sys.exc_info()
frame = traceback.extract_tb(tb)[-1]
if frame.filename:
filename = os.path.basename(frame.filename)
print('%s: error importing: <%s> %s (error at %s:%d)' % (
f, type(e).__name__, e, filename, frame.lineno))
else:
print('%s: error importing module: <%s> %s (line %d)' % (
f, type(e).__name__, e, frame.lineno))
Gregory Szorc
tests: add test for Python 3 compatibility...
r27279 if __name__ == '__main__':
Gregory Szorc
tests: perform an ast parse with Python 3...
r28583 if sys.version_info[0] == 2:
fn = check_compat_py2
else:
fn = check_compat_py3
Gregory Szorc
tests: add test for Python 3 compatibility...
r27279 for f in sys.argv[1:]:
Gregory Szorc
tests: perform an ast parse with Python 3...
r28583 fn(f)
Gregory Szorc
tests: add test for Python 3 compatibility...
r27279
sys.exit(0)