[Python-ideas] Make Python code read-only
Steven D'Aprano
steve at pearwood.info
Wed May 21 03:42:04 CEST 2014
On Wed, May 21, 2014 at 03:37:42AM +1000, Chris Angelico wrote:
> With that (rather big, and yet quite trivial) caveat, though: Looks
> interesting. Optimizing for the >99% of code that doesn't do weird
> things makes very good sense, just as long as the <1% can be catered
> for.
"99% of Python code doesn't do weird things..."
It seems to me that this is a myth, or at least unjustifiable by the
facts as we have seen it. Victor's experiment shows 25 modules from the
standard library are modifiable, with 139 read-only. That's more like
15% than 1% "weird".
I don't consider setting sys.ps1 and sys.stdout to be "weird", which is
why Victor has to leave sys unlocked.
Read-only by default would play havok with such simple idioms as global
variables. (Globals may be considered harmful, but they're not
considered "weird", and they're also more intuitive to many beginners
than function arguments and return values. Strange but true.) As much as
I wish to discourage people from using the global statement to rebind
globals, I consider it completely unacceptable to have to teach
beginners how to disable read-only mode before they've even mastered
writing simple functions.
I applaud Victor for his experiment, and would like to suggest a couple
of approaches he might like to think about. I assume that read-only mode
can be set on a per-module basis.
* For simplicity, read-only mode is all-or-nothing on a per module
basis. If the module is locked, so are the functions and classes defined
by that module. If the module is not locked, neither are the functions
and classes.
(By locked, I mean Victor's read-only mode where globals and class
attributes cannot be re-bound, etc.)
* For backwards compatibility, any (eventual) production use of this
would have to default to off. Perhaps in Python 4 or 5 we can consider
defaulting to on.
* Define an (optional) module global, say, __readonly__, which defaults
to False. The module author must explicitly set it to True if they wish
to lock the module in read-only mode. There's no way to enable the
read-only optimizations by accident, you have to explicitly turn them
on.
* However there are ways to auto-detect when *not* to enable them. E.g.
if a module uses the global statement in any function or method,
read-only mode is disabled for that module.
* Similarly, a Python switch to enable/disable read-only mode. I don't
mind if the switch --enable-readonly is true by defalt, so long as
individual modules default to unlocked.
How about testing? It's very common, useful, and very much non-weird to
reach into a module and monkey-patch it for the purposes of testing. I
don't have a good solution to that, but a couple of stream of
consciousness suggestions:
- Would it help if there was a statement "import unlocked mymodule" that
forces mymodule to remain unlocked rather than read-only?
- Would it help if you could make a copy of a readonly module in an
unlocked state?
- Obviously the "best" (most obvious) solution would be if there was a
way to unlock modules on the fly, but Victor suggests that's hard.
--
Steven
More information about the Python-ideas
mailing list