mirror of
https://github.com/boostorg/python.git
synced 2026-01-19 04:22:16 +00:00
- Fixed a bug where in some classes the virtual methods were being definied incorrectly
[SVN r19525]
This commit is contained in:
@@ -7,6 +7,9 @@ solution.
|
||||
Automatically convert \ to / in Windows systems before passing the paths to
|
||||
gccxml.
|
||||
|
||||
Fixed a bug reported by Prabhu Ramachandran, where in some classes the virtual
|
||||
methods were being definied incorrectly. Thanks a lot Prabhu!
|
||||
|
||||
7 July 2003
|
||||
Applied 2 patches by Prabhu Ramachandran: a fix in the new --multiple method,
|
||||
and two new functions "hold_with_shared_ptr" and its counterpart for auto_ptr.
|
||||
|
||||
@@ -113,6 +113,9 @@ class ClassExporter(Exporter):
|
||||
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])
|
||||
pointers = dict([(x, None) for x in pointers])
|
||||
for level in self.class_.hierarchy:
|
||||
level_exported = False
|
||||
for base in level:
|
||||
@@ -122,7 +125,12 @@ class ClassExporter(Exporter):
|
||||
if type(member) in valid_members:
|
||||
member_copy = copy.deepcopy(member)
|
||||
member_copy.class_ = self.class_.FullName()
|
||||
if member_copy.FullName() not in fullnames:
|
||||
if isinstance(member_copy, Method):
|
||||
pointer = member_copy.PointerDeclaration(True)
|
||||
if pointer not in pointers:
|
||||
self.class_.AddMember(member)
|
||||
pointers[pointer] = None
|
||||
elif member_copy.FullName() not in fullnames:
|
||||
self.class_.AddMember(member)
|
||||
else:
|
||||
level_exported = True
|
||||
@@ -646,7 +654,7 @@ class _VirtualWrapperGenerator(object):
|
||||
'Generates code to export the virtual methods of the given class'
|
||||
|
||||
def __init__(self, class_, bases, info):
|
||||
self.class_ = class_
|
||||
self.class_ = copy.deepcopy(class_)
|
||||
self.bases = bases[:]
|
||||
self.info = info
|
||||
self.wrapper_name = makeid(class_.FullName()) + '_Wrapper'
|
||||
@@ -703,7 +711,7 @@ class _VirtualWrapperGenerator(object):
|
||||
if not wrapper:
|
||||
# return the default implementation of the class
|
||||
if method.abstract:
|
||||
s = indent2 + 'PyErr_SetString(PyExc_RuntimeError, "abstract function called");\n' +\
|
||||
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()
|
||||
@@ -789,14 +797,7 @@ class _VirtualWrapperGenerator(object):
|
||||
return type(m) is Method and \
|
||||
m.virtual and \
|
||||
m.visibility != Scope.private
|
||||
|
||||
all_methods = [x for x in self.class_ if IsVirtual(x)]
|
||||
for base in self.bases:
|
||||
base_methods = [copy.deepcopy(x) for x in base if IsVirtual(x)]
|
||||
for base_method in base_methods:
|
||||
base_method.class_ = self.class_.FullName()
|
||||
all_methods.append(base_method)
|
||||
|
||||
|
||||
# extract the virtual methods, avoiding duplications. The duplication
|
||||
# must take in account the full signature without the class name, so
|
||||
# that inherited members are correctly excluded if the subclass overrides
|
||||
@@ -811,10 +812,22 @@ class _VirtualWrapperGenerator(object):
|
||||
else:
|
||||
result = ''
|
||||
params = ', '.join([x.FullName() for x in method.parameters])
|
||||
return '%s %s(%s) %s' % (result, method.name, params, const)
|
||||
|
||||
self.virtual_methods = []
|
||||
return '%s %s(%s) %s' % (result, method.name, params, const)
|
||||
|
||||
already_added = {}
|
||||
self.virtual_methods = []
|
||||
for member in self.class_:
|
||||
if IsVirtual(member):
|
||||
already_added[MethodSig(member)] = None
|
||||
self.virtual_methods.append(member)
|
||||
|
||||
for base in self.bases:
|
||||
base_methods = [copy.deepcopy(x) for x in base if IsVirtual(x)]
|
||||
for base_method in base_methods:
|
||||
self.class_.AddMember(base_method)
|
||||
|
||||
all_methods = [x for x in self.class_ if IsVirtual(x)]
|
||||
|
||||
for member in all_methods:
|
||||
sig = MethodSig(member)
|
||||
if IsVirtual(member) and not sig in already_added:
|
||||
|
||||
@@ -152,7 +152,6 @@ class CppParser:
|
||||
cache_file = os.path.splitext(interface_name)[0] + '.pystec'
|
||||
cache_file = os.path.join(self.cache_dir, cache_file)
|
||||
return cache_file
|
||||
|
||||
|
||||
|
||||
def GetCache(self, header, interface, tail):
|
||||
|
||||
@@ -123,7 +123,7 @@ class Class(Declaration):
|
||||
m.is_unique = False
|
||||
else:
|
||||
member.is_unique = True
|
||||
self.__member_names[member.name] = 1
|
||||
self.__member_names[member.name] = 1
|
||||
self.__members.append(member)
|
||||
if isinstance(member, ClassOperator):
|
||||
self.operator[member.name] = member
|
||||
@@ -329,6 +329,10 @@ class Constructor(Method):
|
||||
return param_reference and class_as_param and param.const and is_public
|
||||
|
||||
|
||||
def PointerDeclaration(self, force=False):
|
||||
return ''
|
||||
|
||||
|
||||
#==============================================================================
|
||||
# Destructor
|
||||
#==============================================================================
|
||||
@@ -342,6 +346,10 @@ class Destructor(Method):
|
||||
return self.class_ + '::~' + self.name
|
||||
|
||||
|
||||
def PointerDeclaration(self, force=False):
|
||||
return ''
|
||||
|
||||
|
||||
|
||||
#==============================================================================
|
||||
# ClassOperator
|
||||
|
||||
@@ -43,7 +43,7 @@ from CppParser import CppParser, CppParserError
|
||||
import time
|
||||
from declarations import Typedef
|
||||
|
||||
__VERSION__ = '0.9.11'
|
||||
__VERSION__ = '0.9.12'
|
||||
|
||||
def RecursiveIncludes(include):
|
||||
'Return a list containg the include dir and all its subdirectories'
|
||||
|
||||
@@ -4,12 +4,15 @@ struct A
|
||||
{
|
||||
int x;
|
||||
int getx() { return x; }
|
||||
int foo() { return 0; }
|
||||
int foo(int x) { return x; }
|
||||
};
|
||||
|
||||
struct B : A
|
||||
{
|
||||
int y;
|
||||
int gety() { return y; }
|
||||
int foo() { return 1; }
|
||||
};
|
||||
|
||||
struct C : B
|
||||
|
||||
@@ -1,3 +1,2 @@
|
||||
header = AllFromHeader('inherit2.h')
|
||||
exclude(header.A)
|
||||
exclude(header.C)
|
||||
Class('inherit2::B', 'inherit2.h')
|
||||
Class('inherit2::D', 'inherit2.h')
|
||||
|
||||
@@ -16,6 +16,8 @@ class InheritExampleTest(unittest.TestCase):
|
||||
self.assertEqual(d.gety(), 15)
|
||||
self.assertEqual(d.getz(), 10)
|
||||
self.assertEqual(d.getw(), 5)
|
||||
self.assertEqual(b.foo(), 1)
|
||||
self.assertEqual(b.foo(3), 3)
|
||||
|
||||
def wrong():
|
||||
return b.getw()
|
||||
|
||||
@@ -5,7 +5,8 @@ struct A
|
||||
{
|
||||
struct X { int y; };
|
||||
int x;
|
||||
int foo() { return 1; }
|
||||
virtual int foo() { return 0; }
|
||||
virtual int foo(int x) { return x; }
|
||||
A operator+(A o) const
|
||||
{
|
||||
A r;
|
||||
|
||||
@@ -4,16 +4,20 @@ from _inherit3 import *
|
||||
class testInherit3(unittest.TestCase):
|
||||
|
||||
def testIt(self):
|
||||
def testClass(class_):
|
||||
c = class_()
|
||||
def testInst(c):
|
||||
self.assertEqual(c.x, 0)
|
||||
self.assertEqual(c.foo(), 1)
|
||||
x = class_.X()
|
||||
self.assertEqual(c.foo(3), 3)
|
||||
x = c.X()
|
||||
self.assertEqual(x.y, 0)
|
||||
self.assertEqual(class_.E.i, 0)
|
||||
self.assertEqual(class_.E.j, 1)
|
||||
testClass(B)
|
||||
testClass(C)
|
||||
self.assertEqual(c.E.i, 0)
|
||||
self.assertEqual(c.E.j, 1)
|
||||
b = B()
|
||||
c = C()
|
||||
testInst(b)
|
||||
testInst(c)
|
||||
self.assertEqual(b.foo(), 1)
|
||||
self.assertEqual(c.foo(), 0)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
Reference in New Issue
Block a user