2

Let's say I have:

  • Package A that we will call BaseObjects in what follows
  • Project B that installs BaseObjects as a dependency and defines subclasses for some classes defined in BaseOjects
  • Project C that installs BaseObjects as a dependency but does not have access in any way to Project B

Let's call one of the classes defined in BaseObjects: Point. Another class is called Line that takes as attributes 2 Point instances p1 and p2.

Package B implements a class PointB(Point). The objects PointB are therefore also instances of BaseObjects.Point.

While in an environment related to Project B, I create an object Line that uses 2 PointB objects. I do all sort of operations with the special methods that PointB implements.

I now want to pickle this Line object so that it can be loaded in Project C. To that purpose, I cannot keep the PointB instances. I therefore need to "reclass" them to be of the type of the superclass only. I do p1.__class__ = Point and p2.__class__ = Point. I check that: isinstance(p1, PointB) evaluates to False, same for p2.

Therefore, I thought that the object pickled this way will be readable from Project C as it has the dependency to BaseObjects which defines the class Point.

It isn't the case. When I load the pickle file in Project C, it looks for the folder in which I defined the subclasses in Project B. However, as I dig through the object, I do not find any link. All the objects are said to be of type BaseObjects.<class_name>

What's wrong in my process of getting rid of this object's dependency to Project B? Is there a way to see all the dependencies of an object?

Eskapp
  • 3,419
  • 2
  • 22
  • 39
  • Usually "casting" in python is done by using a constructor that takes an instance of the class. In your case: `Point(point_b)`. Changing `__class__` is a bit hacky. Also see: https://stackoverflow.com/a/9112513/14157562 – Wups Sep 25 '20 at 12:09
  • @Wups but casting would change the object address and all related objects would lose the reference to it. Using `__class__` allows me to keep all references to this object valid. – Eskapp Sep 25 '20 at 13:04
  • I probably did not use the right term, seems that it is called "reclassing", seems an acceptable thing to do from https://stackoverflow.com/questions/990758/reclassing-an-instance-in-python I am editing my question. – Eskapp Sep 25 '20 at 13:11
  • 1
    Sure. My suggestion only makes sense if Line is the only object with a reference to the point object. – Wups Sep 25 '20 at 13:13

1 Answers1

0

After a few extra hours digging through this problem, what I describe in the question works perfectly. My issue appeared in a much more complex object with many attributes referring to many other classes. One of those attributes had kept a dependency. This was a non-problem, but learnt a lot on the way!

A good way of finding if the problem comes from a remaining dependency is to implement what is described in the question. Some extremely simple objects that relate to each other in the simplest way possible. If that simple example does not work the problem comes from somewhere else. If it works, it means that there is a dependency left in the object you are trying to load.

Eskapp
  • 3,419
  • 2
  • 22
  • 39