[Types-sig] Re: Inferencing: A case study

Guido van Rossum guido@CNRI.Reston.VA.US
Tue, 14 Dec 1999 15:42:37 -0500


[Paul]
> I've been thinking: I can allow statically checked references to
> type-inferenced module variables if we make the module namespace
> write-only outside of the module. The "trick" is that I need to put a
> boundary around where I expect writes to take place so I can check that
> I can figure the complete list of possible values the variable can take.
> If writes can come from outer space then I need to check every write at
> runtime.

Good -- I've been thinking the same thing.  Here's what I think would
be needed:

1. <module>.<attribute> = <expression> is simply forbidden (this is
setattr for module objects)

2. Somehow we restrict use of <module>.__dict__, globals(), locals(),
and vars().

3. Somehow we restrict exec, eval(), and execfile() when these can
touch a module's globals.

So the only way a module-level variable can be set will be through
assignments in its body (this includes classes and functions contained
in its body); such assignments are easily traceable for the
typechecker.

> So, I can do static type checking on a module variable if:
> 
>  * it is declared only "privately writeable"
>  * or the whole module namespace is "privately writeable"
>  * or it has a type declaration.
> 
> We can provide access to any combination of these options that we
> decide. 
> 
> Privately writable is more pythonic than "const" which was my first
> reaction. Of course the vast, vast majority of module variables are
> privately writable. And one could argue that ALL of them should be.
> Module namespace writability is a security nightmare and it is SO easy
> to move writeable variables to an object:
> 
> sys.path => sys.runtime.path
> sys.version => sys.impl.version

Actually, there's never a need to assign to sys.version, and as for
sys.path, maybe you can't assign a different object to it, you can
still change its value because a list is mutable.

--Guido van Rossum (home page: http://www.python.org/~guido/)