mirror of
https://github.com/boostorg/python.git
synced 2026-01-19 16:32:16 +00:00
Compare commits
22 Commits
boost-0.9.
...
boost-0.9.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4067d820fd | ||
|
|
acbc01933c | ||
|
|
7ec78eecbd | ||
|
|
87c5e37f5e | ||
|
|
d02959e3ed | ||
|
|
b844d8b750 | ||
|
|
0a3010b29f | ||
|
|
2b380d03c9 | ||
|
|
3f70253a3f | ||
|
|
165e294298 | ||
|
|
f7c9f45508 | ||
|
|
af2a924301 | ||
|
|
3981e83de5 | ||
|
|
88b9721e3f | ||
|
|
4946af1448 | ||
|
|
9959dcfa49 | ||
|
|
cfb13fad22 | ||
|
|
4e3f3a052d | ||
|
|
dc7ae9ed20 | ||
|
|
929badf4c6 | ||
|
|
c4a3f2c04f | ||
|
|
a933e458b3 |
14
pyste/NEWS
14
pyste/NEWS
@@ -1,7 +1,21 @@
|
||||
23 August 2003
|
||||
Fixed bug where some Imports where not writing their include files.
|
||||
Now whenever the declarations change, the cache files are rebuilt
|
||||
automatically.
|
||||
|
||||
19 August 2003
|
||||
Fixed a bug related to the generation of the bases<> template.
|
||||
|
||||
17 August 2003
|
||||
Added support for insertion of user code in the generated code.
|
||||
|
||||
16 August 2003
|
||||
Applied a patch by Gottfried Ganssauge that adds exception specifiers to
|
||||
wrapper functions and pointer declarations. Thanks a lot Gottfried!!
|
||||
|
||||
Applied a patch by Prabhu Ramachandran that fixes ae problem with the
|
||||
pure virtual method generation. Thanks again Prabhu!
|
||||
|
||||
10 August 2003
|
||||
Support for incremental generation of the code has been added. This changes
|
||||
how --multiple works; documentation of this new feature will follow. Thanks
|
||||
|
||||
@@ -9,4 +9,4 @@
|
||||
|
||||
- Virtual operators
|
||||
|
||||
- Apply Gottfried patches
|
||||
- args() support
|
||||
|
||||
@@ -39,7 +39,6 @@ class ClassExporter(Exporter):
|
||||
self.sections['include'] = []
|
||||
# a list of Constructor instances
|
||||
self.constructors = []
|
||||
self.wrapper_generator = None
|
||||
# a list of code units, generated by nested declarations
|
||||
self.nested_codeunits = []
|
||||
|
||||
@@ -92,7 +91,7 @@ class ClassExporter(Exporter):
|
||||
self.ExportBases(exported_names)
|
||||
self.ExportConstructors()
|
||||
self.ExportVariables()
|
||||
self.ExportVirtualMethods()
|
||||
self.ExportVirtualMethods(codeunit)
|
||||
self.ExportMethods()
|
||||
self.ExportOperators()
|
||||
self.ExportNestedClasses(exported_names)
|
||||
@@ -111,7 +110,6 @@ class ClassExporter(Exporter):
|
||||
base classes.
|
||||
'''
|
||||
valid_members = (Method, ClassVariable, NestedClass, ClassEnumeration)
|
||||
# these don't work INVESTIGATE!: (ClassOperator, ConverterOperator)
|
||||
fullnames = [x.FullName() for x in self.class_]
|
||||
pointers = [x.PointerDeclaration(True) for x in self.class_ if isinstance(x, Method)]
|
||||
fullnames = dict([(x, None) for x in fullnames])
|
||||
@@ -218,6 +216,8 @@ class ClassExporter(Exporter):
|
||||
for base in level:
|
||||
if base.visibility == Scope.public and base.name in exported_names:
|
||||
exported.append(base.name)
|
||||
if exported:
|
||||
break
|
||||
if exported:
|
||||
code = namespaces.python + 'bases< %s > ' % (', '.join(exported))
|
||||
self.Add('template', code)
|
||||
@@ -385,7 +385,7 @@ class ClassExporter(Exporter):
|
||||
# add wrapper code if this method has one
|
||||
wrapper = method_info.wrapper
|
||||
if wrapper and wrapper.code:
|
||||
self.Add('declaration', wrapper.code)
|
||||
self.Add('declaration-outside', wrapper.code)
|
||||
|
||||
# export staticmethod statements
|
||||
for name in staticmethods:
|
||||
@@ -402,7 +402,7 @@ class ClassExporter(Exporter):
|
||||
member.virtual = not self.info[member.name].no_override
|
||||
|
||||
|
||||
def ExportVirtualMethods(self):
|
||||
def ExportVirtualMethods(self, codeunit):
|
||||
# check if this class has any virtual methods
|
||||
has_virtual_methods = False
|
||||
for member in self.class_:
|
||||
@@ -412,7 +412,7 @@ class ClassExporter(Exporter):
|
||||
|
||||
holder = self.info.holder
|
||||
if has_virtual_methods:
|
||||
generator = _VirtualWrapperGenerator(self.class_, self.ClassBases(), self.info)
|
||||
generator = _VirtualWrapperGenerator(self.class_, self.ClassBases(), self.info, codeunit)
|
||||
if holder:
|
||||
self.Add('template', holder(generator.FullName()))
|
||||
else:
|
||||
@@ -503,7 +503,7 @@ class ClassExporter(Exporter):
|
||||
if wrapper:
|
||||
pointer = '&' + wrapper.FullName()
|
||||
if wrapper.code:
|
||||
self.Add('declaration', wrapper.code)
|
||||
self.Add('declaration-outside', wrapper.code)
|
||||
else:
|
||||
pointer = operator.PointerDeclaration()
|
||||
rename = self.info['operator'][operator.name].rename
|
||||
@@ -653,13 +653,14 @@ def _ParamsInfo(m, count=None):
|
||||
class _VirtualWrapperGenerator(object):
|
||||
'Generates code to export the virtual methods of the given class'
|
||||
|
||||
def __init__(self, class_, bases, info):
|
||||
def __init__(self, class_, bases, info, codeunit):
|
||||
self.class_ = copy.deepcopy(class_)
|
||||
self.bases = bases[:]
|
||||
self.info = info
|
||||
self.wrapper_name = makeid(class_.FullName()) + '_Wrapper'
|
||||
self.virtual_methods = None
|
||||
self._method_count = {}
|
||||
self.codeunit = codeunit
|
||||
self.GenerateVirtualMethods()
|
||||
|
||||
|
||||
@@ -713,13 +714,16 @@ class _VirtualWrapperGenerator(object):
|
||||
if method.abstract:
|
||||
s = indent2 + 'PyErr_SetString(PyExc_RuntimeError, "pure virtual function called");\n' +\
|
||||
indent2 + 'throw_error_already_set();\n'
|
||||
if method.result.FullName() != 'void':
|
||||
s += indent2 + 'return %s();\n' % method.result.FullName()
|
||||
params = ', '.join(param_names)
|
||||
s += indent2 + '%s%s(%s);\n' % \
|
||||
(return_str, method.name, params)
|
||||
return s
|
||||
else:
|
||||
else:
|
||||
return indent2 + '%s%s(%s);\n' % \
|
||||
(return_str, method.FullName(), ', '.join(param_names))
|
||||
(return_str, method.FullName(), ', '.join(param_names))
|
||||
else:
|
||||
if wrapper.code:
|
||||
self.codeunit.Write('declaration-outside', wrapper.code)
|
||||
# return a call for the wrapper
|
||||
params = ', '.join(['this'] + param_names)
|
||||
return indent2 + '%s%s(%s);\n' % (return_str, wrapper.FullName(), params)
|
||||
|
||||
21
pyste/src/Pyste/CodeExporter.py
Normal file
21
pyste/src/Pyste/CodeExporter.py
Normal file
@@ -0,0 +1,21 @@
|
||||
from Exporter import Exporter
|
||||
|
||||
#==============================================================================
|
||||
# CodeExporter
|
||||
#==============================================================================
|
||||
class CodeExporter(Exporter):
|
||||
|
||||
def __init__(self, info):
|
||||
Exporter.__init__(self, info)
|
||||
|
||||
|
||||
def Name(self):
|
||||
return self.info.code
|
||||
|
||||
|
||||
def Export(self, codeunit, exported_names):
|
||||
codeunit.Write(self.info.section, self.info.code)
|
||||
|
||||
|
||||
def WriteInclude(self, codeunit):
|
||||
pass
|
||||
@@ -20,7 +20,7 @@ class CppParserError(Exception): pass
|
||||
class CppParser:
|
||||
'Parses a header file and returns a list of declarations'
|
||||
|
||||
def __init__(self, includes=None, defines=None, cache_dir=None):
|
||||
def __init__(self, includes=None, defines=None, cache_dir=None, version=None):
|
||||
'includes and defines ar the directives given to gcc'
|
||||
if includes is None:
|
||||
includes = []
|
||||
@@ -28,6 +28,7 @@ class CppParser:
|
||||
defines = []
|
||||
self.includes = includes
|
||||
self.defines = defines
|
||||
self.version = version
|
||||
#if cache_dir is None:
|
||||
# cache_dir = tempfile.mktemp()
|
||||
# self.delete_cache = True
|
||||
@@ -168,6 +169,9 @@ class CppParser:
|
||||
if os.path.isfile(cache_file):
|
||||
f = file(cache_file, 'rb')
|
||||
try:
|
||||
version = load(f)
|
||||
if version != self.version:
|
||||
return None
|
||||
cache = load(f)
|
||||
if cache.has_key(key):
|
||||
self.cache_files.append(cache_file)
|
||||
@@ -195,6 +199,7 @@ class CppParser:
|
||||
if os.path.isfile(cache_file):
|
||||
f = file(cache_file, 'rb')
|
||||
try:
|
||||
version = load(f)
|
||||
cache = load(f)
|
||||
finally:
|
||||
f.close()
|
||||
@@ -204,6 +209,7 @@ class CppParser:
|
||||
self.cache_files.append(cache_file)
|
||||
f = file(cache_file, 'wb')
|
||||
try:
|
||||
dump(self.version, f, 1)
|
||||
dump(cache, f, 1)
|
||||
finally:
|
||||
f.close()
|
||||
|
||||
@@ -82,7 +82,8 @@ class Exporter(object):
|
||||
|
||||
|
||||
def __eq__(self, other):
|
||||
return self.Name() == other.Name()
|
||||
return type(self) is type(other) and self.Name() == other.Name() \
|
||||
and self.interface_file == other.interface_file
|
||||
|
||||
def __ne__(self, other):
|
||||
return self.Name() != other.Name()
|
||||
return not self == other
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
import os.path
|
||||
from Exporter import Exporter
|
||||
|
||||
#==============================================================================
|
||||
# IncludeExporter
|
||||
#==============================================================================
|
||||
class IncludeExporter(Exporter):
|
||||
'''Writes an include declaration to the module. Useful to add extra code
|
||||
for use in the Wrappers.
|
||||
This class just reimplements the Parse method to do nothing: the
|
||||
WriteInclude in Exporter already does the work for us.
|
||||
'''
|
||||
|
||||
def __init__(self, info, parser_tail=None):
|
||||
Exporter.__init__(self, info, parser_tail)
|
||||
|
||||
def Parse(self, parser):
|
||||
pass
|
||||
|
||||
def Name(self):
|
||||
return '__all__'
|
||||
|
||||
def Header(self):
|
||||
return None # means "don't try to parse me!"
|
||||
@@ -3,6 +3,11 @@ Defines classes that represent declarations found in C++ header files.
|
||||
|
||||
'''
|
||||
|
||||
# version indicates the version of the declarations. Whenever a declaration
|
||||
# changes, this variable should be updated, so that the caches can be rebuilt
|
||||
# automatically
|
||||
version = '1.0'
|
||||
|
||||
#==============================================================================
|
||||
# Declaration
|
||||
#==============================================================================
|
||||
@@ -198,7 +203,7 @@ class Function(Declaration):
|
||||
@ivar _parameters: list of L{Type} instances.
|
||||
@ivar _throws: exception specifiers or None
|
||||
'''
|
||||
|
||||
|
||||
def __init__(self, name, namespace, result, params, throws=None):
|
||||
Declaration.__init__(self, name, namespace)
|
||||
# the result type: instance of Type, or None (constructors)
|
||||
|
||||
@@ -3,10 +3,10 @@ import copy
|
||||
import exporters
|
||||
from ClassExporter import ClassExporter
|
||||
from FunctionExporter import FunctionExporter
|
||||
from IncludeExporter import IncludeExporter
|
||||
from EnumExporter import EnumExporter
|
||||
from HeaderExporter import HeaderExporter
|
||||
from VarExporter import VarExporter
|
||||
from CodeExporter import CodeExporter
|
||||
from exporterutils import FunctionWrapper
|
||||
from utils import makeid
|
||||
|
||||
@@ -80,20 +80,6 @@ class ClassInfo(DeclarationInfo):
|
||||
exporter.interface_file = exporters.current_interface
|
||||
|
||||
|
||||
#==============================================================================
|
||||
# IncludeInfo
|
||||
#==============================================================================
|
||||
class IncludeInfo(DeclarationInfo):
|
||||
|
||||
def __init__(self, include):
|
||||
DeclarationInfo.__init__(self)
|
||||
self._Attribute('include', include)
|
||||
exporter = IncludeExporter(InfoWrapper(self))
|
||||
if exporter not in exporters.exporters:
|
||||
exporters.exporters.append(exporter)
|
||||
exporter.interface_file = exporters.current_interface
|
||||
|
||||
|
||||
#==============================================================================
|
||||
# templates
|
||||
#==============================================================================
|
||||
@@ -174,6 +160,21 @@ class VarInfo(DeclarationInfo):
|
||||
exporter.interface_file = exporters.current_interface
|
||||
|
||||
|
||||
#==============================================================================
|
||||
# CodeInfo
|
||||
#==============================================================================
|
||||
class CodeInfo(DeclarationInfo):
|
||||
|
||||
def __init__(self, code, section):
|
||||
DeclarationInfo.__init__(self)
|
||||
self._Attribute('code', code)
|
||||
self._Attribute('section', section)
|
||||
exporter = CodeExporter(InfoWrapper(self))
|
||||
if exporter not in exporters.exporters:
|
||||
exporters.exporters.append(exporter)
|
||||
exporter.interface_file = exporters.current_interface
|
||||
|
||||
|
||||
#==============================================================================
|
||||
# InfoWrapper
|
||||
#==============================================================================
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
import profile
|
||||
import pstats
|
||||
import pyste
|
||||
|
||||
import elementtree.XMLTreeBuilder as XMLTreeBuilder
|
||||
import GCCXMLParser
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
#psyco.bind(XMLTreeBuilder.fixtext)
|
||||
#psyco.bind(XMLTreeBuilder.fixname)
|
||||
#psyco.bind(XMLTreeBuilder.TreeBuilder)
|
||||
#psyco.bind(GCCXMLParser.GCCXMLParser)
|
||||
profile.run('pyste.main()', 'profile')
|
||||
p = pstats.Stats('profile')
|
||||
p.strip_dirs().sort_stats('cumulative').print_stats()
|
||||
@@ -41,9 +41,9 @@ import sys
|
||||
from policies import *
|
||||
from CppParser import CppParser, CppParserError
|
||||
import time
|
||||
from declarations import Typedef
|
||||
import declarations
|
||||
|
||||
__VERSION__ = '0.9.13'
|
||||
__version__ = '0.9.21'
|
||||
|
||||
def RecursiveIncludes(include):
|
||||
'Return a list containg the include dir and all its subdirectories'
|
||||
@@ -75,7 +75,7 @@ def ProcessIncludes(includes):
|
||||
def ParseArguments():
|
||||
|
||||
def Usage():
|
||||
print __doc__ % __VERSION__
|
||||
print __doc__ % __version__
|
||||
sys.exit(1)
|
||||
|
||||
try:
|
||||
@@ -125,7 +125,7 @@ def ParseArguments():
|
||||
elif opt in ['-h', '--help']:
|
||||
Usage()
|
||||
elif opt in ['-v', '--version']:
|
||||
print 'Pyste version %s' % __VERSION__
|
||||
print 'Pyste version %s' % __version__
|
||||
sys.exit(2)
|
||||
elif opt == '--generate-main':
|
||||
generate_main = True
|
||||
@@ -167,7 +167,7 @@ def CreateContext():
|
||||
# infos
|
||||
context['Function'] = infos.FunctionInfo
|
||||
context['Class'] = infos.ClassInfo
|
||||
context['Include'] = infos.IncludeInfo
|
||||
context['Include'] = lambda header: infos.CodeInfo('#include <%s>\n' % header, 'include')
|
||||
context['Template'] = infos.ClassTemplateInfo
|
||||
context['Enum'] = infos.EnumInfo
|
||||
context['AllFromHeader'] = infos.HeaderInfo
|
||||
@@ -193,6 +193,8 @@ def CreateContext():
|
||||
context['manage_new_object'] = manage_new_object
|
||||
# utils
|
||||
context['Wrapper'] = exporterutils.FunctionWrapper
|
||||
context['declaration_code'] = lambda code: infos.CodeInfo(code, 'declaration-outside')
|
||||
context['module_code'] = lambda code: infos.CodeInfo(code, 'module')
|
||||
return context
|
||||
|
||||
|
||||
@@ -203,7 +205,7 @@ def Begin():
|
||||
for interface in interfaces:
|
||||
ExecuteInterface(interface)
|
||||
# create the parser
|
||||
parser = CppParser(includes, defines, cache_dir)
|
||||
parser = CppParser(includes, defines, cache_dir, declarations.version)
|
||||
try:
|
||||
if not create_cache:
|
||||
if not generate_main:
|
||||
@@ -297,7 +299,6 @@ def GenerateCode(parser, module, out, interfaces, multiple):
|
||||
exported_names = dict([(x.Name(), None) for x in exports])
|
||||
|
||||
# order the exports
|
||||
interfaces_order = OrderInterfaces(interfaces)
|
||||
order = {}
|
||||
for export in exports:
|
||||
if export.interface_file in order:
|
||||
@@ -305,6 +306,7 @@ def GenerateCode(parser, module, out, interfaces, multiple):
|
||||
else:
|
||||
order[export.interface_file] = [export]
|
||||
exports = []
|
||||
interfaces_order = OrderInterfaces(interfaces)
|
||||
for interface in interfaces_order:
|
||||
exports.extend(order[interface])
|
||||
del order
|
||||
@@ -341,13 +343,13 @@ def GenerateCode(parser, module, out, interfaces, multiple):
|
||||
return 0
|
||||
|
||||
|
||||
def ExpandTypedefs(declarations, exported_names):
|
||||
def ExpandTypedefs(decls, exported_names):
|
||||
'''Check if the names in exported_names are a typedef, and add the real class
|
||||
name in the dict.
|
||||
'''
|
||||
for name in exported_names.keys():
|
||||
for decl in declarations:
|
||||
if isinstance(decl, Typedef):
|
||||
for decl in decls:
|
||||
if isinstance(decl, declarations.Typedef):
|
||||
exported_names[decl.type.FullName()] = None
|
||||
|
||||
def UsePsyco():
|
||||
|
||||
4
pyste/tests/code_test.h
Normal file
4
pyste/tests/code_test.h
Normal file
@@ -0,0 +1,4 @@
|
||||
|
||||
struct A {
|
||||
int x;
|
||||
};
|
||||
9
pyste/tests/code_test.pyste
Normal file
9
pyste/tests/code_test.pyste
Normal file
@@ -0,0 +1,9 @@
|
||||
Class('A', 'code_test.h')
|
||||
Include('string')
|
||||
declaration_code('''
|
||||
int get(A& a) { return a.x; }
|
||||
|
||||
std::string foo() { return "Hello!"; }
|
||||
''')
|
||||
module_code(' def("get", &get);\n')
|
||||
module_code(' def("foo", &foo);\n')
|
||||
14
pyste/tests/code_testUT.py
Normal file
14
pyste/tests/code_testUT.py
Normal file
@@ -0,0 +1,14 @@
|
||||
import unittest
|
||||
from _code_test import *
|
||||
|
||||
class CodeTest(unittest.TestCase):
|
||||
|
||||
def testIt(self):
|
||||
a = A()
|
||||
a.x = 12
|
||||
self.assertEqual(get(a), 12)
|
||||
self.assertEqual(foo(), "Hello!")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
@@ -4,6 +4,7 @@ import os
|
||||
import glob
|
||||
import shutil
|
||||
import sys
|
||||
import time
|
||||
|
||||
#=============================================================================
|
||||
# win32 configuration
|
||||
@@ -94,12 +95,23 @@ def main(multiple, module=None):
|
||||
modules = get_modules()
|
||||
else:
|
||||
modules = [module]
|
||||
|
||||
start = time.clock()
|
||||
for module in modules:
|
||||
build_pyste(multiple, module)
|
||||
print '-'*50
|
||||
print 'Building pyste files: %0.2f seconds' % (time.clock()-start)
|
||||
print
|
||||
|
||||
start = time.clock()
|
||||
for module in modules:
|
||||
if multiple:
|
||||
compile_multiple(module)
|
||||
else:
|
||||
compile_single(module)
|
||||
print '-'*50
|
||||
print 'Compiling files: %0.2f seconds' % (time.clock()-start)
|
||||
print
|
||||
if len(modules) == 1:
|
||||
os.system('python %sUT.py' % modules[0])
|
||||
else:
|
||||
|
||||
Reference in New Issue
Block a user