[pytest-dev] monkeypatch.setattr of functions and from imports
holger krekel
holger at merlinux.eu
Tue Oct 29 06:39:02 CET 2013
On Mon, Oct 28, 2013 at 21:44 +0000, Floris Bruynooghe wrote:
> On 23 October 2013 19:36, holger krekel <holger at merlinux.eu> wrote:
> > As to patching func_code: good idea, i had forgotten about assigning func_code.
> > In earlier Python2.X versions assigning to func_code didn't work but i just
> > checked that it does on py27 and py33. So it's definitely worthwhile to
> > pursue. In your example you could do:
> >
> > monkeypatch.setattr('a.somefunc.func_code', (lambda: 'eh?').func_code)
> >
> > and it works (needs to use __code__ on py3). I guess we could think about a
> >
> > monkeypatch.setcode("a.somefunc", lambda: 'eh?')
> >
> > helper. You could either pass in a function or a code object.
> > We could even think about allowing non-string targets:
> >
> > monkeypatch.setcode(a.somefunc, lambda: 'eh?')
> >
> > Or would "monkeypatch.setfunc" be a better name?
>
> Why does it have to be a new method? Can't setattr simply see if the
> object being patched as well as the object it is being patched with
> has a .func_code or .__code__ attribute and automatically patch the
> code if so? This would be additional to the current patching it does
> so that it's more obvious in a debugger for the current cases. It
> would have solved the OPs problem and I can't think of any real
> downside currently.
Wouldn't it violate what you expect from a "setattr" operation?
Anyway, i played with setting __code__ the other day and there is
a bad limitation::
def test_hello(monkeypatch):
x = "/tmp"
def myabs(somepath):
return x
> monkeypatch.setattr("os.path.abspath.__code__", myabs.__code__)
E ValueError: abspath() requires a code object with 0 free vars, not 1
This means that setting __code__ with closure-using code does not work.
This reduces the usefullness of setting code objects for practical
purposes and speaks against introducing any support at this point.
Setting non-closures might still be useful and the example above is
other compatible to py26++ so it's probably good enough.
best,
holger
More information about the Pytest-dev
mailing list