If you try to modify an array within a nested loop...
sum_b = ([10, 20, 30])
for a in range(3):
for b in range(4):
sum_b[a] += b
...it gives an (apparently benign) warning:
'sum_b...' apparently modified, but can't copy it
No such warning is given when run directly from the command line with python.
Robert Schroll wrote:
This is indeed a problem with Reinteract. The problem lies in the part
of the code that attempts to track and copy objects that are modified,
so that a previous state can be restored when a statement it edited and
re-executed. I don't know what Reinteract is trying and failing to
copy. It's not sum_b itself, since that is properly restored before the
for loop is re-executed.
Owen Taylor wrote:
Sadly, not completely straightforward:
c = [[1, 2], [3,4]]
c[1] += [2]
Then before the line c[1] += [2], we need to make a "backup" copy of c
so we can rewind execution to that point.
Reinteract normally does a backup copy as a shallow copy. But a
shallow copy of c isn't good enough because the line c[1] += [2]
actually goes ahead and "mutates" not just C, but the [3,4] array that
it points. To so, reinteract does a shallow copy of C, and then it
descends one level deeper and makes a shallow copy of [3,4].
Richards example:
for a in range(3):
for b in range(4):
sum_b[a] += b
Is a lot like the c[1] += [2], except that the elements we are doing a
"deep mutation" on are determined at runtime. What reinteract does is
(effectively) rewrite the statement to be:
sum_b = copy.copy(sum_b)
sum_b[a] = copy.copy(sum_b[a])
for a in range(3):
for b in range(4):
sum_b[a] += b
But at the second line, a is undefined, so it fails. What might be
possible to do is to actually insert the "backup" statements right
into place immediately before the modifying statement, so we have
instead:
sum_b = copy.copy(sum_b)
for a in range(3):
for b in range(4):
sum_b[a] = copy.copy(sum_b[a])
sum_b[a] += b
Which should work, though a bit slowly. There might be some other
pitfalls with that that I'm not thinking of right at the moment.