Trim trailing space etgtools directory

This commit is contained in:
Metallicow
2016-12-05 16:26:04 -06:00
parent e6884f7dc0
commit 067569d785
7 changed files with 791 additions and 791 deletions

View File

@@ -38,12 +38,12 @@ def parseDoxyXML(module, class_or_filename_list):
""" """
Parse a list of Doxygen XML files and add the item(s) found there to the Parse a list of Doxygen XML files and add the item(s) found there to the
ModuleDef object. ModuleDef object.
If a name in the list a wx class name then the Doxygen XML filename is If a name in the list a wx class name then the Doxygen XML filename is
calculated from that name, otherwise it is treated as a filename in the calculated from that name, otherwise it is treated as a filename in the
Doxygen XML output folder. Doxygen XML output folder.
""" """
def _classToDoxyName(name, attempts, base='class'): def _classToDoxyName(name, attempts, base='class'):
import string import string
filename = base filename = base
@@ -51,11 +51,11 @@ def parseDoxyXML(module, class_or_filename_list):
if c in string.ascii_uppercase: if c in string.ascii_uppercase:
filename += '_' + c.lower() filename += '_' + c.lower()
else: else:
filename += c filename += c
filename = os.path.join(XMLSRC, filename) + '.xml' filename = os.path.join(XMLSRC, filename) + '.xml'
attempts.append(filename) attempts.append(filename)
return filename return filename
def _includeToDoxyName(name): def _includeToDoxyName(name):
name = os.path.basename(name) name = os.path.basename(name)
name = name.replace('.h', '_8h') name = name.replace('.h', '_8h')
@@ -65,7 +65,7 @@ def parseDoxyXML(module, class_or_filename_list):
else: else:
name = 'interface_2wx_2' + name name = 'interface_2wx_2' + name
return os.path.join(XMLSRC, name) + '.xml', name + '.xml' return os.path.join(XMLSRC, name) + '.xml', name + '.xml'
for class_or_filename in class_or_filename_list: for class_or_filename in class_or_filename_list:
attempts = [] attempts = []
pathname = _classToDoxyName(class_or_filename, attempts) pathname = _classToDoxyName(class_or_filename, attempts)
@@ -80,23 +80,23 @@ def parseDoxyXML(module, class_or_filename_list):
print(msg) print(msg)
print("Tried: %s" % ('\n '.join(attempts))) print("Tried: %s" % ('\n '.join(attempts)))
raise DoxyXMLError(msg) raise DoxyXMLError(msg)
if verbose(): if verbose():
print("Loading %s..." % pathname) print("Loading %s..." % pathname)
_filesparsed.add(pathname) _filesparsed.add(pathname)
root = et.parse(pathname).getroot() root = et.parse(pathname).getroot()
for element in root: for element in root:
# extract and add top-level elements from the XML document # extract and add top-level elements from the XML document
item = module.addElement(element) item = module.addElement(element)
# Also automatically parse the XML for the include file to get related # Also automatically parse the XML for the include file to get related
# typedefs, functions, enums, etc. # typedefs, functions, enums, etc.
# Make sure though, that for interface files we only parse the one # Make sure though, that for interface files we only parse the one
# that belongs to this class. Otherwise, enums, etc. will be defined # that belongs to this class. Otherwise, enums, etc. will be defined
# in multiple places. # in multiple places.
xmlname = class_or_filename.replace('wx', '').lower() xmlname = class_or_filename.replace('wx', '').lower()
if hasattr(item, 'includes'): if hasattr(item, 'includes'):
for inc in item.includes: for inc in item.includes:
pathname, name = _includeToDoxyName(inc) pathname, name = _includeToDoxyName(inc)
@@ -104,15 +104,15 @@ def parseDoxyXML(module, class_or_filename_list):
and pathname not in _filesparsed \ and pathname not in _filesparsed \
and ("interface" not in name or xmlname in name) \ and ("interface" not in name or xmlname in name) \
and name not in class_or_filename_list: and name not in class_or_filename_list:
class_or_filename_list.append(name) class_or_filename_list.append(name)
_filesparsed.clear() _filesparsed.clear()
module.parseCompleted() module.parseCompleted()
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------

File diff suppressed because it is too large Load Diff

View File

@@ -17,18 +17,18 @@ import sys
class WrapperGeneratorBase(object): class WrapperGeneratorBase(object):
def __init__(self): def __init__(self):
pass pass
def generate(self, module, destFile=None): def generate(self, module, destFile=None):
raise NotImplementedError raise NotImplementedError
class DocsGeneratorBase(object): class DocsGeneratorBase(object):
def __init__(self): def __init__(self):
pass pass
def generate(self, module): def generate(self, module):
raise NotImplementedError raise NotImplementedError
class StubbedDocsGenerator(DocsGeneratorBase): class StubbedDocsGenerator(DocsGeneratorBase):
def generate(self, module): def generate(self, module):
pass pass
@@ -44,7 +44,7 @@ class SphinxGenerator(DocsGeneratorBase):
def nci(text, numSpaces=0, stripLeading=True): def nci(text, numSpaces=0, stripLeading=True):
""" """
Normalize Code Indents Normalize Code Indents
First use the count of leading spaces on the first line and remove that First use the count of leading spaces on the first line and remove that
many spaces from the front of all lines, and then indent each line by many spaces from the front of all lines, and then indent each line by
adding numSpaces spaces. This is used so we can convert the arbitrary adding numSpaces spaces. This is used so we can convert the arbitrary
@@ -59,20 +59,20 @@ def nci(text, numSpaces=0, stripLeading=True):
break break
count += 1 count += 1
return count return count
def _allSpaces(text): def _allSpaces(text):
for c in text: for c in text:
if c != ' ': if c != ' ':
return False return False
return True return True
lines = text.rstrip().split('\n') lines = text.rstrip().split('\n')
if stripLeading: if stripLeading:
numStrip = _getLeadingSpaceCount(lines[0]) numStrip = _getLeadingSpaceCount(lines[0])
else: else:
numStrip = 0 numStrip = 0
for idx, line in enumerate(lines): for idx, line in enumerate(lines):
assert _allSpaces(line[:numStrip]), "Indentation inconsistent with first line" assert _allSpaces(line[:numStrip]), "Indentation inconsistent with first line"
lines[idx] = ' '*numSpaces + line[numStrip:] lines[idx] = ' '*numSpaces + line[numStrip:]
@@ -102,8 +102,8 @@ class Utf8EncodingStream(io.StringIO):
if isinstance(text, str): if isinstance(text, str):
text = text.decode('utf-8') text = text.decode('utf-8')
return io.StringIO.write(self, text) return io.StringIO.write(self, text)
def textfile_open(filename, mode='rt'): def textfile_open(filename, mode='rt'):
@@ -119,7 +119,7 @@ def textfile_open(filename, mode='rt'):
return codecs.open(filename, mode, encoding='utf-8') return codecs.open(filename, mode, encoding='utf-8')
else: else:
return open(filename, mode, encoding='utf-8') return open(filename, mode, encoding='utf-8')
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------

View File

@@ -35,7 +35,7 @@ header_pi = """\
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
# This file is generated by wxPython's PI generator. Do not edit by hand. # This file is generated by wxPython's PI generator. Do not edit by hand.
# #
# The *.pi files are used by WingIDE to provide more information than it is # The *.pi files are used by WingIDE to provide more information than it is
# able to glean from introspection of extension types and methods. They are # able to glean from introspection of extension types and methods. They are
# not intended to be imported, executed or used for any other purpose other # not intended to be imported, executed or used for any other purpose other
@@ -72,13 +72,13 @@ header_pyi = """\
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
class PiWrapperGenerator(generators.WrapperGeneratorBase, FixWxPrefix): class PiWrapperGenerator(generators.WrapperGeneratorBase, FixWxPrefix):
def generate(self, module, destFile=None): def generate(self, module, destFile=None):
stream = Utf8EncodingStream() stream = Utf8EncodingStream()
# process the module object and its child objects # process the module object and its child objects
self.generateModule(module, stream) self.generateModule(module, stream)
# Write the contents of the stream to the destination file # Write the contents of the stream to the destination file
if not destFile: if not destFile:
name = module.module name = module.module
@@ -115,14 +115,14 @@ class PiWrapperGenerator(generators.WrapperGeneratorBase, FixWxPrefix):
sectionEndLine = -1 sectionEndLine = -1
sectionBeginMarker = '#-- begin-%s --#' % sectionName sectionBeginMarker = '#-- begin-%s --#' % sectionName
sectionEndMarker = '#-- end-%s --#' % sectionName sectionEndMarker = '#-- end-%s --#' % sectionName
lines = textfile_open(destFile, 'rt').readlines() lines = textfile_open(destFile, 'rt').readlines()
for idx, line in enumerate(lines): for idx, line in enumerate(lines):
if line.startswith(sectionBeginMarker): if line.startswith(sectionBeginMarker):
sectionBeginLine = idx sectionBeginLine = idx
if line.startswith(sectionEndMarker): if line.startswith(sectionEndMarker):
sectionEndLine = idx sectionEndLine = idx
if sectionBeginLine == -1: if sectionBeginLine == -1:
# not there already, add to the end # not there already, add to the end
lines.append(sectionBeginMarker + '\n') lines.append(sectionBeginMarker + '\n')
@@ -131,12 +131,12 @@ class PiWrapperGenerator(generators.WrapperGeneratorBase, FixWxPrefix):
else: else:
# replace the existing lines # replace the existing lines
lines[sectionBeginLine+1:sectionEndLine] = [sectionText] lines[sectionBeginLine+1:sectionEndLine] = [sectionText]
f = textfile_open(destFile, 'wt') f = textfile_open(destFile, 'wt')
f.writelines(lines) f.writelines(lines)
f.close() f.close()
#----------------------------------------------------------------------- #-----------------------------------------------------------------------
def generateModule(self, module, stream): def generateModule(self, module, stream):
@@ -145,14 +145,14 @@ class PiWrapperGenerator(generators.WrapperGeneratorBase, FixWxPrefix):
""" """
assert isinstance(module, extractors.ModuleDef) assert isinstance(module, extractors.ModuleDef)
self.isCore = module.module == '_core' self.isCore = module.module == '_core'
for item in module.imports: for item in module.imports:
if item.startswith('_'): if item.startswith('_'):
item = item[1:] item = item[1:]
if item == 'core': if item == 'core':
continue continue
stream.write('import wx.%s\n' % item) stream.write('import wx.%s\n' % item)
# Move all PyCode items with an order value to the begining of the # Move all PyCode items with an order value to the begining of the
# list as they most likely should appear before everything else. # list as they most likely should appear before everything else.
pycode = list() pycode = list()
@@ -162,7 +162,7 @@ class PiWrapperGenerator(generators.WrapperGeneratorBase, FixWxPrefix):
for item in pycode: for item in pycode:
module.items.remove(item) module.items.remove(item)
module.items = pycode + module.items module.items = pycode + module.items
methodMap = { methodMap = {
extractors.ClassDef : self.generateClass, extractors.ClassDef : self.generateClass,
extractors.DefineDef : self.generateDefine, extractors.DefineDef : self.generateDefine,
@@ -173,18 +173,18 @@ class PiWrapperGenerator(generators.WrapperGeneratorBase, FixWxPrefix):
extractors.WigCode : self.generateWigCode, extractors.WigCode : self.generateWigCode,
extractors.PyCodeDef : self.generatePyCode, extractors.PyCodeDef : self.generatePyCode,
extractors.PyFunctionDef : self.generatePyFunction, extractors.PyFunctionDef : self.generatePyFunction,
extractors.PyClassDef : self.generatePyClass, extractors.PyClassDef : self.generatePyClass,
extractors.CppMethodDef : self.generateCppMethod, extractors.CppMethodDef : self.generateCppMethod,
extractors.CppMethodDef_sip : self.generateCppMethod_sip, extractors.CppMethodDef_sip : self.generateCppMethod_sip,
} }
for item in module: for item in module:
if item.ignored: if item.ignored:
continue continue
function = methodMap[item.__class__] function = methodMap[item.__class__]
function(item, stream) function(item, stream)
#----------------------------------------------------------------------- #-----------------------------------------------------------------------
def generateEnum(self, enum, stream, indent=''): def generateEnum(self, enum, stream, indent=''):
assert isinstance(enum, extractors.EnumDef) assert isinstance(enum, extractors.EnumDef)
@@ -193,9 +193,9 @@ class PiWrapperGenerator(generators.WrapperGeneratorBase, FixWxPrefix):
for v in enum.items: for v in enum.items:
if v.ignored: if v.ignored:
continue continue
name = v.pyName or v.name name = v.pyName or v.name
stream.write('%s%s = 0\n' % (indent, name)) stream.write('%s%s = 0\n' % (indent, name))
#----------------------------------------------------------------------- #-----------------------------------------------------------------------
def generateGlobalVar(self, globalVar, stream): def generateGlobalVar(self, globalVar, stream):
assert isinstance(globalVar, extractors.GlobalVarDef) assert isinstance(globalVar, extractors.GlobalVarDef)
@@ -216,9 +216,9 @@ class PiWrapperGenerator(generators.WrapperGeneratorBase, FixWxPrefix):
valTyp = valTyp.replace(' ', '') valTyp = valTyp.replace(' ', '')
valTyp = self.fixWxPrefix(valTyp) valTyp = self.fixWxPrefix(valTyp)
valTyp += '()' valTyp += '()'
stream.write('%s = %s\n' % (name, valTyp)) stream.write('%s = %s\n' % (name, valTyp))
#----------------------------------------------------------------------- #-----------------------------------------------------------------------
def generateDefine(self, define, stream): def generateDefine(self, define, stream):
assert isinstance(define, extractors.DefineDef) assert isinstance(define, extractors.DefineDef)
@@ -229,7 +229,7 @@ class PiWrapperGenerator(generators.WrapperGeneratorBase, FixWxPrefix):
stream.write('%s = ""\n' % (define.pyName or define.name)) stream.write('%s = ""\n' % (define.pyName or define.name))
else: else:
stream.write('%s = 0\n' % (define.pyName or define.name)) stream.write('%s = 0\n' % (define.pyName or define.name))
#----------------------------------------------------------------------- #-----------------------------------------------------------------------
def generateTypedef(self, typedef, stream, indent=''): def generateTypedef(self, typedef, stream, indent=''):
assert isinstance(typedef, extractors.TypedefDef) assert isinstance(typedef, extractors.TypedefDef)
@@ -241,20 +241,20 @@ class PiWrapperGenerator(generators.WrapperGeneratorBase, FixWxPrefix):
# ignore the typedef and return. # ignore the typedef and return.
if not ('<' in typedef.type and '>' in typedef.type) and not typedef.docAsClass: if not ('<' in typedef.type and '>' in typedef.type) and not typedef.docAsClass:
return return
# Otherwise write a mock class for it that combines the template and class. # Otherwise write a mock class for it that combines the template and class.
# First, extract the info we need. # First, extract the info we need.
if typedef.docAsClass: if typedef.docAsClass:
bases = [self.fixWxPrefix(b, True) for b in typedef.bases] bases = [self.fixWxPrefix(b, True) for b in typedef.bases]
name = self.fixWxPrefix(typedef.name) name = self.fixWxPrefix(typedef.name)
elif '<' in typedef.type and '>' in typedef.type: elif '<' in typedef.type and '>' in typedef.type:
t = typedef.type.replace('>', '') t = typedef.type.replace('>', '')
t = t.replace(' ', '') t = t.replace(' ', '')
bases = t.split('<') bases = t.split('<')
bases = [self.fixWxPrefix(b, True) for b in bases] bases = [self.fixWxPrefix(b, True) for b in bases]
name = self.fixWxPrefix(typedef.name) name = self.fixWxPrefix(typedef.name)
# Now write the Python equivallent class for the typedef # Now write the Python equivallent class for the typedef
if not bases: if not bases:
bases = ['object'] # this should not happpen, but just in case... bases = ['object'] # this should not happpen, but just in case...
@@ -272,14 +272,14 @@ class PiWrapperGenerator(generators.WrapperGeneratorBase, FixWxPrefix):
def generateWigCode(self, wig, stream, indent=''): def generateWigCode(self, wig, stream, indent=''):
assert isinstance(wig, extractors.WigCode) assert isinstance(wig, extractors.WigCode)
# write nothing for this one # write nothing for this one
#----------------------------------------------------------------------- #-----------------------------------------------------------------------
def generatePyCode(self, pc, stream, indent=''): def generatePyCode(self, pc, stream, indent=''):
assert isinstance(pc, extractors.PyCodeDef) assert isinstance(pc, extractors.PyCodeDef)
code = pc.code code = pc.code
if hasattr(pc, 'klass'): if hasattr(pc, 'klass'):
code = code.replace(pc.klass.pyName+'.', '') code = code.replace(pc.klass.pyName+'.', '')
stream.write('\n') stream.write('\n')
stream.write(nci(code, len(indent))) stream.write(nci(code, len(indent)))
@@ -288,9 +288,9 @@ class PiWrapperGenerator(generators.WrapperGeneratorBase, FixWxPrefix):
assert isinstance(pf, extractors.PyFunctionDef) assert isinstance(pf, extractors.PyFunctionDef)
stream.write('\n') stream.write('\n')
if pf.deprecated: if pf.deprecated:
stream.write('%s@wx.deprecated\n' % indent) stream.write('%s@wx.deprecated\n' % indent)
if pf.isStatic: if pf.isStatic:
stream.write('%s@staticmethod\n' % indent) stream.write('%s@staticmethod\n' % indent)
stream.write('%sdef %s%s:\n' % (indent, pf.name, pf.argsString)) stream.write('%sdef %s%s:\n' % (indent, pf.name, pf.argsString))
indent2 = indent + ' '*4 indent2 = indent + ' '*4
if pf.briefDoc: if pf.briefDoc:
@@ -298,11 +298,11 @@ class PiWrapperGenerator(generators.WrapperGeneratorBase, FixWxPrefix):
stream.write(nci(pf.briefDoc, len(indent2))) stream.write(nci(pf.briefDoc, len(indent2)))
stream.write('%s"""\n' % indent2) stream.write('%s"""\n' % indent2)
stream.write('%spass\n' % indent2) stream.write('%spass\n' % indent2)
#----------------------------------------------------------------------- #-----------------------------------------------------------------------
def generatePyClass(self, pc, stream, indent=''): def generatePyClass(self, pc, stream, indent=''):
assert isinstance(pc, extractors.PyClassDef) assert isinstance(pc, extractors.PyClassDef)
# write the class declaration and docstring # write the class declaration and docstring
if pc.deprecated: if pc.deprecated:
stream.write('%s@wx.deprecated\n' % indent) stream.write('%s@wx.deprecated\n' % indent)
@@ -355,8 +355,8 @@ class PiWrapperGenerator(generators.WrapperGeneratorBase, FixWxPrefix):
stream.write(' """\n') stream.write(' """\n')
stream.write(nci(function.pyDocstring, 4)) stream.write(nci(function.pyDocstring, 4))
stream.write(' """\n') stream.write(' """\n')
def generateParameters(self, parameters, stream, indent): def generateParameters(self, parameters, stream, indent):
def _lastParameter(idx): def _lastParameter(idx):
if idx == len(parameters)-1: if idx == len(parameters)-1:
@@ -365,7 +365,7 @@ class PiWrapperGenerator(generators.WrapperGeneratorBase, FixWxPrefix):
if not parameters[i].ignored: if not parameters[i].ignored:
return False return False
return True return True
for idx, param in enumerate(parameters): for idx, param in enumerate(parameters):
if param.ignored: if param.ignored:
continue continue
@@ -374,25 +374,25 @@ class PiWrapperGenerator(generators.WrapperGeneratorBase, FixWxPrefix):
stream.write('=%s' % param.default) stream.write('=%s' % param.default)
if not _lastParameter(idx): if not _lastParameter(idx):
stream.write(', ') stream.write(', ')
#----------------------------------------------------------------------- #-----------------------------------------------------------------------
def generateClass(self, klass, stream, indent=''): def generateClass(self, klass, stream, indent=''):
assert isinstance(klass, extractors.ClassDef) assert isinstance(klass, extractors.ClassDef)
if klass.ignored: if klass.ignored:
return return
# check if there is a pi-customized version of the base class names # check if there is a pi-customized version of the base class names
if hasattr(klass, 'piBases'): if hasattr(klass, 'piBases'):
bases = klass.piBases bases = klass.piBases
else: else:
# check if it's a template with the template parameter as the base class # check if it's a template with the template parameter as the base class
bases = klass.bases[:] bases = klass.bases[:]
for tp in klass.templateParams: for tp in klass.templateParams:
if tp in bases: if tp in bases:
bases.remove(tp) bases.remove(tp)
# write class declaration # write class declaration
klassName = klass.pyName or klass.name klassName = klass.pyName or klass.name
stream.write('\n%sclass %s' % (indent, klassName)) stream.write('\n%sclass %s' % (indent, klassName))
@@ -405,24 +405,24 @@ class PiWrapperGenerator(generators.WrapperGeneratorBase, FixWxPrefix):
stream.write('(object)') stream.write('(object)')
stream.write(':\n') stream.write(':\n')
indent2 = indent + ' '*4 indent2 = indent + ' '*4
# docstring # docstring
stream.write('%s"""\n' % indent2) stream.write('%s"""\n' % indent2)
stream.write(nci(klass.pyDocstring, len(indent2))) stream.write(nci(klass.pyDocstring, len(indent2)))
stream.write('%s"""\n' % indent2) stream.write('%s"""\n' % indent2)
# generate nested classes # generate nested classes
for item in klass.innerclasses: for item in klass.innerclasses:
self.generateClass(item, stream, indent2) self.generateClass(item, stream, indent2)
# Split the items into public and protected groups # Split the items into public and protected groups
enums = [i for i in klass if enums = [i for i in klass if
isinstance(i, extractors.EnumDef) and isinstance(i, extractors.EnumDef) and
i.protection == 'public'] i.protection == 'public']
ctors = [i for i in klass if ctors = [i for i in klass if
isinstance(i, extractors.MethodDef) and isinstance(i, extractors.MethodDef) and
i.protection == 'public' and (i.isCtor or i.isDtor)] i.protection == 'public' and (i.isCtor or i.isDtor)]
public = [i for i in klass if i.protection == 'public' and public = [i for i in klass if i.protection == 'public' and
i not in ctors and i not in enums] i not in ctors and i not in enums]
protected = [i for i in klass if i.protection == 'protected'] protected = [i for i in klass if i.protection == 'protected']
@@ -444,25 +444,25 @@ class PiWrapperGenerator(generators.WrapperGeneratorBase, FixWxPrefix):
item.klass = klass item.klass = klass
self.generateEnum(item, stream, indent2) self.generateEnum(item, stream, indent2)
for item in ctors: for item in ctors:
if item.isCtor: if item.isCtor:
item.klass = klass item.klass = klass
self.generateMethod(item, stream, indent2, self.generateMethod(item, stream, indent2,
name='__init__', docstring=klass.pyDocstring) name='__init__', docstring=klass.pyDocstring)
for item in public: for item in public:
item.klass = klass item.klass = klass
f = dispatch[item.__class__] f = dispatch[item.__class__]
f(item, stream, indent2) f(item, stream, indent2)
for item in protected: for item in protected:
item.klass = klass item.klass = klass
f = dispatch[item.__class__] f = dispatch[item.__class__]
f(item, stream, indent2) f(item, stream, indent2)
stream.write('%s# end of class %s\n\n' % (indent, klassName)) stream.write('%s# end of class %s\n\n' % (indent, klassName))
def generateMemberVar(self, memberVar, stream, indent): def generateMemberVar(self, memberVar, stream, indent):
assert isinstance(memberVar, extractors.MemberVarDef) assert isinstance(memberVar, extractors.MemberVarDef)
if memberVar.ignored: if memberVar.ignored:
@@ -494,7 +494,7 @@ class PiWrapperGenerator(generators.WrapperGeneratorBase, FixWxPrefix):
return return
if method.isDtor: if method.isDtor:
return return
name = name or method.pyName or method.name name = name or method.pyName or method.name
if name in magicMethods: if name in magicMethods:
name = magicMethods[name] name = magicMethods[name]
@@ -527,7 +527,7 @@ class PiWrapperGenerator(generators.WrapperGeneratorBase, FixWxPrefix):
stream.write(argsString) stream.write(argsString)
stream.write(':\n') stream.write(':\n')
indent2 = indent + ' '*4 indent2 = indent + ' '*4
# docstring # docstring
if not docstring: if not docstring:
if hasattr(method, 'pyDocstring'): if hasattr(method, 'pyDocstring'):
@@ -538,8 +538,8 @@ class PiWrapperGenerator(generators.WrapperGeneratorBase, FixWxPrefix):
if docstring.strip(): if docstring.strip():
stream.write(nci(docstring, len(indent2))) stream.write(nci(docstring, len(indent2)))
stream.write('%s"""\n' % indent2) stream.write('%s"""\n' % indent2)
def generateCppMethod(self, method, stream, indent=''): def generateCppMethod(self, method, stream, indent=''):
assert isinstance(method, extractors.CppMethodDef) assert isinstance(method, extractors.CppMethodDef)
@@ -549,7 +549,7 @@ class PiWrapperGenerator(generators.WrapperGeneratorBase, FixWxPrefix):
def generateCppMethod_sip(self, method, stream, indent=''): def generateCppMethod_sip(self, method, stream, indent=''):
assert isinstance(method, extractors.CppMethodDef_sip) assert isinstance(method, extractors.CppMethodDef_sip)
self.generateMethod(method, stream, indent) self.generateMethod(method, stream, indent)
def generatePyMethod(self, pm, stream, indent): def generatePyMethod(self, pm, stream, indent):
assert isinstance(pm, extractors.PyMethodDef) assert isinstance(pm, extractors.PyMethodDef)
@@ -565,9 +565,9 @@ class PiWrapperGenerator(generators.WrapperGeneratorBase, FixWxPrefix):
stream.write('%s"""\n' % indent2) stream.write('%s"""\n' % indent2)
stream.write(nci(pm.pyDocstring, len(indent2))) stream.write(nci(pm.pyDocstring, len(indent2)))
stream.write('%s"""\n' % indent2) stream.write('%s"""\n' % indent2)
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------

View File

@@ -32,27 +32,27 @@ class SipGeneratorError(RuntimeError):
# This is a list of types that are used as return by value or by reference # This is a list of types that are used as return by value or by reference
# function return types that we need to ensure are actually using pointer # function return types that we need to ensure are actually using pointer
# types in their CppMethodDef or cppCode wrappers. # types in their CppMethodDef or cppCode wrappers.
forcePtrTypes = [ 'wxString', forcePtrTypes = [ 'wxString',
] ]
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
class SipWrapperGenerator(generators.WrapperGeneratorBase): class SipWrapperGenerator(generators.WrapperGeneratorBase):
def generate(self, module, destFile=None): def generate(self, module, destFile=None):
stream = Utf8EncodingStream() stream = Utf8EncodingStream()
# generate SIP code from the module and its objects # generate SIP code from the module and its objects
self.generateModule(module, stream) self.generateModule(module, stream)
# Write the contents of the stream to the destination file # Write the contents of the stream to the destination file
if not destFile: if not destFile:
destFile = os.path.join(phoenixRoot, 'sip/gen', module.name + '.sip') destFile = os.path.join(phoenixRoot, 'sip/gen', module.name + '.sip')
f = textfile_open(destFile, 'wt') f = textfile_open(destFile, 'wt')
f.write(stream.getvalue()) f.write(stream.getvalue())
f.close() f.close()
#----------------------------------------------------------------------- #-----------------------------------------------------------------------
def generateModule(self, module, stream): def generateModule(self, module, stream):
assert isinstance(module, extractors.ModuleDef) assert isinstance(module, extractors.ModuleDef)
@@ -60,15 +60,15 @@ class SipWrapperGenerator(generators.WrapperGeneratorBase):
# write the file header # write the file header
stream.write(divider + """\ stream.write(divider + """\
// This file is generated by wxPython's SIP generator. Do not edit by hand. // This file is generated by wxPython's SIP generator. Do not edit by hand.
// //
// Copyright: (c) 2011-2016 by Total Control Software // Copyright: (c) 2011-2016 by Total Control Software
// License: wxWindows License // License: wxWindows License
""") """)
if module.name == module.module: if module.name == module.module:
stream.write(""" stream.write("""
%%Module( name=%s.%s, %%Module( name=%s.%s,
keyword_arguments="All", keyword_arguments="All",
use_argument_names=True, use_argument_names=True,
all_raise_py_exception=True, all_raise_py_exception=True,
language="C++") language="C++")
{ {
@@ -91,7 +91,7 @@ class SipWrapperGenerator(generators.WrapperGeneratorBase):
stream.write("""\ stream.write("""\
%%Extract(id=pycode%s, order=5) %%Extract(id=pycode%s, order=5)
# This file is generated by wxPython's SIP generator. Do not edit by hand. # This file is generated by wxPython's SIP generator. Do not edit by hand.
# #
# Copyright: (c) 2011-2016 by Total Control Software # Copyright: (c) 2011-2016 by Total Control Software
# License: wxWindows License # License: wxWindows License
%s %s
@@ -100,20 +100,20 @@ from .%s import *
%%End %%End
""" % ( module.name, doc, module.name)) """ % ( module.name, doc, module.name))
else: else:
stream.write("//\n// This file will be included by %s.sip\n//\n" % module.module) stream.write("//\n// This file will be included by %s.sip\n//\n" % module.module)
stream.write(divider) stream.write(divider)
self.module_name = module.module self.module_name = module.module
# C++ code to be written to the module's header # C++ code to be written to the module's header
if module.headerCode: if module.headerCode:
stream.write("\n%ModuleHeaderCode\n") stream.write("\n%ModuleHeaderCode\n")
for c in module.headerCode: for c in module.headerCode:
stream.write('%s\n' % c) stream.write('%s\n' % c)
stream.write("%End\n\n") stream.write("%End\n\n")
# %Imports and %Includes # %Imports and %Includes
if module.imports: if module.imports:
for i in module.imports: for i in module.imports:
@@ -123,7 +123,7 @@ from .%s import *
for i in module.includes: for i in module.includes:
stream.write("%%Include %s.sip\n" % i) stream.write("%%Include %s.sip\n" % i)
stream.write("\n") stream.write("\n")
# C++ code to be written out to the generated module # C++ code to be written out to the generated module
if module.cppCode: if module.cppCode:
stream.write("%ModuleCode\n") stream.write("%ModuleCode\n")
@@ -132,31 +132,31 @@ from .%s import *
stream.write("%End\n") stream.write("%End\n")
stream.write('\n%s\n' % divider) stream.write('\n%s\n' % divider)
# Now generate each of the items in the module # Now generate each of the items in the module
self.generateModuleItems(module, stream) self.generateModuleItems(module, stream)
# Add code for the module initialization sections. # Add code for the module initialization sections.
if module.preInitializerCode: if module.preInitializerCode:
stream.write('\n%s\n\n%%PreInitialisationCode\n' % divider) stream.write('\n%s\n\n%%PreInitialisationCode\n' % divider)
for i in module.preInitializerCode: for i in module.preInitializerCode:
stream.write('%s\n' % i) stream.write('%s\n' % i)
stream.write('%End\n') stream.write('%End\n')
if module.initializerCode: if module.initializerCode:
stream.write('\n%s\n\n%%InitialisationCode\n' % divider) stream.write('\n%s\n\n%%InitialisationCode\n' % divider)
for i in module.initializerCode: for i in module.initializerCode:
stream.write('%s\n' % i) stream.write('%s\n' % i)
stream.write('%End\n') stream.write('%End\n')
if module.postInitializerCode: if module.postInitializerCode:
stream.write('\n%s\n\n%%PostInitialisationCode\n' % divider) stream.write('\n%s\n\n%%PostInitialisationCode\n' % divider)
for i in module.postInitializerCode: for i in module.postInitializerCode:
stream.write('%s\n' % i) stream.write('%s\n' % i)
stream.write('%End\n') stream.write('%End\n')
stream.write('\n%s\n' % divider) stream.write('\n%s\n' % divider)
def generateModuleItems(self, module, stream): def generateModuleItems(self, module, stream):
methodMap = { methodMap = {
extractors.ClassDef : self.generateClass, extractors.ClassDef : self.generateClass,
@@ -172,14 +172,14 @@ from .%s import *
extractors.CppMethodDef : self.generateCppMethod, extractors.CppMethodDef : self.generateCppMethod,
extractors.CppMethodDef_sip : self.generateCppMethod_sip, extractors.CppMethodDef_sip : self.generateCppMethod_sip,
} }
for item in module: for item in module:
if item.ignored: if item.ignored:
continue continue
function = methodMap[item.__class__] function = methodMap[item.__class__]
function(item, stream) function(item, stream)
#----------------------------------------------------------------------- #-----------------------------------------------------------------------
def generateFunction(self, function, stream, _needDocstring=True): def generateFunction(self, function, stream, _needDocstring=True):
assert isinstance(function, extractors.FunctionDef) assert isinstance(function, extractors.FunctionDef)
@@ -206,9 +206,9 @@ from .%s import *
raise NotImplementedError() # TODO: See generateMethod for an example, refactor to share code... raise NotImplementedError() # TODO: See generateMethod for an example, refactor to share code...
for f in function.overloads: for f in function.overloads:
self.generateFunction(f, stream, _needDocstring) self.generateFunction(f, stream, _needDocstring)
stream.write('\n') stream.write('\n')
def generateParameters(self, parameters, stream, indent): def generateParameters(self, parameters, stream, indent):
def _lastParameter(idx): def _lastParameter(idx):
if idx == len(parameters)-1: if idx == len(parameters)-1:
@@ -217,7 +217,7 @@ from .%s import *
if not parameters[i].ignored: if not parameters[i].ignored:
return False return False
return True return True
for idx, param in enumerate(parameters): for idx, param in enumerate(parameters):
if param.ignored: if param.ignored:
continue continue
@@ -229,8 +229,8 @@ from .%s import *
if not _lastParameter(idx): if not _lastParameter(idx):
stream.write(',') stream.write(',')
stream.write('\n') stream.write('\n')
#----------------------------------------------------------------------- #-----------------------------------------------------------------------
def generateEnum(self, enum, stream, indent=''): def generateEnum(self, enum, stream, indent=''):
assert isinstance(enum, extractors.EnumDef) assert isinstance(enum, extractors.EnumDef)
@@ -247,8 +247,8 @@ from .%s import *
values.append("%s %s%s" % (indent, v.name, self.annotate(v))) values.append("%s %s%s" % (indent, v.name, self.annotate(v)))
stream.write(',\n'.join(values)) stream.write(',\n'.join(values))
stream.write('%s\n%s};\n\n' % (indent, indent)) stream.write('%s\n%s};\n\n' % (indent, indent))
#----------------------------------------------------------------------- #-----------------------------------------------------------------------
def generateGlobalVar(self, globalVar, stream): def generateGlobalVar(self, globalVar, stream):
assert isinstance(globalVar, extractors.GlobalVarDef) assert isinstance(globalVar, extractors.GlobalVarDef)
@@ -257,14 +257,14 @@ from .%s import *
stream.write('%s %s' % (globalVar.type, globalVar.name)) stream.write('%s %s' % (globalVar.type, globalVar.name))
stream.write('%s;\n\n' % self.annotate(globalVar)) stream.write('%s;\n\n' % self.annotate(globalVar))
#----------------------------------------------------------------------- #-----------------------------------------------------------------------
def generateDefine(self, define, stream): def generateDefine(self, define, stream):
assert isinstance(define, extractors.DefineDef) assert isinstance(define, extractors.DefineDef)
if define.ignored: if define.ignored:
return return
# We're assuming that the #define is either an integer or a string value, # We're assuming that the #define is either an integer or a string value,
# so tell sip that's what it is. # so tell sip that's what it is.
if '"' in define.value: if '"' in define.value:
stream.write('const char* %s;\n' % define.name) stream.write('const char* %s;\n' % define.name)
@@ -274,14 +274,14 @@ from .%s import *
stream.write('%PostInitialisationCode\n') stream.write('%PostInitialisationCode\n')
#stream.write('printf("**** %s: %%d\\n", %s);\n' % (define.name, define.name)) #stream.write('printf("**** %s: %%d\\n", %s);\n' % (define.name, define.name))
stream.write((' PyDict_SetItemString(sipModuleDict, "%s", ' stream.write((' PyDict_SetItemString(sipModuleDict, "%s", '
'wxPyInt_FromLong(static_cast<int>(%s)));\n') % 'wxPyInt_FromLong(static_cast<int>(%s)));\n') %
(define.pyName, define.name)) (define.pyName, define.name))
stream.write('%End\n') stream.write('%End\n')
else: else:
stream.write('const int %s;\n' % define.name) stream.write('const int %s;\n' % define.name)
#----------------------------------------------------------------------- #-----------------------------------------------------------------------
def generateTypedef(self, typedef, stream, indent=''): def generateTypedef(self, typedef, stream, indent=''):
assert isinstance(typedef, extractors.TypedefDef) assert isinstance(typedef, extractors.TypedefDef)
@@ -289,15 +289,15 @@ from .%s import *
return return
stream.write('%stypedef %s %s' % (indent, typedef.type, typedef.name)) stream.write('%stypedef %s %s' % (indent, typedef.type, typedef.name))
stream.write('%s;\n\n' % self.annotate(typedef)) stream.write('%s;\n\n' % self.annotate(typedef))
#----------------------------------------------------------------------- #-----------------------------------------------------------------------
def generateWigCode(self, wig, stream, indent=''): def generateWigCode(self, wig, stream, indent=''):
assert isinstance(wig, extractors.WigCode) assert isinstance(wig, extractors.WigCode)
stream.write(nci(wig.code, len(indent), False)) stream.write(nci(wig.code, len(indent), False))
stream.write('\n\n') stream.write('\n\n')
#----------------------------------------------------------------------- #-----------------------------------------------------------------------
def generatePyCode(self, pc, stream, indent=''): def generatePyCode(self, pc, stream, indent=''):
assert isinstance(pc, extractors.PyCodeDef) assert isinstance(pc, extractors.PyCodeDef)
@@ -314,7 +314,7 @@ from .%s import *
if len(indent) == 0: if len(indent) == 0:
stream.write('\n%End\n\n') stream.write('\n%End\n\n')
#----------------------------------------------------------------------- #-----------------------------------------------------------------------
def generatePyProperty(self, prop, stream, indent=''): def generatePyProperty(self, prop, stream, indent=''):
assert isinstance(prop, extractors.PyPropertyDef) assert isinstance(prop, extractors.PyPropertyDef)
@@ -338,7 +338,7 @@ from .%s import *
setter = prop.setter setter = prop.setter
else: else:
setter = '%s.%s' % (klassName, prop.setter) setter = '%s.%s' % (klassName, prop.setter)
stream.write("%%Extract(id=pycode%s)\n" % self.module_name) stream.write("%%Extract(id=pycode%s)\n" % self.module_name)
stream.write("%s.%s = property(%s" % (klassName, prop.name, getter)) stream.write("%s.%s = property(%s" % (klassName, prop.name, getter))
if prop.setter: if prop.setter:
@@ -372,8 +372,8 @@ from .%s import *
if len(indent) == 0: if len(indent) == 0:
stream.write('\n%End\n') stream.write('\n%End\n')
stream.write('\n') stream.write('\n')
#----------------------------------------------------------------------- #-----------------------------------------------------------------------
def generatePyClass(self, pc, stream, indent=''): def generatePyClass(self, pc, stream, indent=''):
assert isinstance(pc, extractors.PyClassDef) assert isinstance(pc, extractors.PyClassDef)
@@ -411,18 +411,18 @@ from .%s import *
item.klass = pc item.klass = pc
f = dispatch[item.__class__] f = dispatch[item.__class__]
f(item, stream, indent2) f(item, stream, indent2)
if len(indent) == 0: if len(indent) == 0:
stream.write('\n%End\n') stream.write('\n%End\n')
stream.write('\n') stream.write('\n')
#----------------------------------------------------------------------- #-----------------------------------------------------------------------
def generateClass(self, klass, stream, indent=''): def generateClass(self, klass, stream, indent=''):
assert isinstance(klass, extractors.ClassDef) assert isinstance(klass, extractors.ClassDef)
if klass.ignored: if klass.ignored:
return return
# write the class header # write the class header
if klass.templateParams: if klass.templateParams:
stream.write('%stemplate<%s>\n' % (indent, ', '.join(klass.templateParams))) stream.write('%stemplate<%s>\n' % (indent, ', '.join(klass.templateParams)))
@@ -443,20 +443,20 @@ from .%s import *
stream.write('%s #include <%s>\n' % (indent2, inc)) stream.write('%s #include <%s>\n' % (indent2, inc))
stream.write('%s%%End\n\n' % indent2) stream.write('%s%%End\n\n' % indent2)
# C++ code to be written to the Type's header # C++ code to be written to the Type's header
if klass.headerCode: if klass.headerCode:
stream.write("%s%%TypeHeaderCode\n" % indent2) stream.write("%s%%TypeHeaderCode\n" % indent2)
for c in klass.headerCode: for c in klass.headerCode:
stream.write(nci(c, len(indent2)+4)) stream.write(nci(c, len(indent2)+4))
stream.write("%s%%End\n" % indent2) stream.write("%s%%End\n" % indent2)
# C++ code to be written out to the this Type's wrapper code module # C++ code to be written out to the this Type's wrapper code module
if klass.cppCode: if klass.cppCode:
stream.write("%s%%TypeCode\n" % indent2) stream.write("%s%%TypeCode\n" % indent2)
for c in klass.cppCode: for c in klass.cppCode:
stream.write(nci(c, len(indent2)+4)) stream.write(nci(c, len(indent2)+4))
stream.write("%s%%End\n" % indent2) stream.write("%s%%End\n" % indent2)
# C++ code to create a new instance of this class # C++ code to create a new instance of this class
if klass.instanceCode: if klass.instanceCode:
stream.write("%s%%InstanceCode\n" % indent2) stream.write("%s%%InstanceCode\n" % indent2)
@@ -464,19 +464,19 @@ from .%s import *
stream.write("%s%%End\n" % indent2) stream.write("%s%%End\n" % indent2)
# is the generator currently inside the class or after it? # is the generator currently inside the class or after it?
klass.generatingInClass = True klass.generatingInClass = True
# Split the items into public and protected groups # Split the items into public and protected groups
ctors = [i for i in klass if ctors = [i for i in klass if
isinstance(i, extractors.MethodDef) and isinstance(i, extractors.MethodDef) and
i.protection == 'public' and (i.isCtor or i.isDtor)] i.protection == 'public' and (i.isCtor or i.isDtor)]
enums = [i for i in klass if enums = [i for i in klass if
isinstance(i, extractors.EnumDef) and isinstance(i, extractors.EnumDef) and
i.protection == 'public'] i.protection == 'public']
public = [i for i in klass if i.protection == 'public' and i not in ctors+enums] public = [i for i in klass if i.protection == 'public' and i not in ctors+enums]
protected = [i for i in klass if i.protection == 'protected'] protected = [i for i in klass if i.protection == 'protected']
private = [i for i in klass if i.protection == 'private'] private = [i for i in klass if i.protection == 'private']
if klass.kind == 'class': if klass.kind == 'class':
stream.write('%spublic:\n' % indent) stream.write('%spublic:\n' % indent)
@@ -484,18 +484,18 @@ from .%s import *
# methods or in nested classes # methods or in nested classes
for item in enums: for item in enums:
self.dispatchClassItem(klass, item, stream, indent2) self.dispatchClassItem(klass, item, stream, indent2)
# Next do inner classes # Next do inner classes
for item in klass.innerclasses: for item in klass.innerclasses:
if klass.kind == 'class': if klass.kind == 'class':
stream.write('%s%s:\n' % (indent, item.protection)) stream.write('%s%s:\n' % (indent, item.protection))
item.klass = klass item.klass = klass
self.generateClass(item, stream, indent2) self.generateClass(item, stream, indent2)
# and then the ctors and the rest of the items in the class # and then the ctors and the rest of the items in the class
for item in ctors: for item in ctors:
self.dispatchClassItem(klass, item, stream, indent2) self.dispatchClassItem(klass, item, stream, indent2)
for item in public: for item in public:
self.dispatchClassItem(klass, item, stream, indent2) self.dispatchClassItem(klass, item, stream, indent2)
@@ -518,16 +518,16 @@ from .%s import *
self.generateConvertCode('%ConvertFromTypeCode', self.generateConvertCode('%ConvertFromTypeCode',
klass.convertToPyObject, klass.convertToPyObject,
stream, indent + ' '*4) stream, indent + ' '*4)
stream.write('%s}; // end of class %s\n\n\n' % (indent, klass.name)) stream.write('%s}; // end of class %s\n\n\n' % (indent, klass.name))
# Now generate anything that was deferred until after the class is finished # Now generate anything that was deferred until after the class is finished
klass.generatingInClass = False klass.generatingInClass = False
for item in klass.generateAfterClass: for item in klass.generateAfterClass:
self.dispatchClassItem(klass, item, stream, indent) self.dispatchClassItem(klass, item, stream, indent)
def dispatchClassItem(self, klass, item, stream, indent): def dispatchClassItem(self, klass, item, stream, indent):
dispatch = { dispatch = {
extractors.TypedefDef : self.generateTypedef, extractors.TypedefDef : self.generateTypedef,
@@ -551,8 +551,8 @@ from .%s import *
stream.write('%s%s\n' % (indent, kind)) stream.write('%s%s\n' % (indent, kind))
stream.write(nci(code, len(indent)+4)) stream.write(nci(code, len(indent)+4))
stream.write('%s%%End\n' % indent) stream.write('%s%%End\n' % indent)
def generateMemberVar(self, memberVar, stream, indent): def generateMemberVar(self, memberVar, stream, indent):
assert isinstance(memberVar, extractors.MemberVarDef) assert isinstance(memberVar, extractors.MemberVarDef)
if memberVar.ignored: if memberVar.ignored:
@@ -560,7 +560,7 @@ from .%s import *
stream.write('%s%s %s' % (indent, memberVar.type, memberVar.name)) stream.write('%s%s %s' % (indent, memberVar.type, memberVar.name))
stream.write('%s;\n\n' % self.annotate(memberVar)) stream.write('%s;\n\n' % self.annotate(memberVar))
def generateProperty(self, prop, stream, indent): def generateProperty(self, prop, stream, indent):
assert isinstance(prop, extractors.PropertyDef) assert isinstance(prop, extractors.PropertyDef)
if prop.ignored: if prop.ignored:
@@ -572,18 +572,18 @@ from .%s import *
if prop.briefDoc: if prop.briefDoc:
stream.write(' // %s' % prop.briefDoc) stream.write(' // %s' % prop.briefDoc)
stream.write('\n') stream.write('\n')
def generateDocstring(self, item, stream, indent): def generateDocstring(self, item, stream, indent):
item.pyDocstring = "" item.pyDocstring = ""
if item.name.startswith('operator'): if item.name.startswith('operator'):
return # Apparently sip doesn't like operators to have docstrings... return # Apparently sip doesn't like operators to have docstrings...
# get the docstring text # get the docstring text
text = nci(extractors.flattenNode(item.briefDoc, False)) text = nci(extractors.flattenNode(item.briefDoc, False))
text = wrapText(text) text = wrapText(text)
#if isinstance(item, extractors.ClassDef): #if isinstance(item, extractors.ClassDef):
# # append the function signatures for the class constructors (if any) to the class' docstring # # append the function signatures for the class constructors (if any) to the class' docstring
@@ -596,12 +596,12 @@ from .%s import *
# pass # pass
#else: #else:
# # Prepend function signature string(s) for functions and methods # # Prepend function signature string(s) for functions and methods
# sigs = item.collectPySignatures() # sigs = item.collectPySignatures()
# if sigs: # if sigs:
# if text: # if text:
# text = '\n\n' + text # text = '\n\n' + text
# text = '\n'.join(sigs) + text # text = '\n'.join(sigs) + text
sigs = None sigs = None
if isinstance(item, extractors.ClassDef): if isinstance(item, extractors.ClassDef):
try: try:
@@ -610,12 +610,12 @@ from .%s import *
except extractors.ExtractorError: except extractors.ExtractorError:
pass pass
else: else:
sigs = item.collectPySignatures() sigs = item.collectPySignatures()
if sigs: if sigs:
if text: if text:
text = '\n\n' + text text = '\n\n' + text
text = '\n'.join(sigs) + text text = '\n'.join(sigs) + text
# write the docstring directive and the text # write the docstring directive and the text
stream.write('%s%%Docstring\n' % indent) stream.write('%s%%Docstring\n' % indent)
stream.write(nci(text, len(indent)+4)) stream.write(nci(text, len(indent)+4))
@@ -625,7 +625,7 @@ from .%s import *
# generators later on # generators later on
item.pyDocstring = nci(text) item.pyDocstring = nci(text)
def generateMethod(self, method, stream, indent): def generateMethod(self, method, stream, indent):
assert isinstance(method, extractors.MethodDef) assert isinstance(method, extractors.MethodDef)
_needDocstring = getattr(method, '_needDocstring', True) _needDocstring = getattr(method, '_needDocstring', True)
@@ -648,17 +648,17 @@ from .%s import *
stream.write(' const') stream.write(' const')
if method.isPureVirtual: if method.isPureVirtual:
stream.write(' = 0') stream.write(' = 0')
cppSig = " [ %s ]" % method.cppSignature if method.cppSignature else "" cppSig = " [ %s ]" % method.cppSignature if method.cppSignature else ""
if cppSig: if cppSig:
stream.write(cppSig) stream.write(cppSig)
stream.write('%s;\n' % self.annotate(method)) stream.write('%s;\n' % self.annotate(method))
if _needDocstring and not (method.isCtor or method.isDtor): if _needDocstring and not (method.isCtor or method.isDtor):
self.generateDocstring(method, stream, indent) self.generateDocstring(method, stream, indent)
# We only write a docstring for the first overload, otherwise # We only write a docstring for the first overload, otherwise
# SIP appends them all together. # SIP appends them all together.
_needDocstring = False _needDocstring = False
if method.cppCode: if method.cppCode:
#checkOverloads = False ## SIP now allows overloads to have %MethodCode #checkOverloads = False ## SIP now allows overloads to have %MethodCode
code, codeType = method.cppCode code, codeType = method.cppCode
@@ -674,25 +674,25 @@ from .%s import *
# and virtual catcher code, so we can just return from # and virtual catcher code, so we can just return from
# here. # here.
return return
if method.virtualCatcherCode: if method.virtualCatcherCode:
stream.write('%s%%VirtualCatcherCode\n' % indent) stream.write('%s%%VirtualCatcherCode\n' % indent)
stream.write(nci(method.virtualCatcherCode, len(indent)+4)) stream.write(nci(method.virtualCatcherCode, len(indent)+4))
stream.write('%s%%End\n' % indent) stream.write('%s%%End\n' % indent)
stream.write('\n') stream.write('\n')
if checkOverloads and method.overloads: if checkOverloads and method.overloads:
for m in method.overloads: for m in method.overloads:
m._needDocstring = _needDocstring m._needDocstring = _needDocstring
self.dispatchClassItem(method.klass, m, stream, indent) self.dispatchClassItem(method.klass, m, stream, indent)
def generateCppMethod(self, method, stream, indent='', skipDeclaration=False): def generateCppMethod(self, method, stream, indent='', skipDeclaration=False):
# Add a new C++ method to a class. This one adds the code as a # Add a new C++ method to a class. This one adds the code as a
# separate function and then adds a call to that function in the # separate function and then adds a call to that function in the
# MethodCode directive. # MethodCode directive.
def _removeIgnoredParams(argsString, paramList): def _removeIgnoredParams(argsString, paramList):
# if there are ignored parameters adjust the argsString to match # if there are ignored parameters adjust the argsString to match
lastP = argsString.rfind(')') lastP = argsString.rfind(')')
@@ -702,7 +702,7 @@ from .%s import *
args[idx] = '' args[idx] = ''
args = [a for a in args if a != ''] args = [a for a in args if a != '']
return '(' + ', '.join(args) + ')' return '(' + ', '.join(args) + ')'
assert isinstance(method, extractors.CppMethodDef) assert isinstance(method, extractors.CppMethodDef)
if method.ignored: if method.ignored:
return return
@@ -713,40 +713,40 @@ from .%s import *
pnames = argsString[:lastP].strip('()').split(',') pnames = argsString[:lastP].strip('()').split(',')
for idx, pn in enumerate(pnames): for idx, pn in enumerate(pnames):
# take only the part before the =, if there is one # take only the part before the =, if there is one
name = pn.split('=')[0].strip() name = pn.split('=')[0].strip()
# remove annotations # remove annotations
name = re.sub('/[A-Za-z]*/', '', name) name = re.sub('/[A-Za-z]*/', '', name)
name = name.strip() name = name.strip()
# now get just the part after any space, * or &, which should be # now get just the part after any space, * or &, which should be
# the parameter name # the parameter name
name = re.split(r'[ \*\&]+', name)[-1] name = re.split(r'[ \*\&]+', name)[-1]
pnames[idx] = name pnames[idx] = name
pnames = ', '.join(pnames) pnames = ', '.join(pnames)
typ = method.type typ = method.type
if not skipDeclaration: if not skipDeclaration:
cppSig = " [ %s ]" % method.cppSignature if method.cppSignature else "" cppSig = " [ %s ]" % method.cppSignature if method.cppSignature else ""
# First insert the method declaration # First insert the method declaration
if method.isCtor or method.isDtor: if method.isCtor or method.isDtor:
virtual = 'virtual ' if method.isVirtual else '' virtual = 'virtual ' if method.isVirtual else ''
stream.write('%s%s%s%s%s%s;\n' % stream.write('%s%s%s%s%s%s;\n' %
(indent, virtual, method.name, argsString, self.annotate(method), cppSig)) (indent, virtual, method.name, argsString, self.annotate(method), cppSig))
else: else:
constMod = " const" if method.isConst else "" constMod = " const" if method.isConst else ""
static = "static " if method.isStatic else "" static = "static " if method.isStatic else ""
virtual = "virtual " if method.isVirtual else "" virtual = "virtual " if method.isVirtual else ""
pure = " = 0" if method.isPureVirtual else "" pure = " = 0" if method.isPureVirtual else ""
stream.write('%s%s%s%s %s%s%s%s%s%s;\n' % stream.write('%s%s%s%s %s%s%s%s%s%s;\n' %
(indent, static, virtual, typ, (indent, static, virtual, typ,
method.name, argsString, constMod, pure, self.annotate(method), cppSig)) method.name, argsString, constMod, pure, self.annotate(method), cppSig))
# write the docstring # write the docstring
if _needDocstring and not (method.isCtor or method.isDtor): if _needDocstring and not (method.isCtor or method.isDtor):
self.generateDocstring(method, stream, indent) self.generateDocstring(method, stream, indent)
# We only write a docstring for the first overload, otherwise # We only write a docstring for the first overload, otherwise
# SIP appends them all together. # SIP appends them all together.
_needDocstring = False _needDocstring = False
klass = method.klass klass = method.klass
if klass: if klass:
assert isinstance(klass, extractors.ClassDef) assert isinstance(klass, extractors.ClassDef)
@@ -757,7 +757,7 @@ from .%s import *
fargs = argsString[:lastP].strip('()').split(',') fargs = argsString[:lastP].strip('()').split(',')
for idx, arg in enumerate(fargs): for idx, arg in enumerate(fargs):
# take only the part before the =, if there is one # take only the part before the =, if there is one
arg = arg.split('=')[0].strip() arg = arg.split('=')[0].strip()
arg = arg.replace('&', '*') # SIP will always want to use pointers for parameters arg = arg.replace('&', '*') # SIP will always want to use pointers for parameters
arg = re.sub('/[A-Za-z]*/', '', arg) # remove annotations arg = re.sub('/[A-Za-z]*/', '', arg) # remove annotations
fargs[idx] = arg fargs[idx] = arg
@@ -774,7 +774,7 @@ from .%s import *
fstream.write(nci(method.body, len(indent)+4)) fstream.write(nci(method.body, len(indent)+4))
fstream.write('%s}\n' % indent) fstream.write('%s}\n' % indent)
fstream.write('%s%%End\n' % indent) fstream.write('%s%%End\n' % indent)
elif method.isDtor: elif method.isDtor:
fname = '_%s_dtor' % klass.name fname = '_%s_dtor' % klass.name
fargs = '(%s* self)' % klass.name fargs = '(%s* self)' % klass.name
@@ -783,7 +783,7 @@ from .%s import *
fstream.write(nci(method.body, len(indent)+4)) fstream.write(nci(method.body, len(indent)+4))
fstream.write('%s}\n' % indent) fstream.write('%s}\n' % indent)
fstream.write('%s%%End\n' % indent) fstream.write('%s%%End\n' % indent)
else: else:
if klass: if klass:
fname = '_%s_%s' % (klass.name, method.name) fname = '_%s_%s' % (klass.name, method.name)
@@ -803,7 +803,7 @@ from .%s import *
fname = '_%s_function' % method.name fname = '_%s_function' % method.name
fargs = '(%s)' % fargs fargs = '(%s)' % fargs
fstream.write('%s%%ModuleCode\n' % indent) fstream.write('%s%%ModuleCode\n' % indent)
# If the return type is in the forcePtrTypes list then make sure # If the return type is in the forcePtrTypes list then make sure
# that it is a pointer, not a return by value or reference, since # that it is a pointer, not a return by value or reference, since
# SIP almost always deals with pointers to newly allocated # SIP almost always deals with pointers to newly allocated
@@ -814,7 +814,7 @@ from .%s import *
typPtr.replace('&', '*') typPtr.replace('&', '*')
elif '*' not in typPtr: elif '*' not in typPtr:
typPtr += '*' typPtr += '*'
fstream.write('%s%s %s%s\n%s{\n' % (indent, typPtr, fname, fargs, indent)) fstream.write('%s%s %s%s\n%s{\n' % (indent, typPtr, fname, fargs, indent))
fstream.write(nci(method.body, len(indent)+4)) fstream.write(nci(method.body, len(indent)+4))
fstream.write('%s}\n' % indent) fstream.write('%s}\n' % indent)
@@ -827,14 +827,14 @@ from .%s import *
# _THREAD macros are intentionally not used in this case # _THREAD macros are intentionally not used in this case
stream.write('PyErr_Clear();\n') stream.write('PyErr_Clear();\n')
stream.write('%ssipCpp = %s(%s);\n' % (indent+' '*4, fname, pnames)) stream.write('%ssipCpp = %s(%s);\n' % (indent+' '*4, fname, pnames))
elif method.isDtor: elif method.isDtor:
stream.write('PyErr_Clear();\n') stream.write('PyErr_Clear();\n')
stream.write('%sPy_BEGIN_ALLOW_THREADS\n' % (indent+' '*4)) stream.write('%sPy_BEGIN_ALLOW_THREADS\n' % (indent+' '*4))
stream.write(indent+' '*4) stream.write(indent+' '*4)
stream.write('%s(sipCpp);\n' % fname) stream.write('%s(sipCpp);\n' % fname)
stream.write('%sPy_END_ALLOW_THREADS\n' % (indent+' '*4)) stream.write('%sPy_END_ALLOW_THREADS\n' % (indent+' '*4))
else: else:
stream.write('PyErr_Clear();\n') stream.write('PyErr_Clear();\n')
stream.write('%sPy_BEGIN_ALLOW_THREADS\n' % (indent+' '*4)) stream.write('%sPy_BEGIN_ALLOW_THREADS\n' % (indent+' '*4))
@@ -852,7 +852,7 @@ from .%s import *
stream.write('%s(sipCpp%s);\n' % (fname, pnames)) stream.write('%s(sipCpp%s);\n' % (fname, pnames))
else: else:
stream.write('%s(%s);\n' % (fname, pnames)) stream.write('%s(%s);\n' % (fname, pnames))
stream.write('%sPy_END_ALLOW_THREADS\n' % (indent+' '*4)) stream.write('%sPy_END_ALLOW_THREADS\n' % (indent+' '*4))
stream.write('%sif (PyErr_Occurred()) sipIsErr = 1;\n' % (indent+' '*4)) stream.write('%sif (PyErr_Occurred()) sipIsErr = 1;\n' % (indent+' '*4))
stream.write('%s%%End\n' % indent) stream.write('%s%%End\n' % indent)
@@ -860,7 +860,7 @@ from .%s import *
stream.write('%s%%VirtualCatcherCode\n' % indent) stream.write('%s%%VirtualCatcherCode\n' % indent)
stream.write(nci(method.virtualCatcherCode, len(indent)+4)) stream.write(nci(method.virtualCatcherCode, len(indent)+4))
stream.write('%s%%End\n' % indent) stream.write('%s%%End\n' % indent)
# and finally, add the new function itself # and finally, add the new function itself
stream.write(fstream.getvalue()) stream.write(fstream.getvalue())
stream.write('\n') stream.write('\n')
@@ -869,29 +869,29 @@ from .%s import *
for m in method.overloads: for m in method.overloads:
m._needDocstring = _needDocstring m._needDocstring = _needDocstring
self.dispatchClassItem(method.klass, m, stream, indent) self.dispatchClassItem(method.klass, m, stream, indent)
def generateCppMethod_sip(self, method, stream, indent=''): def generateCppMethod_sip(self, method, stream, indent=''):
# Add a new C++ method to a class without the extra generated # Add a new C++ method to a class without the extra generated
# function, so SIP specific stuff can be done in the function body. # function, so SIP specific stuff can be done in the function body.
assert isinstance(method, extractors.CppMethodDef_sip) assert isinstance(method, extractors.CppMethodDef_sip)
if method.ignored: if method.ignored:
return return
cppSig = " [ %s ]" % method.cppSignature if method.cppSignature else "" cppSig = " [ %s ]" % method.cppSignature if method.cppSignature else ""
if method.isCtor: if method.isCtor:
stream.write('%s%s%s%s%s;\n' % stream.write('%s%s%s%s%s;\n' %
(indent, method.name, method.argsString, self.annotate(method), cppSig)) (indent, method.name, method.argsString, self.annotate(method), cppSig))
else: else:
stream.write('%s%s %s%s%s%s;\n' % stream.write('%s%s %s%s%s%s;\n' %
(indent, method.type, method.name, method.argsString, (indent, method.type, method.name, method.argsString,
self.annotate(method), cppSig)) self.annotate(method), cppSig))
stream.write('%s%%MethodCode\n' % indent) stream.write('%s%%MethodCode\n' % indent)
stream.write(nci(method.body, len(indent)+4)) stream.write(nci(method.body, len(indent)+4))
stream.write('%s%%End\n\n' % indent) stream.write('%s%%End\n\n' % indent)
def generatePyMethod(self, pm, stream, indent): def generatePyMethod(self, pm, stream, indent):
assert isinstance(pm, extractors.PyMethodDef) assert isinstance(pm, extractors.PyMethodDef)
if pm.ignored: if pm.ignored:
@@ -943,7 +943,7 @@ from .%s import *
annotations.append('ArraySize') annotations.append('ArraySize')
if item.keepReference: if item.keepReference:
annotations.append('KeepReference') annotations.append('KeepReference')
if isinstance(item, (extractors.ParamDef, extractors.FunctionDef)): if isinstance(item, (extractors.ParamDef, extractors.FunctionDef)):
if item.transfer: if item.transfer:
annotations.append('Transfer') annotations.append('Transfer')
@@ -953,7 +953,7 @@ from .%s import *
annotations.append('TransferThis') annotations.append('TransferThis')
if item.pyInt: if item.pyInt:
annotations.append('PyInt') annotations.append('PyInt')
if isinstance(item, extractors.VariableDef): if isinstance(item, extractors.VariableDef):
if item.pyInt: if item.pyInt:
annotations.append('PyInt') annotations.append('PyInt')
@@ -967,21 +967,21 @@ from .%s import *
annotations.append('Deprecated') annotations.append('Deprecated')
if item.factory: if item.factory:
annotations.append('Factory') annotations.append('Factory')
if item.pyReleaseGIL: if item.pyReleaseGIL:
annotations.append('ReleaseGIL') annotations.append('ReleaseGIL')
if item.pyHoldGIL: if item.pyHoldGIL:
annotations.append('HoldGIL') annotations.append('HoldGIL')
if item.noCopy: if item.noCopy:
annotations.append('NoCopy') annotations.append('NoCopy')
if item.noArgParser: if item.noArgParser:
annotations.append('NoArgParser') annotations.append('NoArgParser')
if isinstance(item, extractors.MethodDef): if isinstance(item, extractors.MethodDef):
if item.defaultCtor: if item.defaultCtor:
annotations.append('Default') annotations.append('Default')
if item.noDerivedCtor: if item.noDerivedCtor:
annotations.append('NoDerived') annotations.append('NoDerived')
if isinstance(item, extractors.ClassDef): if isinstance(item, extractors.ClassDef):
if item.abstract: if item.abstract:
annotations.append('Abstract') annotations.append('Abstract')
@@ -995,7 +995,7 @@ from .%s import *
annotations.append('NoDefaultCtors') annotations.append('NoDefaultCtors')
if item.singlton: if item.singlton:
annotations.append('DelayDtor') annotations.append('DelayDtor')
if annotations: if annotations:
return ' /%s/' % ', '.join(annotations) return ' /%s/' % ', '.join(annotations)
else: else:

File diff suppressed because it is too large Load Diff

View File

@@ -54,7 +54,7 @@ def removeWxPrefixes(node):
if item.name.startswith('wxEVT_') and 'CATEGORY' not in item.name: if item.name.startswith('wxEVT_') and 'CATEGORY' not in item.name:
# give these their actual name so the auto-renamer won't touch them # give these their actual name so the auto-renamer won't touch them
item.pyName = item.name item.pyName = item.name
def removeWxPrefix(name): def removeWxPrefix(name):
""" """
@@ -62,13 +62,13 @@ def removeWxPrefix(name):
""" """
if name.startswith('wx.') or name.startswith('``wx.'): if name.startswith('wx.') or name.startswith('``wx.'):
return name return name
if name.startswith('wx') and not name.startswith('wxEVT_'): if name.startswith('wx') and not name.startswith('wxEVT_'):
name = name[2:] name = name[2:]
if name.startswith('``wx') and not name.startswith('``wxEVT_'): if name.startswith('``wx') and not name.startswith('``wxEVT_'):
name = name[0:2] + name[4:] name = name[0:2] + name[4:]
return name return name
@@ -78,25 +78,25 @@ class FixWxPrefix(object):
A mixin class that can help with removing the wx prefix, or changing it A mixin class that can help with removing the wx prefix, or changing it
in to a "wx.Name" depending on where it is being used from. in to a "wx.Name" depending on where it is being used from.
""" """
_coreTopLevelNames = None _coreTopLevelNames = None
def fixWxPrefix(self, name, checkIsCore=False): def fixWxPrefix(self, name, checkIsCore=False):
# By default remove the wx prefix like normal # By default remove the wx prefix like normal
name = removeWxPrefix(name) name = removeWxPrefix(name)
if not checkIsCore or self.isCore: if not checkIsCore or self.isCore:
return name return name
# Otherwise, if we're not processing the core module currently then check # Otherwise, if we're not processing the core module currently then check
# if the name is local or if it resides in core. If it does then return # if the name is local or if it resides in core. If it does then return
# the name as 'wx.Name' # the name as 'wx.Name'
if FixWxPrefix._coreTopLevelNames is None: if FixWxPrefix._coreTopLevelNames is None:
self._getCoreTopLevelNames() self._getCoreTopLevelNames()
testName = name testName = name
if '(' in name: if '(' in name:
testName = name[:name.find('(')] testName = name[:name.find('(')]
if testName in FixWxPrefix._coreTopLevelNames: if testName in FixWxPrefix._coreTopLevelNames:
return 'wx.'+name return 'wx.'+name
else: else:
@@ -119,7 +119,7 @@ class FixWxPrefix(object):
names.append(item.name) names.append(item.name)
elif isinstance(item, ast.FunctionDef): elif isinstance(item, ast.FunctionDef):
names.append(item.name) names.append(item.name)
names = list() names = list()
filename = 'wx/core.pi' filename = 'wx/core.pi'
if PY3: if PY3:
@@ -133,8 +133,8 @@ class FixWxPrefix(object):
_processItem(item, names) _processItem(item, names)
FixWxPrefix._coreTopLevelNames = names FixWxPrefix._coreTopLevelNames = names
def ignoreAssignmentOperators(node): def ignoreAssignmentOperators(node):
@@ -145,7 +145,7 @@ def ignoreAssignmentOperators(node):
if isinstance(item, extractors.MethodDef) and item.name == 'operator=': if isinstance(item, extractors.MethodDef) and item.name == 'operator=':
item.ignore() item.ignore()
def ignoreAllOperators(node): def ignoreAllOperators(node):
""" """
Set the ignored flag for all class methods that are any kind of operator Set the ignored flag for all class methods that are any kind of operator
@@ -170,7 +170,7 @@ def ignoreConstOverloads(node):
item2 = overloads[j] item2 = overloads[j]
if item1.ignored or item2.ignored: if item1.ignored or item2.ignored:
continue continue
if (item1.argsString.replace(' const', '').strip() == if (item1.argsString.replace(' const', '').strip() ==
item2.argsString.replace(' const', '').strip()): item2.argsString.replace(' const', '').strip()):
if item1.isConst: if item1.isConst:
item1.ignore() item1.ignore()
@@ -178,13 +178,13 @@ def ignoreConstOverloads(node):
elif item2.isConst: elif item2.isConst:
item2.ignore() item2.ignore()
return return
for item in node.items: for item in node.items:
if isinstance(item, extractors.MethodDef) and item.overloads: if isinstance(item, extractors.MethodDef) and item.overloads:
_checkOverloads(item) _checkOverloads(item)
def addAutoProperties(node): def addAutoProperties(node):
""" """
Call klass.addAutoProperties for all classes in node with Call klass.addAutoProperties for all classes in node with
@@ -199,7 +199,7 @@ def addAutoProperties(node):
continue continue
item.addAutoProperties() item.addAutoProperties()
def fixEventClass(klass, ignoreProtected=True): def fixEventClass(klass, ignoreProtected=True):
""" """
Add the extra stuff that an event class needs that are lacking from the Add the extra stuff that an event class needs that are lacking from the
@@ -223,9 +223,9 @@ def fixEventClass(klass, ignoreProtected=True):
for item in klass.allItems(): for item in klass.allItems():
if isinstance(item, extractors.MethodDef) and item.protection == 'protected': if isinstance(item, extractors.MethodDef) and item.protection == 'protected':
item.ignore(False) item.ignore(False)
def fixWindowClass(klass, hideVirtuals=True, ignoreProtected=True): def fixWindowClass(klass, hideVirtuals=True, ignoreProtected=True):
""" """
Do common tweaks for a window class. Do common tweaks for a window class.
@@ -267,7 +267,7 @@ def fixWindowClass(klass, hideVirtuals=True, ignoreProtected=True):
def fixTopLevelWindowClass(klass, hideVirtuals=True, ignoreProtected=True): def fixTopLevelWindowClass(klass, hideVirtuals=True, ignoreProtected=True):
""" """
Tweaks for TLWs Tweaks for TLWs
""" """
# TLW tweaks are a little different. We use the function annotation for # TLW tweaks are a little different. We use the function annotation for
# TransferThis instead of the argument annotation. # TransferThis instead of the argument annotation.
@@ -306,17 +306,17 @@ def fixSizerClass(klass):
removeVirtuals(klass) removeVirtuals(klass)
klass.find('CalcMin').isVirtual = True klass.find('CalcMin').isVirtual = True
klass.find('RecalcSizes').isVirtual = True klass.find('RecalcSizes').isVirtual = True
# in the wxSizer class they are pure-virtual # in the wxSizer class they are pure-virtual
if klass.name == 'wxSizer': if klass.name == 'wxSizer':
klass.find('CalcMin').isPureVirtual = True klass.find('CalcMin').isPureVirtual = True
klass.find('RecalcSizes').isPureVirtual = True klass.find('RecalcSizes').isPureVirtual = True
def fixBookctrlClass(klass, treeBook=False): def fixBookctrlClass(klass, treeBook=False):
""" """
Add declarations of the pure virtual methods from the base class. Add declarations of the pure virtual methods from the base class.
""" """
klass.addItem(extractors.WigCode("""\ klass.addItem(extractors.WigCode("""\
virtual int GetPageImage(size_t nPage) const; virtual int GetPageImage(size_t nPage) const;
virtual bool SetPageImage(size_t page, int image); virtual bool SetPageImage(size_t page, int image);
@@ -332,7 +332,7 @@ def fixBookctrlClass(klass, treeBook=False):
bool select = false, int imageId = NO_IMAGE); bool select = false, int imageId = NO_IMAGE);
""")) """))
def fixHtmlSetFonts(klass): def fixHtmlSetFonts(klass):
# Use wxArrayInt instead of a C array of ints. # Use wxArrayInt instead of a C array of ints.
m = klass.find('SetFonts') m = klass.find('SetFonts')
@@ -373,13 +373,13 @@ def removeVirtuals(klass):
if isinstance(item, extractors.MethodDef): if isinstance(item, extractors.MethodDef):
item.isVirtual = item.isPureVirtual = False item.isVirtual = item.isPureVirtual = False
def addWindowVirtuals(klass): def addWindowVirtuals(klass):
""" """
Either turn the virtual flag back on or add a declaration for the subset of Either turn the virtual flag back on or add a declaration for the subset of
the C++ virtuals in wxWindow classes that we will be supporting. the C++ virtuals in wxWindow classes that we will be supporting.
""" """
publicWindowVirtuals = [ publicWindowVirtuals = [
('GetClientAreaOrigin', 'wxPoint GetClientAreaOrigin() const'), ('GetClientAreaOrigin', 'wxPoint GetClientAreaOrigin() const'),
('Validate', 'bool Validate()'), ('Validate', 'bool Validate()'),
('TransferDataToWindow', 'bool TransferDataToWindow()'), ('TransferDataToWindow', 'bool TransferDataToWindow()'),
@@ -393,19 +393,19 @@ def addWindowVirtuals(klass):
('InheritAttributes', 'void InheritAttributes()'), ('InheritAttributes', 'void InheritAttributes()'),
('ShouldInheritColours', 'bool ShouldInheritColours() const'), ('ShouldInheritColours', 'bool ShouldInheritColours() const'),
('OnInternalIdle', 'void OnInternalIdle()'), ('OnInternalIdle', 'void OnInternalIdle()'),
('GetMainWindowOfCompositeControl', ('GetMainWindowOfCompositeControl',
'wxWindow *GetMainWindowOfCompositeControl()'), 'wxWindow *GetMainWindowOfCompositeControl()'),
('InformFirstDirection', 'bool InformFirstDirection(int direction, int size, int availableOtherDir)'), ('InformFirstDirection', 'bool InformFirstDirection(int direction, int size, int availableOtherDir)'),
('SetCanFocus', 'void SetCanFocus(bool canFocus)'), ('SetCanFocus', 'void SetCanFocus(bool canFocus)'),
('Destroy', 'bool Destroy()'), ('Destroy', 'bool Destroy()'),
## What about these? ## What about these?
#bool HasMultiplePages() const #bool HasMultiplePages() const
#void UpdateWindowUI(long flags = wxUPDATE_UI_NONE); #void UpdateWindowUI(long flags = wxUPDATE_UI_NONE);
#void DoUpdateWindowUI(wxUpdateUIEvent& event) ; #void DoUpdateWindowUI(wxUpdateUIEvent& event) ;
] ]
protectedWindowVirtuals = [ protectedWindowVirtuals = [
('ProcessEvent', 'bool ProcessEvent(wxEvent & event)'), ('ProcessEvent', 'bool ProcessEvent(wxEvent & event)'),
('DoEnable', 'void DoEnable(bool enable)'), ('DoEnable', 'void DoEnable(bool enable)'),
('DoGetPosition', 'void DoGetPosition(int *x, int *y) const'), ('DoGetPosition', 'void DoGetPosition(int *x, int *y) const'),
@@ -432,7 +432,7 @@ def addWindowVirtuals(klass):
#('DoSetVirtualSize', 'void DoSetVirtualSize( int x, int y )'), #('DoSetVirtualSize', 'void DoSetVirtualSize( int x, int y )'),
#('DoGetVirtualSize', 'wxSize DoGetVirtualSize() const'), #('DoGetVirtualSize', 'wxSize DoGetVirtualSize() const'),
] ]
def _processItems(klass, prot, virtuals): def _processItems(klass, prot, virtuals):
txt = '' txt = ''
for name, decl in virtuals: for name, decl in virtuals:
@@ -445,14 +445,14 @@ def addWindowVirtuals(klass):
if txt: if txt:
txt = prot + txt txt = prot + txt
return txt return txt
txt = _processItems(klass, 'public:\n', publicWindowVirtuals) txt = _processItems(klass, 'public:\n', publicWindowVirtuals)
klass.addItem(extractors.WigCode(txt)) klass.addItem(extractors.WigCode(txt))
txt = _processItems(klass, 'protected:\n', protectedWindowVirtuals) txt = _processItems(klass, 'protected:\n', protectedWindowVirtuals)
klass.addItem(extractors.WigCode(txt)) klass.addItem(extractors.WigCode(txt))
klass.addPublic() klass.addPublic()
def addSipConvertToSubClassCode(klass): def addSipConvertToSubClassCode(klass):
""" """
Teach SIP how to convert to specific subclass types Teach SIP how to convert to specific subclass types
@@ -467,14 +467,14 @@ def addSipConvertToSubClassCode(klass):
name = info->GetClassName(); name = info->GetClassName();
exists = sipFindType(name) != NULL; exists = sipFindType(name) != NULL;
} }
if (info) if (info)
sipType = sipFindType(name); sipType = sipFindType(name);
else else
sipType = NULL; sipType = NULL;
%End %End
""")) """))
def getEtgFiles(names): def getEtgFiles(names):
""" """
Create a list of the files from the basenames in the names list that Create a list of the files from the basenames in the names list that
@@ -490,7 +490,7 @@ def getNonEtgFiles(names, template='src/%s.sip'):
""" """
return getMatchingFiles(names, template) return getMatchingFiles(names, template)
def getMatchingFiles(names, template): def getMatchingFiles(names, template):
""" """
Create a list of files from the basenames in names that match the template Create a list of files from the basenames in names that match the template
@@ -502,9 +502,9 @@ def getMatchingFiles(names, template):
if os.path.exists(name): if os.path.exists(name):
files.append(name) files.append(name)
return files return files
def doCommonTweaks(module): def doCommonTweaks(module):
""" """
A collection of tweaks that should probably be done to all modules. A collection of tweaks that should probably be done to all modules.
@@ -512,8 +512,8 @@ def doCommonTweaks(module):
ignoreAssignmentOperators(module) ignoreAssignmentOperators(module)
removeWxPrefixes(module) removeWxPrefixes(module)
addAutoProperties(module) addAutoProperties(module)
def changeTypeNames(module, oldName, newName, skipTypedef=False): def changeTypeNames(module, oldName, newName, skipTypedef=False):
""" """
Changes the matching type names for functions and parameters to a new Changes the matching type names for functions and parameters to a new
@@ -559,13 +559,13 @@ def getWrapperGenerator():
else: else:
# The default is sip # The default is sip
from etgtools import sip_generator from etgtools import sip_generator
gClass = sip_generator.SipWrapperGenerator gClass = sip_generator.SipWrapperGenerator
return gClass() return gClass()
def getDocsGenerator(): def getDocsGenerator():
if '--nodoc' in sys.argv: if '--nodoc' in sys.argv:
from etgtools import generators from etgtools import generators
return generators.StubbedDocsGenerator() return generators.StubbedDocsGenerator()
elif '--sphinx' in sys.argv: elif '--sphinx' in sys.argv:
from etgtools import sphinx_generator from etgtools import sphinx_generator
@@ -574,20 +574,20 @@ def getDocsGenerator():
# the current default is sphinx # the current default is sphinx
from etgtools import sphinx_generator from etgtools import sphinx_generator
return sphinx_generator.SphinxGenerator() return sphinx_generator.SphinxGenerator()
def runGenerators(module): def runGenerators(module):
checkForUnitTestModule(module) checkForUnitTestModule(module)
generators = list() generators = list()
# Create the code generator selected from command line args # Create the code generator selected from command line args
generators.append(getWrapperGenerator()) generators.append(getWrapperGenerator())
# Toss in the PI generator too # Toss in the PI generator too
from etgtools import pi_generator from etgtools import pi_generator
generators.append(pi_generator.PiWrapperGenerator()) generators.append(pi_generator.PiWrapperGenerator())
# Now the item map generator # Now the item map generator
from etgtools import map_generator from etgtools import map_generator
@@ -599,7 +599,7 @@ def runGenerators(module):
# run the generators # run the generators
for g in generators: for g in generators:
g.generate(module) g.generate(module)
def checkForUnitTestModule(module): def checkForUnitTestModule(module):
@@ -625,15 +625,15 @@ def convertTwoIntegersTemplate(CLASS):
int rval = 1; int rval = 1;
PyObject* o1 = PySequence_ITEM(sipPy, 0); PyObject* o1 = PySequence_ITEM(sipPy, 0);
PyObject* o2 = PySequence_ITEM(sipPy, 1); PyObject* o2 = PySequence_ITEM(sipPy, 1);
if (!PyNumber_Check(o1) || !PyNumber_Check(o2)) if (!PyNumber_Check(o1) || !PyNumber_Check(o2))
rval = 0; rval = 0;
Py_DECREF(o1); Py_DECREF(o1);
Py_DECREF(o2); Py_DECREF(o2);
return rval; return rval;
}} }}
return 0; return 0;
}} }}
// otherwise do the conversion // otherwise do the conversion
if (sipCanConvertToType(sipPy, sipType_{CLASS}, SIP_NO_CONVERTORS)) {{ if (sipCanConvertToType(sipPy, sipType_{CLASS}, SIP_NO_CONVERTORS)) {{
// Just fetch the existing instance // Just fetch the existing instance
@@ -641,7 +641,7 @@ def convertTwoIntegersTemplate(CLASS):
sipPy, sipType_{CLASS}, sipTransferObj, SIP_NO_CONVERTORS, 0, sipIsErr)); sipPy, sipType_{CLASS}, sipTransferObj, SIP_NO_CONVERTORS, 0, sipIsErr));
return 0; // not a new instance return 0; // not a new instance
}} }}
// or create a new instance // or create a new instance
PyObject* o1 = PySequence_ITEM(sipPy, 0); PyObject* o1 = PySequence_ITEM(sipPy, 0);
PyObject* o2 = PySequence_ITEM(sipPy, 1); PyObject* o2 = PySequence_ITEM(sipPy, 1);
@@ -660,14 +660,14 @@ def convertFourIntegersTemplate(CLASS):
// is it already an instance of {CLASS}? // is it already an instance of {CLASS}?
if (sipCanConvertToType(sipPy, sipType_{CLASS}, SIP_NO_CONVERTORS)) if (sipCanConvertToType(sipPy, sipType_{CLASS}, SIP_NO_CONVERTORS))
return 1; return 1;
if (PySequence_Check(sipPy) && PySequence_Size(sipPy) == 4) {{ if (PySequence_Check(sipPy) && PySequence_Size(sipPy) == 4) {{
int rval = 1; int rval = 1;
PyObject* o1 = PySequence_ITEM(sipPy, 0); PyObject* o1 = PySequence_ITEM(sipPy, 0);
PyObject* o2 = PySequence_ITEM(sipPy, 1); PyObject* o2 = PySequence_ITEM(sipPy, 1);
PyObject* o3 = PySequence_ITEM(sipPy, 2); PyObject* o3 = PySequence_ITEM(sipPy, 2);
PyObject* o4 = PySequence_ITEM(sipPy, 3); PyObject* o4 = PySequence_ITEM(sipPy, 3);
if (!PyNumber_Check(o1) || !PyNumber_Check(o2) || !PyNumber_Check(o3) || !PyNumber_Check(o4)) if (!PyNumber_Check(o1) || !PyNumber_Check(o2) || !PyNumber_Check(o3) || !PyNumber_Check(o4))
rval = 0; rval = 0;
Py_DECREF(o1); Py_DECREF(o1);
Py_DECREF(o2); Py_DECREF(o2);
@@ -676,8 +676,8 @@ def convertFourIntegersTemplate(CLASS):
return rval; return rval;
}} }}
return 0; return 0;
}} }}
// otherwise do the conversion // otherwise do the conversion
if (sipCanConvertToType(sipPy, sipType_{CLASS}, SIP_NO_CONVERTORS)) {{ if (sipCanConvertToType(sipPy, sipType_{CLASS}, SIP_NO_CONVERTORS)) {{
// Just fetch the existing instance // Just fetch the existing instance
@@ -689,7 +689,7 @@ def convertFourIntegersTemplate(CLASS):
PyObject* o1 = PySequence_ITEM(sipPy, 0); PyObject* o1 = PySequence_ITEM(sipPy, 0);
PyObject* o2 = PySequence_ITEM(sipPy, 1); PyObject* o2 = PySequence_ITEM(sipPy, 1);
PyObject* o3 = PySequence_ITEM(sipPy, 2); PyObject* o3 = PySequence_ITEM(sipPy, 2);
PyObject* o4 = PySequence_ITEM(sipPy, 3); PyObject* o4 = PySequence_ITEM(sipPy, 3);
*sipCppPtr = new {CLASS}(wxPyInt_AsLong(o1), wxPyInt_AsLong(o2), *sipCppPtr = new {CLASS}(wxPyInt_AsLong(o1), wxPyInt_AsLong(o2),
wxPyInt_AsLong(o3), wxPyInt_AsLong(o4)); wxPyInt_AsLong(o3), wxPyInt_AsLong(o4));
Py_DECREF(o1); Py_DECREF(o1);
@@ -707,20 +707,20 @@ def convertTwoDoublesTemplate(CLASS):
// is it already an instance of {CLASS}? // is it already an instance of {CLASS}?
if (sipCanConvertToType(sipPy, sipType_{CLASS}, SIP_NO_CONVERTORS)) if (sipCanConvertToType(sipPy, sipType_{CLASS}, SIP_NO_CONVERTORS))
return 1; return 1;
if (PySequence_Check(sipPy) && PySequence_Size(sipPy) == 2) {{ if (PySequence_Check(sipPy) && PySequence_Size(sipPy) == 2) {{
int rval = 1; int rval = 1;
PyObject* o1 = PySequence_ITEM(sipPy, 0); PyObject* o1 = PySequence_ITEM(sipPy, 0);
PyObject* o2 = PySequence_ITEM(sipPy, 1); PyObject* o2 = PySequence_ITEM(sipPy, 1);
if (!PyNumber_Check(o1) || !PyNumber_Check(o2)) if (!PyNumber_Check(o1) || !PyNumber_Check(o2))
rval = 0; rval = 0;
Py_DECREF(o1); Py_DECREF(o1);
Py_DECREF(o2); Py_DECREF(o2);
return rval; return rval;
}} }}
return 0; return 0;
}} }}
// otherwise do the conversion // otherwise do the conversion
if (sipCanConvertToType(sipPy, sipType_{CLASS}, SIP_NO_CONVERTORS)) {{ if (sipCanConvertToType(sipPy, sipType_{CLASS}, SIP_NO_CONVERTORS)) {{
// Just fetch the existing instance // Just fetch the existing instance
@@ -728,7 +728,7 @@ def convertTwoDoublesTemplate(CLASS):
sipPy, sipType_{CLASS}, sipTransferObj, SIP_NO_CONVERTORS, 0, sipIsErr)); sipPy, sipType_{CLASS}, sipTransferObj, SIP_NO_CONVERTORS, 0, sipIsErr));
return 0; // not a new instance return 0; // not a new instance
}} }}
// or create a new instance // or create a new instance
PyObject* o1 = PySequence_ITEM(sipPy, 0); PyObject* o1 = PySequence_ITEM(sipPy, 0);
PyObject* o2 = PySequence_ITEM(sipPy, 1); PyObject* o2 = PySequence_ITEM(sipPy, 1);
@@ -747,14 +747,14 @@ def convertFourDoublesTemplate(CLASS):
// is it already an instance of {CLASS}? // is it already an instance of {CLASS}?
if (sipCanConvertToType(sipPy, sipType_{CLASS}, SIP_NO_CONVERTORS)) if (sipCanConvertToType(sipPy, sipType_{CLASS}, SIP_NO_CONVERTORS))
return 1; return 1;
if (PySequence_Check(sipPy) && PySequence_Size(sipPy) == 4) {{ if (PySequence_Check(sipPy) && PySequence_Size(sipPy) == 4) {{
int rval = 1; int rval = 1;
PyObject* o1 = PySequence_ITEM(sipPy, 0); PyObject* o1 = PySequence_ITEM(sipPy, 0);
PyObject* o2 = PySequence_ITEM(sipPy, 1); PyObject* o2 = PySequence_ITEM(sipPy, 1);
PyObject* o3 = PySequence_ITEM(sipPy, 2); PyObject* o3 = PySequence_ITEM(sipPy, 2);
PyObject* o4 = PySequence_ITEM(sipPy, 3); PyObject* o4 = PySequence_ITEM(sipPy, 3);
if (!PyNumber_Check(o1) || !PyNumber_Check(o2) || !PyNumber_Check(o3) || !PyNumber_Check(o4)) if (!PyNumber_Check(o1) || !PyNumber_Check(o2) || !PyNumber_Check(o3) || !PyNumber_Check(o4))
rval = 0; rval = 0;
Py_DECREF(o1); Py_DECREF(o1);
Py_DECREF(o2); Py_DECREF(o2);
@@ -763,8 +763,8 @@ def convertFourDoublesTemplate(CLASS):
return rval; return rval;
}} }}
return 0; return 0;
}} }}
// otherwise do the conversion // otherwise do the conversion
if (sipCanConvertToType(sipPy, sipType_{CLASS}, SIP_NO_CONVERTORS)) {{ if (sipCanConvertToType(sipPy, sipType_{CLASS}, SIP_NO_CONVERTORS)) {{
// Just fetch the existing instance // Just fetch the existing instance
@@ -772,12 +772,12 @@ def convertFourDoublesTemplate(CLASS):
sipPy, sipType_{CLASS}, sipTransferObj, SIP_NO_CONVERTORS, 0, sipIsErr)); sipPy, sipType_{CLASS}, sipTransferObj, SIP_NO_CONVERTORS, 0, sipIsErr));
return 0; // not a new instance return 0; // not a new instance
}} }}
// or create a new instance // or create a new instance
PyObject* o1 = PySequence_ITEM(sipPy, 0); PyObject* o1 = PySequence_ITEM(sipPy, 0);
PyObject* o2 = PySequence_ITEM(sipPy, 1); PyObject* o2 = PySequence_ITEM(sipPy, 1);
PyObject* o3 = PySequence_ITEM(sipPy, 2); PyObject* o3 = PySequence_ITEM(sipPy, 2);
PyObject* o4 = PySequence_ITEM(sipPy, 3); PyObject* o4 = PySequence_ITEM(sipPy, 3);
*sipCppPtr = new {CLASS}(PyFloat_AsDouble(o1), PyFloat_AsDouble(o2), *sipCppPtr = new {CLASS}(PyFloat_AsDouble(o1), PyFloat_AsDouble(o2),
PyFloat_AsDouble(o3), PyFloat_AsDouble(o4)); PyFloat_AsDouble(o3), PyFloat_AsDouble(o4));
Py_DECREF(o1); Py_DECREF(o1);
@@ -791,26 +791,26 @@ def convertFourDoublesTemplate(CLASS):
# Templates for creating wrappers for type-specific wxList and wxArray classes # Templates for creating wrappers for type-specific wxList and wxArray classes
def wxListWrapperTemplate(ListClass, ItemClass, module, RealItemClass=None, def wxListWrapperTemplate(ListClass, ItemClass, module, RealItemClass=None,
includeConvertToType=False, fakeListClassName=None): includeConvertToType=False, fakeListClassName=None):
if RealItemClass is None: if RealItemClass is None:
RealItemClass = ItemClass RealItemClass = ItemClass
if fakeListClassName: if fakeListClassName:
TypeDef = "typedef %s %s;" % (ListClass, fakeListClassName) TypeDef = "typedef %s %s;" % (ListClass, fakeListClassName)
ListClass = fakeListClassName ListClass = fakeListClassName
else: else:
TypeDef = "" TypeDef = ""
moduleName = module.module moduleName = module.module
ListClass_pyName = removeWxPrefix(ListClass) ListClass_pyName = removeWxPrefix(ListClass)
# *** TODO: This can probably be done in a way that is not SIP-specfic. # *** TODO: This can probably be done in a way that is not SIP-specfic.
# Try creating extractor objects from scratch and attach cppMethods to # Try creating extractor objects from scratch and attach cppMethods to
# them as needed, etc.. # them as needed, etc..
klassCode = '''\ klassCode = '''\
class {ListClass}_iterator /Abstract/ class {ListClass}_iterator /Abstract/
{{ {{
// the C++ implementation of this class // the C++ implementation of this class
%TypeHeaderCode %TypeHeaderCode
@@ -819,7 +819,7 @@ class {ListClass}_iterator /Abstract/
public: public:
{ListClass}_iterator({ListClass}::compatibility_iterator start) {ListClass}_iterator({ListClass}::compatibility_iterator start)
: m_node(start) {{}} : m_node(start) {{}}
{ItemClass}* __next__() {{ {ItemClass}* __next__() {{
{RealItemClass}* obj = NULL; {RealItemClass}* obj = NULL;
if (m_node) {{ if (m_node) {{
@@ -842,13 +842,13 @@ public:
if (PyErr_Occurred()) if (PyErr_Occurred())
return NULL; return NULL;
%End %End
}}; }};
class {ListClass} class {ListClass}
{{ {{
%TypeHeaderCode %TypeHeaderCode
{TypeDef} {TypeDef}
%End %End
public: public:
SIP_SSIZE_T __len__(); SIP_SSIZE_T __len__();
%MethodCode %MethodCode
@@ -859,7 +859,7 @@ public:
%MethodCode %MethodCode
if (index < sipCpp->size()) {{ if (index < sipCpp->size()) {{
{ListClass}::compatibility_iterator node = sipCpp->Item(index); {ListClass}::compatibility_iterator node = sipCpp->Item(index);
if (node) if (node)
sipRes = ({ItemClass}*)node->GetData(); sipRes = ({ItemClass}*)node->GetData();
}} }}
else {{ else {{
@@ -891,7 +891,7 @@ public:
}} }}
sipRes = idx; sipRes = idx;
%End %End
@ConvertToTypeCode@ @ConvertToTypeCode@
}}; }};
@@ -912,7 +912,7 @@ del _{ListClass_pyName}___repr__
if (sipCanConvertToType(sipPy, sipType_{ListClass}, SIP_NO_CONVERTORS)) if (sipCanConvertToType(sipPy, sipType_{ListClass}, SIP_NO_CONVERTORS))
return success; return success;
// otherwise ensure that it is a sequence // otherwise ensure that it is a sequence
if (! PySequence_Check(sipPy)) if (! PySequence_Check(sipPy))
success = FALSE; success = FALSE;
// ensure it is not a string or unicode object (they are sequences too) // ensure it is not a string or unicode object (they are sequences too)
else if (PyBytes_Check(sipPy) || PyUnicode_Check(sipPy)) else if (PyBytes_Check(sipPy) || PyUnicode_Check(sipPy))
@@ -928,9 +928,9 @@ del _{ListClass_pyName}___repr__
break; break;
}} }}
Py_DECREF(item); Py_DECREF(item);
}} }}
}} }}
if (!success) if (!success)
PyErr_SetString(PyExc_TypeError, "Sequence of {ItemClass} compatible objects expected."); PyErr_SetString(PyExc_TypeError, "Sequence of {ItemClass} compatible objects expected.");
return success; return success;
}} }}
@@ -938,11 +938,11 @@ del _{ListClass_pyName}___repr__
// Is it already a {ListClass}? Return the exiting instance if so // Is it already a {ListClass}? Return the exiting instance if so
if (sipCanConvertToType(sipPy, sipType_{ListClass}, SIP_NO_CONVERTORS)) {{ if (sipCanConvertToType(sipPy, sipType_{ListClass}, SIP_NO_CONVERTORS)) {{
*sipCppPtr = reinterpret_cast<{ListClass}*>( *sipCppPtr = reinterpret_cast<{ListClass}*>(
sipConvertToType(sipPy, sipType_{ListClass}, NULL, sipConvertToType(sipPy, sipType_{ListClass}, NULL,
SIP_NO_CONVERTORS, 0, sipIsErr)); SIP_NO_CONVERTORS, 0, sipIsErr));
return 0; return 0;
}} }}
// Create a new {ListClass} and convert compatible PyObjects from the sequence // Create a new {ListClass} and convert compatible PyObjects from the sequence
{ListClass} *list = new {ListClass}; {ListClass} *list = new {ListClass};
list->DeleteContents(true); // tell the list to take ownership of the items list->DeleteContents(true); // tell the list to take ownership of the items
@@ -951,7 +951,7 @@ del _{ListClass_pyName}___repr__
int state; int state;
PyObject* pyItem = PySequence_ITEM(sipPy, i); PyObject* pyItem = PySequence_ITEM(sipPy, i);
{ItemClass}* cItem = reinterpret_cast<{ItemClass}*>( {ItemClass}* cItem = reinterpret_cast<{ItemClass}*>(
sipConvertToType(pyItem, sipType_{ItemClass}, sipConvertToType(pyItem, sipType_{ItemClass},
NULL, 0, &state, sipIsErr)); NULL, 0, &state, sipIsErr));
if (!state) // a temporary was not created for us, make one now if (!state) // a temporary was not created for us, make one now
cItem = new {ItemClass}(*cItem); cItem = new {ItemClass}(*cItem);
@@ -971,7 +971,7 @@ del _{ListClass_pyName}___repr__
def wxArrayWrapperTemplate(ArrayClass, ItemClass, module, itemIsPtr=False): def wxArrayWrapperTemplate(ArrayClass, ItemClass, module, itemIsPtr=False):
moduleName = module.module moduleName = module.module
ArrayClass_pyName = removeWxPrefix(ArrayClass) ArrayClass_pyName = removeWxPrefix(ArrayClass)
itemRef = '*' if itemIsPtr else '&' itemRef = '*' if itemIsPtr else '&'
itemDeref = '' if itemIsPtr else '*' itemDeref = '' if itemIsPtr else '*'
@@ -980,9 +980,9 @@ def wxArrayWrapperTemplate(ArrayClass, ItemClass, module, itemIsPtr=False):
# *** TODO: This can probably be done in a way that is not SIP-specfic. # *** TODO: This can probably be done in a way that is not SIP-specfic.
# Try creating extractor objects from scratch and attach cppMethods to # Try creating extractor objects from scratch and attach cppMethods to
# them as needed, etc.. # them as needed, etc..
return extractors.WigCode('''\ return extractors.WigCode('''\
class {ArrayClass} class {ArrayClass}
{{ {{
public: public:
SIP_SSIZE_T __len__(); SIP_SSIZE_T __len__();
@@ -1037,15 +1037,15 @@ del _{ArrayClass_pyName}___repr__
# Same as the above, but for use with WX_DEFINE_ARRAY_PTR # Same as the above, but for use with WX_DEFINE_ARRAY_PTR
def wxArrayPtrWrapperTemplate(ArrayClass, ItemClass, module): def wxArrayPtrWrapperTemplate(ArrayClass, ItemClass, module):
moduleName = module.module moduleName = module.module
ArrayClass_pyName = removeWxPrefix(ArrayClass) ArrayClass_pyName = removeWxPrefix(ArrayClass)
# *** TODO: This can probably be done in a way that is not SIP-specfic. # *** TODO: This can probably be done in a way that is not SIP-specfic.
# Try creating extractor objects from scratch and attach cppMethods to # Try creating extractor objects from scratch and attach cppMethods to
# them as needed, etc.. # them as needed, etc..
return extractors.WigCode('''\ return extractors.WigCode('''\
class {ArrayClass} class {ArrayClass}
{{ {{
public: public:
SIP_SSIZE_T __len__(); SIP_SSIZE_T __len__();
@@ -1104,8 +1104,8 @@ def ObjArrayHelperTemplate(objType, sipType, errmsg):
Generates a helper function that can convert from a Python sequence of Generates a helper function that can convert from a Python sequence of
objects (or items that can be converted to the target type) into a C objects (or items that can be converted to the target type) into a C
array of values. Copies are made of the items so the object types should array of values. Copies are made of the items so the object types should
support implicit or explicit copies and the copy should be cheap. support implicit or explicit copies and the copy should be cheap.
This kind of helper is useful for situations where the C/C++ API takes a This kind of helper is useful for situations where the C/C++ API takes a
simple pointer and a count, and there is no higher level container object simple pointer and a count, and there is no higher level container object
(like a wxList or wxArray) being used. If there is an overloaded method (like a wxList or wxArray) being used. If there is an overloaded method
@@ -1113,9 +1113,9 @@ def ObjArrayHelperTemplate(objType, sipType, errmsg):
ignored. But for those cases where the C array is the only option then this ignored. But for those cases where the C array is the only option then this
helper can be used to make the array from a sequence. helper can be used to make the array from a sequence.
""" """
cppCode = """\ cppCode = """\
// Convert a Python sequence of {objType} objects, or items that can be converted // Convert a Python sequence of {objType} objects, or items that can be converted
// to {objType} into a C array of {objType} instances. // to {objType} into a C array of {objType} instances.
static static
{objType}* {objType}_array_helper(PyObject* source, size_t *count) {objType}* {objType}_array_helper(PyObject* source, size_t *count)
@@ -1123,9 +1123,9 @@ static
{objType}* array; {objType}* array;
Py_ssize_t idx, len; Py_ssize_t idx, len;
wxPyThreadBlocker blocker; wxPyThreadBlocker blocker;
// ensure that it is a sequence // ensure that it is a sequence
if (! PySequence_Check(source)) if (! PySequence_Check(source))
goto error0; goto error0;
// ensure it is not a string or unicode object (they are sequences too) // ensure it is not a string or unicode object (they are sequences too)
else if (PyBytes_Check(source) || PyUnicode_Check(source)) else if (PyBytes_Check(source) || PyUnicode_Check(source))
@@ -1142,7 +1142,7 @@ static
Py_DECREF(item); Py_DECREF(item);
}} }}
}} }}
// The length of the sequence is returned in count. // The length of the sequence is returned in count.
*count = len; *count = len;
array = new {objType}[*count]; array = new {objType}[*count];