Advertisement
Rnery

Insane Python..

May 20th, 2021 (edited)
295
1
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.74 KB | Source Code | 1 0
  1. import types
  2. from functools import wraps
  3. from copy import copy
  4.  
  5. def private_context(method):
  6.     @wraps(method)
  7.     def wrapper(self, *args, **kwargs):
  8.         try:
  9.             object.__setattr__(self, '__private_context__', True)
  10.             return method(self, *args, **kwargs)
  11.         finally:
  12.             object.__setattr__(self, '__private_context__', False)
  13.     return wrapper
  14.  
  15.  
  16. class PrivateProperty(property):
  17.     def __init__(self, prop):
  18.         fget = private_context(prop.fget) if prop.fget else None
  19.         fset = private_context(prop.fset) if prop.fset else None
  20.         fdel = private_context(prop.fdel) if prop.fdel else None
  21.         doc = prop.__doc__
  22.        
  23.         super().__init__(fget, fset, fdel, doc)
  24.        
  25.    
  26. class MetaPrivate(type):
  27.     """Allows the definition of private methods
  28.    It has two modes of operation:
  29.        If you set __private__ as a list of private attributes,
  30.            the only private methods and attributes are the ones in the list
  31.        If you set __public__ as a list of public attributes,
  32.            all attributes and methods become private, except the ones in the list
  33.    """
  34.     def __new__(cls, name, bases, dct):
  35.         if '__private__' in dct or '__public__' in dct:
  36.             private = set(dct.get('__private__', []))
  37.             public = set(dct.get('__public__', []))
  38.             new_dct = copy(dct)
  39.  
  40.             def accessible_key(self, key):
  41.                 is_public = key in public
  42.                 is_private = '__public__' in dct or key in private
  43.                 in_private_context = object.__getattribute__(self, '__private_context__')
  44.                 return is_public or not is_private or in_private_context
  45.  
  46.             def __getattribute__(self, key):
  47.                 if accessible_key(self, key):
  48.                     return object.__getattribute__(self, key)
  49.                 raise AttributeError(f'Attempt to access private attribute "{key}"')
  50.  
  51.             def __setattr__(self, key, value):
  52.                 if accessible_key(self, key):
  53.                     return object.__setattr__(self, key, value)
  54.                 raise AttributeError(f'Attempt to set private attribute "{key}"')
  55.            
  56.             new_dct['__private_context__'] = False
  57.             new_dct['__getattribute__'] = __getattribute__
  58.             new_dct['__setattr__'] = __setattr__
  59.            
  60.             for key, value in dct.items():
  61.                 if isinstance(value, types.FunctionType):
  62.                     new_dct[key] = private_context(value)
  63.                 if isinstance(value, property):
  64.                     new_dct[key] = PrivateProperty(value)
  65.            
  66.             dct = new_dct
  67.         result = super().__new__(cls, name, bases, dct)
  68.         return result
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement