Add support for building with Python 3

Python 3 introduces some language changes that cause issues when running
c_client.py. This also breaks compatibility with Python 2.5 since it does not
support the "as" statement in try/except blocks and does not have reduce() in
the functools package.

The main changes are:
* try/except blocks require `except ... as ...:` to resolve syntactical ambiguity
* map() and filter() return iterators rather than lists in Python 3
* reduce() is now in functools package (and not built-in in Python 3)
* Dictionaries don't have a has_key() method in Python 3
* None and int types can't be directly compared in Python 3
* print() is a statement in Python 3

See http://diveintopython3.org/porting-code-to-python-3-with-2to3.html and
PEP-3110 for details.

Verified on Python 2.6.5 and 3.1.3.

Signed-off-by: David Coles <dcoles@gaikai.com>
Signed-off-by: Julien Danjou <julien@danjou.info>
This commit is contained in:
David Coles 2011-04-08 17:47:05 -07:00 committed by Julien Danjou
parent e300ee4920
commit 294c9f455c
2 changed files with 21 additions and 20 deletions

View File

@ -9,7 +9,7 @@ AC_CONFIG_SRCDIR([xcb.pc.in])
AM_INIT_AUTOMAKE([foreign dist-bzip2]) AM_INIT_AUTOMAKE([foreign dist-bzip2])
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
AM_PATH_PYTHON([2.5]) AM_PATH_PYTHON([2.6])
PKG_CHECK_MODULES(CHECK, [check >= 0.9.4], [HAVE_CHECK=yes], [HAVE_CHECK=no]) PKG_CHECK_MODULES(CHECK, [check >= 0.9.4], [HAVE_CHECK=yes], [HAVE_CHECK=no])
AM_CONDITIONAL(HAVE_CHECK, test x$HAVE_CHECK = xyes) AM_CONDITIONAL(HAVE_CHECK, test x$HAVE_CHECK = xyes)

View File

@ -1,6 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
from xml.etree.cElementTree import * from xml.etree.cElementTree import *
from os.path import basename from os.path import basename
from functools import reduce
import getopt import getopt
import sys import sys
import re import re
@ -323,7 +324,7 @@ def _c_type_setup(self, name, postfix):
field.c_field_type = _t(field.field_type) field.c_field_type = _t(field.field_type)
field.c_field_const_type = ('' if field.type.nmemb == 1 else 'const ') + field.c_field_type field.c_field_const_type = ('' if field.type.nmemb == 1 else 'const ') + field.c_field_type
field.c_field_name = _cpp(field.field_name) field.c_field_name = _cpp(field.field_name)
field.c_subscript = '[%d]' % field.type.nmemb if (field.type.nmemb > 1) else '' field.c_subscript = '[%d]' % field.type.nmemb if (field.type.nmemb and field.type.nmemb > 1) else ''
field.c_pointer = ' ' if field.type.nmemb == 1 else '*' field.c_pointer = ' ' if field.type.nmemb == 1 else '*'
# correct the c_pointer field for variable size non-list types # correct the c_pointer field for variable size non-list types
@ -443,7 +444,7 @@ def _c_helper_field_mapping(complex_type, prefix, flat=False):
else: else:
for f in complex_type.fields: for f in complex_type.fields:
fname = _c_helper_absolute_name(prefix, f) fname = _c_helper_absolute_name(prefix, f)
if all_fields.has_key(f.field_name): if f.field_name in all_fields:
raise Exception("field name %s has been registered before" % f.field_name) raise Exception("field name %s has been registered before" % f.field_name)
all_fields[f.field_name] = (fname, f) all_fields[f.field_name] = (fname, f)
@ -524,7 +525,7 @@ def get_expr_fields(self):
prefix.append(('', '', self)) prefix.append(('', '', self))
all_fields = _c_helper_resolve_field_names (prefix) all_fields = _c_helper_resolve_field_names (prefix)
resolved_fields_names = filter(lambda x: x in all_fields.keys(), unresolved_fields_names) resolved_fields_names = list(filter(lambda x: x in all_fields.keys(), unresolved_fields_names))
if len(unresolved_fields_names) != len(resolved_fields_names): if len(unresolved_fields_names) != len(resolved_fields_names):
raise Exception("could not resolve all fields for %s" % self.name) raise Exception("could not resolve all fields for %s" % self.name)
@ -743,8 +744,8 @@ def _c_serialize_helper_list_field(context, self, field,
param_names = [p[2] for p in params] param_names = [p[2] for p in params]
expr_fields_names = [f.field_name for f in get_expr_fields(field.type)] expr_fields_names = [f.field_name for f in get_expr_fields(field.type)]
resolved = filter(lambda x: x in param_names, expr_fields_names) resolved = list(filter(lambda x: x in param_names, expr_fields_names))
unresolved = filter(lambda x: x not in param_names, expr_fields_names) unresolved = list(filter(lambda x: x not in param_names, expr_fields_names))
field_mapping = {} field_mapping = {}
for r in resolved: for r in resolved:
@ -757,8 +758,8 @@ def _c_serialize_helper_list_field(context, self, field,
field.c_field_name) field.c_field_name)
field_mapping.update(_c_helper_resolve_field_names(prefix)) field_mapping.update(_c_helper_resolve_field_names(prefix))
resolved += filter(lambda x: x in field_mapping, unresolved) resolved += list(filter(lambda x: x in field_mapping, unresolved))
unresolved = filter(lambda x: x not in field_mapping, unresolved) unresolved = list(filter(lambda x: x not in field_mapping, unresolved))
if len(unresolved)>0: if len(unresolved)>0:
raise Exception('could not resolve the length fields required for list %s' % field.c_field_name) raise Exception('could not resolve the length fields required for list %s' % field.c_field_name)
@ -1083,7 +1084,7 @@ def _c_serialize(context, self):
param_str.append("%s%s%s %s%s /**< */" % (indent, typespec, spacing, pointerspec, field_name)) param_str.append("%s%s%s %s%s /**< */" % (indent, typespec, spacing, pointerspec, field_name))
# insert function name # insert function name
param_str[0] = "%s (%s" % (func_name, param_str[0].strip()) param_str[0] = "%s (%s" % (func_name, param_str[0].strip())
param_str = map(lambda x: "%s," % x, param_str) param_str = list(map(lambda x: "%s," % x, param_str))
for s in param_str[:-1]: for s in param_str[:-1]:
_hc(s) _hc(s)
_h("%s);" % param_str[-1].rstrip(',')) _h("%s);" % param_str[-1].rstrip(','))
@ -1159,7 +1160,7 @@ def _c_serialize(context, self):
if not (self.is_switch or self.var_followed_by_fixed_fields): if not (self.is_switch or self.var_followed_by_fixed_fields):
# look if we have to declare an '_aux' variable at all # look if we have to declare an '_aux' variable at all
if len(filter(lambda x: x.find('_aux')!=-1, code_lines))>0: if len(list(filter(lambda x: x.find('_aux')!=-1, code_lines)))>0:
if not self.var_followed_by_fixed_fields: if not self.var_followed_by_fixed_fields:
_c(' const %s *_aux = (%s *)_buffer;', self.c_type, self.c_type) _c(' const %s *_aux = (%s *)_buffer;', self.c_type, self.c_type)
else: else:
@ -2282,9 +2283,9 @@ output = {'open' : c_open,
# Check for the argument that specifies path to the xcbgen python package. # Check for the argument that specifies path to the xcbgen python package.
try: try:
opts, args = getopt.getopt(sys.argv[1:], 'p:') opts, args = getopt.getopt(sys.argv[1:], 'p:')
except getopt.GetoptError, err: except getopt.GetoptError as err:
print str(err) print(err)
print 'Usage: c_client.py [-p path] file.xml' print('Usage: c_client.py [-p path] file.xml')
sys.exit(1) sys.exit(1)
for (opt, arg) in opts: for (opt, arg) in opts:
@ -2295,13 +2296,13 @@ for (opt, arg) in opts:
try: try:
from xcbgen.state import Module from xcbgen.state import Module
except ImportError: except ImportError:
print '' print('''
print 'Failed to load the xcbgen Python package!' Failed to load the xcbgen Python package!
print 'Make sure that xcb/proto installed it on your Python path.' Make sure that xcb/proto installed it on your Python path.
print 'If not, you will need to create a .pth file or define $PYTHONPATH' If not, you will need to create a .pth file or define $PYTHONPATH
print 'to extend the path.' to extend the path.
print 'Refer to the README file in xcb/proto for more info.' Refer to the README file in xcb/proto for more info.
print '' ''')
raise raise
# Parse the xml header # Parse the xml header