I will subclass the type defined in the C module for the alias of some attributes and methods so that my script works in different contexts.
How to do this to work, I need to manually configure the dictionary of my class? If I do not add a link to DistanceTo in dictionnary, I get Point3d has no attribute named DistanceTo .
class Point3d(App.Base.Vector): def __new__(cls, x, y, z): obj = super(Point3d, cls).__new__(cls) obj.x, obj.y, obj.z = x, y, z obj.__dict__.update({ 'X':property(lambda self: self.x), 'Y':property(lambda self: self.y), 'Z':property(lambda self: self.z), 'DistanceTo':lambda self, p: self.distanceToPoint(p)}) return obj def DistanceTo(self, p): return self.distanceToPoint(p)
I thought that as soon as __new__ returned the instance, I could still populate it with methods and attributes. Can anyone shed some light on this?
EDIT: The module I'm importing from is FreeCAD. Base type C is defined there . Then the Vector is derived from this definition here
EDIT2: I also tried the following:
class Point3d(App.Base.Vector): def __new__(cls, x, y, z): obj = super(Point3d, cls).__new__(cls) obj.x, obj.y, obj.z = x, y, z obj.__dict__.update({ 'X': x, 'Y': y, 'Z': z, 'DistanceTo':lambda self, p: self.distanceToPoint(p)}) return obj def DistanceTo(self, p): return self.distanceToPoint(p)
and after creating the second point, as Point3d p returns the value of the last point for pX , pY and pZ regardless of what parameters x,y,z were passed when creating the instance. px, py, pz return the expected values. It seems that the dictionary is shared between instances.
EDIT 3: Problem solved! The Py_TPFLAGS_BASETYPE bit is set to zero to prevent subclassing, as described in the answer below.