Fix executing certain spied methods under Python 3.6.
Review Request #9710 — Created Feb. 28, 2018 and submitted
Python 3.6 made some changes to how methods are executed and how unbound
methods are converted into bound methods. This led to some breakages
when spying on methods containing list comprehensions (and likely other
generators) and when spying on unbound methods. In the former, directly
accessing arguments passed to the function didn't work (but using
locals()was fine), and in the latter the unbound function stayed
unbound on instances (due to attempting to clone and re-set unbound
methods). In some cases, though,
locals()didn't at all work.
Now, on Python 3.x, we check both places. If the parameter is in
locals(), we'll use that. Otherwise, we fall back on the actual
argument. This seems to catch all instances that we've hit.
We also no longer try to clone unbound methods at all, fixing
compatibility on all versions.
Unit tests pass on Python 2.7 and 3.4 through 3.6.
Fixed some edge cases hit in different Python 3.x versions.
Revision 2 (+110 -5)