-1

This is a condensed version of the code I'm dealing with:

def main():
    foo()
    print("Only this line will get printed")

def foo():
    bar()
    print("This line is never reached")

main()

The output of this program is "Only this line will get printed", and I cannot figure out why. Effectively, it's acting as if there's a return statement at or right after the line where bar() gets called.

My only guess was that bar() raises an exception, but I surrounded it with a blank try/catch block and it's not catching anything.

Any idea what could be happening here?

P.S. this is running inside a Jupyter notebook.

Goh
  • 167
  • 5
  • 3
    "NameError: bar is not defined" – Sayse Feb 25 '20 at 16:42
  • 3
    Highly dependent on what `bar()` looks like. We can;t reproduce from this sample code. (See: [mcve]) – G. Anderson Feb 25 '20 at 16:43
  • 2
    It sounds like the code is calling `sys.exit()`. – John Gordon Feb 25 '20 at 16:43
  • It could be an endless loop, a request that doesn't resolve or any type of code that never resolves – Alexandre Senges Feb 25 '20 at 16:43
  • 2
    Please add the code contained within the `bar` function. If there is no `bar` function then that's the problem.... – KJTHoward Feb 25 '20 at 16:45
  • What do you mean by "blank `try`/`catch`"? – chepner Feb 25 '20 at 16:49
  • @JohnGordon it can't be `sys.exit()` inside `bar()` since then "Only this line will get printed" would not. – Goh Feb 25 '20 at 16:57
  • @G.Anderson `bar()` is a gateway to an entire call tree containing massive amounts of code. It would take me days just to read all of it. The reason I'm posting this question is because I can't see a reason why _anything_ that could possibly happen inside `bar()` would cause this problem. Generally, either `bar()` terminates the program somehow (in which nothing will get printed) or it raises an exception (in which case again nothing will get printed) or it blocks forever (same result). Either way, nothing gets printed. – Goh Feb 25 '20 at 17:01
  • 1
    My guess is that `foo()` is being overwritten by another definition somewhere later in the code, that doesn't have the `print`. The way to find out what's actually going on here is to run the code in a debugger. – jasonharper Feb 25 '20 at 17:27
  • Are you asking *"how could code possibly have this behaviour?"* or are you asking *"what is the most likely explanation?"* - the former is maybe a little bit too broad (I'm not sure), the latter is probably subjective. – kaya3 Feb 25 '20 at 17:45

1 Answers1

3

There are several ways I can think of that a program might have this behaviour, but all of them seem really unlikely. It is hard to imagine that this could happen unless someone did it intentionally as a prank, or as the solution to an abstract puzzle/challenge, like "can you make a program do this?".

There is certainly no sensible way that calling bar could cause foo to return immediately. If bar raises an exception, foo would stop before printing, but so would main since it has no try/except block. There are some things you can do with sys.excepthook to set a global exception handler, which could explain why bar is able to stop foo without you seeing a stack trace, but the exception handler would not cause main to continue where foo left off.

Well, here is my solution to the puzzle, which I hope is not what your program is actually doing:

def bar():
    # we will change which function `print` refers to
    global print

    # keep a reference to the built-in `print` function
    old_print = print

    # define a function which ignores its argument, then restores the old `print` function
    def ignore_one_print(s):
        global print
        print = old_print

    # change `print` to be the function we just defined
    print = ignore_one_print

When combined with your code, it outputs:

Only this line will get printed
kaya3
  • 47,440
  • 4
  • 68
  • 97