Python Feature Request: Add the "using" keyword which works like "with" in Visual Basic

Steven D'Aprano steve at REMOVE.THIS.cybersource.com.au
Sun Apr 15 00:02:13 EDT 2007


On Sat, 14 Apr 2007 03:42:52 -0700, samjnaa wrote:

> Please check for sanity and approve for posting at python-dev.
> 
> In Visual Basic there is the keyword "with" which allows an object-
> name to be declared as governing the following statements. For
> example:
> 
> with quitCommandButton
>  .enabled = true
>  .default = true
> end with
> 
> This is syntactic sugar for:
> 
> quitCommandButton.enabled=true
> quitCommandButton.default=true

Which is very much like Pascal's with block.

This question has been asked before:

http://effbot.org/pyfaq/why-doesn-t-python-have-a-with-statement-like-some-other-languages.htm

Despite what the Effbot says, I believe that there is no ambiguity that
can't be resolved.

Specifying that names used in a using-block have a leading dot makes it
obvious to the compiler which names are shortened:

using longname:
    x = .attribute # must be longname.attribute


If we forbid nested using-blocks, then all you need is a pre-processor to
change ".attribute" to "longname.attribute". There's never any ambiguity.

But if you want to be really ambitious, one might allow nested
using-blocks. Now the compiler can't resolve names with leading dots at
parse-time, and has to search namespaces at runtime, but that's no
different from what Python already does.


using longname:
    using anotherlongname:
        x = .attr

In this case, at Python has to determine at runtime which object has an
attribute "attr". If that sounds familiar, it should: that's exactly what
happens when you say instance.attribute: Python searches
instance.__dict__ then instance.__class__.__dict__, and any superclasses.

There is one slight ambiguity left: should Python search longname first or
anotherlongname? But that decision has come up before, for nested scopes
in functions. It seems obvious to me that Python should search deepest to
most shallow, the same way that function nested scopes work.

So the above nested block would be equivalent to:

try:
    x = anotherlongname.attr
except AttributeError:
    try:
        x = longname.attr
    except AttributeError:
        raise UsingError('no such attribute')


One might even allow a construct like this:

using longname, anotherlongname:
    x = .attr

In this case, the search resolution order would be from left to right,
that is, longname before anotherlongname.



-- 
Steven.




More information about the Python-list mailing list