#!/bin/bash set -e fixers=" lib2to3.fixes.fix_apply lib2to3.fixes.fix_except lib2to3.fixes.fix_exitfunc lib2to3.fixes.fix_funcattrs lib2to3.fixes.fix_has_key lib2to3.fixes.fix_idioms lib2to3.fixes.fix_intern lib2to3.fixes.fix_isinstance lib2to3.fixes.fix_methodattrs lib2to3.fixes.fix_ne lib2to3.fixes.fix_numliterals lib2to3.fixes.fix_paren lib2to3.fixes.fix_reduce lib2to3.fixes.fix_renames lib2to3.fixes.fix_repr lib2to3.fixes.fix_standarderror lib2to3.fixes.fix_sys_exc lib2to3.fixes.fix_throw lib2to3.fixes.fix_tuple_params lib2to3.fixes.fix_types lib2to3.fixes.fix_ws_comma lib2to3.fixes.fix_xreadlines libfuturize.fixes.fix_absolute_import libfuturize.fixes.fix_future_standard_library_urllib libfuturize.fixes.fix_next_call libfuturize.fixes.fix_print_with_import libfuturize.fixes.fix_raise libmodernize.fixes.fix_basestring libfuturize.fixes.fix_division_safe libmodernize.fixes.fix_file libmodernize.fixes.fix_filter libmodernize.fixes.fix_imports_six libmodernize.fixes.fix_input_six libmodernize.fixes.fix_int_long_tuple libmodernize.fixes.fix_map libmodernize.fixes.fix_raise_six libmodernize.fixes.fix_xrange_six libmodernize.fixes.fix_zip libmodernize.fixes.fix_unicode_type libpasteurize.fixes.fix_newstyle " echo; echo "Testing for additions of Python 2 patterns we've removed as part of moving towards Python 3 compatibility."; echo if [ -n "$(git status --porcelain)" ]; then echo "The repository is not clean. check-py3 can only be run if the repository is clean." exit 1 fi script_dir=$(dirname "$0") lister_path="$script_dir/lister.py" python_files="$($lister_path -f py)" if [ -z "$python_files" ]; then echo "There are no python files to check in the current directory." exit 0 fi quick=1 if [ "$1" == "--find-fixers" ]; then quick=0 fi fixer_options="" for fixer in $fixers; do fixer_options+="-f $fixer " done failed=0 # run quick check echo "Running quick Python 3 compatibility test" echo "$python_files" | xargs futurize $fixer_options -j4 -n -w >/dev/null 2>/dev/null if ! git diff --exit-code; then # Clear the output from this one git reset --hard >/dev/null failed=1 fi # run slow check if [ "$failed" = "1" -a "$quick" == "0" ]; then echo "Running each fixer separately to find out which fixers need to be applied" for fixer in $fixers; do echo "Running Python 3 compatibility test $fixer" echo "$python_files" | xargs futurize -f $fixer -j4 -n -w >/dev/null 2>/dev/null if ! git diff --exit-code; then # Clear the output from this one git reset --hard >/dev/null fi done fi # The dict fixer tries to add list() even in for loops over an # iterator where it's just counterproductive. To address this, we run # the fixer but check for lines which don't include code that works # with iterators (currently for, join, and from_iterable). fixer="libmodernize.fixes.fix_dict_six" echo "Running python 3 compatability test $fixer" echo "$python_files" | xargs python-modernize -f $fixer -j4 -n -w >/dev/null 2>/dev/null if git --no-pager diff | grep "^+ " | grep -v '[ ]*for' | grep -v [.]join | grep -v from_iterable; then echo echo "Error: the above are changes suggested by python-modernize " echo "to handle the list=>iterator transition in Python 3." echo "Because 'python-modernize -f libmodernize.fixes.fix_dict_six' is spammy " echo "and also changes places where an iterator works fine, this output " echo "does not display the full context; you can find the diff with context by " echo "searching through the (unfortunately very spammy) full output below:" echo git --no-pager diff echo echo "That was a lot of text! Read this output from the top for more readable details." failed=1 fi # Clear the output git reset --hard >/dev/null if git grep -q '\(^\W*import StringIO\|^\W*from StringIO\)'; then echo "ERROR: StringIO imports not compatible with python 2+3:" git grep '\(^\W*import StringIO\|^\W*from StringIO\)' echo "Please use 'from six.moves import cStringIO as StringIO'" failed=1 fi echo if [ "$failed" == "0" ]; then echo "No issues detected!" else echo "Python 3 compatibility error(s) detected! See diffs above for what you need to change." exit 1 fi