Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #56644 > unrolled thread
| Started by | Cameron Simpson <cs@zip.com.au> |
|---|---|
| First post | 2013-10-11 15:36 +1100 |
| Last post | 2013-10-11 17:40 +1100 |
| Articles | 3 — 2 participants |
Back to article view | Back to comp.lang.python
This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by
below is the oldest one visible, not the original post.
Re: Skipping decorators in unit tests Cameron Simpson <cs@zip.com.au> - 2013-10-11 15:36 +1100
Re: Skipping decorators in unit tests Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-10-11 05:51 +0000
Re: Skipping decorators in unit tests Cameron Simpson <cs@zip.com.au> - 2013-10-11 17:40 +1100
| From | Cameron Simpson <cs@zip.com.au> |
|---|---|
| Date | 2013-10-11 15:36 +1100 |
| Subject | Re: Skipping decorators in unit tests |
| Message-ID | <mailman.983.1381466200.18130.python-list@python.org> |
On 11Oct2013 14:42, Ben Finney <ben+python@benfinney.id.au> wrote: > Cameron Simpson <cs@zip.com.au> writes: > > On 11Oct2013 02:55, Steven D'Aprano <steve+comp.lang.python@pearwood.info> wrote: > > > def undecorate(f): > > > """Return the undecorated inner function from function f.""" > > > return f.func_closure[0].cell_contents > > > > Whereas this feels like black magic. Is this portable to any decorated > > function? If so, I'd have hoped it was in the stdlib. If not: black > > magic. > > What would you expect? The purpose of decorating functions is to do > magic to make it appear as though the original function isn't there any > more. Any technique to getting at that original function anyway is *of > course* going to look like black magic at the implementation level. Sigh. Yes of course. It is no uglier than walking a frame stack etc. But is it reliable? Will it work on any decorated function? If so, fine, and I'd be happy to squirrel it away as a useful standard incantation for something. If not, then it's nasty only-mostly-reliable magic and I either want little to do with it, OR I want to know its specific limitations so I know when to use it and when not. -- Cameron Simpson <cs@zip.com.au> But pessimism IS realism! - D.L.Bahr
[toc] | [next] | [standalone]
| From | Steven D'Aprano <steve+comp.lang.python@pearwood.info> |
|---|---|
| Date | 2013-10-11 05:51 +0000 |
| Message-ID | <525791e2$0$29984$c3e8da3$5496439d@news.astraweb.com> |
| In reply to | #56644 |
On Fri, 11 Oct 2013 15:36:29 +1100, Cameron Simpson wrote:
> But is it reliable? Will it work on any decorated function?
*Any* decorated function? No, of course not, since decorators can do
anything they like:
def decorate(func):
return lambda *args: "Surprise!"
@decorate
def something_useful(x, y):
return x+y
They don't even have to return a function. Or the function being
decorated can end up in a different cell:
def factory(x, y):
def decorator(func):
def inner(*args):
_ = (x, y) # pretend x and y are useful
return func(*args)
return inner
return decorator
@factory(lambda: None, 42)
def func(a):
return a
py> func.func_closure[0].cell_contents
42
py> func.func_closure[1].cell_contents
<function <lambda> at 0xb7c4609c>
py> func.func_closure[2].cell_contents
<function func at 0xb7c4617c>
So consider this a *cooperative* undecorator. It can only undecorate
things that are decorated the way you expect them to be decorated.
--
Steven
[toc] | [prev] | [next] | [standalone]
| From | Cameron Simpson <cs@zip.com.au> |
|---|---|
| Date | 2013-10-11 17:40 +1100 |
| Message-ID | <mailman.987.1381473621.18130.python-list@python.org> |
| In reply to | #56645 |
On 11Oct2013 05:51, Steven D'Aprano <steve+comp.lang.python@pearwood.info> wrote: > On Fri, 11 Oct 2013 15:36:29 +1100, Cameron Simpson wrote: > > But is it reliable? Will it work on any decorated function? > > *Any* decorated function? No, of course not, since decorators can do > anything they like: [... examples ...] That was what I thought; I was pretty sure I could quite reasonably write all sorts of decorators this wouldn't work with. > So consider this a *cooperative* undecorator. It can only undecorate > things that are decorated the way you expect them to be decorated. Fine. And that is why I wrote my example as I did; I'd rather expose the inner function by name if it is to be tested rather than write a somewhat opaque special function that relies on all my decorators following the same internal scheme. I'd only have to forget in the frenzy of writing some special decorator to have my tests break (or, worse, test the wrong thing). So, for me, _if_ I intend to test the inner function alone, it is worth the trade off of an extra name to avoid any need for special knowledge of the inner workings of the decorators. Cheers, -- Cameron Simpson <cs@zip.com.au> A childproof cap is a Gordian knot to any adult who drinks. ______ wrote that he had seen the best minds of his generation destroyed by madness. I have seen the best minds of mine go at a bottle of aspirin with a ball-peen hammer. - P.J. O'Rourke
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.python
csiph-web