[C++-sig] Re: [SPAM] Re: Ellipsis parameter not handled in PYSTE
GameGuy
gameguy at eastlink.ca
Tue Feb 17 19:41:23 CET 2004
I'm not really sure. I guess it depends on your intentions for pyste.
If, for example, pyste is to be used as a tool to help in the creation of C++ files (meaning that
some editing is required after pyste is run), then flagging these cases with warning output and
writing a meaningful member function stub in the .cpp file might be a good solution. That way
programmers can pick up where pyste leaves off.
Alternately, if pyste is to output C++ code that shouldn't be modified, than the guts of the
wrapped member functions must be filled properly. That's difficult to do in a cross-platform way, I
think.
Regardless, I think the output of pyste should always compile.
Below is a pretty quick hack, but I think it produces something that compiles in all ellipsis cases
(it's not very careful with outputting proper warning messages and whatnot, nor is it the most
elegant solution ever ;) ). It isn't complete either, because the variable argument list is
untouched within the wrapped member functions.
Attached are some test files I was using while producing this patch.
I hope this helps,
~Shaun
Index: ClassExporter.py
===================================================================
RCS file: /boost/boost/libs/python/pyste/src/Pyste/ClassExporter.py,v
retrieving revision 1.15
diff -u -r1.15 ClassExporter.py
--- ClassExporter.py 23 Oct 2003 22:56:33 -0000 1.15
+++ ClassExporter.py 17 Feb 2004 18:24:50 -0000
@@ -345,7 +345,7 @@
def IsExportable(m):
'Returns true if the given method is exportable by this routine'
ignore = (Constructor, ClassOperator, Destructor)
- return isinstance(m, Function) and not isinstance(m, ignore) and not m.virtual
+ return isinstance(m, Function) and not isinstance(m, ignore) and not m.virtual and not
m.has_ellipsis
methods = [x for x in self.public_members if IsExportable(x)]
methods.extend(self.GetAddedMethods())
@@ -645,12 +645,18 @@
if count is None:
count = len(m.parameters)
param_names = ['p%i' % i for i in range(count)]
+ has_ellipsis = False
+ if count > 0 and type(m.parameters[count-1]) == EllipsisType:
+ param_names[count-1] = ''
+ has_ellipsis = True
param_types = [x.FullName() for x in m.parameters[:count]]
params = ['%s %s' % (t, n) for t, n in zip(param_types, param_names)]
#for i, p in enumerate(m.parameters[:count]):
# if p.default is not None:
# #params[i] += '=%s' % p.default
# params[i] += '=%s' % (p.name + '()')
+ if has_ellipsis:
+ param_names = param_names[:-1]
params = ', '.join(params)
return params, param_names, param_types
@@ -856,7 +862,7 @@
for method in self.virtual_methods:
exclude = self.info[method.name].exclude
# generate definitions only for public methods and non-abstract methods
- if method.visibility == Scope.public and not exclude:
+ if method.visibility == Scope.public and not exclude and not method.has_ellipsis:
defs.extend(self.MethodDefinition(method))
return defs
Index: FunctionExporter.py
===================================================================
RCS file: /boost/boost/libs/python/pyste/src/Pyste/FunctionExporter.py,v
retrieving revision 1.7
diff -u -r1.7 FunctionExporter.py
--- FunctionExporter.py 6 Oct 2003 19:10:50 -0000 1.7
+++ FunctionExporter.py 17 Feb 2004 18:24:50 -0000
@@ -33,6 +33,8 @@
def ExportDeclaration(self, decl, unique, codeunit):
+ if decl.has_ellipsis:
+ return
name = self.info.rename or decl.name
defs = namespaces.python + 'def("%s", ' % name
wrapper = self.info.wrapper
Index: GCCXMLParser.py
===================================================================
RCS file: /boost/boost/libs/python/pyste/src/Pyste/GCCXMLParser.py,v
retrieving revision 1.3
diff -u -r1.3 GCCXMLParser.py
--- GCCXMLParser.py 6 Oct 2003 19:10:50 -0000 1.3
+++ GCCXMLParser.py 17 Feb 2004 18:24:50 -0000
@@ -190,12 +190,19 @@
def GetArguments(self, element):
args = []
+ has_ellipsis = False
for child in element:
if child.tag == 'Argument':
type = self.GetType(child.get('type'))
type.default = child.get('default')
args.append(type)
- return args
+ elif child.tag == 'Ellipsis':
+ args.append(EllipsisType())
+ has_ellipsis = True
+ else:
+ print "Warning: Unhandled '"+child.tag+"' in", element.get('name'),
+ print "from", self.GetLocation(element.get('location'))
+ return args, has_ellipsis
def GetExceptions(self, exception_list):
@@ -216,10 +223,11 @@
returns = self.GetType(element.get('returns'))
namespace = self.GetDecl(element.get('context'))
location = self.GetLocation(element.get('location'))
- params = self.GetArguments(element)
+ params, has_ellipsis = self.GetArguments(element)
incomplete = bool(int(element.get('incomplete', 0)))
throws = self.GetExceptions(element.get('throw', None))
function = functionType(name, namespace, returns, params, throws)
+ function.has_ellipsis = has_ellipsis
function.location = location
self.AddDecl(function)
self.Update(id, function)
@@ -354,16 +362,18 @@
def ParseFunctionType(self, id, element):
result = self.GetType(element.get('returns'))
- args = self.GetArguments(element)
+ args, has_ellipsis = self.GetArguments(element)
func = FunctionType(result, args)
+ func.has_ellipsis = has_ellipsis
self.Update(id, func)
def ParseMethodType(self, id, element):
class_ = self.GetDecl(element.get('basetype')).FullName()
result = self.GetType(element.get('returns'))
- args = self.GetArguments(element)
+ args, has_ellipsis = self.GetArguments(element)
method = MethodType(result, args, class_)
+ method.has_ellipsis = has_ellipsis
self.Update(id, method)
@@ -390,9 +400,10 @@
const = bool(int(element.get('const', '0')))
location = self.GetLocation(element.get('location'))
throws = self.GetExceptions(element.get('throw', None))
- params = self.GetArguments(element)
+ params, has_ellipsis = self.GetArguments(element)
method = methodType(
name, classname, result, params, visib, virtual, abstract, static, const, throws)
+ method.has_ellipsis = has_ellipsis
method.location = location
self.Update(id, method)
@@ -406,8 +417,9 @@
visib = element.get('access', Scope.public)
classname = self.GetDecl(element.get('context')).FullName()
location = self.GetLocation(element.get('location'))
- params = self.GetArguments(element)
+ params, has_ellipsis = self.GetArguments(element)
ctor = Constructor(name, classname, params, visib)
+ ctor.has_ellipsis = has_ellipsis
ctor.location = location
self.Update(id, ctor)
Index: declarations.py
===================================================================
RCS file: /boost/boost/libs/python/pyste/src/Pyste/declarations.py,v
retrieving revision 1.6
diff -u -r1.6 declarations.py
--- declarations.py 6 Oct 2003 19:10:50 -0000 1.6
+++ declarations.py 17 Feb 2004 18:24:50 -0000
@@ -486,6 +486,17 @@
#==============================================================================
+# EllipsisType
+#==============================================================================
+class EllipsisType(Type):
+ 'An ellipsis argument.'
+
+ def __init__(self):
+ Type.__init__(self, "...", False, None)
+
+
+
+#==============================================================================
# FunctionType
#==============================================================================
class FunctionType(Type):
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: Foo.cpp
URL: <http://mail.python.org/pipermail/cplusplus-sig/attachments/20040217/19249cac/attachment.txt>
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: Foo.pyste
URL: <http://mail.python.org/pipermail/cplusplus-sig/attachments/20040217/19249cac/attachment-0001.txt>
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: Foo.h
URL: <http://mail.python.org/pipermail/cplusplus-sig/attachments/20040217/19249cac/attachment-0002.txt>
More information about the Cplusplus-sig
mailing list