Package: protected-class
python_protected_classProtect class attributes in any python object instanceSupports (virtually) any python objectUses Cython to build a C extensionDoes not leave a back door like:Attributes still accessible usingobject.__getattribute__(myobj, atribute)Looking at python stack frameTested on Python 2.7.17 and python 3.6.9, 3.7.5, 3.8.0Should work on any Python 3 versionWell documented (docstring)doctests in tests directoryTested (only) on Ubuntu Bionic 18.04. Should work on any Linux distributionShould work wherever cython worksIf you want to CHANGE the source and recompile protected_class.c, and you want it
to work with Python 3.7+, you need to install cython version >= 0.27.3
Do this withsudo pip3 install --upgrade cython>=0.27.3This README.md is not completely up to date. Usepydoc protected_classfor the most up-to-date documentationUsage# Use any custom class of your ownclassMyClass(object):def__init__(self):self.__hidden=1self._private=2self.public=3# Get an instance of your classmyinst=MyClass()# import + ONE line to wrap and protect class attributesfromprotected_classimportProtectedwrapped=Protected(myinst)That's it!Options: Proteced class constructor keyword arguments:OptionTypeDefaultDescriptionOverridesaddboolTrueWhether attributes can be ADDEDfrozenboolFalseIf True, no attributes can be CHANGED or ADDEDaddrwprotect_classboolTruePrevents modification of CLASS of wrapped objectDoesn't PREVENT modification, but modification has no effecthide_allboolFalseAll attributes will be hiddenCan override selectively with 'show'hide_databoolFalseData (non-method) attributes will be hiddenOverride selectively with 'show'hide_methodboolFalseMethod attributes will be hiddenOverride selectively with 'show'hide_privateboolFalsePrivate vars (form _var) will be hiddenOverride selectively with 'show'hide_dunderboolFalse'dunder-vars' will be hiddenOverride selectively with 'show'ro_allboolFalseAll attributes will be read-onlyCan override selectively with 'rw'ro_databoolFalseData (non-method) attributes will be read-onlyOverride selectively with 'rw'ro_methodboolTrueMethod attributes will be read-onlyOverride selectively with 'rw'ro_dunderboolTrue'dunder-vars' will be  read-onlyOverride selectively with 'rw'rolist of str[ ]Attributes that will be read-onlyCan selectively override with 'rw'rwlist of str[ ]Attributes that will be read-writero_allro_dataro_methodro_dunderrohidelist of str[ ]Attributes that will be hiddenOverride selectively with 'show'showlist of str[ ]Attributes that will be visiblehide_allhide_datahide_methodhide_dunderhideVISIBILITY versus READABILITY or ACCESSIBILITYVISIBILITY: appears in dir(object)Never affected by Protected class:object.__dir__(myinst)will still show ALL attributeNAMESNote: visibility in Protected object IS controlled by Protected class:object.__dir__(wrapped)will show attributes based on options used with Protected classREADABILITY or ACCESSIBILITY: Accessing the VALUE of the attributeApplies to Protected object instance - NOT original wrapped objectCode of original wrapped object instance is completely UNAFFECTED by Protected ClassAccessibility of attributes of original wrapped object through Protected class instance IS controled by Protected classAffectsgetattr,hasattr,object.__getattribute__etcMUTABILITY: Ability to CHANGE or DELETE an attributeProtected class will not allow CHANGING OR DELETING an attribute that is not VISIBLE - per rules of Protected classAttributes set to read-only using Protected class cannot be modified through Protected class instance. The code of the original wrapped object is not affected by this.OptionAttribute TypeReadabilityMutabilityfrozenAnyNOYESaddAdded at run-timeNONOprotect_classobject classNOYEShide_allANYYESYES (Indirect)hide_dataData attributesYESYES (Indirect)hide_methodMethod attributesYESYES (Indirect)hide_privatePrivate attributesYESYES (Indirect)hide_dunderdunder-attributesYESYES (Indirect)ro_allANYNOYESro_dataData attributesNOYESro_methodMethod attributesNOYESro_dunderdunder-attributesNOYESroANYNOYESrwANYNOYEShideANYYESYES (Indirect)showANYYESNODefault settings:Traditional (mangled) Python private vars are ALWAYS hiddenCANNOT be overriddenPrivate vars (form _var) will be read-onlyCan use hide_private to hide themThey CANNOT be made read-writeadd == True: New attributes can be added (Python philosophy)protect_class == True: Prevents modification of CLASS of wrapped objectro_dunder == True: 'dunder-vars' will be  read-onlyro_method == True: Method attributes will be read-onlyAll other non-dunder non-private data attributes are read-writeNon-overrideable behaviors of Protected class:Traditional python 'private' vars - start with__but do not end with__- can never be read, written or deletedIf an attribute cannot be read, it cannot be written or deletedAttributes can NEVER be DELETED UNLESS they were added at run-timeAttributes that are properties are ALWAYS visible AND WRITABLE (except if 'frozen' is used)Properties indicate an intention of class author to expose themWhether they are actually writable depends on whether class author implemented property.setterThe following attributes of wrapped object are NEVER visible:__dict__,__delattr__,__setattr__,__slots__,__getattribute__You cannot subclass Protected classPython rules for attributes of type 'property':Properties are defined in the CLASS, and cannot be changed in the object INSTANCEProperties cannot be DELETEDProperties cannot be WRITTEN to unless property has a 'setter' method defined in the CLASSThese rules are implemented by the python language (interpreter) and Protected class does not enforce or checkWhat kind of python objects can be wrapped?Pretty much anything. Protected only mediates attribute access usingobject.__getattribute__,object.__setattr__andobject.__delatr__. If these methods work on your object, your object can be wrappedCan a Protected class instance be wrapped again using Protected?YES !Why can't I subclass Protected class?Protected class is only for wrapping a python object INSTANCENONE of the atributes of Protected class are exposed - only (selecive) attributes of the WRAPPED objectOverriding methods of Protected class is not possible - since Protected is implemented in COverriding attributes of wrapped object is not possible, since the original object is wrapped inside Protected and all accesses are hrough the Proteced class instanceNew attributes defined in sub-class will not be accessible, since attribute access is mediated by Protected classBecause of this, Protected class PREVENTS sub-classingSubclass your python object BEFORE wrapping with ProtectedHow do IMake my object completely read-onlyUseadd=False, frozen=TrueCompletely hide private variables hat are normally read-only, but visibleUsehide_private=TrueHide all except propertiesUsero_all=TrueHide all dunder-attributes except specific onesUsehide_dunder=True, show=['exception1', 'exception2']Hide all attributes except specific onesUsehide_all=True, show=['exception1', 'exception2']Make all attributes read-only except specific onesUsero_all=True, rw=['exception1', 'exception2']How can I get close to default python behaviorUseadd=True, protect_class=False, ro_method=False, ro_dunder=FalseMangled private variables still won't be visiblePrivate variables (form_var) will still be read-onlySome RUN-TIME behaviors to AVOID in wrapped objects:Do not create attribute - these will not be detected once the object instance is wrapped in ProtectedDo not delete attributes - these will still appear to be part of the wrapped object when accessing through the wrapping Protected class. Actual access will result inAttributeErroras expectedDo not change attribute TYPE - from METHOD to DATA or vice-versaThis will cause predictable effects if Protected instance was created using any of the following options:
hide_method
hide_data
ro_method
ro_dataNone of the above run-time behaviors should be common or recommended - especially when wanting to expose a wrapped interface with visibility and/or mutability protectionsWork in progressCompleting setup.py to allow installation withpipUploading to pypi.org