BreakError (sfi.BreakError) StataNow

class sfi.BreakError

This class is used to handle interrupting Python execution using the Break key in Stata. It is part of StataNow.

When executing Python code, especially some time-consuming task, it may be necessary to interrupt that task and return control to Stata. This is similar to when you want to stop any command in Stata, whether you are running Stata code or Python code.

To interrupt Python execution and return control to Stata, we can use the Break key when calling either SFIToolkit.pollnow() or SFIToolkit.pollstd(). When the Break key has been pressed, a BreakError exception will be thrown when executing pollnow() or pollstd(). If the Break key has not been pressed then pollnow() and pollstd() simply tell the Stata interface to remain responsive to user input from the keyboard and mouse. When a BreakError exception is encountered, the Python code stops execution and a return code of 1 is sent back to Stata; control is also returned to Stata at this time. If you need to handle a BreakError exception in a specific way, you can put your code within a try/except block. For example, you may want to handle some clean-up task before returning control to Stata.

Examples

Suppose you have a do-file called test.do with the following content:

python:
import time

while True:
    print('In a loop')
    time.sleep(1)

end

sysuse auto, clear
summarize mpg price

The Python code prints in an endless loop every second. Running this do-file directly in Stata will make Stata unresponsive and the endless loop will never exit. Since the Python code never exits, control is never returned to Stata.

To terminate the execution of the Python code using the Break key, we added two lines of Python code as follows:

python:
import time
from sfi import SFIToolkit

while True:
    print('In a loop')
    time.sleep(1)

    SFIToolkit.pollnow()

end

sysuse auto, clear
summarize mpg price

We first import the SFIToolkit class from the Stata Function Interface (sfi) module and then call the pollnow() method within the while loop. We used pollnow() to request that Stata polls its GUI immediately and looks for the Break key. Generally, pollstd() is preferred and more efficient, but because we call sleep(1) in this loop, pollnow() is a better choice. Here is the sample output from pressing the Break key while running the code above:

. do test
. python:
----------------------------------------------- python (type end to exit) ------
>>> import time
>>> from sfi import SFIToolkit
>>>
>>> while True:
...     print('In a loop')
...     time.sleep(1)
...
...     SFIToolkit.pollnow()
...
In a loop
In a loop
In a loop
Traceback (most recent call last):
  File "<stdin>", line 4, in <module>
  File "C:\Program Files\Stata18\ado\base\py\sfi.py", line 5350, in pollnow
    return _stp._st_pollnow()
           ^^^^^^^^^^^^^^^^^^
sfi.BreakError: --Break--
(3 lines skipped)
--------------------------------------------------------------------------------
--Break--
r(1);

end of do-file

--Break--
r(1);

The Python code was terminated successfully and a return code of 1 was issued by Stata, which caused the do-file to exit without executing the Stata code.

Next, we put the Python code within a try/except block and also catch the BreakError exception as follows:

python:
import time
from sfi import SFIToolkit, BreakError

try:
    while True:
        print('In a loop')
        time.sleep(1)

        SFIToolkit.pollnow()
except BreakError:
    print('Break key was pressed')

end

sysuse auto, clear
summarize mpg price

Running the do-file again in Stata and then pressing the Break key, you will get output similar to that shown below:

. do test
. python:
----------------------------------------------- python (type end to exit) ------
>>> import time
>>> from sfi import SFIToolkit, BreakError
>>>
>>> try:
...     while True:
...         print('In a loop')
...         time.sleep(1)
...
...         SFIToolkit.pollnow()
... except BreakError:
...     print('Break key was pressed')
...
In a loop
In a loop
In a loop
In a loop
Break key was pressed
>>> end
--------------------------------------------------------------------------------

.
. sysuse auto, clear
(1978 automobile data)

. summarize mpg price

    Variable |        Obs        Mean    Std. dev.       Min        Max
-------------+---------------------------------------------------------
         mpg |         74     21.2973    5.785503         12         41
       price |         74    6165.257    2949.496       3291      15906

.
end of do-file

.

From the above output, we can see that the Python code terminated and the BreakError exception was caught and handled successfully. Thus, no error was returned by Stata and the Stata code was executed too.