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])
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])
AM_CONDITIONAL(HAVE_CHECK, test x$HAVE_CHECK = xyes)

View File

@ -1,6 +1,7 @@
#!/usr/bin/env python
from xml.etree.cElementTree import *
from os.path import basename
from functools import reduce
import getopt
import sys
import re
@ -323,7 +324,7 @@ def _c_type_setup(self, name, postfix):
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_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 '*'
# 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:
for f in complex_type.fields:
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)
all_fields[f.field_name] = (fname, f)
@ -524,7 +525,7 @@ def get_expr_fields(self):
prefix.append(('', '', self))
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):
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]
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)
unresolved = filter(lambda x: x not in param_names, expr_fields_names)
resolved = list(filter(lambda x: x in param_names, expr_fields_names))
unresolved = list(filter(lambda x: x not in param_names, expr_fields_names))
field_mapping = {}
for r in resolved:
@ -757,8 +758,8 @@ def _c_serialize_helper_list_field(context, self, field,
field.c_field_name)
field_mapping.update(_c_helper_resolve_field_names(prefix))
resolved += filter(lambda x: x in field_mapping, unresolved)
unresolved = filter(lambda x: x not in field_mapping, unresolved)
resolved += list(filter(lambda x: x in field_mapping, unresolved))
unresolved = list(filter(lambda x: x not in field_mapping, unresolved))
if len(unresolved)>0:
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))
# insert function name
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]:
_hc(s)
_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):
# 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:
_c(' const %s *_aux = (%s *)_buffer;', self.c_type, self.c_type)
else:
@ -2282,9 +2283,9 @@ output = {'open' : c_open,
# Check for the argument that specifies path to the xcbgen python package.
try:
opts, args = getopt.getopt(sys.argv[1:], 'p:')
except getopt.GetoptError, err:
print str(err)
print 'Usage: c_client.py [-p path] file.xml'
except getopt.GetoptError as err:
print(err)
print('Usage: c_client.py [-p path] file.xml')
sys.exit(1)
for (opt, arg) in opts:
@ -2295,13 +2296,13 @@ for (opt, arg) in opts:
try:
from xcbgen.state import Module
except ImportError:
print ''
print 'Failed to load the xcbgen Python package!'
print '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'
print 'to extend the path.'
print 'Refer to the README file in xcb/proto for more info.'
print ''
print('''
Failed to load the xcbgen Python package!
Make sure that xcb/proto installed it on your Python path.
If not, you will need to create a .pth file or define $PYTHONPATH
to extend the path.
Refer to the README file in xcb/proto for more info.
''')
raise
# Parse the xml header