Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #96274 > unrolled thread

Context-aware return

Started bySteven D'Aprano <steve@pearwood.info>
First post2015-09-11 03:54 +1000
Last post2015-09-12 03:11 +0100
Articles 20 on this page of 22 — 13 participants

Back to article view | Back to comp.lang.python


Contents

  Context-aware return Steven D'Aprano <steve@pearwood.info> - 2015-09-11 03:54 +1000
    Re: Context-aware return "Sven R. Kunze" <srkunze@mail.de> - 2015-09-10 20:03 +0200
    Re: Context-aware return Ben Finney <ben+python@benfinney.id.au> - 2015-09-11 04:12 +1000
    Re: Context-aware return Ben Finney <ben+python@benfinney.id.au> - 2015-09-11 04:14 +1000
    Re: Context-aware return "Sven R. Kunze" <srkunze@mail.de> - 2015-09-10 20:21 +0200
    Re: Context-aware return "Sven R. Kunze" <srkunze@mail.de> - 2015-09-10 20:24 +0200
    Re: Context-aware return "Sven R. Kunze" <srkunze@mail.de> - 2015-09-10 20:34 +0200
    Re: Context-aware return Chris Angelico <rosuav@gmail.com> - 2015-09-11 04:39 +1000
    Re: Context-aware return Laura Creighton <lac@openend.se> - 2015-09-10 20:40 +0200
    Re: Context-aware return "Sven R. Kunze" <srkunze@mail.de> - 2015-09-10 20:45 +0200
    Re: Context-aware return "Sven R. Kunze" <srkunze@mail.de> - 2015-09-10 20:56 +0200
    Re: Context-aware return Paul Rubin <no.email@nospam.invalid> - 2015-09-10 12:19 -0700
    Re: Context-aware return Grant Edwards <invalid@invalid.invalid> - 2015-09-10 19:23 +0000
      Re: Context-aware return Akira Li <4kir4.1i@gmail.com> - 2015-09-10 23:15 +0300
        Re: Context-aware return Grant Edwards <invalid@invalid.invalid> - 2015-09-10 20:27 +0000
      Re: Context-aware return random832@fastmail.us - 2015-09-10 16:42 -0400
      Re: Context-aware return Rustom Mody <rustompmody@gmail.com> - 2015-09-11 08:55 -0700
      Re: Context-aware return Rustom Mody <rustompmody@gmail.com> - 2015-09-11 08:55 -0700
    Re: Context-aware return Denis McMahon <denismfmcmahon@gmail.com> - 2015-09-11 00:41 +0000
      Re: Context-aware return Ned Batchelder <ned@nedbatchelder.com> - 2015-09-12 16:27 -0700
        Re: Context-aware return Steven D'Aprano <steve@pearwood.info> - 2015-09-17 12:31 +1000
    Re: Context-aware return Mark Lawrence <breamoreboy@yahoo.co.uk> - 2015-09-12 03:11 +0100

Page 1 of 2  [1] 2  Next page →


#96274 — Context-aware return

FromSteven D'Aprano <steve@pearwood.info>
Date2015-09-11 03:54 +1000
SubjectContext-aware return
Message-ID<55f1c3c6$0$1659$c3e8da3$5496439d@news.astraweb.com>
I have a function which is intended for use at the interactive interpreter,
but may sometimes be used non-interactively. I wish to change it's output
depending on the context of how it is being called.

If the function is being called as if it were a procedure or command, that
is the return result is just ignored, I want to return one thing. But if it
is being called where the return result goes somewhere, I want to return
something else. Most importantly, I don't want to pass a flag to the
function myself, I want the function to know its own context.

I don't mind if it is CPython only, or if it is a bit expensive.


E.g.

def func():
    do_stuff()
    if procedure:  # FIXME what goes here???
        return "Awesome"
    else:
        return 999

Now I can do this:


x = func()
assert x == 999

L = [1, 2, func(), 4]
assert L[2] == 999

func()
# interactive interpreter prints "Awesome"

Is such a thing possible, and if so, how would I do it?

If I did this thing, would people follow me down the street booing and
jeering and throwing things at me?




-- 
Steven

[toc] | [next] | [standalone]


#96275

From"Sven R. Kunze" <srkunze@mail.de>
Date2015-09-10 20:03 +0200
Message-ID<mailman.325.1441908195.8327.python-list@python.org>
In reply to#96274
http://stackoverflow.com/questions/2356399/tell-if-python-is-in-interactive-mode


On 10.09.2015 19:54, Steven D'Aprano wrote:
> I have a function which is intended for use at the interactive interpreter,
> but may sometimes be used non-interactively. I wish to change it's output
> depending on the context of how it is being called.
>
> If the function is being called as if it were a procedure or command, that
> is the return result is just ignored, I want to return one thing. But if it
> is being called where the return result goes somewhere, I want to return
> something else. Most importantly, I don't want to pass a flag to the
> function myself, I want the function to know its own context.
>
> I don't mind if it is CPython only, or if it is a bit expensive.
>
>
> E.g.
>
> def func():
>      do_stuff()
>      if procedure:  # FIXME what goes here???
>          return "Awesome"
>      else:
>          return 999
>
> Now I can do this:
>
>
> x = func()
> assert x == 999
>
> L = [1, 2, func(), 4]
> assert L[2] == 999
>
> func()
> # interactive interpreter prints "Awesome"
>
> Is such a thing possible, and if so, how would I do it?
>
> If I did this thing, would people follow me down the street booing and
> jeering and throwing things at me?

Probably. ;)

But it it solve a problem, why not.


Best,
Sven

[toc] | [prev] | [next] | [standalone]


#96276

FromBen Finney <ben+python@benfinney.id.au>
Date2015-09-11 04:12 +1000
Message-ID<mailman.326.1441908814.8327.python-list@python.org>
In reply to#96274
Steven D'Aprano <steve@pearwood.info> writes:

> I have a function which is intended for use at the interactive
> interpreter, but may sometimes be used non-interactively. I wish to
> change it's output depending on the context of how it is being called.
> […]
>
> x = func()
> assert x == 999
>
> L = [1, 2, func(), 4]
> assert L[2] == 999
>
> func()
> # interactive interpreter prints "Awesome"
>
> Is such a thing possible, and if so, how would I do it?

That makes my skin creep. In the name of all the tea I've sacrificed to
Python over the years, I pray this isn't possible.

> If I did this thing, would people follow me down the street booing and
> jeering and throwing things at me?

First thing in the morning I will purchase a head of cabbage and store
it in a warm place to make it rot, on the off chance you find some
obscure way to achieve your benighted goal, just so I can be first in
line to throw it as you pass.

If ever I have to worry that some arbitrary Python function, unbenownst
to me, might have a branch that will make it behave differently
depending on *whether I bind a reference to its return value*, then I'll
know you are sent to us as an evil spirit to make all software suck.

-- 
 \       “Nothing exists except atoms and empty space; everything else |
  `\                                          is opinion.” —Democritus |
_o__)                                                                  |
Ben Finney

[toc] | [prev] | [next] | [standalone]


#96278

FromBen Finney <ben+python@benfinney.id.au>
Date2015-09-11 04:14 +1000
Message-ID<mailman.327.1441909216.8327.python-list@python.org>
In reply to#96274
"Sven R. Kunze" <srkunze@mail.de> writes:

> http://stackoverflow.com/questions/2356399/tell-if-python-is-in-interactive-mode

I'm pretty sure Steven knows full well the answer to that question,
which is not anything like the one he asked. Would you care to read the
question he did ask?

-- 
 \       “The optimist thinks this is the best of all possible worlds. |
  `\           The pessimist fears it is true.” —J. Robert Oppenheimer |
_o__)                                                                  |
Ben Finney

[toc] | [prev] | [next] | [standalone]


#96279

From"Sven R. Kunze" <srkunze@mail.de>
Date2015-09-10 20:21 +0200
Message-ID<mailman.328.1441909301.8327.python-list@python.org>
In reply to#96274
I need to add: you need to look up the stack to see if you have been 
called by __main__ and if __main__.__file__ is missing.

Implementation: I would write decorator for your func.

Best,
Sven

PS: did I say it would probably be a bad idea? If not, it would probably 
be a bad idea.

PPS: what is the reason for this special behavior?

On 10.09.2015 20:03, Sven R. Kunze wrote:
> http://stackoverflow.com/questions/2356399/tell-if-python-is-in-interactive-mode 
>
>
>
> On 10.09.2015 19:54, Steven D'Aprano wrote:
>> I have a function which is intended for use at the interactive 
>> interpreter,
>> but may sometimes be used non-interactively. I wish to change it's 
>> output
>> depending on the context of how it is being called.
>>
>> If the function is being called as if it were a procedure or command, 
>> that
>> is the return result is just ignored, I want to return one thing. But 
>> if it
>> is being called where the return result goes somewhere, I want to return
>> something else. Most importantly, I don't want to pass a flag to the
>> function myself, I want the function to know its own context.
>>
>> I don't mind if it is CPython only, or if it is a bit expensive.
>>
>>
>> E.g.
>>
>> def func():
>>      do_stuff()
>>      if procedure:  # FIXME what goes here???
>>          return "Awesome"
>>      else:
>>          return 999
>>
>> Now I can do this:
>>
>>
>> x = func()
>> assert x == 999
>>
>> L = [1, 2, func(), 4]
>> assert L[2] == 999
>>
>> func()
>> # interactive interpreter prints "Awesome"
>>
>> Is such a thing possible, and if so, how would I do it?
>>
>> If I did this thing, would people follow me down the street booing and
>> jeering and throwing things at me?
>
> Probably. ;)
>
> But it it solve a problem, why not.
>
>
> Best,
> Sven

[toc] | [prev] | [next] | [standalone]


#96280

From"Sven R. Kunze" <srkunze@mail.de>
Date2015-09-10 20:24 +0200
Message-ID<mailman.329.1441909461.8327.python-list@python.org>
In reply to#96274
On 10.09.2015 20:12, Ben Finney wrote:
> First thing in the morning I will purchase a head of cabbage and store
> it in a warm place to make it rot, on the off chance you find some
> obscure way to achieve your benighted goal, just so I can be first in
> line to throw it as you pass.

Well, go ahead. And make photos!

[toc] | [prev] | [next] | [standalone]


#96282

From"Sven R. Kunze" <srkunze@mail.de>
Date2015-09-10 20:34 +0200
Message-ID<mailman.331.1441910056.8327.python-list@python.org>
In reply to#96274
On 10.09.2015 20:14, Ben Finney wrote:
> "Sven R. Kunze" <srkunze@mail.de> writes:
>
>> http://stackoverflow.com/questions/2356399/tell-if-python-is-in-interactive-mode
> I'm pretty sure Steven knows full well the answer to that question,
> which is not anything like the one he asked. Would you care to read the
> question he did ask?
You are right. I turned out to me harder that I first thought.

My initial guess was like: use AST. But now I see, it would be hard to 
get the source code.

So, what actually could work, would be faking the interactive 
interpreter wrapping it up and thus have control over the source code 
typed in.

Best,
Sven

[toc] | [prev] | [next] | [standalone]


#96285

FromChris Angelico <rosuav@gmail.com>
Date2015-09-11 04:39 +1000
Message-ID<mailman.333.1441910364.8327.python-list@python.org>
In reply to#96274
On Fri, Sep 11, 2015 at 3:54 AM, Steven D'Aprano <steve@pearwood.info> wrote:
> If the function is being called as if it were a procedure or command, that
> is the return result is just ignored, I want to return one thing. But if it
> is being called where the return result goes somewhere, I want to return
> something else. Most importantly, I don't want to pass a flag to the
> function myself, I want the function to know its own context.

The first thing that comes to mind is a repr hack. If you make your
function return an int-like object with a different repr, it could
look like it's returning "Awesome" interactively. The usefulness of
that depends on what the two forms are you're trying to return,
though.

Advantage: Doesn't get Ben's cabbage. I think.

Disadvantage: Looks weird if you try to debug stuff and get the repr
staring back at you.

ChrisA

[toc] | [prev] | [next] | [standalone]


#96286

FromLaura Creighton <lac@openend.se>
Date2015-09-10 20:40 +0200
Message-ID<mailman.334.1441910470.8327.python-list@python.org>
In reply to#96274
In a message of Fri, 11 Sep 2015 03:54:14 +1000, "Steven D'Aprano" writes:

>def func():
>    do_stuff()
>    if procedure:  # FIXME what goes here???
>        return "Awesome"
>    else:
>        return 999
>
>Now I can do this:
>
>
>x = func()
>assert x == 999
>
>L = [1, 2, func(), 4]
>assert L[2] == 999
>
>func()
># interactive interpreter prints "Awesome"
>
>Is such a thing possible, and if so, how would I do it?

Why, why, why do you want such a horrid thing?
I have an function that isn't always doing what I want.
I make a reference to it, so I can print it from time to time,
and do some other things to try to see why sometimes I am getting
an unwanted result.

I can no longer debug my problem.
You are seriously proposing this?

>If I did this thing, would people follow me down the street booing and
>jeering and throwing things at me?

I might start ahead of time, just for thinking of it ...

There has got to be a better way to get what you want -- or perhaps
for you to want something saner.

Laura

[toc] | [prev] | [next] | [standalone]


#96287

From"Sven R. Kunze" <srkunze@mail.de>
Date2015-09-10 20:45 +0200
Message-ID<mailman.335.1441910725.8327.python-list@python.org>
In reply to#96274
On 10.09.2015 20:34, Sven R. Kunze wrote:
> You are right. I turned out to me harder that I first thought.
>
> My initial guess was like: use AST. But now I see, it would be hard to 
> get the source code.
>
> So, what actually could work, would be faking the interactive 
> interpreter wrapping it up and thus have control over the source code 
> typed in.

Ha, got it:  sys.settrace

 >>> def traceit(frame, event, arg):
...     return traceit

 >>> sys.settrace(traceit)

 >>> a=1
(<frame object at 0x7ff9016785c0>, 'call', None)
(<frame object at 0x7ff9016785c0>, 'line', None)
(<frame object at 0x7ff9016785c0>, 'return', (u'a=1\n', 4))
(<frame object at 0x7ff90168a1f8>, 'call', None)
(<frame object at 0x7ff90168a1f8>, 'line', None)
(<frame object at 0x7ff90168a1f8>, 'return', None)


There you got the source. The use an AST to find out whether the line 
fits your definition of 'interactive'.

That should only be necessary when the top frame is interactive.


Best,
Sven

[toc] | [prev] | [next] | [standalone]


#96288

From"Sven R. Kunze" <srkunze@mail.de>
Date2015-09-10 20:56 +0200
Message-ID<mailman.336.1441911387.8327.python-list@python.org>
In reply to#96274
Oops, missing print:

On 10.09.2015 20:45, Sven R. Kunze wrote:
> On 10.09.2015 20:34, Sven R. Kunze wrote:
>> You are right. I turned out to me harder that I first thought.
>>
>> My initial guess was like: use AST. But now I see, it would be hard 
>> to get the source code.
>>
>> So, what actually could work, would be faking the interactive 
>> interpreter wrapping it up and thus have control over the source code 
>> typed in.
>
> Ha, got it:  sys.settrace
>
> >>> def traceit(frame, event, arg):
...    print(frame, event, arg)
> ... return traceit
>
> >>> sys.settrace(traceit)
>
> >>> a=1
> (<frame object at 0x7ff9016785c0>, 'call', None)
> (<frame object at 0x7ff9016785c0>, 'line', None)
> (<frame object at 0x7ff9016785c0>, 'return', (u'a=1\n', 4))
> (<frame object at 0x7ff90168a1f8>, 'call', None)
> (<frame object at 0x7ff90168a1f8>, 'line', None)
> (<frame object at 0x7ff90168a1f8>, 'return', None)
>
>
> There you got the source. The use an AST to find out whether the line 
> fits your definition of 'interactive'.
>
> That should only be necessary when the top frame is interactive.
>
>
> Best,
> Sven

[toc] | [prev] | [next] | [standalone]


#96293

FromPaul Rubin <no.email@nospam.invalid>
Date2015-09-10 12:19 -0700
Message-ID<87twr2rsio.fsf@jester.gateway.pace.com>
In reply to#96274
Steven D'Aprano <steve@pearwood.info> writes:
> I want the function to know its own context.
> I don't mind if it is CPython only, or if it is a bit expensive.

That sounds crazy but if it's really what you want, you can probably
fake it by examining the control stack using the backtrace module.  I
remember doing some hack of raising and catching an exception in order
to retrieve the backtrace, but there might be a cleaner way that I
didn't bother researching since it was just for a quick debugging
problem.

[toc] | [prev] | [next] | [standalone]


#96294

FromGrant Edwards <invalid@invalid.invalid>
Date2015-09-10 19:23 +0000
Message-ID<msslas$pf8$1@reader1.panix.com>
In reply to#96274
On 2015-09-10, Steven D'Aprano <steve@pearwood.info> wrote:

> I have a function which is intended for use at the interactive interpreter,
> but may sometimes be used non-interactively. I wish to change it's output
> depending on the context of how it is being called.

[...]

Sounds like an excellent way to waste somebody's afternoon when they
start to troubleshoot code that's using your function.  Over and over
and over we tell newbies who have questions about what something
returns or how it works

    "Start up an interactive session, and try it!".

If word gets out about functions like yours, we sort of end up looking
like twits.  

> If I did this thing, would people follow me down the street booing
> and jeering and throwing things at me?

Only the people who use your function. :)

-- 
Grant Edwards               grant.b.edwards        Yow! FROZEN ENTREES may
                                  at               be flung by members of
                              gmail.com            opposing SWANSON SECTS ...

[toc] | [prev] | [next] | [standalone]


#96300

FromAkira Li <4kir4.1i@gmail.com>
Date2015-09-10 23:15 +0300
Message-ID<mailman.339.1441916238.8327.python-list@python.org>
In reply to#96294
Grant Edwards <invalid@invalid.invalid> writes:

> On 2015-09-10, Steven D'Aprano <steve@pearwood.info> wrote:
>
>> I have a function which is intended for use at the interactive interpreter,
>> but may sometimes be used non-interactively. I wish to change it's output
>> depending on the context of how it is being called.
>
> [...]
>
> Sounds like an excellent way to waste somebody's afternoon when they
> start to troubleshoot code that's using your function.  Over and over
> and over we tell newbies who have questions about what something
> returns or how it works
>
>     "Start up an interactive session, and try it!".
>
> If word gets out about functions like yours, we sort of end up looking
> like twits.  
>
>> If I did this thing, would people follow me down the street booing
>> and jeering and throwing things at me?
>
> Only the people who use your function. :)

There are cases when it might be justified to alter the behavior e.g.,
*colorama* allows to strip ANSI codes (e.g., disable colored output) if
stdout is not a tty or *win-unicode-console* make sys.stdout to use
WriteConsoleW() to write Unicode to Windows console (interactive case).

[toc] | [prev] | [next] | [standalone]


#96301

FromGrant Edwards <invalid@invalid.invalid>
Date2015-09-10 20:27 +0000
Message-ID<mssp2u$7m7$1@reader1.panix.com>
In reply to#96300
On 2015-09-10, Akira Li <4kir4.1i@gmail.com> wrote:
> Grant Edwards <invalid@invalid.invalid> writes:
>
>> On 2015-09-10, Steven D'Aprano <steve@pearwood.info> wrote:
>>
>>> I have a function which is intended for use at the interactive interpreter,
>>> but may sometimes be used non-interactively. I wish to change it's output
>>> depending on the context of how it is being called.
>>
>> [...]
>>
>> Sounds like an excellent way to waste somebody's afternoon when they
>> start to troubleshoot code that's using your function.  Over and over
>> and over we tell newbies who have questions about what something
>> returns or how it works
>>
>>     "Start up an interactive session, and try it!".
>>
>> If word gets out about functions like yours, we sort of end up looking
>> like twits.  
>>
>>> If I did this thing, would people follow me down the street booing
>>> and jeering and throwing things at me?
>>
>> Only the people who use your function. :)
>
> There are cases when it might be justified to alter the behavior e.g.,
> *colorama* allows to strip ANSI codes (e.g., disable colored output) if
> stdout is not a tty or *win-unicode-console* make sys.stdout to use
> WriteConsoleW() to write Unicode to Windows console (interactive case).

I hate that sort of behavior also, but there's a long historical
precident on Unix of command line utilities changing output format
based on the results of isatty(STDIN_FILENO).  IMO, that was
definitely a mistake, and to this day regularly wastes my time when
troubleshooting bash programs. But, it's been that way for 45 years,
and it's not going to get fixed now.  That sort of auto-magical
"trying to guess what the user wants" instead of doing what the user
says is what makes PHP smell so bad.  

A bad idea copied by thousand of people over several decades is still
a bad idea.

Let's not duplicate that mistake in Python.
   
But, just to clarify, we're talking about the function's return value,
not what it writes to stdout, right?

-- 
Grant Edwards               grant.b.edwards        Yow! I would like to
                                  at               urinate in an OVULAR,
                              gmail.com            porcelain pool --

[toc] | [prev] | [next] | [standalone]


#96303

Fromrandom832@fastmail.us
Date2015-09-10 16:42 -0400
Message-ID<mailman.341.1441917750.8327.python-list@python.org>
In reply to#96294
On Thu, Sep 10, 2015, at 16:15, Akira Li wrote:
> There are cases when it might be justified to alter the behavior e.g.,
> *colorama* allows to strip ANSI codes (e.g., disable colored output) if
> stdout is not a tty or *win-unicode-console* make sys.stdout to use
> WriteConsoleW() to write Unicode to Windows console (interactive case).

These conditions have nothing to do with whether it is running in the
interactive interpreter, since you can still be on the console (or a
tty) without being in the interactive interpreter. What you are talking
about is detecting file redirection.

[toc] | [prev] | [next] | [standalone]


#96350

FromRustom Mody <rustompmody@gmail.com>
Date2015-09-11 08:55 -0700
Message-ID<bb3cfdcc-992f-457f-85ee-11e7e2853271@googlegroups.com>
In reply to#96294
On Friday, September 11, 2015 at 12:53:28 AM UTC+5:30, Grant Edwards wrote:
> On 2015-09-10, Steven D'Aprano  wrote:
> 
> > I have a function which is intended for use at the interactive interpreter,
> > but may sometimes be used non-interactively. I wish to change it's output
> > depending on the context of how it is being called.
> 
> [...]
> 
> Sounds like an excellent way to waste somebody's afternoon when they
> start to troubleshoot code that's using your function.  Over and over
> and over we tell newbies who have questions about what something
> returns or how it works
> 
>     "Start up an interactive session, and try it!".
> 
> If word gets out about functions like yours, we sort of end up looking
> like twits.  
> 
> > If I did this thing, would people follow me down the street booing
> > and jeering and throwing things at me?
> 
> Only the people who use your function. :)


In emacs:
You can make a function a 'command' by putting an (interactive) into it.
And then in the function if you check interactive-p (nowadays more fashionably
'called-interactively-p' ) then it can figure out whether it was called from 
elisp or from emacs (top level)... and then change behavior accordingly.

IOW this behavior is quite routine in emacs-land
The norm being 
- Some functions are meant to be called only from Lisp
- Some functions (commands) only from emacs
- And then there are the 'Steven-functions'

I find it curious that the people getting upset about this are all the
emacs users [as far as I know] ;-)

[toc] | [prev] | [next] | [standalone]


#96351

FromRustom Mody <rustompmody@gmail.com>
Date2015-09-11 08:55 -0700
Message-ID<79f7cf3b-b656-4a3b-9dba-d86e2b797700@googlegroups.com>
In reply to#96294
On Friday, September 11, 2015 at 12:53:28 AM UTC+5:30, Grant Edwards wrote:
> On 2015-09-10, Steven D'Aprano  wrote:
> 
> > I have a function which is intended for use at the interactive interpreter,
> > but may sometimes be used non-interactively. I wish to change it's output
> > depending on the context of how it is being called.
> 
> [...]
> 
> Sounds like an excellent way to waste somebody's afternoon when they
> start to troubleshoot code that's using your function.  Over and over
> and over we tell newbies who have questions about what something
> returns or how it works
> 
>     "Start up an interactive session, and try it!".
> 
> If word gets out about functions like yours, we sort of end up looking
> like twits.  
> 
> > If I did this thing, would people follow me down the street booing
> > and jeering and throwing things at me?
> 
> Only the people who use your function. :)


In emacs:
You can make a function a 'command' by putting an (interactive) into it.
And then in the function if you check interactive-p (nowadays more fashionably
'called-interactively-p' ) then it can figure out whether it was called from 
elisp or from emacs (top level)... and then change behavior accordingly.

IOW this behavior is quite routine in emacs-land
The norm being 
- Some functions are meant to be called only from Lisp
- Some functions (commands) only from emacs
- And then there are the 'Steven-functions'

I find it curious that the people getting upset about this are all the
emacs users [as far as I know] ;-)

[toc] | [prev] | [next] | [standalone]


#96310

FromDenis McMahon <denismfmcmahon@gmail.com>
Date2015-09-11 00:41 +0000
Message-ID<mst80l$1lv$1@dont-email.me>
In reply to#96274
On Fri, 11 Sep 2015 03:54:14 +1000, Steven D'Aprano wrote:

> If I did this thing, would people follow me down the street booing and
> jeering and throwing things at me?

Yes

>>> x = func()
>>> x
>>> func()
>>> print x == func() 
>>> assert x == func()

Would you expect the last two calls to func() to return 999 or "Awesome"? 
Why? What is the material difference if any between interpreter (a) 
displaying the return value and (b) comparing the return value with 
another value.

Debugging nightmare!

-- 
Denis McMahon, denismfmcmahon@gmail.com

[toc] | [prev] | [next] | [standalone]


#96468

FromNed Batchelder <ned@nedbatchelder.com>
Date2015-09-12 16:27 -0700
Message-ID<c52d15cd-c043-47d3-859c-fdeea87f08a5@googlegroups.com>
In reply to#96310
On Thursday, September 10, 2015 at 8:44:01 PM UTC-4, Denis McMahon wrote:
> On Fri, 11 Sep 2015 03:54:14 +1000, Steven D'Aprano wrote:
> 
> > If I did this thing, would people follow me down the street booing and
> > jeering and throwing things at me?
> 
> Yes
> 
> >>> x = func()
> >>> x
> >>> func()
> >>> print x == func() 
> >>> assert x == func()
> 
> Would you expect the last two calls to func() to return 999 or "Awesome"? 
> Why? What is the material difference if any between interpreter (a) 
> displaying the return value and (b) comparing the return value with 
> another value.
> 
> Debugging nightmare!

I'll add my voice to the rising chorus condemning the very notion
of a function that behaves this way!

Then, I'll give you an implementation (Python 2):

    import inspect
    import opcode


    def magic_return():
        frame = inspect.stack()[1][0]
        code = frame.f_code
        next_opcode = opcode.opname[ord(code.co_code[frame.f_lasti+3])]
        if next_opcode == "PRINT_EXPR":
            ret = "Used at the prompt"
        elif next_opcode == "POP_TOP":
            ret = "Value ignored"
        else:
            ret = "Normal call"
        print ret
        return ret

    def try_it():
        magic_return()
        x = magic_return()
        print magic_return()
        magic_return() + ""

This examines the byte code of the caller to determine the next
byte code after the CALL_FUNCTION that called us.  The byte code
used next shows what will happen to the return value.

Try it out:

    $ python -i detect_caller.py
    >>> magic_return()
    Used at the prompt
    'Used at the prompt'
    >>> try_it()
    Value ignored
    Normal call
    Normal call
    Normal call
    Normal call
    >>>

I'm sure there are plenty of cases this gets wrong.  If you try
to pin this on me, I will swear up and down that someone hacked
into my account to send this message...

--Ned.

[toc] | [prev] | [next] | [standalone]


Page 1 of 2  [1] 2  Next page →

Back to top | Article view | comp.lang.python


csiph-web