Merge pull request from tansly/build-python3

Make build.py compatible with Python 2 and 3
This commit is contained in:
Ron de las Alas 2023-10-25 11:32:45 -04:00 committed by GitHub
commit f116732bbb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 43 additions and 40 deletions

View file

@ -35,11 +35,16 @@
# msg/js/<LANG>.js for every language <LANG> defined in msg/js/<LANG>.json. # msg/js/<LANG>.js for every language <LANG> defined in msg/js/<LANG>.json.
import sys import sys
if sys.version_info[0] != 2:
raise Exception("Blockly build only compatible with Python 2.x.\n"
"You are using: " + sys.version)
import errno, glob, httplib, json, os, re, subprocess, threading, urllib import errno, glob, json, os, re, subprocess, threading, codecs, functools
if sys.version_info[0] == 2:
import httplib
from urllib import urlencode
else:
import http.client as httplib
from urllib.parse import urlencode
from importlib import reload
REMOTE_COMPILER = "remote" REMOTE_COMPILER = "remote"
@ -194,7 +199,7 @@ if (isNodeJS) {
key_whitelist = self.closure_env.keys() key_whitelist = self.closure_env.keys()
keys_pipe_separated = reduce(lambda accum, key: accum + "|" + key, key_whitelist) keys_pipe_separated = functools.reduce(lambda accum, key: accum + "|" + key, key_whitelist)
begin_brace = re.compile(r"\{(?!%s)" % (keys_pipe_separated,)) begin_brace = re.compile(r"\{(?!%s)" % (keys_pipe_separated,))
end_brace = re.compile(r"\}") end_brace = re.compile(r"\}")
@ -336,7 +341,7 @@ class Gen_compressed(threading.Thread):
return dict( return dict(
compiledCode=stdout, compiledCode=stdout,
statistics=dict( statistics=dict(
originalSize=reduce(lambda v, size: v + size, filesizes, 0), originalSize=functools.reduce(lambda v, size: v + size, filesizes, 0),
compressedSize=len(stdout), compressedSize=len(stdout),
) )
) )
@ -373,9 +378,10 @@ class Gen_compressed(threading.Thread):
headers = {"Content-type": "application/x-www-form-urlencoded"} headers = {"Content-type": "application/x-www-form-urlencoded"}
conn = httplib.HTTPSConnection("closure-compiler.appspot.com") conn = httplib.HTTPSConnection("closure-compiler.appspot.com")
conn.request("POST", "/compile", urllib.urlencode(remoteParams), headers) conn.request("POST", "/compile", urlencode(remoteParams), headers)
response = conn.getresponse() response = conn.getresponse()
json_str = response.read() # Decode is necessary for Python 3.4 compatibility
json_str = response.read().decode("utf-8")
conn.close() conn.close()
# Parse the JSON response. # Parse the JSON response.
@ -388,12 +394,12 @@ class Gen_compressed(threading.Thread):
n = int(name[6:]) - 1 n = int(name[6:]) - 1
return filenames[n] return filenames[n]
if json_data.has_key("serverErrors"): if "serverErrors" in json_data:
errors = json_data["serverErrors"] errors = json_data["serverErrors"]
for error in errors: for error in errors:
print("SERVER ERROR: %s" % target_filename) print("SERVER ERROR: %s" % target_filename)
print(error["error"]) print(error["error"])
elif json_data.has_key("errors"): elif "errors" in json_data:
errors = json_data["errors"] errors = json_data["errors"]
for error in errors: for error in errors:
print("FATAL ERROR") print("FATAL ERROR")
@ -405,7 +411,7 @@ class Gen_compressed(threading.Thread):
print((" " * error["charno"]) + "^") print((" " * error["charno"]) + "^")
sys.exit(1) sys.exit(1)
else: else:
if json_data.has_key("warnings"): if "warnings" in json_data:
warnings = json_data["warnings"] warnings = json_data["warnings"]
for warning in warnings: for warning in warnings:
print("WARNING") print("WARNING")
@ -422,11 +428,11 @@ class Gen_compressed(threading.Thread):
return False return False
def write_output(self, target_filename, remove, json_data): def write_output(self, target_filename, remove, json_data):
if not json_data.has_key("compiledCode"): if "compiledCode" not in json_data:
print("FATAL ERROR: Compiler did not return compiledCode.") print("FATAL ERROR: Compiler did not return compiledCode.")
sys.exit(1) sys.exit(1)
code = HEADER + "\n" + json_data["compiledCode"] code = HEADER + "\n" + json_data["compiledCode"].decode("utf-8")
code = code.replace(remove, "") code = code.replace(remove, "")
# Trim down Google's (and only Google's) Apache licences. # Trim down Google's (and only Google's) Apache licences.
@ -500,7 +506,7 @@ class Gen_langfiles(threading.Thread):
# If a destination file was missing, rebuild. # If a destination file was missing, rebuild.
return True return True
else: else:
print("Error checking file creation times: " + e) print("Error checking file creation times: " + str(e))
def run(self): def run(self):
# The files msg/json/{en,qqq,synonyms}.json depend on msg/messages.js. # The files msg/json/{en,qqq,synonyms}.json depend on msg/messages.js.
@ -573,7 +579,7 @@ if __name__ == "__main__":
test_args = [closure_compiler, os.path.join("build", "test_input.js")] test_args = [closure_compiler, os.path.join("build", "test_input.js")]
test_proc = subprocess.Popen(test_args, stdin=subprocess.PIPE, stdout=subprocess.PIPE) test_proc = subprocess.Popen(test_args, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
(stdout, _) = test_proc.communicate() (stdout, _) = test_proc.communicate()
assert stdout == read(os.path.join("build", "test_expect.js")) assert stdout.decode("utf-8") == read(os.path.join("build", "test_expect.js"))
print("Using local compiler: %s ...\n" % CLOSURE_COMPILER_NPM) print("Using local compiler: %s ...\n" % CLOSURE_COMPILER_NPM)
except (ImportError, AssertionError): except (ImportError, AssertionError):
@ -602,11 +608,11 @@ if __name__ == "__main__":
developers.google.com/blockly/guides/modify/web/closure""") developers.google.com/blockly/guides/modify/web/closure""")
sys.exit(1) sys.exit(1)
search_paths = calcdeps.ExpandDirectories( search_paths = list(calcdeps.ExpandDirectories(
["core", os.path.join(closure_root, closure_library)]) ["core", os.path.join(closure_root, closure_library)]))
search_paths_horizontal = filter(exclude_vertical, search_paths) search_paths_horizontal = list(filter(exclude_vertical, search_paths))
search_paths_vertical = filter(exclude_horizontal, search_paths) search_paths_vertical = list(filter(exclude_horizontal, search_paths))
closure_env = { closure_env = {
"closure_dir": closure_dir, "closure_dir": closure_dir,

View file

@ -59,7 +59,7 @@ def read_json_file(filename):
if '@metadata' in defs: if '@metadata' in defs:
del defs['@metadata'] del defs['@metadata']
return defs return defs
except ValueError, e: except ValueError as e:
print('Error reading ' + filename) print('Error reading ' + filename)
raise InputError(filename, str(e)) raise InputError(filename, str(e))
@ -85,7 +85,7 @@ def _create_qqq_file(output_dir):
""" """
qqq_file_name = os.path.join(os.curdir, output_dir, 'qqq.json') qqq_file_name = os.path.join(os.curdir, output_dir, 'qqq.json')
qqq_file = codecs.open(qqq_file_name, 'w', 'utf-8') qqq_file = codecs.open(qqq_file_name, 'w', 'utf-8')
print 'Created file: ' + qqq_file_name print('Created file: ' + qqq_file_name)
qqq_file.write('{\n') qqq_file.write('{\n')
return qqq_file return qqq_file
@ -126,7 +126,7 @@ def _create_lang_file(author, lang, output_dir):
""" """
lang_file_name = os.path.join(os.curdir, output_dir, lang + '.json') lang_file_name = os.path.join(os.curdir, output_dir, lang + '.json')
lang_file = codecs.open(lang_file_name, 'w', 'utf-8') lang_file = codecs.open(lang_file_name, 'w', 'utf-8')
print 'Created file: ' + lang_file_name print('Created file: ' + lang_file_name)
# string.format doesn't like printing braces, so break up our writes. # string.format doesn't like printing braces, so break up our writes.
lang_file.write('{\n\t"@metadata": {') lang_file.write('{\n\t"@metadata": {')
lang_file.write(""" lang_file.write("""
@ -166,7 +166,7 @@ def _create_key_file(output_dir):
key_file_name = os.path.join(os.curdir, output_dir, 'keys.json') key_file_name = os.path.join(os.curdir, output_dir, 'keys.json')
key_file = open(key_file_name, 'w') key_file = open(key_file_name, 'w')
key_file.write('{\n') key_file.write('{\n')
print 'Created file: ' + key_file_name print('Created file: ' + key_file_name)
return key_file return key_file

View file

@ -29,11 +29,8 @@ _NEWLINE_PATTERN = re.compile('[\n\r]')
def string_is_ascii(s): def string_is_ascii(s):
try: # This approach is better for compatibility
s.decode('ascii') return all(ord(c) < 128 for c in s)
return True
except UnicodeEncodeError:
return False
def load_constants(filename): def load_constants(filename):
"""Read in constants file, which must be output in every language.""" """Read in constants file, which must be output in every language."""
@ -81,14 +78,14 @@ def main():
print('ERROR: definition of {0} in {1} contained a newline character.'. print('ERROR: definition of {0} in {1} contained a newline character.'.
format(key, args.source_lang_file)) format(key, args.source_lang_file))
sys.exit(1) sys.exit(1)
sorted_keys = source_defs.keys() sorted_keys = sorted(source_defs.keys())
sorted_keys.sort()
# Read in synonyms file, which must be output in every language. # Read in synonyms file, which must be output in every language.
synonym_defs = read_json_file(os.path.join( synonym_defs = read_json_file(os.path.join(
os.curdir, args.source_synonym_file)) os.curdir, args.source_synonym_file))
# synonym_defs is also being sorted to ensure the same order is kept
synonym_text = '\n'.join(['Blockly.Msg.{0} = Blockly.Msg.{1};'.format( synonym_text = '\n'.join(['Blockly.Msg.{0} = Blockly.Msg.{1};'.format(
key, synonym_defs[key]) for key in synonym_defs]) key, synonym_defs[key]) for key in sorted(synonym_defs)])
# Read in constants file, which must be output in every language. # Read in constants file, which must be output in every language.
constants_text = load_constants(os.path.join(os.curdir, args.source_constants_file)) constants_text = load_constants(os.path.join(os.curdir, args.source_constants_file))

View file

@ -51,9 +51,9 @@ def main():
try: try:
with codecs.open(filename, 'r', 'utf-8') as infile: with codecs.open(filename, 'r', 'utf-8') as infile:
j = json.load(infile) j = json.load(infile)
except ValueError, e: except ValueError as e:
print('Error reading ' + filename) print('Error reading ' + filename)
raise InputError(file, str(e)) raise InputError(filename, str(e))
# Built up output strings as an array to make output of delimiters easier. # Built up output strings as an array to make output of delimiters easier.
output = [] output = []

View file

@ -100,7 +100,7 @@ def _process_file(path_to_json, target_lang, key_dict):
if key != '@metadata': if key != '@metadata':
try: try:
identifier = key_dict[key] identifier = key_dict[key]
except KeyError, e: except KeyError as e:
print('Key "%s" is in %s but not in %s' % print('Key "%s" is in %s but not in %s' %
(key, keyfile, args.key_file)) (key, keyfile, args.key_file))
raise e raise e

View file

@ -37,7 +37,7 @@ class TestSequenceFunctions(unittest.TestCase):
u'block of actions.'] u'block of actions.']
for sentence in sentences: for sentence in sentences:
output = common.insert_breaks(sentence, 30, 50) output = common.insert_breaks(sentence, 30, 50)
self.assert_(contains_all_chars(sentence, output), self.assertTrue(contains_all_chars(sentence, output),
u'Mismatch between:\n{0}\n{1}'.format( u'Mismatch between:\n{0}\n{1}'.format(
re.sub(spaces, '', sentence), re.sub(spaces, '', sentence),
re.sub(spaces, '', output))) re.sub(spaces, '', output)))

View file

@ -65,7 +65,7 @@ def _parse_trans_unit(trans_unit):
try: try:
result['source'] = get_value('source') result['source'] = get_value('source')
result['target'] = get_value('target') result['target'] = get_value('target')
except InputError, e: except InputError as e:
raise InputError(key, e.msg) raise InputError(key, e.msg)
# Get notes, using the from value as key and the data as value. # Get notes, using the from value as key and the data as value.
@ -112,8 +112,8 @@ def _process_file(filename):
except IOError: except IOError:
# Don't get caught by below handler # Don't get caught by below handler
raise raise
except Exception, e: except Exception as e:
print print()
raise InputError(filename, str(e)) raise InputError(filename, str(e))
# Make sure needed fields are present and non-empty. # Make sure needed fields are present and non-empty.
@ -146,8 +146,8 @@ def _process_file(filename):
results.append(unit) results.append(unit)
return results return results
except IOError, e: except IOError as e:
print 'Error with file {0}: {1}'.format(filename, e.strerror) print('Error with file {0}: {1}'.format(filename, e.strerror))
sys.exit(1) sys.exit(1)