benjaminp / six

Python 2 and 3 compatibility library
https://six.readthedocs.io/
MIT License
987 stars 274 forks source link

Failure when using six.with_metaclass in python 2.7 when metaclass doesn't directly inherit from type #373

Open herronelou opened 1 year ago

herronelou commented 1 year ago

Hello.

I've been trying really hard to make a class with a new metaclass in a way that's compatible with both python 2 and 3, and ran into issues both while using six.with_metaclass and future.utils.with_metaclass which is a little bit different. I'm happy to report that the six.add_metaclass decorator did the job, however.

Now I'm sure with_metaclass works fine in most cases, but here is the situation:

I'm using the library PySide2 https://pypi.org/project/PySide2/

I'm trying to subclass a PySide2.QtCore.QObject with a new metaclass. For this, I need my metaclass to inherit from the original metaclass of QObject, which is Shiboken.ObjectType.

I then try to define my class with the new meta, which fails because with_metaclass attempts to use type.__new__ directly, instead of Shiboken.ObjectType.__new__

from PySide2 import QtCore
from six import with_metaclass

class MyMeta(type(QtCore.QObject)):
    pass

class MyClass(with_metaclass(MyMeta, QtCore.QObject)):
    pass
TypeError: type.__new__(metaclass) is not safe, use Shiboken.ObjectType.__new__()

It does work fine in Python 3