Quickstart¶
A five-minute tour of every feature.
Decorate the class¶
from strictaccess import strict_access_control, private, protected, public
@strict_access_control()
class Counter:
def __init__(self) -> None:
self._value = 0 # protected by convention
@public
def increment(self) -> None:
self._step() # internal call to protected: OK
@protected
def _step(self) -> None:
self._value += 1
@private
def _reset(self) -> None:
self._value = 0
Use it¶
c = Counter()
c.increment() # OK
c._value # raises ProtectedAccessError
c._step() # raises ProtectedAccessError
c._reset() # raises PrivateAccessError
Catch the violations¶
from strictaccess import PrivateAccessError, ProtectedAccessError
try:
c._reset()
except PrivateAccessError as e:
print(e)
# Access to private member '_reset' of class 'Counter'
# from 'caller_qualname' is forbidden.
Subclass it¶
class FastCounter(Counter):
def jump(self) -> None:
self._step() # OK: protected reachable from subclass
# self._reset() # would still raise PrivateAccessError
Run in debug mode¶
import logging
logging.basicConfig(level=logging.WARNING)
@strict_access_control(debug=True)
class Soft(Counter):
pass
s = Soft()
s._reset() # logs a WARNING via the 'strictaccess' logger
# returns the result; does NOT raise
See Debug mode for how to use this during refactors.
Next¶
@private— strict same-class restriction.@protected— class + subclasses.@public— explicit opt-out of the underscore convention.- Limitations — what strictaccess cannot do.