[IPython-dev] Should we disable autocall by default from now on?
Wed Nov 30 13:40:33 CST 2011
On Wed, Nov 30, 2011 at 10:50 AM, Warren Weckesser
> On Wed, Nov 30, 2011 at 5:18 AM, Robert Kern <email@example.com> wrote:
>> On 11/30/11 7:07 AM, Fernando Perez wrote:
>> > Hi folks,
>> > over the years, we've had a number of bug reports that ultimately boil
>> > down to ipython doing an extra getattr call on objects at the prompt,
>> > such as
>> > https://github.com/ipython/ipython/issues/988
>> > https://github.com/ipython/ipython/issues/851
>> > While this may appear odd, people do have code out there that mutates
>> > the state of objects on simple getattr calls, and so *any*
>> > introspection on such objects, no matter how carefully done, mutates
>> > them. The last example comes from Traits code, which is famous for
>> > having complex semantics attached to attribute access.
>> > Since this is a recurring problem, I'm trying to decide whether the
>> > convenience of autocall being on by default is worth against the
>> > occasional surprise of situations like these.
>> > Obviously we'd leave the functionality of autocall as-is, and people
>> > could still enable it if they wanted to. I'm only talking about
>> > whether it should be completely off by default. The reason why
>> > defaults matter a lot is that the vast majority of users never ever
>> > change them (I've seen countless long-term users with the wrong colors
>> > for a light bacgkround, the one default we can't pick for them and
>> > that leads to unreadable tracebacks, yet people live with it for
>> > years). So it's up to us to give people defaults that lead to the
>> > best experience possible.
>> > I personally had always fallen on the side of saying that autocall is
>> > a big convenience of ipython, and that code that mutates on simple
>> > attribute access is special enough that we shouldn't sacrifice that
>> > convenience for most users to accommodate such a special case.
>> I don't think it's *that* special of a case. There are all kinds of good
>> to set up a special case for the first time an attribute is looked up
>> mutating the object to let future lookups go through a different path.
>> *Usually*, getting the attribute in the autocall code is innocuous, but
>> sometimes it isn't.
> I'll second Robert's comment.
> Here's a "user story" where the double evaluation of an attribute caused
> me headaches until I realized what was happening.
> We (Enthought) developed some some classes that provide interfaces to
> test equipment (oscilloscopes, power supplies, etc). By using properties,
> we developed interfaces to the instruments that were very easy to use.
> For example, a statement such as
> instr.voltage = 5
> would cause a command to be sent to the instrument to set the voltage to 5.
> v = instr.voltage
> would trigger a query to get the current voltage setting from the
> and return it as a floating point value.
> Working with such a class from within ipython is slick, but no doubt you
> can already see the potential problem. Using ipython as follows
> In : instr.voltage
> Out : 5.0
> actually sent the query to the instrument twice. This can be a relatively
> query, because the communication might be over a serial line or GPIB
> OK, so it is slower than necessary; that is a minor annoyance. The real
> headache occurred when I was using a property that accessed the error
> state of the instrument. Reading the attribute 'system_error' sent the
> appropriate query to the instrument, but that query also caused the
> to reset its internal error state. It took me a long time to figure out
> when I intentionally did something wrong, the following
> In : instr.system_error
> always resulted in no errors! Eventually I realized that it was triggering
> two queries. I wasn't aware of autocall at the time, so my solution was to
> always use print, e.g.
> In : print instr.system_error
> So, there's another "real world" use-case where reading an attribute twice
> at the command prompt caused problems. (Whether that particular attribute
> should have been a method instead--e.g. read_and_reset_system_error()--is
> a separate topic, but there were good reasons for the property
To me, this is not a different topic. You should not assume that an
attribute will not be read multiple times. A system like IPython will
need to do things like this to do its magic. There are other things
that will mess this up too. I can't imagine what would happen to that
system if you tried running it through a graphical debugger!
On the other hand, virtually nothing would automatically do
instr.system_error(), because it's kind of known that calling
something changes state (in general). It's just two characters more,
and shouldn't be that much different on the programatic side either,
so I can't see why it was done the other way (but I haven't done much
on the programatic side, so maybe it really isn't as easy).
Regarding autocall, I think it should be disabled by default, not
because it messes with magic things like this (so you can't mix two
kinds of magic, no surprises there), but because it's very
unintuitive, and unpythonic. I agree with Matthew that when I first
saw this, I went "huh", and then immediately, "how do I disable this"?
To put it another way, magic that literally changes the syntax of
Python should perhaps not be for beginner users (I'll put ?help magic
as an exception to this).
But that's just my opinion as a user of IPython.
>> I've always been in favor of turning autocall off by default, though I
>> really say that I have a strong argument beyond personal preference. I
>> like to keep two parallel Python syntaxes in my head (and muscle memory!),
>> especially when one of them is only informally specified and only works in
>> specific environment.
>> Robert Kern
>> "I have come to believe that the whole world is an enigma, a harmless
>> that is made terrible by our own mad attempt to interpret it as though it
>> an underlying truth."
>> -- Umberto Eco
>> IPython-dev mailing list
> IPython-dev mailing list
More information about the IPython-dev