File: TestSubClass.py

package info (click to toggle)
vtk9 9.5.2%2Bdfsg3-4
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 205,916 kB
  • sloc: cpp: 2,336,565; ansic: 327,116; python: 111,200; yacc: 4,104; java: 3,977; sh: 3,032; xml: 2,771; perl: 2,189; lex: 1,787; makefile: 178; javascript: 165; objc: 153; tcl: 59
file content (163 lines) | stat: -rw-r--r-- 6,167 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
"""Test subclassing support in VTK-Python

VTK classes can be subclassed in Python.  There are
some caveats, such as:
 - protected items are inaccessible to the python class
 - virtual method calls from C++ are not propagated to python

To be tested:
 - make sure that subclassing works
 - make sure that unbound superclass methods can be called

Created on Sept 26, 2010 by David Gobbi

"""

import sys
from vtkmodules.vtkCommonCore import (
    vtkCollection,
    vtkDataArray,
    vtkIntArray,
    vtkObject,
    vtkObjectBase,
    vtkPoints,
)
from vtkmodules.vtkCommonDataModel import vtkImageData
from vtkmodules.vtkFiltersSources import vtkSphereSource
from vtkmodules.vtkImagingSources import vtkImageGridSource
from vtkmodules.test import Testing

class vtkCustomObject(vtkObject):
    def __init__(self, extra=None):
        """Initialize all attributes."""
        if extra is None:
            extra = vtkObject()
        self._ExtraObject = extra

    def GetClassName(self):
        """Get the class name."""
        return self.__class__.__name__

    def GetExtraObject(self):
        """Getter method."""
        return self._ExtraObject

    def SetExtraObject(self, o):
        """Setter method."""
        # make sure it is "None" or a vtkobject instance
        if o == None or isinstance(o, vtkObjectBase):
            self._ExtraObject = o
            self.Modified()
        else:
            raise TypeError("requires None or a vtkobject")

    def GetMTime(self):
        """Override a method (only works when called from Python)"""
        t = vtkObject.GetMTime(self)
        if self._ExtraObject:
            t = max(t, self._ExtraObject.GetMTime())
        return t

class vtkPointsCustom(vtkPoints):
    def __init__(self):
        self.some_attribute = "custom"

class vtkImageDataWarning(vtkImageData):
    def __init__(self, spacing=(1.0, 1.0, 1.0)):
        # this sets the spacing when the constructor is called without any
        # arguments, which generates a warning in testOverrideWarning (see
        # the test code below for an explanation)
        self.SetSpacing(spacing)

class TestSubclass(Testing.vtkTest):
    def testSubclassInstantiate(self):
        """Instantiate a python vtkObject subclass"""
        o = vtkCustomObject()
        self.assertEqual(o.GetClassName(), "vtkCustomObject")

    def testConstructorArgs(self):
        """Test the use of constructor arguments."""
        extra = vtkObject()
        o = vtkCustomObject(extra)
        self.assertEqual(o.GetClassName(), "vtkCustomObject")
        self.assertEqual(id(o.GetExtraObject()), id(extra))

    def testCallUnboundMethods(self):
        """Test calling an unbound method in an overridden method"""
        o = vtkCustomObject()
        a = vtkIntArray()
        o.SetExtraObject(a)
        a.Modified()
        # GetMTime should return a's mtime
        self.assertEqual(o.GetMTime(), a.GetMTime())
        # calling the vtkObject mtime should give a lower MTime
        self.assertNotEqual(o.GetMTime(), vtkObject.GetMTime(o))
        # another couple quick unbound method check
        vtkDataArray.InsertNextTuple1(a, 2)
        self.assertEqual(a.GetTuple1(0), 2)

    def testPythonRTTI(self):
        """Test the python isinstance and issubclass methods """
        o = vtkCustomObject()
        d = vtkIntArray()
        self.assertEqual(True, isinstance(o, vtkObjectBase))
        self.assertEqual(True, isinstance(d, vtkObjectBase))
        self.assertEqual(True, isinstance(o, vtkCustomObject))
        self.assertEqual(False, isinstance(d, vtkCustomObject))
        self.assertEqual(False, isinstance(o, vtkDataArray))
        self.assertEqual(True, issubclass(vtkCustomObject, vtkObject))
        self.assertEqual(False, issubclass(vtkObject, vtkCustomObject))
        self.assertEqual(False, issubclass(vtkCustomObject, vtkDataArray))

    def testSubclassGhost(self):
        """Make sure ghosting of the class works"""
        o = vtkCustomObject()
        c = vtkCollection()
        c.AddItem(o)
        i = id(o)
        del o
        o = vtkObject()
        o = c.GetItemAsObject(0)
        # make sure the id has changed, but class the same
        self.assertEqual(o.__class__, vtkCustomObject)
        self.assertNotEqual(i, id(o))

    def testOverride(self):
        """Make sure that overwriting with a subclass works"""
        self.assertFalse(isinstance(vtkPoints(), vtkPointsCustom))
        # check that object has the correct class
        vtkPoints.override(vtkPointsCustom)
        self.assertTrue(isinstance(vtkPoints(), vtkPointsCustom))
        # check object created deep in c++
        source = vtkSphereSource()
        source.Update()
        points = source.GetOutput().GetPoints()
        self.assertTrue(isinstance(points, vtkPointsCustom))
        # check that __init__ is called
        self.assertEqual(points.some_attribute, "custom")
        # check that overrides can be removed
        vtkPoints.override(None)
        self.assertTrue(vtkPoints().__class__ == vtkPoints)

    def testOverrideWarning(self):
        """Check if a late call to __init__() modifies the C++ object"""
        # check that the object has the correct class
        vtkImageData.override(vtkImageDataWarning)
        self.assertTrue(isinstance(vtkImageData(), vtkImageDataWarning))
        # check object created deep in c++
        source = vtkImageGridSource()
        source.SetDataExtent(0, 255, 0, 255, 0, 0)
        source.SetDataSpacing(0.1, 0.1, 1.0)
        # calling Update() instantiates the data object in C++
        source.Update()
        # calling GetOutput() instantiates the data object in Python,
        # and reports RuntimeWarning because our override modifies the data
        with self.assertWarns(RuntimeWarning):
            data = source.GetOutput()
        # the custom __init__() method modified the spacing to be (1.0,1.0,1.0),
        # the purpose of the RuntimeWarning is to let the user know that an odd
        # modification like this has occurred
        self.assertEqual(data.GetSpacing(), (1.0, 1.0, 1.0))

if __name__ == "__main__":
    Testing.main([(TestSubclass, 'test')])