Show off your Python chops and compete with others

  • Thread starter Nathaniel Sokoll-Ward
  • Start date
R

Roy Smith

alex23 <[email protected]> said:
Well, if you want to be truly pedantic about it (*), this defines a
function without an explicit return and which does not return None:

def foo():
raise Exception


In [2]: import dis
In [3]: dis.dis(foo)
2 0 LOAD_GLOBAL 0 (Exception)
3 RAISE_VARARGS 1
6 LOAD_CONST 0 (None)
9 RETURN_VALUE

Seeing as we're being pedantic, the function *does* return None, it's
just that the return value is never seen because an exception is raise.

Dead code doesn't count.
 
R

Roy Smith

alex23 <[email protected]> said:
Neither do shifting goalposts.

It's not a shifting goalpost. My original statement was that:

def foo():
raise Exception

defines a function which 1) has no explicit return statement and 2) does
not return None. I stand by that statement. There is no possible
codepath, no possible calling sequence, no possible execution
environment, which will cause that function to return None. That fact
that one particular Python implementation happens to produce unreachable
bytecode for returning None is meaningless. Would you say that:

def baz():
return None
print "I got here"

is a function which prints "I got here"?
 
C

Chris Angelico

It's not a shifting goalpost. My original statement was that:

def foo():
raise Exception

defines a function which 1) has no explicit return statement and 2) does
not return None. I stand by that statement. There is no possible
codepath, no possible calling sequence, no possible execution
environment, which will cause that function to return None. That fact
that one particular Python implementation happens to produce unreachable
bytecode for returning None is meaningless. Would you say that:

def baz():
return None
print "I got here"

is a function which prints "I got here"?

Granted, but I would describe this:

def foo(x):
return "Hello, world!\n" + str(x)

as a function which returns a string. Is it? Well, not if str raises
an exception. Even if the only arguments you can give to foo will
result in exceptions, I would still say that, per design, this is a
function that returns a string. The possibility of raising an
exception (and thus not returning anything) doesn't change a
function's return type (by which I mean more than just what C would
use as the declaration - I could just as well say "Returns the name of
an employee", and the same argument would apply).

ChrisA
 
T

Tim Chase

It's not a shifting goalpost. My original statement was that:

def foo():
raise Exception

defines a function which 1) has no explicit return statement and 2)
does not return None. I stand by that statement. There is no
possible codepath, no possible calling sequence, no possible
execution environment, which will cause that function to return
None.

Well, for varying definitions of "that function", you can do
.... def wrapper(*args, **kwargs):
.... try:
.... fn(*args, **kwargs)
.... except:
.... return None
.... return wrapper
........ def foo():
.... raise Exception
....None

;-)

Beyond that, I'm sure one could resort to bytecode hacking to have
"that function" skip the raise...

-tkc
 
S

Steven D'Aprano

It's not a shifting goalpost. My original statement was that:

def foo():
raise Exception

defines a function which 1) has no explicit return statement and 2)
does not return None. I stand by that statement. There is no possible
codepath, no possible calling sequence, no possible execution
environment, which will cause that function to return None.

Well, for varying definitions of "that function", you can do [snip modified functions]
Beyond that, I'm sure one could resort to bytecode hacking to have "that
function" skip the raise...

Now who's shifting the goalposts? Whether you edit the function's source
code, wrap it in a decorator, or hack it's byte-code, it's not the same
function as the one Roy showed above by any reasonable definition of "the
same". As an intellectual exercise of how one might subvert the standard
semantics of the Python compiler, it is interesting to consider (say)
byte-code hacks that turn this source code:

def foo():
raise Exception

into something that returns None, but by the same logic one might say
that this function:

def spam():
return 42

connects to some database over the Internet and deletes any table
containing more than seven records. If we're going to allow those sorts
of debating shenanigans, the obvious counter is "yes, but when I said
that the function doesn't return None, I actually meant that it doesn't
solve the Halting Problem, and it still doesn't do that, so I win nyah
nyah nyah".
 
G

Gregory Ewing

alex23 said:
In [2]: import dis
In [3]: dis.dis(foo)
2 0 LOAD_GLOBAL 0 (Exception)
3 RAISE_VARARGS 1
6 LOAD_CONST 0 (None)
9 RETURN_VALUE

Seeing as we're being pedantic, the function *does* return None, it's
just that the return value is never seen because an exception is raise.

Koan for the day:

If a man goes into the forest and never returns,
does he bring back nothing?
 
M

Mark Lawrence

It's not a shifting goalpost. My original statement was that:

def foo():
raise Exception

defines a function which 1) has no explicit return statement and 2) does
not return None. I stand by that statement. There is no possible
codepath, no possible calling sequence, no possible execution
environment, which will cause that function to return None. That fact
that one particular Python implementation happens to produce unreachable
bytecode for returning None is meaningless. Would you say that:

def baz():
return None
print "I got here"

is a function which prints "I got here"?

Game, set and match to Roy Smith? :)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,090
Messages
2,570,603
Members
47,223
Latest member
smithjens316

Latest Threads

Top