Files
impala/bin/generate_xml_config.py
Joe McDonnell 2b550634d2 IMPALA-11952 (part 2): Fix print function syntax
Python 3 now treats print as a function and requires
the parenthesis in invocation.

print "Hello World!"
is now:
print("Hello World!")

This fixes all locations to use the function
invocation. This is more complicated when the output
is being redirected to a file or when avoiding the
usual newline.

print >> sys.stderr , "Hello World!"
is now:
print("Hello World!", file=sys.stderr)

To support this properly and guarantee equivalent behavior
between python 2 and python 3, all files that use print
now add this import:
from __future__ import print_function

This also fixes random flake8 issues that intersect with
the changes.

Testing:
 - check-python-syntax.sh shows no errors related to print

Change-Id: Ib634958369ad777a41e72d80c8053b74384ac351
Reviewed-on: http://gerrit.cloudera.org:8080/19552
Reviewed-by: Joe McDonnell <joemcdonnell@cloudera.com>
Reviewed-by: Michael Smith <michael.smith@cloudera.com>
Tested-by: Michael Smith <michael.smith@cloudera.com>
2023-02-28 17:11:50 +00:00

127 lines
3.8 KiB
Python
Executable File

#!/usr/bin/env python
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
"""
Script which uses a Python "template" to generate a Hadoop-style XML
configuration file.
The "template" is a Python module which should export a global variable called
'CONFIG'. This variable should be a dictionary of keys/values. The values may
use the special syntax '${FOO}' to substitute an environment variable (as a
convenience over manually implementing the same).
If you have an existing XML configuration and want to see it in convenient
python form, you can use a snippet like the following from within the Python
REPL:
import xml.etree.ElementTree as ET
import pprint
def convert(path):
e = ET.parse(path)
c = dict([(property.findtext('name'), property.findtext('value'))
for property in e.getroot()])
pprint.pprint(c, stream=file(path + ".py", "w"))
"""
from __future__ import with_statement
from __future__ import print_function
import imp
import os
import re
import sys
from textwrap import dedent
from xml.sax.saxutils import escape as xmlescape
ENV_VAR_RE = re.compile(r'\${(.+?)\}')
def _substitute_env_vars(s):
""" Substitute ${FOO} with the $FOO environment variable in 's' """
def lookup_func(match):
return os.environ[match.group(1)]
return ENV_VAR_RE.sub(lookup_func, s)
def dump_config(d, source_path, out):
"""
Dump a Hadoop-style XML configuration file.
'd': a dictionary of name/value pairs.
'source_path': the path where 'd' was parsed from.
'out': stream to write to
"""
header = """\
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<!--
NOTE: THIS FILE IS AUTO-GENERATED FROM:
{source_path}
EDITS BY HAND WILL BE LOST!
-->
<configuration>""".format(source_path=os.path.abspath(source_path))
print(dedent(header), file=out)
for k, v in sorted(d.iteritems()):
try:
k_new = _substitute_env_vars(k)
if isinstance(v, int):
v = str(v)
v_new = _substitute_env_vars(v)
except KeyError as e:
raise Exception("failed environment variable substitution for value {k}: {e}"
.format(k=k, e=e))
print("""\
<property>
<name>{name}</name>
<value>{value}</value>
</property>""".format(name=xmlescape(k_new), value=xmlescape(v_new)), file=out)
print("</configuration>", file=out)
def main():
if len(sys.argv) != 3:
print("usage: {prog} <template> <out>".format(prog=sys.argv[0]), file=sys.stderr)
sys.exit(1)
_, in_path, out_path = sys.argv
try:
mod = imp.load_source('template', in_path)
except: # noqa
print("Unable to load template: %s" % in_path, file=sys.stderr)
raise
conf = mod.__dict__.get('CONFIG')
if not isinstance(conf, dict):
raise Exception("module in '{path}' should define a dict named CONFIG"
.format(path=in_path))
tmp_path = out_path + ".tmp"
with file(tmp_path, "w") as out:
try:
dump_config(conf, in_path, out)
except: # noqa
os.unlink(tmp_path)
raise
os.rename(tmp_path, out_path)
if __name__ == "__main__":
main()