Calling methods on base class gives mutation error

0 views
Skip to first unread message

ack

unread,
Nov 6, 2011, 5:23:22 PM11/6/11
to Reinteract
First off, thanks for Reinteract! Believe it or not, I've been using
it as my main editor for prototyping in Python for some time now.

When I define in a worksheet a subclass in which a method calls a
method on a base class, for example:

class SubClass(BaseClass):
def __init__(self):
BaseClass.__init__(self)

and recalculate, Reinteract gives me the error: Mutating global
variable 'BaseClass' inside a function is not supported .

I've worked around this by moving the class definitions into a library
in the notebook and importing from that, which works, but testing the
classes is somewhat cumbersome, because for library files, the editor
doesn't support error highlighting and has no line numbers.

Is it possible to make Reinteract allow the definition of subclasses
which call methods on their base classes?

Kind regards,

ack

Robert Schroll

unread,
Nov 6, 2011, 8:36:09 PM11/6/11
to reint...@googlegroups.com
On 11/06/2011 05:23 PM, ack wrote:
> First off, thanks for Reinteract! Believe it or not, I've been using
> it as my main editor for prototyping in Python for some time now.

Good to hear!


>
> When I define in a worksheet a subclass in which a method calls a
> method on a base class, for example:
>
> class SubClass(BaseClass):
> def __init__(self):
> BaseClass.__init__(self)
>
> and recalculate, Reinteract gives me the error: Mutating global
> variable 'BaseClass' inside a function is not supported .

Reinteract is mistaking this as a method call on the object 'BaseClass'.
Since the result isn't assigned to a variable, it assumes a mutation
happened. I've filed a bug about this:
https://bugzilla.gnome.org/show_bug.cgi?id=663533


>
> I've worked around this by moving the class definitions into a library
> in the notebook and importing from that, which works, but testing the
> classes is somewhat cumbersome, because for library files, the editor
> doesn't support error highlighting and has no line numbers.

For now, you can work around this behavior in a worksheet by doing
_ = BaseClass.__init__(self)
This fakes out the mutation-detection code.


>
> Is it possible to make Reinteract allow the definition of subclasses
> which call methods on their base classes?

I hope so, but doing it correctly might not be so easy. If I understand
this code correctly, it's raising the error when the syntax is being
analyzed, which means it can't tell that BaseClass is a class.

Tangentially related: I thought we might be able to work around this
with super(). But Reinteract objects to a().b() as a mutation of a.
This strikes me as wrong. That code may be mutating something, but we
can't make a reasonable guess one way or the other just from the syntax.

Thanks for the report,
Robert

Owen Taylor

unread,
Nov 7, 2011, 10:27:53 AM11/7/11
to reint...@googlegroups.com
Various thoughts:

* When we can't tell what is going on, we should error on the side of
assuming that the code is doing something harmless and let it through
... it's not at all hard to intentionally confuse reinteract, and one
of the central ideas of reinteract is that normal Python code _isn't_
doing anything strange or unexpected. It's possible that we should
just give everything inside a class or function definition a "free
pass". After all, that's what we'd do if it was in a library file.

* There is some difference between 'A.b = c' and 'A.b(arg)' - the
first is pretty clearly a mutation of A, but the second one could be a
mutation of A, or it could be a mutation of arg. So, even if we want
to keep the first an error, the second should possibly be not errored
on the principle that if we don't know, we should let the user do what
they are trying to do.

* There's no hard reason we have to produce an error at compilation
time rather than execution time - we can remember that the mutation
occurred inside a function, remember the line number, then decide
whether to produce an error or not at execution time by resolving
against the current scope.

So, multiple avenues here to a solution - just have to pick one.

- Owen

> --
> You received this message because you are subscribed to the Google Groups "Reinteract" group.
> To post to this group, send email to reint...@googlegroups.com.
> To unsubscribe from this group, send email to reinteract+...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/reinteract?hl=en.
>
>

ack

unread,
Nov 7, 2011, 4:00:27 PM11/7/11
to Reinteract
Robert, thanks for the suggestion of assigning the method call result
to a dummy variable, works like a charm.

Excellent analysis, Owen, thanks :-)

Personally, I would be happy if reinteract showed me a warning in such
a case.

Concerning analysis at execution time: I'm currently using a small
module based on [1], defining a decorator which logs function and
method calls with their arguments. It even has functions which can
apply the decorator to all methods in a class, or all functions and
classes in a module.

I'm wondering if it would be possible for reinteract to do use
something like this to track any mutations at execution time.

[1]: http://wordaligned.org/articles/echo , bottom of page
(My module uses the PyPI decorator module, which better preserves
function signatures and docstrings.)
Reply all
Reply to author
Forward
0 new messages