# This file is for detecting whether the current interpreter has enabled computed gotos.
# See https://stackoverflow.com/q/61860463/2142577 for details.

import sys


def global_tracer(frame, event_type, arg):
    assert event_type == "call"
    last_i = frame.f_back.f_lasti  # Win: 38, Linux and Mac: 40
    assert last_i in {40, 38}
    # If program prints 40, computed_gotos is enabled. If prints 38, it's disabled.
    print(last_i == 40, end="")


sys.settrace(global_tracer)

x = [1 for i in range(3)]

# Part of the bytecode generated by this list comprehension is:
#              32 LOAD_NAME                3 (range)
#              34 LOAD_CONST               6 (3)
#              36 CALL_FUNCTION            1
#              38 GET_ITER
#              40 CALL_FUNCTION            1
#              42 STORE_NAME               4 (x)
#
# There's a PREDICT(CALL_FUNCTION) in GET_ITER's handler, see
# https://github.com/python/cpython/blob/v3.8.3/Python/ceval.c#L3165
# If computed goto is not enabled, last_i is not updated after CALL_FUNCTION is
# executed, so in the frame.f_back.f_lasti is still 38.
# If computed goto is enabled, last_i will be the correct value, which is 40.
