Debug mode¶
Set debug=True and violations are logged as WARNING instead of
raising. The attribute is still returned to the caller, so existing code
keeps running while you track down each offender.
import logging
logging.basicConfig(level=logging.WARNING)
from strictaccess import strict_access_control, private
@strict_access_control(debug=True)
class Audit:
@private
def _secret(self) -> int:
return 42
a = Audit()
a._secret()
# WARNING:strictaccess:Access to private member '_secret' of class 'Audit'
# from '__main__' is forbidden.
# returns 42
When to use it¶
- Adopting strictaccess on a legacy codebase. Turn it on in staging, collect a week of warnings, fix the call sites, then flip back to strict.
- Investigating a noisy migration. A single PR that touches many internals can be hard to review; debug mode emits the full call list.
- Documentation of current coupling. The warnings reveal exactly which external callers reach into the class' internals.
Don't use it in production¶
- It silently leaks access to private state.
- It pays the logging cost on every violation.
- Users of your code will not expect a public-facing class to log when they touch it.
For production, treat debug=True like an assert: useful in dev, off in
ship.
Configuring the logger¶
The library emits to the logger named "strictaccess". It does not
attach handlers or touch the root logger — that is your application's job.
import logging
logging.getLogger("strictaccess").setLevel(logging.WARNING)
# Or route to a dedicated file:
handler = logging.FileHandler("access_violations.log")
handler.setFormatter(logging.Formatter("%(asctime)s %(message)s"))
logging.getLogger("strictaccess").addHandler(handler)
Capturing in tests¶
pytest's caplog fixture works directly: