contrib/check-py3-compat.py
author Gregory Szorc <gregory.szorc@gmail.com>
Fri, 18 Mar 2016 16:15:12 -0700
changeset 28583 260ce2eed951
parent 28475 ae522fb493d4
child 28584 d69172ddfdca
permissions -rwxr-xr-x
tests: perform an ast parse with Python 3 Previously, test-check-py3-compat.t parsed Python files with Python 2 and looked for known patterns that are incompatible with Python 3. Now that we have a mechanism for invoking Python 3 interpreters from tests, we can expand check-py3-compat.py and its corresponding .t test to perform an additional AST parse using Python 3. As the test output shows, we identify a number of new parse failures on Python 3. There are some redundant warnings for missing parentheses for the print function. Given the recent influx of patches around fixing these, the redundancy shouldn't last for too long.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
27279
40eb385f798f tests: add test for Python 3 compatibility
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
     1
#!/usr/bin/env python
40eb385f798f tests: add test for Python 3 compatibility
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
     2
#
40eb385f798f tests: add test for Python 3 compatibility
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
     3
# check-py3-compat - check Python 3 compatibility of Mercurial files
40eb385f798f tests: add test for Python 3 compatibility
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
     4
#
40eb385f798f tests: add test for Python 3 compatibility
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
     5
# Copyright 2015 Gregory Szorc <gregory.szorc@gmail.com>
40eb385f798f tests: add test for Python 3 compatibility
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
     6
#
40eb385f798f tests: add test for Python 3 compatibility
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
     7
# This software may be used and distributed according to the terms of the
40eb385f798f tests: add test for Python 3 compatibility
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
     8
# GNU General Public License version 2 or any later version.
40eb385f798f tests: add test for Python 3 compatibility
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
     9
40eb385f798f tests: add test for Python 3 compatibility
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    10
from __future__ import absolute_import, print_function
40eb385f798f tests: add test for Python 3 compatibility
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    11
40eb385f798f tests: add test for Python 3 compatibility
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    12
import ast
40eb385f798f tests: add test for Python 3 compatibility
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    13
import sys
40eb385f798f tests: add test for Python 3 compatibility
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    14
28583
260ce2eed951 tests: perform an ast parse with Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28475
diff changeset
    15
def check_compat_py2(f):
260ce2eed951 tests: perform an ast parse with Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28475
diff changeset
    16
    """Check Python 3 compatibility for a file with Python 2"""
27279
40eb385f798f tests: add test for Python 3 compatibility
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    17
    with open(f, 'rb') as fh:
40eb385f798f tests: add test for Python 3 compatibility
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    18
        content = fh.read()
28475
ae522fb493d4 test: make check-py3-compat.py ignore empty code more reliably
Yuya Nishihara <yuya@tcha.org>
parents: 27331
diff changeset
    19
    root = ast.parse(content)
27279
40eb385f798f tests: add test for Python 3 compatibility
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    20
27331
35e69407b1ac contrib: ignore empty files in check-py3-compat.py
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27279
diff changeset
    21
    # Ignore empty files.
28475
ae522fb493d4 test: make check-py3-compat.py ignore empty code more reliably
Yuya Nishihara <yuya@tcha.org>
parents: 27331
diff changeset
    22
    if not root.body:
27331
35e69407b1ac contrib: ignore empty files in check-py3-compat.py
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27279
diff changeset
    23
        return
35e69407b1ac contrib: ignore empty files in check-py3-compat.py
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27279
diff changeset
    24
27279
40eb385f798f tests: add test for Python 3 compatibility
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    25
    futures = set()
40eb385f798f tests: add test for Python 3 compatibility
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    26
    haveprint = False
40eb385f798f tests: add test for Python 3 compatibility
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    27
    for node in ast.walk(root):
40eb385f798f tests: add test for Python 3 compatibility
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    28
        if isinstance(node, ast.ImportFrom):
40eb385f798f tests: add test for Python 3 compatibility
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    29
            if node.module == '__future__':
40eb385f798f tests: add test for Python 3 compatibility
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    30
                futures |= set(n.name for n in node.names)
40eb385f798f tests: add test for Python 3 compatibility
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    31
        elif isinstance(node, ast.Print):
40eb385f798f tests: add test for Python 3 compatibility
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    32
            haveprint = True
40eb385f798f tests: add test for Python 3 compatibility
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    33
40eb385f798f tests: add test for Python 3 compatibility
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    34
    if 'absolute_import' not in futures:
40eb385f798f tests: add test for Python 3 compatibility
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    35
        print('%s not using absolute_import' % f)
40eb385f798f tests: add test for Python 3 compatibility
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    36
    if haveprint and 'print_function' not in futures:
40eb385f798f tests: add test for Python 3 compatibility
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    37
        print('%s requires print_function' % f)
40eb385f798f tests: add test for Python 3 compatibility
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    38
28583
260ce2eed951 tests: perform an ast parse with Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28475
diff changeset
    39
def check_compat_py3(f):
260ce2eed951 tests: perform an ast parse with Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28475
diff changeset
    40
    """Check Python 3 compatibility of a file with Python 3."""
260ce2eed951 tests: perform an ast parse with Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28475
diff changeset
    41
    with open(f, 'rb') as fh:
260ce2eed951 tests: perform an ast parse with Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28475
diff changeset
    42
        content = fh.read()
260ce2eed951 tests: perform an ast parse with Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28475
diff changeset
    43
260ce2eed951 tests: perform an ast parse with Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28475
diff changeset
    44
    try:
260ce2eed951 tests: perform an ast parse with Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28475
diff changeset
    45
        ast.parse(content)
260ce2eed951 tests: perform an ast parse with Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28475
diff changeset
    46
    except SyntaxError as e:
260ce2eed951 tests: perform an ast parse with Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28475
diff changeset
    47
        print('%s: invalid syntax: %s' % (f, e))
260ce2eed951 tests: perform an ast parse with Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28475
diff changeset
    48
        return
260ce2eed951 tests: perform an ast parse with Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28475
diff changeset
    49
27279
40eb385f798f tests: add test for Python 3 compatibility
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    50
if __name__ == '__main__':
28583
260ce2eed951 tests: perform an ast parse with Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28475
diff changeset
    51
    if sys.version_info[0] == 2:
260ce2eed951 tests: perform an ast parse with Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28475
diff changeset
    52
        fn = check_compat_py2
260ce2eed951 tests: perform an ast parse with Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28475
diff changeset
    53
    else:
260ce2eed951 tests: perform an ast parse with Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28475
diff changeset
    54
        fn = check_compat_py3
260ce2eed951 tests: perform an ast parse with Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28475
diff changeset
    55
27279
40eb385f798f tests: add test for Python 3 compatibility
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    56
    for f in sys.argv[1:]:
28583
260ce2eed951 tests: perform an ast parse with Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28475
diff changeset
    57
        fn(f)
27279
40eb385f798f tests: add test for Python 3 compatibility
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    58
40eb385f798f tests: add test for Python 3 compatibility
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    59
    sys.exit(0)