Package: protected-method-metaclass
protected_method_metaclass - Metaclass enabling the protected feature on methodsThis package contains several metaclasses that allow the protected feature on the applied class and this all the subclasses.The mechanism should works with multiple inheritance but you should still be carefull in this case.When overloading a protected method, the overloaded method can still be accessed with the '__old' prefix (see later)Simple exampleCreating a base classfromprotected_method_metaclassimportProtectedMethodMetaClass,Protected# ==========================================================classBaseClass(object,metaclass=ProtectedMethodMetaClass):# The base class must use the ProtectedMethodMetaClass metaclass# ====================def__init__(self,a):self.__a=a# ==============defget_a(self):returnself.__a# ========@Protected# Use the Protected decorator on private methods you want to make protecteddef__set_a(self,a):print("IN BASE CLASS")self.__a=aUse with sub class and overloading# ==========================classSubClass_1(BaseClass):# ===================def__set_a(self,a):# You don't need to repeat the Protected decorator to overloadprint("IN SUB CLASS 1")self.__old_set_a(a)# use the '__old' prefix for the overloaded method# =============================defcall_former_set_a(self,a):self.__old_set_a(a)# ==========================defcall_new_set_a(self,a):self.__set_a(a)# ========@Protected# You an declare protected method in any subclass of a class using the ProtectedMethodMetaClass metaclassdef__new_protected_method(self):print("new_protected_method")the_instance=SubClass_1("a")the_instance.call_former_set_a("a1)>>>INBASECLASSthe_instance.get_a()>>>a1the_instance.call_new_set_a("a2")>>>INSUBCLASS1>>>INBASECLASSthe_instance.get_a()>>>a2Multiple sub classesThe following example details the behaviour of a protected method and of the '__old' prefix when there is a  hierarchy of sub classes.# ===========================classSubClass_2(SubClass_1):# ===================def__set_a(self,a):print("IN SUB CLASS 2")self.__old_set_a(a)the_instance=SubClass_2("a")the_instance.call_former_set_a("a1)  # The behaviour is not modified': __old_set_a' used in SubClass_1 still refers '__set_a' of BaseClass>>>INBASECLASSthe_instance.get_a()>>>a1the_instance.call_new_set_a("a2")# The behaviours is modified as '__set_a' always points to the latest overloaded method>>>INSUBCLASS2>>>INSUBCLASS1>>>INBASECLASSthe_instance.get_a()>>>a2PyQt5 and PySide2As most classes from PyQt or PySide2 use their own metaclass, the standard ProtectedMethodMetaClass is not directly usable for Qt classes.The package protected_method_metaclass contains two other metaclasses compatible with PyQt5 or PySide2.
They are designed to be used exactly as the native ProtectedMethodMetaClass with one for PyQt5 and one for PySide2.Yet, you do not need to have any of those library installed as a requirement for the protected_method_metalass package.
The matching metaclasses will be available only if the Qt libraries are installed and disabled otherwise.Example with PyQt5fromprotected_method_metaclassimportProtectedMethodMetaClass_QtfromPyQt5.QtWidgetsimportQWidgetclassMyBaseWidget(QWidget,metaclass=ProtectedMethodMetaClass_Qt):passExample with PySide2fromprotected_method_metaclassimportProtectedMethodMetaClass_PySide2fromPySide2.QtWidgetsimportQWidgetclassMyBaseWidget(QWidget,metaclass=ProtectedMethodMetaClass_PySide2):pass