strictaccess¶
strictaccess enforces Java/C++-style access modifiers on Python classes.
Decorate a class with @strict_access_control() and use @private,
@protected, and @public to mark methods. Violations raise typed
exceptions; an optional debug mode downgrades them to log warnings.
from strictaccess import strict_access_control, private, protected
@strict_access_control()
class Account:
def __init__(self, balance: int) -> None:
self._balance = balance # protected by convention
@private
def _adjust(self, delta: int) -> None:
self._balance += delta
def deposit(self, amount: int) -> None:
self._adjust(amount) # OK: internal call
Where to next¶
- Installation — install and verify.
- Quickstart — five-minute tour.
@private,@protected,@public— what each decorator does, with examples.- Debug mode — log violations instead of raising.
- Limitations — known constraints. Read this before treating strictaccess as a security tool. It is not one.
- API reference — autogenerated from docstrings.
Why not just rely on the underscore convention?¶
The underscore prefix is documentation. strictaccess turns it into an enforced contract: violations fail loud at runtime instead of silently breaking encapsulation. It is the same model Java and C++ use; the philosophy is "make wrong code look wrong, and refuse to run it."
Why use this at all?¶
- Codebases shared across teams. Convention drifts; enforcement does not.
- Legacy refactors. Run in debug mode to surface every site that touches private state before you commit to a hardened API.
- Library boundaries. Mark internals so consumers cannot accidentally build on them and complain when you change them.
Why not?¶
- You need a security boundary.
object.__getattribute__bypasses strictaccess in one line. See Limitations. - You need C-level performance for attribute access. The override pays roughly 20-30x over native attribute access (still nanoseconds — fine for business logic, not for hot inner loops).