From b5fd477dd942461a35584acc23fb43f72f4f25b7 Mon Sep 17 00:00:00 2001 From: Christian Clauss Date: Thu, 5 Sep 2019 15:56:12 +0200 Subject: [PATCH] build: explain how to test Python 3.6 or 3.7 This helps contributors understand how they can test Python 3.6 or 3.7 on Travis CI. Helps with issues like: - https://github.com/nodejs/node/issues/29246#issuecomment-528075665 --- .travis.yml | 6 ++- configure | 38 +++++++++++-------- .../inspector_protocol/code_generator.py | 5 ++- tools/inspector_protocol/code_generator.py | 5 ++- 4 files changed, 35 insertions(+), 19 deletions(-) diff --git a/.travis.yml b/.travis.yml index 82a55c76e19b7f..2739628df5c62a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,9 +6,13 @@ x-ccache-setup-steps: &ccache-setup-steps os: linux language: cpp +# Currently this file can only support one PYTHON_VERSION. +# To experiment with Python 3, comment out Python 2.7 and uncomment one of the Python 3 versions. env: global: - - PYTHON_VERSION="2.7.15" + # - PYTHON_VERSION="2.7.15" + # - PYTHON_VERSION="3.6.7" + - PYTHON_VERSION="3.7.1" jobs: include: - stage: "Compile" diff --git a/configure b/configure index 9156e13f7aed0d..9259feb9e61671 100755 --- a/configure +++ b/configure @@ -1,28 +1,34 @@ #!/bin/sh -# Locate python2 interpreter and re-execute the script. Note that the -# mix of single and double quotes is intentional, as is the fact that -# the ] goes on a new line. +# Locate an acceptable python interpreter and then re-execute the script. +# Note that the mix of single and double quotes is intentional, +# as is the fact that the ] goes on a new line. +# When a 'which' call is made for a specific version of Python on Travis CI, +# pyenv will alert which shims are available and then will fail the build. _=[ 'exec' '/bin/sh' '-c' ''' +test ${TRAVIS} && exec python "$0" "$@" # workaround for pyenv on Travis CI which python2.7 >/dev/null && exec python2.7 "$0" "$@" -which python2 >/dev/null && exec python2 "$0" "$@" +which python3.7 >/dev/null && exec python3.7 "$0" "$@" +which python3.6 >/dev/null && exec python3.6 "$0" "$@" +which python3.5 >/dev/null && exec python3.5 "$0" "$@" exec python "$0" "$@" ''' "$0" "$@" ] del _ import sys -from distutils.spawn import find_executable as which -if sys.version_info[:2] != (2, 7): - sys.stderr.write('Please use Python 2.7') +from distutils.spawn import find_executable - python2 = which('python2') or which('python2.7') - - if python2: - sys.stderr.write(':\n\n') - sys.stderr.write(' ' + python2 + ' ' + ' '.join(sys.argv)) - - sys.stderr.write('\n') +print('Node configure: Found Python {0}.{1}.{2}...'.format(*sys.version_info)) +acceptable_pythons = ((2, 7), (3, 7), (3, 6), (3, 5)) +if sys.version_info[:2] in acceptable_pythons: + import configure +else: + python_cmds = ['python{0}.{1}'.format(*vers) for vers in acceptable_pythons] + sys.stderr.write('Please use {0}.\n'.format(' or '.join(python_cmds))) + for python_cmd in python_cmds: + python_cmd_path = find_executable(python_cmd) + if python_cmd_path and 'pyenv/shims' not in python_cmd_path: + sys.stderr.write('\t{0} {1}\n'.format(python_cmd_path, + ' '.join(sys.argv[:1]))) sys.exit(1) - -import configure diff --git a/deps/v8/third_party/inspector_protocol/code_generator.py b/deps/v8/third_party/inspector_protocol/code_generator.py index 7c72cc70e4fbeb..c234578aafdb03 100755 --- a/deps/v8/third_party/inspector_protocol/code_generator.py +++ b/deps/v8/third_party/inspector_protocol/code_generator.py @@ -43,6 +43,9 @@ def json_object_hook(object_dict): items = [(k, os.path.join(output_base, v) if k == "output" else v) for (k, v) in items] keys, values = list(zip(*items)) + # 'async' is a Python 3.7+ keyword. Don't use namedtuple(rename=True) + # because that would only rename async on Python 3 but not on Python 2. + keys = ['async_' if k == 'async' else k for k in keys] return collections.namedtuple('X', keys)(*values) return json.loads(data, object_hook=json_object_hook) @@ -555,7 +558,7 @@ def is_async_command(self, domain, command): if not self.config.protocol.options: return False return self.check_options(self.config.protocol.options, domain, command, - "async", None, False) + "async_", None, False) def is_exported(self, domain, name): if not self.config.protocol.options: diff --git a/tools/inspector_protocol/code_generator.py b/tools/inspector_protocol/code_generator.py index 7b555d7478a0c7..6a91b96376df51 100755 --- a/tools/inspector_protocol/code_generator.py +++ b/tools/inspector_protocol/code_generator.py @@ -41,6 +41,9 @@ def json_object_hook(object_dict): items = [(k, os.path.join(output_base, v) if k == "path" else v) for (k, v) in object_dict.items()] items = [(k, os.path.join(output_base, v) if k == "output" else v) for (k, v) in items] keys, values = list(zip(*items)) + # 'async' is a python 3 keyword. Don't use namedtuple(rename=True) + # because that only renames it in python 3 but not python 2. + keys = tuple('async_' if k == 'async' else k for k in keys) return collections.namedtuple('X', keys)(*values) return json.loads(data, object_hook=json_object_hook) @@ -521,7 +524,7 @@ def generate_type(self, domain, typename): def is_async_command(self, domain, command): if not self.config.protocol.options: return False - return self.check_options(self.config.protocol.options, domain, command, "async", None, False) + return self.check_options(self.config.protocol.options, domain, command, "async_", None, False) def is_exported(self, domain, name):