Rect() TypeError while converting from python 2 to python 3

I’m getting the weirdest error while converting an application from python 2 to python 3.
Briefly this application uses wxPython to create an interface where the user can draw different objects on a canvas, and when clicking on objects the user can edit them and set different parameters. All these edits can be saved when closing the application. This save is performed with shelve library frome python.

This app was perfectly working with python 2, however for compatibility reasons I was trying to bring it on python 3 but here comes the problem: on python 3 I can save all the possible objects, however, if I add a specific object that instead of consisting of an icon is just a line between two icons, I can not reopen the project. I can add the object, work with it, change its settings, save the file, however I can not reopen it.

Biggest problem is that I don’t have a call stack to analyze. It just says that it is trying to unpickle the object in the shelf and next info I have is:

File "\Unpickle.py", line 25, in renamed_load
    return RenameUnpickler(file_obj, encoding=encoding).load()
TypeError: Rect(): arguments did not match any overloaded call:
  overload 1: too many arguments
  overload 2: not enough arguments
  overload 3: argument 1 has unexpected type 'float'
  overload 4: argument 1 has unexpected type 'float'
  overload 5: argument 1 has unexpected type 'float'
  overload 6: argument 1 has unexpected type 'float'

What is really weired is that if I open a file generated in python 2 (which is converted using something really similar to this, I don’t get the same error, I can open and edit the file. However the problem still arises when the file is closed and reopened once again.

This is the class performing the read, that inherits from Unpickler so that I can override the find_class method. Biggest problem with this error, that is really driving me crazy is that the call stack doesn’t tell me where the error is during the unpickling process and that if I scan my code for occurences of Rect I can’t find any.

class RenameUnpickler(pickle.Unpickler):
    def find_class(self, module, name):
        renamed_module = module
        if module == "wx._gdi":
            renamed_module = "wx"
        return super(RenameUnpickler, self).find_class(renamed_module, name)

def renamed_load(file_obj, encoding):
    return RenameUnpickler(file_obj, encoding=encoding).load()

def renamed_loads(pickled_bytes):
    file_obj = io.BytesIO(pickled_bytes)
    return renamed_load(file_obj)

class ShelfFileVO( shelve.DbfilenameShelf ):

    def __init__(self, *args, **kwds):
        kwds[ 'protocol' ] = 2
        shelve.DbfilenameShelf.__init__( self, *args, **kwds )
        self._semaphore = threading.BoundedSemaphore( 1 )
        self.find_globals = None

    def keys(self):
        return [ k.decode() for k in self.dict.keys() ]

    def has_key(self, key):
        return key.encode() in self.dict

    def __contains__(self, key):
        return key.encode() in self.dict

    def get(self, key, default=None):
        #key = key.encode()
        if key in self.dict:
            return self[ key ]
        else:
            return default

    def __getitem__(self, key):
        #key = key.encode()
        if key in list(self.cache.keys()):
            value = self.cache[ key ]
        else:
            f = BytesIO( self.dict[ key ] )
            value = renamed_load(f, encoding='latin1')

The issue is likely that some float values are being passed to Rect() whereas since Python 3.10, extension modules that accept ints will no longer silently automatically convert float values to ints. I would look at what you’re pickling and look for float values that may be getting passed to wxPython eventually.

BTW is this you?

no, we are colleagues! once we realized it was an issue with the wxpython itself we submitted a bug report with reproducible test on github page.

BTW the more rigorous handling of parameters was made in Python and not in wxPython, or if you had programmed to the docu of wxPython you wouldn’t have noticed the change :rofl:

In this case, it was actually a bug in wxPython too.