Thank you for the feedback Kyle. 
As I understand it (and if I'm remembering correctly), there are at
least three issues with ob-python sessions:
4. session and non-session code differs significantly as you have already mentioned 
So for non-session code and value results, the main idea is to get rid
of the need for "return" at the end?
Yes, that's the greatest offense to the Python code. 

This seems useful to me.  Requiring a trailing "return", which is a
syntax error when the code is taken by itself, is a quirk of the
implementation (the code ends up being wrapped in a function to get the
return value).  Also, it would allow switching from ":results value" to
":results output" without needing to remove "return" in order to avoid a
syntax error.
Yes, these would be the obvious benefits. 
But what about when :results != value?  Doesn't your proposal only
handle returning the last value?
You mean :results output ? In that case it could just omit the "open(...).write(...) " part and capture anything the console prints before the primary prompt appears again.
Or it could capture stdout into a file, but I think that's needlessly complicated:
python -i << HEREDOC_END
import sys
sys.stdout = open(<TMP FILE or PIPE>)   # replace stdout with some file
_ = block_eval("""
<CODE BLOCK BODY>
""")
sys.stdout.close()
sys.stdout = sys.__stdout__  # restore stdout
HEREDOC_END

After thinking about this, perhaps it is better to capture the block result into "_" instead of "ret", because
a) it prevents name clashes
b) it is more in line with what "_" is used for

Kind regards,
Ondřej Grover