On Mon, Oct 31, 2011 at 3:58 PM, Bruce Leban <span dir="ltr"><<a href="mailto:bruce@leapyear.org">bruce@leapyear.org</a>></span> wrote:<br><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<div class="gmail_quote">On Sun, Oct 30, 2011 at 8:11 PM, Mike Meyer <span dir="ltr"><<a href="mailto:mwm@mired.org" target="_blank">mwm@mired.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div>Any attempt to mutate an object that isn't currently locked will raise<br>
an exception. Possibly ValueError, possibly a new exception class just<br>
for this purpose. This includes rebinding attributes of objects that<br>
aren't locked.<br></div></blockquote></div><div><br></div>Do you mean that at any time attempting to mutate an unlocked object throws an exception?</blockquote><div><br></div><div>Yes, that's the idea. There are some exceptions, but you have to explicitly work around that restriction.</div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">That would mean that all of my current code is broken.</blockquote><div><br></div><div>Pretty much, yes. It's like adding garbage collection and removing alloc*/free. It's going to break a *lot* of code. That's why I said "not in 3. and possibly never in cPython."</div>
<div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">Do you mean, that inside the control of 'locking', you can't mutate an unlocked object? That still breaks lots of code that is safe. You can't use itertools.cycle anymore until that's updated in a completely unnecessary way:<div>
<div><div><font face="'courier new', monospace"><span style="font-family:sans-serif;line-height:20px;background-color:rgb(238, 255, 204)"><pre style="overflow-x:auto;overflow-y:hidden;padding-top:5px;padding-right:5px;padding-bottom:5px;padding-left:5px;background-color:rgb(238, 255, 204);line-height:15px;border-top-width:1px;border-bottom-width:1px;border-top-style:solid;border-bottom-style:solid;border-top-color:rgb(170, 204, 153);border-bottom-color:rgb(170, 204, 153);border-left-style:none;border-left-width:initial;border-left-color:initial;border-right-style:none;border-right-width:initial;border-right-color:initial">
<span style="color:rgb(0, 112, 32);font-weight:bold">def</span><font color="#333333"> </font><span style="color:rgb(6, 40, 126)">cycle</span><span style="color:rgb(51, 51, 51)">(</span><span style="color:rgb(51, 51, 51)">iterable</span><span style="color:rgb(51, 51, 51)">):</span><font color="#333333">
</font><span style="color:rgb(64, 128, 144);font-style:italic"># cycle('ABCD') --> A B C D A B C D A B C D ...</span><font color="#333333">
</font><span style="color:rgb(51, 51, 51)">saved</span><font color="#333333"> </font><span style="color:rgb(102, 102, 102)">=</span><font color="#333333"> </font><span style="color:rgb(51, 51, 51)">[]</span><font color="#333333">
</font><span style="color:rgb(0, 112, 32);font-weight:bold">for</span><font color="#333333"> </font><span style="color:rgb(51, 51, 51)">element</span><font color="#333333"> </font><span style="color:rgb(0, 112, 32);font-weight:bold">in</span><font color="#333333"> </font><span style="color:rgb(51, 51, 51)">iterable</span><span style="color:rgb(51, 51, 51)">:</span><font color="#333333">
</font><span style="color:rgb(0, 112, 32);font-weight:bold">yield</span><font color="#333333"> </font><span style="color:rgb(51, 51, 51)">element</span><font color="#333333">
</font><span style="color:rgb(51, 51, 51)">saved</span><span style="color:rgb(102, 102, 102)">.</span><span style="color:rgb(51, 51, 51)">append</span><span style="color:rgb(51, 51, 51)">(</span><span style="color:rgb(51, 51, 51)">element</span><span><font color="#333333">) </font><font color="#990000"> <i># throws an exception when called on a locked iterable</i></font></span><font color="#333333">
</font><span style="color:rgb(0, 112, 32);font-weight:bold">while</span><font color="#333333"> </font><span style="color:rgb(51, 51, 51)">saved</span><span style="color:rgb(51, 51, 51)">:</span><font color="#333333">
</font><span style="color:rgb(0, 112, 32);font-weight:bold">for</span><font color="#333333"> </font><span style="color:rgb(51, 51, 51)">element</span><font color="#333333"> </font><span style="color:rgb(0, 112, 32);font-weight:bold">in</span><font color="#333333"> </font><span style="color:rgb(51, 51, 51)">saved</span><span style="color:rgb(51, 51, 51)">:</span><font color="#333333">
</font><span style="color:rgb(0, 112, 32);font-weight:bold">yield</span><font color="#333333"> </font><span style="color:rgb(51, 51, 51)">element</span></pre></span></font></div></div></div></blockquote><div>
<br></div><div>According to what I wrote, yes, it does.Since the list being mutated is only visible inside the function, it doesn't need to be. It might be possible to figure out that this is the case at compile time and thus allow the code to run unmodified. But that's 1) hard, 2) will miss some cases, 3) seems like a corner case. This proposal would break enough code that not breaking this case doesn't seem to be worth the effort. That's a question that needs to be answered.</div>
<div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;"><div><div><div><div><font face="arial, helvetica, sans-serif">I think the semantics of this need to be tightened up.</font></div>
</div></div></div></blockquote><div><br></div><div>That's why I brought it up. I'm trying to get more eyes on the issue.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<div><div><div><div><font face="arial, helvetica, sans-serif">Furthermore, merely *reading* an object that isn't locked can cause problems. This code is not thread-safe:</font></div>
<div><font face="arial, helvetica, sans-serif"><br></font></div><div><font face="'courier new', monospace"> if element in dictionary: return dictionary[element] </font></div>
<div><font face="arial, helvetica, sans-serif"><br></font></div><div><font face="arial, helvetica, sans-serif">so you have to decide how much safety you want and what cost we're willing to pay for this.</font></div></div>
</div></div></blockquote><div><br></div><div>You're right - it's not thread safe. However, it also doesn't suffer from the problem I'm trying to deal with, where you mutate an object in a way that leaves things broken, but won't be detected at that point. If it breaks because someone mutates the object underneath it, it'll throw an exception at that point. I know you can construct cases where that isn't so. Maybe we need two types of locking - one that allows readers, and one that doesn't. I could live with that, as you'd still have to consider the issue where you mutate the object.</div>
<div><br></div><div> <mike</div><div><br></div></div>