2
0
mirror of https://github.com/boostorg/python.git synced 2026-01-19 16:32:16 +00:00

- Various bug fixes

- Changed the internal code to the way it was


[SVN r18941]
This commit is contained in:
Bruno da Silva de Oliveira
2003-07-04 22:47:27 +00:00
parent d476e67067
commit ba0fcd27c3
30 changed files with 471 additions and 421 deletions

View File

@@ -1,3 +1,8 @@
4 July 2003
Applied patch that solved a bug in ClassExporter and added a distutils install
script (install/setup.py), both contributed by Prabhu Ramachandran.
Thanks Prabhu!
2 July 2003
Jim Wilson found a bug where types like "char**" were being interpreted as
"char*". Thanks Jim!

View File

@@ -6,3 +6,5 @@
- Expose programmability to the Pyste files (listing members of a class, for
instance)
- Virtual operators

4
pyste/install/pyste.py Normal file
View File

@@ -0,0 +1,4 @@
#!/usr/bin/env python
from Pyste import pyste
pyste.main()

18
pyste/install/setup.py Normal file
View File

@@ -0,0 +1,18 @@
# contributed by Prabhu Ramachandran
from distutils.core import setup
import sys
setup (name = "Pyste",
version = "0.9.7",
description = "Pyste - Python Semi-Automatic Exporter",
maintainer = "Bruno da Silva de Oliveira",
maintainer_email = "nicodemus@globalite.com.br",
licence = "Boost License",
long_description = "Pyste is a Boost.Python code generator",
url = "http://www.boost.org/libs/python/pyste/index.html",
platforms = ['Any'],
packages = ['Pyste'],
scripts = ['pyste.py'],
package_dir = {'Pyste': '../src/Pyste'},
)

View File

@@ -46,24 +46,24 @@ class ClassExporter(Exporter):
def ScopeName(self):
return makeid(self.class_._FullName()) + '_scope'
return makeid(self.class_.FullName()) + '_scope'
def Unit(self):
return makeid(self.class_._name)
return makeid(self.class_.name)
def Name(self):
return self.class_._FullName()
return self.class_.FullName()
def SetDeclarations(self, declarations):
Exporter.SetDeclarations(self, declarations)
decl = self.GetDeclaration(self.info.name)
if isinstance(decl, Typedef):
self.class_ = self.GetDeclaration(decl._type._name)
self.class_ = self.GetDeclaration(decl.type.name)
if not self.info.rename:
self.info.rename = decl._name
self.info.rename = decl.name
else:
self.class_ = decl
self.class_ = copy.deepcopy(self.class_)
@@ -72,10 +72,10 @@ class ClassExporter(Exporter):
def ClassBases(self):
all_bases = []
for level in self.class_._hierarchy:
for level in self.class_.hierarchy:
for base in level:
all_bases.append(base)
return [self.GetDeclaration(x._name) for x in all_bases]
return [self.GetDeclaration(x.name) for x in all_bases]
def Order(self):
@@ -83,7 +83,7 @@ class ClassExporter(Exporter):
bases' bases. Do this because base classes must be instantialized
before the derived classes in the module definition.
'''
return '%s_%s' % (len(self.ClassBases()), self.class_._FullName())
return '%s_%s' % (len(self.ClassBases()), self.class_.FullName())
def Export(self, codeunit, exported_names):
@@ -113,23 +113,23 @@ class ClassExporter(Exporter):
'''
valid_members = (Method, ClassVariable, NestedClass, ClassOperator,
ConverterOperator, ClassEnumeration)
for level in self.class_._hierarchy:
for level in self.class_.hierarchy:
level_exported = False
for base in level:
base = self.GetDeclaration(base._name)
if base._FullName() not in exported_names:
base = self.GetDeclaration(base.name)
if base.FullName() not in exported_names:
for member in base:
if type(member) in valid_members:
member = copy.deepcopy(member)
#if type(member) not in (ClassVariable,:
# member.class_ = self.class_._FullName()
self.class_._AddMember(member)
# member.class_ = self.class_.FullName()
self.class_.AddMember(member)
else:
level_exported = True
if level_exported:
break
def IsValid(member):
return isinstance(member, valid_members) and member._visibility == Scope.public
return isinstance(member, valid_members) and member.visibility == Scope.public
self.public_members = [x for x in self.class_ if IsValid(x)]
@@ -196,19 +196,19 @@ class ClassExporter(Exporter):
def ExportBasics(self):
'Export the name of the class and its class_ statement'
self.Add('template', self.class_._FullName())
name = self.info.rename or self.class_._name
self.Add('template', self.class_.FullName())
name = self.info.rename or self.class_.name
self.Add('constructor', '"%s"' % name)
def ExportBases(self, exported_names):
'Expose the bases of the class into the template section'
hierarchy = self.class_._hierarchy
hierarchy = self.class_.hierarchy
for level in hierarchy:
exported = []
for base in level:
if base._visibility == Scope.public and base._name in exported_names:
exported.append(base._name)
if base.visibility == Scope.public and base.name in exported_names:
exported.append(base.name)
if exported:
code = namespaces.python + 'bases< %s > ' % (', '.join(exported))
self.Add('template', code)
@@ -223,9 +223,9 @@ class ClassExporter(Exporter):
def init_code(cons):
'return the init<>() code for the given contructor'
param_list = [p._FullName() for p in cons._parameters]
min_params_list = param_list[:cons._minArgs]
max_params_list = param_list[cons._minArgs:]
param_list = [p.FullName() for p in cons.parameters]
min_params_list = param_list[:cons.minArgs]
max_params_list = param_list[cons.minArgs:]
min_params = ', '.join(min_params_list)
max_params = ', '.join(max_params_list)
init = py_ns + 'init< '
@@ -240,9 +240,9 @@ class ClassExporter(Exporter):
constructors = [x for x in self.public_members if isinstance(x, Constructor)]
self.constructors = constructors[:]
# don't export the copy constructor if the class is abstract
if self.class_._abstract:
if self.class_.abstract:
for cons in constructors:
if cons._IsCopy():
if cons.IsCopy():
constructors.remove(cons)
break
if not constructors:
@@ -252,7 +252,7 @@ class ClassExporter(Exporter):
# write the constructor with less parameters to the constructor section
smaller = None
for cons in constructors:
if smaller is None or len(cons._parameters) < len(smaller._parameters):
if smaller is None or len(cons.parameters) < len(smaller.parameters):
smaller = cons
assert smaller is not None
self.Add('constructor', init_code(smaller))
@@ -262,7 +262,7 @@ class ClassExporter(Exporter):
code = '.def(%s)' % init_code(cons)
self.Add('inside', code)
# check if the class is copyable
if not self.class_._HasCopyConstructor() or self.class_._abstract:
if not self.class_.HasCopyConstructor() or self.class_.abstract:
self.Add('template', namespaces.boost + 'noncopyable')
@@ -270,11 +270,11 @@ class ClassExporter(Exporter):
'Export the variables of the class, both static and simple variables'
vars = [x for x in self.public_members if isinstance(x, Variable)]
for var in vars:
if self.info[var._name].exclude:
if self.info[var.name].exclude:
continue
name = self.info[var._name].rename or var._name
fullname = var._FullName()
if var._type._const:
name = self.info[var.name].rename or var.name
fullname = var.FullName()
if var.type.const:
def_ = '.def_readonly'
else:
def_ = '.def_readwrite'
@@ -284,8 +284,8 @@ class ClassExporter(Exporter):
def OverloadName(self, method):
'Returns the name of the overloads struct for the given method'
name = makeid(method._FullName())
overloads = '_overloads_%i_%i' % (method._minArgs, method._maxArgs)
name = makeid(method.FullName())
overloads = '_overloads_%i_%i' % (method.minArgs, method.maxArgs)
return name + overloads
@@ -307,13 +307,13 @@ class ClassExporter(Exporter):
declared = {}
def DeclareOverloads(m):
'Declares the macro for the generation of the overloads'
if (isinstance(m, Method) and m._static) or type(m) == Function:
func = m._FullName()
if (isinstance(m, Method) and m.static) or type(m) == Function:
func = m.FullName()
macro = 'BOOST_PYTHON_FUNCTION_OVERLOADS'
else:
func = m._name
func = m.name
macro = 'BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS'
code = '%s(%s, %s, %i, %i)\n' % (macro, self.OverloadName(m), func, m._minArgs, m._maxArgs)
code = '%s(%s, %s, %i, %i)\n' % (macro, self.OverloadName(m), func, m.minArgs, m.maxArgs)
if code not in declared:
declared[code] = True
self.Add('declaration', code)
@@ -322,29 +322,29 @@ class ClassExporter(Exporter):
def Pointer(m):
'returns the correct pointer declaration for the method m'
# check if this method has a wrapper set for him
wrapper = self.info[m._name].wrapper
wrapper = self.info[m.name].wrapper
if wrapper:
return '&' + wrapper.FullName()
else:
return m._PointerDeclaration()
return m.PointerDeclaration()
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
methods = [x for x in self.public_members if IsExportable(x)]
methods.extend(self.GetAddedMethods())
for method in methods:
method_info = self.info[method._name]
method_info = self.info[method.name]
# skip this method if it was excluded by the user
if method_info.exclude:
continue
# rename the method if the user requested
name = method_info.rename or method._name
name = method_info.rename or method.name
# warn the user if this method needs a policy and doesn't have one
method_info.policy = exporterutils.HandlePolicy(method, method_info.policy)
@@ -355,7 +355,7 @@ class ClassExporter(Exporter):
policy = ', %s%s()' % (namespaces.python, policy.Code())
# check for overloads
overload = ''
if method._minArgs != method._maxArgs:
if method.minArgs != method.maxArgs:
# add the overloads for this method
DeclareOverloads(method)
overload_name = self.OverloadName(method)
@@ -369,7 +369,7 @@ class ClassExporter(Exporter):
code += ')'
self.Add('inside', code)
# static method
if isinstance(method, Method) and method._static:
if isinstance(method, Method) and method.static:
code = '.staticmethod("%s")' % name
self.Add('inside', code)
# add wrapper code if this method has one
@@ -382,15 +382,15 @@ class ClassExporter(Exporter):
'''Make all methods that the user indicated to no_override no more virtual, delegating their
export to the ExportMethods routine'''
for member in self.class_:
if type(member) == Method and member._virtual:
member._virtual = not self.info[member._name].no_override
if type(member) == Method and member.virtual:
member.virtual = not self.info[member.name].no_override
def ExportVirtualMethods(self):
# check if this class has any virtual methods
has_virtual_methods = False
for member in self.class_:
if type(member) == Method and member._virtual:
if type(member) == Method and member.virtual:
has_virtual_methods = True
break
@@ -436,26 +436,26 @@ class ClassExporter(Exporter):
for decl in self.declarations:
if isinstance(decl, Operator):
# check if one of the params is this class
for param in decl._parameters:
if param._name == self.class_._FullName():
for param in decl.parameters:
if param.name == self.class_.FullName():
operators.append(decl)
break
return operators
def GetOperand(param):
'Returns the operand of this parameter (either "self", or "other<type>")'
if param._name == self.class_._FullName():
if param.name == self.class_.FullName():
return namespaces.python + 'self'
else:
return namespaces.python + ('other< %s >()' % param._name)
return namespaces.python + ('other< %s >()' % param.name)
def HandleSpecialOperator(operator):
# gatter information about the operator and its parameters
result_name = operator._result._name
result_name = operator.result.name
param1_name = ''
if operator._parameters:
param1_name = operator._parameters[0]._name
if operator.parameters:
param1_name = operator.parameters[0].name
# check for str
ostream = 'basic_ostream'
@@ -473,21 +473,21 @@ class ClassExporter(Exporter):
frees = GetFreeOperators()
members = [x for x in self.public_members if type(x) == ClassOperator]
all_operators = frees + members
operators = [x for x in all_operators if not self.info['operator'][x._name].exclude]
operators = [x for x in all_operators if not self.info['operator'][x.name].exclude]
for operator in operators:
# gatter information about the operator, for use later
wrapper = self.info['operator'][operator._name].wrapper
wrapper = self.info['operator'][operator.name].wrapper
if wrapper:
pointer = '&' + wrapper.FullName()
if wrapper.code:
self.Add('declaration', wrapper.code)
else:
pointer = operator._PointerDeclaration()
rename = self.info['operator'][operator._name].rename
pointer = operator.PointerDeclaration()
rename = self.info['operator'][operator.name].rename
# check if this operator will be exported as a method
export_as_method = wrapper or rename or operator._name in self.BOOST_RENAME_OPERATORS
export_as_method = wrapper or rename or operator.name in self.BOOST_RENAME_OPERATORS
# check if this operator has a special representation in boost
special_code = HandleSpecialOperator(operator)
@@ -499,9 +499,9 @@ class ClassExporter(Exporter):
if wrapper:
rename = wrapper.name
else:
rename = self.BOOST_RENAME_OPERATORS[operator._name]
rename = self.BOOST_RENAME_OPERATORS[operator.name]
policy = ''
policy_obj = self.info['operator'][operator._name].policy
policy_obj = self.info['operator'][operator.name].policy
if policy_obj:
policy = ', %s()' % policy_obj.Code()
self.Add('inside', '.def("%s", %s%s)' % (rename, pointer, policy))
@@ -509,24 +509,24 @@ class ClassExporter(Exporter):
elif has_special_representation:
self.Add('inside', special_code)
elif operator._name in self.BOOST_SUPPORTED_OPERATORS:
elif operator.name in self.BOOST_SUPPORTED_OPERATORS:
# export this operator using boost's facilities
op = operator
is_unary = isinstance(op, Operator) and len(op._parameters) == 1 or\
isinstance(op, ClassOperator) and len(op._parameters) == 0
is_unary = isinstance(op, Operator) and len(op.parameters) == 1 or\
isinstance(op, ClassOperator) and len(op.parameters) == 0
if is_unary:
self.Add('inside', '.def( %s%sself )' % \
(operator._name, namespaces.python))
(operator.name, namespaces.python))
else:
# binary operator
if len(operator._parameters) == 2:
left_operand = GetOperand(operator._parameters[0])
right_operand = GetOperand(operator._parameters[1])
if len(operator.parameters) == 2:
left_operand = GetOperand(operator.parameters[0])
right_operand = GetOperand(operator.parameters[1])
else:
left_operand = namespaces.python + 'self'
right_operand = GetOperand(operator._parameters[0])
right_operand = GetOperand(operator.parameters[0])
self.Add('inside', '.def( %s %s %s )' % \
(left_operand, operator._name, right_operand))
(left_operand, operator.name, right_operand))
# export the converters.
# export them as simple functions with a pre-determined name
@@ -534,8 +534,8 @@ class ClassExporter(Exporter):
converters = [x for x in self.public_members if type(x) == ConverterOperator]
def ConverterMethodName(converter):
result_fullname = converter._result._FullName()
result_name = converter._result._name
result_fullname = converter.result.FullName()
result_name = converter.result.name
for regex, method_name in self.SPECIAL_CONVERTERS.items():
if regex.match(result_fullname):
return method_name
@@ -545,7 +545,7 @@ class ClassExporter(Exporter):
return 'to_' + result_name
for converter in converters:
info = self.info['operator'][converter._result._FullName()]
info = self.info['operator'][converter.result.FullName()]
# check if this operator should be excluded
if info.exclude:
continue
@@ -554,7 +554,7 @@ class ClassExporter(Exporter):
if info.rename or not special_code:
# export as method
name = info.rename or ConverterMethodName(converter)
pointer = converter._PointerDeclaration()
pointer = converter.PointerDeclaration()
policy_code = ''
if info.policy:
policy_code = ', %s()' % info.policy.Code()
@@ -568,9 +568,9 @@ class ClassExporter(Exporter):
def ExportNestedClasses(self, exported_names):
nested_classes = [x for x in self.public_members if isinstance(x, NestedClass)]
for nested_class in nested_classes:
nested_info = self.info[nested_class._name]
nested_info = self.info[nested_class.name]
nested_info.include = self.info.include
nested_info.name = nested_class._FullName()
nested_info.name = nested_class.FullName()
exporter = ClassExporter(nested_info)
exporter.SetDeclarations(self.declarations)
codeunit = SingleCodeUnit(None, None)
@@ -581,9 +581,9 @@ class ClassExporter(Exporter):
def ExportNestedEnums(self):
nested_enums = [x for x in self.public_members if isinstance(x, ClassEnumeration)]
for enum in nested_enums:
enum_info = self.info[enum._name]
enum_info = self.info[enum.name]
enum_info.include = self.info.include
enum_info.name = enum._FullName()
enum_info.name = enum.FullName()
exporter = EnumExporter(enum_info)
exporter.SetDeclarations(self.declarations)
codeunit = SingleCodeUnit(None, None)
@@ -594,7 +594,7 @@ class ClassExporter(Exporter):
def ExportSmartPointer(self):
smart_ptr = self.info.smart_ptr
if smart_ptr:
class_name = self.class_._FullName()
class_name = self.class_.FullName()
smart_ptr = smart_ptr % class_name
self.Add('scope', '%s::register_ptr_to_python< %s >();' % (namespaces.python, smart_ptr))
@@ -604,8 +604,8 @@ class ClassExporter(Exporter):
methods = [x for x in self.public_members if isinstance(x, Method)]
for method in methods:
return_opaque_policy = return_value_policy(return_opaque_pointer)
if self.info[method._name].policy == return_opaque_policy:
macro = 'BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID(%s)' % method._result._name
if self.info[method.name].policy == return_opaque_policy:
macro = 'BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID(%s)' % method.result.name
if macro not in self._exported_opaque_pointers:
self.Add('declaration-outside', macro)
self._exported_opaque_pointers[macro] = 1
@@ -617,9 +617,9 @@ class ClassExporter(Exporter):
def _ParamsInfo(m, count=None):
if count is None:
count = len(m._parameters)
count = len(m.parameters)
param_names = ['p%i' % i for i in range(count)]
param_types = [x._FullName() for x in m._parameters[:count]]
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:
@@ -636,7 +636,7 @@ class _VirtualWrapperGenerator(object):
self.class_ = class_
self.bases = bases[:]
self.info = info
self.wrapper_name = makeid(class_._FullName()) + '_Wrapper'
self.wrapper_name = makeid(class_.FullName()) + '_Wrapper'
self.virtual_methods = None
self._method_count = {}
self.GenerateVirtualMethods()
@@ -647,9 +647,9 @@ class _VirtualWrapperGenerator(object):
number of default arguments. Always returns at least one name, and return from
the one with most arguments to the one with the least.
'''
base_name = 'default_' + method._name
minArgs = method._minArgs
maxArgs = method._maxArgs
base_name = 'default_' + method.name
minArgs = method.minArgs
maxArgs = method.maxArgs
if minArgs == maxArgs:
return [base_name]
else:
@@ -663,18 +663,18 @@ class _VirtualWrapperGenerator(object):
'''
pyste = namespaces.pyste
python = namespaces.python
rename = self.info[method._name].rename or method._name
result = method._result._FullName()
rename = self.info[method.name].rename or method.name
result = method.result.FullName()
return_str = 'return '
if result == 'void':
return_str = ''
params, param_names, param_types = _ParamsInfo(method)
constantness = ''
if method._const:
if method.const:
constantness = ' const'
# call_method callback
decl = indent + '%s %s(%s)%s {\n' % (result, method._name, params, constantness)
decl = indent + '%s %s(%s)%s {\n' % (result, method.name, params, constantness)
param_names_str = ', '.join(param_names)
if param_names_str:
param_names_str = ', ' + param_names_str
@@ -685,19 +685,19 @@ class _VirtualWrapperGenerator(object):
# default implementations (with overloading)
def DefaultImpl(method, param_names):
'Return the body of a default implementation wrapper'
wrapper = self.info[method._name].wrapper
wrapper = self.info[method.name].wrapper
if not wrapper:
# return the default implementation of the class
return '%s%s::%s(%s);\n' % \
(return_str, self.class_._FullName(), method._name, ', '.join(param_names))
return '%s%s(%s);\n' % \
(return_str, method.FullName(), ', '.join(param_names))
else:
# return a call for the wrapper
params = ', '.join(['this'] + param_names)
return '%s%s(%s);\n' % (return_str, wrapper.FullName(), params)
if not method._abstract and method._visibility != Scope.private:
minArgs = method._minArgs
maxArgs = method._maxArgs
if not method.abstract and method.visibility != Scope.private:
minArgs = method.minArgs
maxArgs = method.maxArgs
impl_names = self.DefaultImplementationNames(method)
for impl_name, argNum in zip(impl_names, range(minArgs, maxArgs+1)):
params, param_names, param_types = _ParamsInfo(method, argNum)
@@ -713,35 +713,35 @@ class _VirtualWrapperGenerator(object):
statement to export this method.'''
# dont define abstract methods
pyste = namespaces.pyste
rename = self.info[method._name].rename or method._name
rename = self.info[method.name].rename or method.name
default_names = self.DefaultImplementationNames(method)
class_name = self.class_._FullName()
class_name = self.class_.FullName()
wrapper_name = pyste + self.wrapper_name
result = method._result._FullName()
is_method_unique = method._is_unique
result = method.result.FullName()
is_method_unique = method.is_unique
constantness = ''
if method._const:
if method.const:
constantness = ' const'
# create a list of default-impl pointers
minArgs = method._minArgs
maxArgs = method._maxArgs
minArgs = method.minArgs
maxArgs = method.maxArgs
if is_method_unique:
default_pointers = ['&%s::%s' % (wrapper_name, x) for x in default_names]
else:
default_pointers = []
for impl_name, argNum in zip(default_names, range(minArgs, maxArgs+1)):
param_list = [x._FullName() for x in method._parameters[:argNum]]
param_list = [x.FullName() for x in method.parameters[:argNum]]
params = ', '.join(param_list)
signature = '%s (%s::*)(%s)%s' % (result, wrapper_name, params, constantness)
default_pointer = '(%s)&%s::%s' % (signature, wrapper_name, impl_name)
default_pointers.append(default_pointer)
# get the pointer of the method
pointer = method._PointerDeclaration()
pointer = method.PointerDeclaration()
# Add policy to overloaded methods also
policy = self.info[method._name].policy or ''
policy = self.info[method.name].policy or ''
if policy:
policy = ', %s%s()' % (namespaces.python, policy.Code())
@@ -766,14 +766,14 @@ class _VirtualWrapperGenerator(object):
'''
def IsVirtual(m):
return type(m) is Method and \
m._virtual and \
m._visibility != Scope.private
m.virtual and \
m.visibility != Scope.private
all_methods = [x for x in self.class_ if IsVirtual(x)]
for base in self.bases:
base_methods = [copy.deepcopy(x) for x in base if IsVirtual(x)]
for base_method in base_methods:
base_method.class_ = self.class_._FullName()
base_method.class_ = self.class_.FullName()
all_methods.append(base_method)
# extract the virtual methods, avoiding duplications. The duplication
@@ -781,16 +781,16 @@ class _VirtualWrapperGenerator(object):
# that inherited members are correctly excluded if the subclass overrides
# them.
def MethodSig(method):
if method._const:
if method.const:
const = 'const'
else:
const = ''
if method._result:
result = method._result._FullName()
if method.result:
result = method.result.FullName()
else:
result = ''
params = ', '.join([x._FullName() for x in method._parameters])
return '%s %s(%s) %s' % (result, method._name, params, const)
params = ', '.join([x.FullName() for x in method.parameters])
return '%s %s(%s) %s' % (result, method.name, params, const)
self.virtual_methods = []
already_added = {}
@@ -802,15 +802,15 @@ class _VirtualWrapperGenerator(object):
def Constructors(self):
return self.class_._Constructors(publics_only=True)
return self.class_.Constructors(publics_only=True)
def GenerateDefinitions(self):
defs = []
for method in self.virtual_methods:
exclude = self.info[method._name].exclude
exclude = self.info[method.name].exclude
# generate definitions only for public methods and non-abstract methods
if method._visibility == Scope.public and not method._abstract and not exclude:
if method.visibility == Scope.public and not method.abstract and not exclude:
defs.extend(self.MethodDefinition(method))
return defs
@@ -819,13 +819,13 @@ class _VirtualWrapperGenerator(object):
'Return the wrapper for this class'
# generate the class code
class_name = self.class_._FullName()
class_name = self.class_.FullName()
code = 'struct %s: %s\n' % (self.wrapper_name, class_name)
code += '{\n'
# generate constructors (with the overloads for each one)
for cons in self.Constructors(): # only public constructors
minArgs = cons._minArgs
maxArgs = cons._maxArgs
minArgs = cons.minArgs
maxArgs = cons.maxArgs
# from the min number of arguments to the max number, generate
# all version of the given constructor
cons_code = ''
@@ -841,7 +841,7 @@ class _VirtualWrapperGenerator(object):
# generate the body
body = []
for method in self.virtual_methods:
if not self.info[method._name].exclude:
if not self.info[method.name].exclude:
body.append(self.Declaration(method, indent))
body = '\n'.join(body)
code += body + '\n'

View File

@@ -21,16 +21,16 @@ class EnumExporter(Exporter):
if not self.info.exclude:
indent = self.INDENT
in_indent = self.INDENT*2
rename = self.info.rename or self.enum._name
full_name = self.enum._FullName()
rename = self.info.rename or self.enum.name
full_name = self.enum.FullName()
if rename == "$_0" or rename == '._0':
full_name = "int"
rename = "unnamed"
code = indent + namespaces.python
code += 'enum_< %s >("%s")\n' % (full_name, rename)
for name in self.enum._values:
for name in self.enum.values:
rename = self.info[name].rename or name
value_fullname = self.enum._ValueFullName(name)
value_fullname = self.enum.ValueFullName(name)
code += in_indent + '.value("%s", %s)\n' % (rename, value_fullname)
code += indent + ';\n\n'
codeunit.Write('module', code)

View File

@@ -55,7 +55,7 @@ class Exporter:
def GetDeclarations(self, fullname):
decls = []
for decl in self.declarations:
if decl._FullName() == fullname:
if decl.FullName() == fullname:
decls.append(decl)
if not decls:
raise RuntimeError, 'no %s declaration found!' % fullname

View File

@@ -28,13 +28,13 @@ class FunctionExporter(Exporter):
def ExportDeclaration(self, decl, unique, codeunit):
name = self.info.rename or decl._name
name = self.info.rename or decl.name
defs = namespaces.python + 'def("%s", ' % name
wrapper = self.info.wrapper
if wrapper:
pointer = '&' + wrapper.FullName()
else:
pointer = decl._PointerDeclaration()
pointer = decl.PointerDeclaration()
defs += pointer
defs += self.PolicyCode()
overload = self.OverloadName(decl)
@@ -48,9 +48,9 @@ class FunctionExporter(Exporter):
def OverloadName(self, decl):
if decl._minArgs != decl._maxArgs:
if decl.minArgs != decl.maxArgs:
return '%s_overloads_%i_%i' % \
(decl._name, decl._minArgs, decl._maxArgs)
(decl.name, decl.minArgs, decl.maxArgs)
else:
return ''
@@ -61,7 +61,7 @@ class FunctionExporter(Exporter):
overload = self.OverloadName(decl)
if overload and overload not in codes:
code = 'BOOST_PYTHON_FUNCTION_OVERLOADS(%s, %s, %i, %i)' %\
(overload, decl._FullName(), decl._minArgs, decl_.maxArgs)
(overload, decl.FullName(), decl.minArgs, decl_.maxArgs)
codeunit.Write('declaration', code + '\n')
codes[overload] = None
@@ -77,7 +77,7 @@ class FunctionExporter(Exporter):
def ExportOpaquePointer(self, function, codeunit):
if self.info.policy == return_value_policy(return_opaque_pointer):
type = function._result._name
type = function.result.name
macro = 'BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID(%s)' % type
if macro not in self._exported_opaque_pointers:
codeunit.Write('declaration-outside', macro)

View File

@@ -44,12 +44,12 @@ class GCCXMLParser(object):
def AddDecl(self, decl):
if decl._FullName() in self._names:
decl._is_unique= False
if decl.FullName() in self._names:
decl.is_unique= False
for d in self.declarations:
if d._FullName() == decl._FullName():
d._is_unique = False
self._names[decl._FullName()] = 0
if d.FullName() == decl.FullName():
d.is_unique = False
self._names[decl.FullName()] = 0
self.declarations.append(decl)
@@ -117,15 +117,15 @@ class GCCXMLParser(object):
if isinstance(decl, Type):
res = deepcopy(decl)
if const:
res._const = const
res.const = const
if volatile:
res._volatile = volatile
res.volatile = volatile
if restricted:
res._restricted = restricted
res.restricted = restricted
else:
res = Type(decl._FullName(), const)
res._volatile = volatile
res._restricted = restricted
res = Type(decl.FullName(), const)
res.volatile = volatile
res.restricted = restricted
return res
@@ -171,14 +171,14 @@ class GCCXMLParser(object):
if isinstance(context, Class):
self.ParseField(id, element)
elem, decl = self.elements[id]
decl._static = True
decl.static = True
else:
namespace = context
name = element.get('name')
type_ = self.GetType(element.get('type'))
location = self.GetLocation(element.get('location'))
variable = Variable(type_, name, namespace)
variable._location = location
variable.location = location
self.AddDecl(variable)
self.Update(id, variable)
@@ -188,7 +188,7 @@ class GCCXMLParser(object):
for child in element:
if child.tag == 'Argument':
type = self.GetType(child.get('type'))
type._default = child.get('default')
type.default = child.get('default')
args.append(type)
return args
@@ -203,7 +203,7 @@ class GCCXMLParser(object):
params = self.GetArguments(element)
incomplete = bool(int(element.get('incomplete', 0)))
function = functionType(name, namespace, returns, params)
function._location = location
function.location = location
self.AddDecl(function)
self.Update(id, function)
@@ -237,10 +237,10 @@ class GCCXMLParser(object):
# "Unimplemented" tag, but we are not interested in this classes
# anyway
continue
base = Base(decl._FullName(), visib)
base = Base(decl.FullName(), visib)
this_level.append(base)
# normalize with the other levels
for index, level in enumerate(decl._hierarchy):
for index, level in enumerate(decl.hierarchy):
if index < len(next_levels):
next_levels[index] = next_levels[index] + level
else:
@@ -253,14 +253,18 @@ class GCCXMLParser(object):
return hierarchy
def GetMembers(self, members):
def GetMembers(self, member_list):
# members must be a string with the ids of the members
if members is None:
if member_list is None:
return []
memberobjs = []
for member in members.split():
memberobjs.append(self.GetDecl(member))
return memberobjs
members = []
for member in member_list.split():
decl = self.GetDecl(member)
if type(decl) in Class.ValidMemberTypes():
if type(decl) is str:
print decl
members.append(decl)
return members
def ParseClass(self, id, element):
@@ -275,20 +279,22 @@ class GCCXMLParser(object):
# a nested class
visib = element.get('access', Scope.public)
class_ = NestedClass(
name, context._FullName(), visib, [], abstract)
class_._incomplete = incomplete
name, context.FullName(), visib, [], abstract)
class_.incomplete = incomplete
# we have to add the declaration of the class before trying
# to parse its members and bases, to avoid recursion.
self.AddDecl(class_)
class_._location = location
class_.location = location
self.Update(id, class_)
# now we can get the members and the bases
class_._hierarchy = self.GetHierarchy(element.get('bases'))
if class_._hierarchy:
class_._bases = class_._hierarchy[0]
class_.hierarchy = self.GetHierarchy(element.get('bases'))
if class_.hierarchy:
class_.bases = class_.hierarchy[0]
members = self.GetMembers(element.get('members'))
for member in members:
class_._AddMember(member)
if type(member) is str:
print member
class_.AddMember(member)
def ParseStruct(self, id, element):
@@ -305,21 +311,21 @@ class GCCXMLParser(object):
type = self.GetType(element.get('type'))
min = element.get('min')
max = element.get('max')
array = ArrayType(type._name, type._const, min, max)
array = ArrayType(type.name, type.const, min, max)
self.Update(id, array)
def ParseReferenceType(self, id, element):
type = self.GetType(element.get('type'))
expand = not isinstance(type, FunctionType)
ref = ReferenceType(type._name, type._const, None, expand, type._suffix)
ref = ReferenceType(type.name, type.const, None, expand, type.suffix)
self.Update(id, ref)
def ParsePointerType(self, id, element):
type = self.GetType(element.get('type'))
expand = not isinstance(type, FunctionType)
ref = PointerType(type._name, type._const, None, expand, type._suffix)
ref = PointerType(type.name, type.const, None, expand, type.suffix)
self.Update(id, ref)
@@ -331,7 +337,7 @@ class GCCXMLParser(object):
def ParseMethodType(self, id, element):
class_ = self.GetDecl(element.get('basetype'))._FullName()
class_ = self.GetDecl(element.get('basetype')).FullName()
result = self.GetType(element.get('returns'))
args = self.GetArguments(element)
method = MethodType(result, args, class_)
@@ -341,19 +347,19 @@ class GCCXMLParser(object):
def ParseField(self, id, element):
name = element.get('name')
visib = element.get('access', Scope.public)
classname = self.GetDecl(element.get('context'))._FullName()
classname = self.GetDecl(element.get('context')).FullName()
type_ = self.GetType(element.get('type'))
static = bool(int(element.get('extern', '0')))
location = self.GetLocation(element.get('location'))
var = ClassVariable(type_, name, classname, visib, static)
var._location = location
var.location = location
self.Update(id, var)
def ParseMethod(self, id, element, methodType=Method):
name = element.get('name')
result = self.GetType(element.get('returns'))
classname = self.GetDecl(element.get('context'))._FullName()
classname = self.GetDecl(element.get('context')).FullName()
visib = element.get('access', Scope.public)
static = bool(int(element.get('static', '0')))
virtual = bool(int(element.get('virtual', '0')))
@@ -363,7 +369,7 @@ class GCCXMLParser(object):
params = self.GetArguments(element)
method = methodType(
name, classname, result, params, visib, virtual, abstract, static, const)
method._location = location
method.location = location
self.Update(id, method)
@@ -374,22 +380,22 @@ class GCCXMLParser(object):
def ParseConstructor(self, id, element):
name = element.get('name')
visib = element.get('access', Scope.public)
classname = self.GetDecl(element.get('context'))._FullName()
classname = self.GetDecl(element.get('context')).FullName()
location = self.GetLocation(element.get('location'))
params = self.GetArguments(element)
ctor = Constructor(name, classname, params, visib)
ctor._location = location
ctor.location = location
self.Update(id, ctor)
def ParseDestructor(self, id, element):
name = element.get('name')
visib = element.get('access', Scope.public)
classname = self.GetDecl(element.get('context'))._FullName()
classname = self.GetDecl(element.get('context')).FullName()
virtual = bool(int(element.get('virtual', '0')))
location = self.GetLocation(element.get('location'))
des = Destructor(name, classname, visib, virtual)
des._location = location
des.location = location
self.Update(id, des)
@@ -402,7 +408,7 @@ class GCCXMLParser(object):
type = self.GetType(element.get('type'))
context = self.GetDecl(element.get('context'))
if isinstance(context, Class):
context = context._FullName()
context = context.FullName()
typedef = Typedef(type, name, context)
self.Update(id, typedef)
self.AddDecl(typedef)
@@ -417,15 +423,15 @@ class GCCXMLParser(object):
enum = Enumeration(name, context)
else:
visib = element.get('access', Scope.public)
enum = ClassEnumeration(name, context._FullName(), visib)
enum = ClassEnumeration(name, context.FullName(), visib)
self.AddDecl(enum)
enum._location = location
enum.location = location
for child in element:
if child.tag == 'EnumValue':
name = child.get('name')
value = int(child.get('init'))
enum._values[name] = value
enum._incomplete = incomplete
enum.values[name] = value
enum.incomplete = incomplete
self.Update(id, enum)

View File

@@ -32,8 +32,8 @@ class HeaderExporter(Exporter):
header = os.path.normpath(self.parser_header)
for decl in self.declarations:
# check if this declaration is in the header
location = os.path.normpath(decl._location[0])
if location == header and not self.IsInternalName(decl._name):
location = os.path.normpath(decl.location[0])
if location == header and not self.IsInternalName(decl.name):
# ok, check the type of the declaration and export it accordingly
self.HandleDeclaration(decl, codeunit, exported_names)
@@ -57,9 +57,9 @@ class HeaderExporter(Exporter):
def HandleExporter(self, decl, exporter_type, codeunit, exported_names):
# only export complete declarations
if not getattr(decl, "_incomplete", False):
info = self.info[decl._name]
info.name = decl._FullName()
if not decl.incomplete:
info = self.info[decl.name]
info.name = decl.FullName()
info.include = self.info.include
exporter = exporter_type(info)
exporter.SetDeclarations(self.declarations)

View File

@@ -16,7 +16,7 @@ class VarExporter(Exporter):
def Export(self, codeunit, exported_names):
if self.info.exclude: return
decl = self.GetDeclaration(self.info.name)
if not decl._type._const:
if not decl.type.const:
msg = '---> Warning: The global variable "%s" is non-const:\n' \
' changes in Python will not reflect in C++.'
print msg % self.info.name

View File

View File

@@ -8,8 +8,8 @@ Defines classes that represent declarations found in C++ header files.
#==============================================================================
class Declaration(object):
'''Base class for all declarations.
@ivar _name: The name of the declaration.
@ivar _namespace: The namespace of the declaration.
@ivar name: The name of the declaration.
@ivar namespace: The namespace of the declaration.
'''
def __init__(self, name, namespace):
@@ -19,34 +19,33 @@ class Declaration(object):
@type namespace: string
@param namespace: the full namespace where this declaration resides.
'''
self._name = name
self._namespace = namespace
self._location = '', -1 # (filename, line)
self._incomplete = False
self._is_unique = True
self.name = name
self.namespace = namespace
self.location = '', -1 # (filename, line)
self.incomplete = False
self.is_unique = True
def _FullName(self):
def FullName(self):
'''
Returns the full qualified name: "boost::inner::Test"
@rtype: string
@return: The full name of the declaration.
'''
namespace = self._namespace or ''
namespace = self.namespace or ''
if namespace and not namespace.endswith('::'):
namespace += '::'
return namespace + self._name
return namespace + self.name
def __repr__(self):
return '<Declaration %s at %s>' % (self._FullName(), id(self))
return '<Declaration %s at %s>' % (self.FullName(), id(self))
def __str__(self):
return 'Declaration of %s' % self._FullName()
return 'Declaration of %s' % self.FullName()
#==============================================================================
# Class
#==============================================================================
@@ -54,25 +53,26 @@ class Class(Declaration):
'''
Represents a C++ class or struct. Iteration through it yields its members.
@type _abstract: bool
@ivar _abstract: if the class has any abstract methods.
@type abstract: bool
@ivar abstract: if the class has any abstract methods.
@type _bases: tuple
@ivar _bases: tuple with L{Base} instances, representing the most direct
@type bases: tuple
@ivar bases: tuple with L{Base} instances, representing the most direct
inheritance.
@type _hierarchy: list
@ivar _hierarchy: a list of tuples of L{Base} instances, representing
@type hierarchy: list
@ivar hierarchy: a list of tuples of L{Base} instances, representing
the entire hierarchy tree of this object. The first tuple is the parent
classes, and the other ones go up in the hierarchy.
'''
def __init__(self, name, namespace, members, abstract):
Declaration.__init__(self, name, namespace)
self.__members = members
self._abstract = abstract
self._bases = ()
self._hierarchy = ()
self.__member_names = {}
self.abstract = abstract
self.bases = ()
self.hierarchy = ()
self.operator = {}
@@ -82,77 +82,83 @@ class Class(Declaration):
return iter(self.__members)
def _Constructors(self, publics_only=True):
def Constructors(self, publics_only=True):
'''Returns a list of the constructors for this class.
@rtype: list
'''
constructors = []
for member in self:
if isinstance(member, Constructor):
if publics_only and member._visibility != Scope.public:
if publics_only and member.visibility != Scope.public:
continue
constructors.append(member)
return constructors
def _HasCopyConstructor(self):
def HasCopyConstructor(self):
'''Returns true if this class has a public copy constructor.
@rtype: bool
'''
for cons in self._Constructors():
if cons._IsCopy():
for cons in self.Constructors():
if cons.IsCopy():
return True
return False
def _HasDefaultConstructor(self):
def HasDefaultConstructor(self):
'''Returns true if this class has a public default constructor.
@rtype: bool
'''
for cons in self.Constructors():
if cons._IsDefault():
if cons.IsDefault():
return True
return False
def _AddMember(self, member):
slot = getattr(self, member._name, [])
if slot:
member._is_unique = False
for m in slot:
m._is_unique = False
slot.append(member)
setattr(self, member._name, slot)
def AddMember(self, member):
if member.name in self.__member_names:
member.is_unique = False
for m in self:
if m.name == member.name:
m.is_unique = False
else:
member.is_unique = True
self.__member_names[member.name] = 1
self.__members.append(member)
if isinstance(member, ClassOperator):
self.operator[member._name] = member
self.operator[member.name] = member
def ValidMemberTypes():
return (NestedClass, Method, Constructor, Destructor, ClassVariable,
ClassOperator, ConverterOperator, ClassEnumeration)
ValidMemberTypes = staticmethod(ValidMemberTypes)
#==============================================================================
# NestedClass
#==============================================================================
class NestedClass(Class):
'''The declaration of a class/struct inside another class/struct.
@type _class: string
@ivar _class: fullname of the class where this class is contained.
@type class: string
@ivar class: fullname of the class where this class is contained.
@type _visibility: L{Scope}
@ivar _visibility: the visibility of this class.
@type visibility: L{Scope}
@ivar visibility: the visibility of this class.
'''
def __init__(self, name, _class, visib, members, abstract):
def __init__(self, name, class_, visib, members, abstract):
Class.__init__(self, name, None, members, abstract)
self._class = _class
self._visibility = visib
self.class_ = class_
self.visibility = visib
def _FullName(self):
def FullName(self):
'''The full name of this class, like ns::outer::inner.
@rtype: string
'''
return '%s::%s' % (self._class, self._name)
return '%s::%s' % (self.class_, self.name)
#==============================================================================
@@ -179,8 +185,8 @@ class Base:
'''
def __init__(self, name, visibility=Scope.public):
self._name = name
self._visibility = visibility
self.name = name
self.visibility = visibility
#==============================================================================
@@ -195,38 +201,38 @@ class Function(Declaration):
def __init__(self, name, namespace, result, params):
Declaration.__init__(self, name, namespace)
# the result type: instance of Type, or None (constructors)
self._result = result
self.result = result
# the parameters: instances of Type
self._parameters = params
self.parameters = params
def _PointerDeclaration(self, force=False):
def PointerDeclaration(self, force=False):
'''Returns a declaration of a pointer to this function.
@param force: If True, returns a complete pointer declaration regardless
if this function is unique or not.
'''
if self._is_unique and not force:
return '&%s' % self._FullName()
if self.is_unique and not force:
return '&%s' % self.FullName()
else:
result = self._result._FullName()
params = ', '.join([x._FullName() for x in self._parameters])
return '(%s (*)(%s))&%s' % (result, params, self._FullName())
result = self.result.FullName()
params = ', '.join([x.FullName() for x in self.parameters])
return '(%s (*)(%s))&%s' % (result, params, self.FullName())
def _MinArgs(self):
def MinArgs(self):
min = 0
for arg in self._parameters:
if arg._default is None:
for arg in self.parameters:
if arg.default is None:
min += 1
return min
_minArgs = property(_MinArgs)
minArgs = property(MinArgs)
def _MaxArgs(self):
return len(self._parameters)
def MaxArgs(self):
return len(self.parameters)
_maxArgs = property(_MaxArgs)
maxArgs = property(MaxArgs)
@@ -239,11 +245,11 @@ class Operator(Function):
"+".
'''
def _FullName(self):
namespace = self._namespace or ''
def FullName(self):
namespace = self.namespace or ''
if not namespace.endswith('::'):
namespace += '::'
return namespace + 'operator' + self._name
return namespace + 'operator' + self.name
#==============================================================================
@@ -262,36 +268,36 @@ class Method(Function):
def __init__(self, name, class_, result, params, visib, virtual, abstract, static, const):
Function.__init__(self, name, None, result, params)
self._visibility = visib
self._virtual = virtual
self._abstract = abstract
self._static = static
self._class = class_
self._const = const
self.visibility = visib
self.virtual = virtual
self.abstract = abstract
self.static = static
self.class_ = class_
self.const = const
def _FullName(self):
return self._class + '::' + self._name
def FullName(self):
return self.class_ + '::' + self.name
def _PointerDeclaration(self, force=False):
def PointerDeclaration(self, force=False):
'''Returns a declaration of a pointer to this member function.
@param force: If True, returns a complete pointer declaration regardless
if this function is unique or not.
'''
if self._static:
if self.static:
# static methods are like normal functions
return Function._PointerDeclaration(self, force)
if self._is_unique and not force:
return '&%s' % self._FullName()
return Function.PointerDeclaration(self, force)
if self.is_unique and not force:
return '&%s' % self.FullName()
else:
result = self._result._FullName()
params = ', '.join([x._FullName() for x in self._parameters])
result = self.result.FullName()
params = ', '.join([x.FullName() for x in self.parameters])
const = ''
if self._const:
if self.const:
const = 'const'
return '(%s (%s::*)(%s) %s)&%s' %\
(result, self._class, params, const, self._FullName())
(result, self.class_, params, const, self.FullName())
#==============================================================================
@@ -305,22 +311,22 @@ class Constructor(Method):
Method.__init__(self, name, class_, None, params, visib, False, False, False, False)
def _IsDefault(self):
def IsDefault(self):
'''Returns True if this constructor is a default constructor.
'''
return len(self._parameters) == 0 and self._visibility == Scope.public
return len(self.parameters) == 0 and self.visibility == Scope.public
def _IsCopy(self):
def IsCopy(self):
'''Returns True if this constructor is a copy constructor.
'''
if len(self._parameters) != 1:
if len(self.parameters) != 1:
return False
param = self._parameters[0]
class_as_param = self._parameters[0]._name == self._class
param = self.parameters[0]
class_as_param = self.parameters[0].name == self.class_
param_reference = isinstance(param, ReferenceType)
is_public = self._visibility = Scope.public
return param_reference and class_as_param and param._const and is_public
is_public = self.visibility = Scope.public
return param_reference and class_as_param and param.const and is_public
#==============================================================================
@@ -332,8 +338,8 @@ class Destructor(Method):
def __init__(self, name, class_, visib, virtual):
Method.__init__(self, name, class_, None, [], visib, virtual, False, False, False)
def _FullName(self):
return self._class + '::~' + self._name
def FullName(self):
return self.class_ + '::~' + self.name
@@ -343,8 +349,8 @@ class Destructor(Method):
class ClassOperator(Method):
'A custom operator in a class.'
def _FullName(self):
return self._class + '::operator ' + self._name
def FullName(self):
return self.class_ + '::operator ' + self.name
@@ -354,8 +360,8 @@ class ClassOperator(Method):
class ConverterOperator(ClassOperator):
'An operator in the form "operator OtherClass()".'
def _FullName(self):
return self._class + '::operator ' + self._result._FullName()
def FullName(self):
return self.class_ + '::operator ' + self.result.FullName()
@@ -375,12 +381,12 @@ class Type(Declaration):
def __init__(self, name, const=False, default=None, suffix=''):
Declaration.__init__(self, name, None)
# whatever the type is constant or not
self._const = const
self.const = const
# used when the Type is a function argument
self._default = default
self._volatile = False
self._restricted = False
self._suffix = suffix
self.default = default
self.volatile = False
self.restricted = False
self.suffix = suffix
def __repr__(self):
if self.const:
@@ -390,12 +396,12 @@ class Type(Declaration):
return '<Type ' + const + self.name + '>'
def _FullName(self):
if self._const:
def FullName(self):
if self.const:
const = 'const '
else:
const = ''
return const + self._name + self._suffix
return const + self.name + self.suffix
#==============================================================================
@@ -424,7 +430,7 @@ class ReferenceType(Type):
def __init__(self, name, const=False, default=None, expandRef=True, suffix=''):
Type.__init__(self, name, const, default)
if expandRef:
self._suffix = suffix + '&'
self.suffix = suffix + '&'
#==============================================================================
@@ -436,7 +442,7 @@ class PointerType(Type):
def __init__(self, name, const=False, default=None, expandPointer=False, suffix=''):
Type.__init__(self, name, const, default)
if expandPointer:
self._suffix = suffix + '*'
self.suffix = suffix + '*'
#==============================================================================
@@ -462,14 +468,14 @@ class FunctionType(Type):
def __init__(self, result, parameters):
Type.__init__(self, '', False)
self._result = result
self._parameters = parameters
self._name = self._FullName()
self.result = result
self.parameters = parameters
self.name = self.FullName()
def _FullName(self):
full = '%s (*)' % self._result._FullName()
params = [x._FullName() for x in self._parameters]
def FullName(self):
full = '%s (*)' % self.result.FullName()
params = [x.FullName() for x in self.parameters]
full += '(%s)' % ', '.join(params)
return full
@@ -483,13 +489,13 @@ class MethodType(FunctionType):
'''
def __init__(self, result, parameters, class_):
self._class = class_
self.class_ = class_
FunctionType.__init__(self, result, parameters)
def _FullName(self):
full = '%s (%s::*)' % (self._result._FullName(), self._class)
params = [x._FullName() for x in self._parameters]
def FullName(self):
full = '%s (%s::*)' % (self.result.FullName(), self.class_)
params = [x.FullName() for x in self.parameters]
full += '(%s)' % ', '.join(params)
return full
@@ -506,7 +512,7 @@ class Variable(Declaration):
def __init__(self, type, name, namespace):
Declaration.__init__(self, name, namespace)
self._type = type
self.type = type
#==============================================================================
@@ -526,13 +532,13 @@ class ClassVariable(Variable):
def __init__(self, type, name, class_, visib, static):
Variable.__init__(self, type, name, None)
self._visibility = visib
self._static = static
self._class = class_
self.visibility = visib
self.static = static
self.class_ = class_
def _FullName(self):
return self._class + '::' + self._name
def FullName(self):
return self.class_ + '::' + self.name
#==============================================================================
@@ -547,20 +553,22 @@ class Enumeration(Declaration):
def __init__(self, name, namespace):
Declaration.__init__(self, name, namespace)
self._values = {} # dict of str => int
self.values = {} # dict of str => int
def _ValueFullName(self, name):
def ValueFullName(self, name):
'''Returns the full name for a value in the enum.
'''
assert name in self._values
namespace = self._namespace
assert name in self.values
namespace = self.namespace
if namespace:
namespace += '::'
return namespace + name
#==============================================================================
# ClassEnumeration
#==============================================================================
class ClassEnumeration(Enumeration):
'''Represents an enum inside a class.
@@ -570,17 +578,17 @@ class ClassEnumeration(Enumeration):
def __init__(self, name, class_, visib):
Enumeration.__init__(self, name, None)
self._class = class_
self._visibility = visib
self.class_ = class_
self.visibility = visib
def _FullName(self):
return '%s::%s' % (self._class, self._name)
def FullName(self):
return '%s::%s' % (self.class_, self.name)
def _ValueFullName(self, name):
assert name in self._values
return '%s::%s' % (self._class, name)
def ValueFullName(self, name):
assert name in self.values
return '%s::%s' % (self.class_, name)
#==============================================================================
@@ -598,10 +606,13 @@ class Typedef(Declaration):
def __init__(self, type, name, namespace):
Declaration.__init__(self, name, namespace)
self._type = type
self._visibility = Scope.public
self.type = type
self.visibility = Scope.public
#==============================================================================
# Unknown
#==============================================================================

View File

@@ -41,17 +41,17 @@ def HandlePolicy(function, policy):
def IsString(type):
'Return True if the Type instance can be considered a string'
return type._FullName() == 'const char*'
return type.FullName() == 'const char*'
def IsPyObject(type):
return type._FullName() == '_object *' # internal name of PyObject
return type.FullName() == '_object *' # internal name of PyObject
result = function._result
result = function.result
# if the function returns const char*, a policy is not needed
if IsString(result) or IsPyObject(result):
return policy
# if returns a const T&, set the default policy
if policy is None and result._const and isinstance(result, ReferenceType):
if policy is None and result.const and isinstance(result, ReferenceType):
policy = return_value_policy(copy_const_reference)
# basic test if the result type demands a policy
needs_policy = isinstance(result, (ReferenceType, PointerType))
@@ -59,7 +59,7 @@ def HandlePolicy(function, policy):
if needs_policy and policy is None:
global _printed_warnings
warning = '---> Error: %s returns a pointer or a reference, ' \
'but no policy was specified.' % function._FullName()
'but no policy was specified.' % function.FullName()
if warning not in _printed_warnings:
print warning
print

View File

@@ -39,7 +39,7 @@ from policies import *
from CppParser import CppParser, CppParserError
import time
__VERSION__ = '0.9.6'
__VERSION__ = '0.9.7'
def RecursiveIncludes(include):
'Return a list containg the include dir and all its subdirectories'
@@ -154,7 +154,7 @@ def CreateContext():
return context
def Main():
def Begin():
includes, defines, module, out, interfaces, multiple = ParseArguments()
# execute the interface files
for interface in interfaces:
@@ -229,10 +229,14 @@ def UsePsyco():
psyco.profile()
except: pass
if __name__ == '__main__':
def main():
start = time.clock()
UsePsyco()
status = Main()
status = Begin()
print '%0.2f seconds' % (time.clock()-start)
sys.exit(status)
sys.exit(status)
if __name__ == '__main__':
main()

View File

@@ -11,36 +11,36 @@ class Tester(unittest.TestCase):
def TestConstructor(self, class_, method, visib):
self.assert_(isinstance(method, Constructor))
self.assertEqual(method._FullName(), class_._FullName() + '::' + method._name)
self.assertEqual(method._result, None)
self.assertEqual(method._visibility, visib)
self.assert_(not method._virtual)
self.assert_(not method._abstract)
self.assert_(not method._static)
self.assertEqual(method.FullName(), class_.FullName() + '::' + method.name)
self.assertEqual(method.result, None)
self.assertEqual(method.visibility, visib)
self.assert_(not method.virtual)
self.assert_(not method.abstract)
self.assert_(not method.static)
def TestDefaultConstructor(self, class_, method, visib):
self.TestConstructor(class_, method, visib)
self.assert_(method._IsDefault())
self.assert_(method.IsDefault())
def TestCopyConstructor(self, class_, method, visib):
self.TestConstructor(class_, method, visib)
self.assertEqual(len(method._parameters), 1)
param = method._parameters[0]
self.assertEqual(len(method.parameters), 1)
param = method.parameters[0]
self.TestType(
param,
ReferenceType,
class_._FullName(),
'const %s&' % class_._FullName(),
class_.FullName(),
'const %s&' % class_.FullName(),
True)
self.assert_(method._IsCopy())
self.assert_(method.IsCopy())
def TestType(self, type_, classtype_, name, fullname, const):
self.assert_(isinstance(type_, classtype_))
self.assertEqual(type_._name, name)
self.assertEqual(type_._namespace, None)
self.assertEqual(type_._FullName(), fullname)
self.assertEqual(type_._const, const)
self.assertEqual(type_.name, name)
self.assertEqual(type_.namespace, None)
self.assertEqual(type_.FullName(), fullname)
self.assertEqual(type_.const, const)
class ClassBaseTest(Tester):
@@ -51,48 +51,48 @@ class ClassBaseTest(Tester):
def testClass(self):
'test the properties of the class Base'
self.assert_(isinstance(self.base, Class))
self.assert_(self.base._abstract)
self.assert_(self.base.abstract)
def testFoo(self):
'test function foo in class Base'
foo = GetMember(self.base, 'foo')
self.assert_(isinstance(foo, Method))
self.assertEqual(foo._visibility, Scope.public)
self.assert_(foo._virtual)
self.assert_(foo._abstract)
self.failIf(foo._static)
self.assertEqual(foo._class, 'test::Base')
self.failIf(foo._const)
self.assertEqual(foo._FullName(), 'test::Base::foo')
self.assertEqual(foo._result._name, 'void')
self.assertEqual(len(foo._parameters), 1)
param = foo._parameters[0]
self.assertEqual(foo.visibility, Scope.public)
self.assert_(foo.virtual)
self.assert_(foo.abstract)
self.failIf(foo.static)
self.assertEqual(foo.class_, 'test::Base')
self.failIf(foo.const)
self.assertEqual(foo.FullName(), 'test::Base::foo')
self.assertEqual(foo.result.name, 'void')
self.assertEqual(len(foo.parameters), 1)
param = foo.parameters[0]
self.TestType(param, FundamentalType, 'int', 'int', False)
self.assertEqual(foo._namespace, None)
self.assertEqual(foo.namespace, None)
self.assertEqual(
foo._PointerDeclaration(1), '(void (test::Base::*)(int) )&test::Base::foo')
foo.PointerDeclaration(1), '(void (test::Base::*)(int) )&test::Base::foo')
def testX(self):
'test the member x in class Base'
x = GetMember(self.base, 'x')
self.assertEqual(x._class, 'test::Base')
self.assertEqual(x._FullName(), 'test::Base::x')
self.assertEqual(x._namespace, None)
self.assertEqual(x._visibility, Scope.private)
self.TestType(x._type, FundamentalType, 'int', 'int', False)
self.assertEqual(x._static, False)
self.assertEqual(x.class_, 'test::Base')
self.assertEqual(x.FullName(), 'test::Base::x')
self.assertEqual(x.namespace, None)
self.assertEqual(x.visibility, Scope.private)
self.TestType(x.type, FundamentalType, 'int', 'int', False)
self.assertEqual(x.static, False)
def testConstructors(self):
'test constructors in class Base'
constructors = GetMembers(self.base, 'Base')
for cons in constructors:
if len(cons._parameters) == 0:
if len(cons.parameters) == 0:
self.TestDefaultConstructor(self.base, cons, Scope.public)
elif len(cons._parameters) == 1: # copy constructor
elif len(cons.parameters) == 1: # copy constructor
self.TestCopyConstructor(self.base, cons, Scope.public)
elif len(cons._parameters) == 2: # other constructor
intp, floatp = cons._parameters
elif len(cons.parameters) == 2: # other constructor
intp, floatp = cons.parameters
self.TestType(intp, FundamentalType, 'int', 'int', False)
self.TestType(floatp, FundamentalType, 'float', 'float', False)
@@ -100,25 +100,25 @@ class ClassBaseTest(Tester):
'test function simple in class Base'
simple = GetMember(self.base, 'simple')
self.assert_(isinstance(simple, Method))
self.assertEqual(simple._visibility, Scope.protected)
self.assertEqual(simple._FullName(), 'test::Base::simple')
self.assertEqual(len(simple._parameters), 1)
param = simple._parameters[0]
self.assertEqual(simple.visibility, Scope.protected)
self.assertEqual(simple.FullName(), 'test::Base::simple')
self.assertEqual(len(simple.parameters), 1)
param = simple.parameters[0]
self.TestType(param, ReferenceType, 'std::string', 'const std::string&', True)
self.TestType(simple._result, FundamentalType, 'bool', 'bool', False)
self.TestType(simple.result, FundamentalType, 'bool', 'bool', False)
self.assertEqual(
simple._PointerDeclaration(1),
simple.PointerDeclaration(1),
'(bool (test::Base::*)(const std::string&) )&test::Base::simple')
def testZ(self):
z = GetMember(self.base, 'z')
self.assert_(isinstance(z, Variable))
self.assertEqual(z._visibility, Scope.public)
self.assertEqual(z._FullName(), 'test::Base::z')
self.assertEqual(z._type._name, 'int')
self.assertEqual(z._type._const, False)
self.assert_(z._static)
self.assertEqual(z.visibility, Scope.public)
self.assertEqual(z.FullName(), 'test::Base::z')
self.assertEqual(z.type.name, 'int')
self.assertEqual(z.type.const, False)
self.assert_(z.static)
class ClassTemplateTest(Tester):
@@ -129,18 +129,18 @@ class ClassTemplateTest(Tester):
def testClass(self):
'test the properties of the Template<int> class'
self.assert_(isinstance(self.template, Class))
self.assert_(not self.template._abstract)
self.assertEqual(self.template._FullName(), 'Template<int>')
self.assertEqual(self.template._namespace, '')
self.assertEqual(self.template._name, 'Template<int>')
self.assert_(not self.template.abstract)
self.assertEqual(self.template.FullName(), 'Template<int>')
self.assertEqual(self.template.namespace, '')
self.assertEqual(self.template.name, 'Template<int>')
def testConstructors(self):
'test the automatic constructors of the class Template<int>'
constructors = GetMembers(self.template, 'Template')
for cons in constructors:
if len(cons._parameters) == 0:
if len(cons.parameters) == 0:
self.TestDefaultConstructor(self.template, cons, Scope.public)
elif len(cons._parameters) == 1:
elif len(cons.parameters) == 1:
self.TestCopyConstructor(self.template, cons, Scope.public)
@@ -148,21 +148,21 @@ class ClassTemplateTest(Tester):
'test the class variable value'
value = GetMember(self.template, 'value')
self.assert_(isinstance(value, ClassVariable))
self.assert_(value._name, 'value')
self.TestType(value._type, FundamentalType, 'int', 'int', False)
self.assert_(not value._static)
self.assertEqual(value._visibility, Scope.public)
self.assertEqual(value._class, 'Template<int>')
self.assertEqual(value._FullName(), 'Template<int>::value')
self.assert_(value.name, 'value')
self.TestType(value.type, FundamentalType, 'int', 'int', False)
self.assert_(not value.static)
self.assertEqual(value.visibility, Scope.public)
self.assertEqual(value.class_, 'Template<int>')
self.assertEqual(value.FullName(), 'Template<int>::value')
def testBase(self):
'test the superclasses of Template<int>'
bases = self.template._bases
bases = self.template.bases
self.assertEqual(len(bases), 1)
base = bases[0]
self.assert_(isinstance(base, Base))
self.assertEqual(base._name, 'test::Base')
self.assertEqual(base._visibility, Scope.protected)
self.assertEqual(base.name, 'test::Base')
self.assertEqual(base.visibility, Scope.protected)
@@ -174,27 +174,27 @@ class FreeFuncTest(Tester):
def testFunc(self):
'test attributes of FreeFunc'
self.assert_(isinstance(self.func, Function))
self.assertEqual(self.func._name, 'FreeFunc')
self.assertEqual(self.func._FullName(), 'test::FreeFunc')
self.assertEqual(self.func._namespace, 'test')
self.assertEqual(self.func.name, 'FreeFunc')
self.assertEqual(self.func.FullName(), 'test::FreeFunc')
self.assertEqual(self.func.namespace, 'test')
self.assertEqual(
self.func._PointerDeclaration(1),
self.func.PointerDeclaration(1),
'(const test::Base& (*)(const std::string&, int))&test::FreeFunc')
def testResult(self):
'test the return value of FreeFunc'
res = self.func._result
res = self.func.result
self.TestType(res, ReferenceType, 'test::Base', 'const test::Base&', True)
def testParameters(self):
'test the parameters of FreeFunc'
self.assertEqual(len(self.func._parameters), 2)
strp, intp = self.func._parameters
self.assertEqual(len(self.func.parameters), 2)
strp, intp = self.func.parameters
self.TestType(strp, ReferenceType, 'std::string', 'const std::string&', True)
self.assertEqual(strp._default, None)
self.assertEqual(strp.default, None)
self.TestType(intp, FundamentalType, 'int', 'int', False)
self.assertEqual(intp._default, '10')
self.assertEqual(intp.default, '10')
@@ -203,14 +203,14 @@ class testFunctionPointers(Tester):
def testMethodPointer(self):
'test declaration of a pointer-to-method'
meth = GetDecl('MethodTester')
param = meth._parameters[0]
param = meth.parameters[0]
fullname = 'void (test::Base::*)(int)'
self.TestType(param, PointerType, fullname, fullname, False)
def testFunctionPointer(self):
'test declaration of a pointer-to-function'
func = GetDecl('FunctionTester')
param = func._parameters[0]
param = func.parameters[0]
fullname = 'void (*)(int)'
self.TestType(param, PointerType, fullname, fullname, False)
@@ -295,7 +295,7 @@ declarations = GetDeclarations()
def GetDecl(name):
'returns one of the top declarations given its name'
for decl in declarations:
if decl._name == name:
if decl.name == name:
return decl
else:
raise RuntimeError, 'Declaration not found: %s' % name
@@ -307,7 +307,7 @@ def GetMember(class_, name):
res = None
multipleFound = False
for member in class_:
if member._name == name:
if member.name == name:
if res is not None:
multipleFound = True
break
@@ -315,7 +315,7 @@ def GetMember(class_, name):
if res is None or multipleFound:
raise RuntimeError, \
'No member or more than one member found in class %s: %s' \
% (class_._name, name)
% (class_.name, name)
return res
@@ -323,12 +323,12 @@ def GetMembers(class_, name):
'gets the members of the given class by its name'
res = []
for member in class_:
if member._name == name:
if member.name == name:
res.append(member)
if len(res) in (0, 1):
raise RuntimeError, \
'GetMembers: 0 or 1 members found in class %s: %s' \
% (class_._name, name)
% (class_.name, name)
return res

View File

@@ -1,7 +1,7 @@
#!/usr/bin/python
import sys
sys.path.append('../src')
sys.path.append('../src/Pyste')
import unittest
import os.path
from glob import glob

View File

@@ -11,7 +11,7 @@ import sys
if sys.platform == 'win32':
includes = '-ID:/programming/libraries/boost-cvs/boost -IC:/Python/include'
build_pyste_cmd = 'python ../src/pyste.py %s ' % includes
build_pyste_cmd = 'python ../src/Pyste/pyste.py %s ' % includes
compile_single_cmd = 'icl /nologo /GR /GX -c %s -I. ' % includes
link_single_cmd = 'link /nologo /DLL '\
'/libpath:D:/programming/libraries/boost-cvs/lib /libpath:C:/Python/libs '\
@@ -23,7 +23,7 @@ if sys.platform == 'win32':
#=============================================================================
elif sys.platform == 'linux2':
build_pyste_cmd = 'python ../src/pyste.py -I. '
build_pyste_cmd = 'python ../src/Pyste/pyste.py -I. '
compile_single_cmd = 'g++ -shared -c -I. -I/usr/include/python2.2 '
link_single_cmd = 'g++ -shared -o _%s.so -lboost_python '
obj_ext = 'o'