From c30cd07c7e00992a8cb3c6d5cc26f4a6d342d2b4 Mon Sep 17 00:00:00 2001 From: Shane Carr Date: Fri, 7 Dec 2018 17:22:10 -0800 Subject: [PATCH] ICU-20299 Adds Python 2.7 support to data build script. --- .travis.yml | 4 +- icu4c/source/configure | 47 ++++++++++++------- icu4c/source/configure.ac | 13 ++--- icu4c/source/data/BUILDRULES.py | 4 ++ icu4c/source/data/buildtool/__main__.py | 8 +++- icu4c/source/data/buildtool/filtration.py | 14 ++++-- .../data/buildtool/renderers/makefile.py | 4 ++ icu4c/source/data/buildtool/utils.py | 4 ++ 8 files changed, 69 insertions(+), 29 deletions(-) diff --git a/.travis.yml b/.travis.yml index d0473dbb8d..25487aff54 100644 --- a/.travis.yml +++ b/.travis.yml @@ -42,7 +42,9 @@ matrix: env: BUILD=MACINTOSH os: osx compiler: clang - script: cd icu4c/source && ./runConfigureICU MacOSX && make -j2 check + # Use the macOS target to test Python 2 in data build script. + # TODO(ICU-20301): Change this back to the default Python version 3. + script: cd icu4c/source && PYTHON=python2 ./runConfigureICU MacOSX && make -j2 check # Clang Linux with address sanitizer. # Note - the 'sudo: true' option forces Travis to use a Virtual machine on GCE instead of diff --git a/icu4c/source/configure b/icu4c/source/configure index 441e30e6bd..659832e249 100755 --- a/icu4c/source/configure +++ b/icu4c/source/configure @@ -694,7 +694,7 @@ GREP DOXYGEN cross_buildroot U_MAKE -PYTHON3 +PYTHON cross_compiling INSTALL_DATA INSTALL_SCRIPT @@ -753,6 +753,7 @@ infodir docdir oldincludedir includedir +runstatedir localstatedir sharedstatedir sysconfdir @@ -857,6 +858,7 @@ datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' +runstatedir='${localstatedir}/run' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' @@ -1109,6 +1111,15 @@ do | -silent | --silent | --silen | --sile | --sil) silent=yes ;; + -runstatedir | --runstatedir | --runstatedi | --runstated \ + | --runstate | --runstat | --runsta | --runst | --runs \ + | --run | --ru | --r) + ac_prev=runstatedir ;; + -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ + | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ + | --run=* | --ru=* | --r=*) + runstatedir=$ac_optarg ;; + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ @@ -1246,7 +1257,7 @@ fi for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ - libdir localedir mandir + libdir localedir mandir runstatedir do eval ac_val=\$$ac_var # Remove trailing slashes. @@ -1399,6 +1410,7 @@ Fine tuning of the installation directories: --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] @@ -4188,17 +4200,18 @@ fi #AC_CHECK_PROG(AUTOCONF, autoconf, autoconf, true) #AC_CHECK_PROG(STRIP, strip, strip, true) -for ac_prog in python3 "py -3" +# TODO(ICU-20301): Remove fallback to Python 2. +for ac_prog in python3 "py -3" python "py" do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_PYTHON3+:} false; then : +if ${ac_cv_prog_PYTHON+:} false; then : $as_echo_n "(cached) " >&6 else - if test -n "$PYTHON3"; then - ac_cv_prog_PYTHON3="$PYTHON3" # Let the user override the test. + if test -n "$PYTHON"; then + ac_cv_prog_PYTHON="$PYTHON" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH @@ -4207,7 +4220,7 @@ do test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_PYTHON3="$ac_prog" + ac_cv_prog_PYTHON="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi @@ -4217,17 +4230,17 @@ IFS=$as_save_IFS fi fi -PYTHON3=$ac_cv_prog_PYTHON3 -if test -n "$PYTHON3"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PYTHON3" >&5 -$as_echo "$PYTHON3" >&6; } +PYTHON=$ac_cv_prog_PYTHON +if test -n "$PYTHON"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PYTHON" >&5 +$as_echo "$PYTHON" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi - test -n "$PYTHON3" && break + test -n "$PYTHON" && break done @@ -9109,19 +9122,19 @@ $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi -if test -z "$PYTHON3"; +if test -z "$PYTHON"; then echo "" > data/rules.mk else echo "Spawning Python to generate data/rules.mk..." - PYTHONPATH="$srcdir/data" $PYTHON3 -m buildtool \ + PYTHONPATH="$srcdir/data" $PYTHON -m buildtool \ --format gnumake \ --seqmode parallel \ --glob_dir "$srcdir/data" \ --filter_file "$ICU_DATA_FILTER_FILE" \ > data/rules.mk echo "Spawning Python to generate test/testdata/rules.mk..." - PYTHONPATH="$srcdir/test/testdata:$srcdir/data" $PYTHON3 -m buildtool \ + PYTHONPATH="$srcdir/test/testdata:$srcdir/data" $PYTHON -m buildtool \ --format gnumake \ --seqmode parallel \ --glob_dir "$srcdir/test/testdata" \ @@ -9210,9 +9223,9 @@ then echo "## Expect build failures in the 'data', 'test', and other directories." fi -if test -z "$PYTHON3"; +if test -z "$PYTHON"; then - echo "** Note: Python 3 not found. You will not be able to build data from source." + echo "** Note: Python not found. You will not be able to build data from source." fi $as_unset _CXX_CXXSUFFIX diff --git a/icu4c/source/configure.ac b/icu4c/source/configure.ac index 81f7e10ca1..80da9255f5 100644 --- a/icu4c/source/configure.ac +++ b/icu4c/source/configure.ac @@ -195,7 +195,8 @@ fi #AC_CHECK_PROG(AUTOCONF, autoconf, autoconf, true) #AC_CHECK_PROG(STRIP, strip, strip, true) -AC_CHECK_PROGS(PYTHON3, python3 "py -3") +# TODO(ICU-20301): Remove fallback to Python 2. +AC_CHECK_PROGS(PYTHON, python3 "py -3" python "py") # Check for the platform make AC_PATH_PROGS(U_MAKE, gmake gnumake, make) @@ -1385,19 +1386,19 @@ AC_CONFIG_FILES([icudefs.mk \ samples/cal/Makefile samples/layout/Makefile]) AC_OUTPUT -if test -z "$PYTHON3"; +if test -z "$PYTHON"; then echo "" > data/rules.mk else echo "Spawning Python to generate data/rules.mk..." - PYTHONPATH="$srcdir/data" $PYTHON3 -m buildtool \ + PYTHONPATH="$srcdir/data" $PYTHON -m buildtool \ --format gnumake \ --seqmode parallel \ --glob_dir "$srcdir/data" \ --filter_file "$ICU_DATA_FILTER_FILE" \ > data/rules.mk echo "Spawning Python to generate test/testdata/rules.mk..." - PYTHONPATH="$srcdir/test/testdata:$srcdir/data" $PYTHON3 -m buildtool \ + PYTHONPATH="$srcdir/test/testdata:$srcdir/data" $PYTHON -m buildtool \ --format gnumake \ --seqmode parallel \ --glob_dir "$srcdir/test/testdata" \ @@ -1483,9 +1484,9 @@ then echo "## Expect build failures in the 'data', 'test', and other directories." fi -if test -z "$PYTHON3"; +if test -z "$PYTHON"; then - echo "** Note: Python 3 not found. You will not be able to build data from source." + echo "** Note: Python not found. You will not be able to build data from source." fi $as_unset _CXX_CXXSUFFIX diff --git a/icu4c/source/data/BUILDRULES.py b/icu4c/source/data/BUILDRULES.py index 3a75a608f8..68e0ef8522 100644 --- a/icu4c/source/data/BUILDRULES.py +++ b/icu4c/source/data/BUILDRULES.py @@ -1,6 +1,10 @@ # Copyright (C) 2018 and later: Unicode, Inc. and others. # License & terms of use: http://www.unicode.org/copyright.html +# Python 2/3 Compatibility (ICU-20299) +# TODO(ICU-20301): Remove this. +from __future__ import print_function + from distutils.sysconfig import parse_makefile from buildtool import * diff --git a/icu4c/source/data/buildtool/__main__.py b/icu4c/source/data/buildtool/__main__.py index 88b1387dd7..23e9572325 100644 --- a/icu4c/source/data/buildtool/__main__.py +++ b/icu4c/source/data/buildtool/__main__.py @@ -1,6 +1,10 @@ # Copyright (C) 2018 and later: Unicode, Inc. and others. # License & terms of use: http://www.unicode.org/copyright.html +# Python 2/3 Compatibility (ICU-20299) +# TODO(ICU-20301): Remove this. +from __future__ import print_function + import argparse import glob as pyglob import json @@ -119,8 +123,8 @@ class Config(object): self.filters_json_data = hjson.load(f) except ImportError: self.filters_json_data = json.load(f) - except FileNotFoundError: - print("Error: Filter file not found at %s." % args.filter_file, file=sys.stderr) + except IOError: + print("Error: Could not read filter file %s." % args.filter_file, file=sys.stderr) exit(1) def has_feature(self, feature_name): diff --git a/icu4c/source/data/buildtool/filtration.py b/icu4c/source/data/buildtool/filtration.py index b86466c596..0ade314be9 100644 --- a/icu4c/source/data/buildtool/filtration.py +++ b/icu4c/source/data/buildtool/filtration.py @@ -1,7 +1,11 @@ # Copyright (C) 2018 and later: Unicode, Inc. and others. # License & terms of use: http://www.unicode.org/copyright.html -from abc import ABC, abstractmethod +# Python 2/3 Compatibility (ICU-20299) +# TODO(ICU-20301): Remove this. +from __future__ import print_function + +from abc import abstractmethod from collections import defaultdict import re import sys @@ -10,7 +14,10 @@ from . import * from . import utils -class Filter(ABC): +# Note: for this to be a proper abstract class, it should extend abc.ABC. +# There is no nice way to do this that works in both Python 2 and 3. +# TODO(ICU-20301): Make this inherit from abc.ABC. +class Filter(object): @staticmethod def create_from_json(json_data): if "filterType" in json_data: @@ -216,7 +223,8 @@ class LanguageFilter(WhitelistBlacklistFilter): class RegexFilter(WhitelistBlacklistFilter): def __init__(self, *args): - super().__init__(*args) + # TODO(ICU-20301): Change this to: super().__init__(*args) + super(RegexFilter, self).__init__(*args) if self.is_whitelist: self.whitelist = [re.compile(pat) for pat in self.whitelist] else: diff --git a/icu4c/source/data/buildtool/renderers/makefile.py b/icu4c/source/data/buildtool/renderers/makefile.py index cf0559ed6c..0029378867 100644 --- a/icu4c/source/data/buildtool/renderers/makefile.py +++ b/icu4c/source/data/buildtool/renderers/makefile.py @@ -1,6 +1,10 @@ # Copyright (C) 2018 and later: Unicode, Inc. and others. # License & terms of use: http://www.unicode.org/copyright.html +# Python 2/3 Compatibility (ICU-20299) +# TODO(ICU-20301): Remove this. +from __future__ import print_function + from . import * from .. import * from .. import utils diff --git a/icu4c/source/data/buildtool/utils.py b/icu4c/source/data/buildtool/utils.py index fb5cf6d747..feab298f65 100644 --- a/icu4c/source/data/buildtool/utils.py +++ b/icu4c/source/data/buildtool/utils.py @@ -1,6 +1,10 @@ # Copyright (C) 2018 and later: Unicode, Inc. and others. # License & terms of use: http://www.unicode.org/copyright.html +# Python 2/3 Compatibility (ICU-20299) +# TODO(ICU-20301): Remove this. +from __future__ import print_function + import sys from . import *