Special Notes for macOS Users#
Although much progress has been made getting py5 to work on macOS, there are a few remaining issues and limitations. The issues that are fixable will be addressed in future py5 releases. The remaining issues are minor and in line with typical macOS experiences.
TL;DR
When using Jupyter Notebooks, start each notebook with the
%gui osx
magicThe run_sketch() method’s
block
parameter is by necessity set toFalse
when run through Jupyter Notebooks and set toTrue
when run through a generic Python interpreterThe py5bot Jupyter kernel and some py5 magics cannot use the OpenGL renderers
The render helper tools cannot use the OpenGL renderers
When using Jupyter notebooks, the select methods select_folder(), select_input(), and select_output() will not work.
Ignore the warnings you see when exiting a Sketch (Issue #6)
None of these will stop you from using py5 productively on macOS.
Jupyter Notebooks#
Everything will work just fine after executing the following IPython magic at the start of each notebook:
%gui osx
This changes how Jupyter executes later notebook cells to allow GUI windows to open and be usable. Do this before importing py5. If you import py5 without doing this, py5 will run the magic for you after giving you a polite warning.
That magic command should not be run on non-macOS machines. If you need your notebook code to run on multiple platforms, use the following code instead:
import sys
if sys.platform == 'darwin':
get_ipython().run_line_magic('gui', 'osx')
The %gui osx
magic will enable macOS Cocoa event loop integration. Use of this
magic is not unique to py5; it is also used for other Python applications that
open interactive windows. It instructs Jupyter’s Python kernel to share the main
thread with the window. On macOS, all GUIs are required to run on the main thread.
The Python kernel, however, also needs to use the main thread to execute cells.
Therefore, the main thread must be shared.
To see an example demonstrating the consequences of this sharing, try running the following Sketch on macOS:
import time
def setup():
py5.size(200, 200, py5.P2D)
def draw():
if py5.frame_count % 50 == 0:
py5.println(py5.frame_count)
py5.square(py5.random_int(py5.width), py5.random_int(py5.height), 10)
py5.run_sketch(block=False)
print('start pause')
time.sleep(3)
print('end pause')
When this code is run on a Linux or Windows computer, the output will be similar to this:
start pause
50
100
end pause
150
200
...
But when run on macOS, the output will be:
start pause
end pause
50
100
150
200
...
Also, you’ll notice the Sketch window does not open on the screen until after
“end pause” is printed. This will be the case for the OpenGL renderers P2D
and
P3D
as well as the default renderer JAVA2D
.
Furthermore, if your Sketch uses the default renderer JAVA2D
and you were to
later execute time.sleep(3)
in another notebook cell, you would momentarily
see the Sketch stop animating. The Sketch actually is still running, but the new
frames are not being drawn to the screen. For the above Sketch this will be
apparent at the end of the 3 seconds when many new squares appear at the same
time. The Sketch really is running normally during this time, but because of
the shared main thread, the new frames are not being drawn to the screen. This
behavior only applies to the JAVA2D
renderer and not the OpenGL
renderers P2D
and P3D
.
There are just a few more things macOS users need to know about using py5 in a Jupyter notebook.
Blocking#
In Jupyter, the run_sketch() method will never “block”,
which means that the method will return right away and let you execute lines of
code that appear after it or in other notebook cells. This shouldn’t be a
problem for notebook users as this is most certainly what you would want to
happen anyway. If you want some code to run right when the Sketch exits,
implement an exiting()
function, which will be called by py5 as the Sketch is
shutting down.
If you need to simultaneously run multiple Sketches in the same process on macOS, running them through a Jupyter notebook (using class-mode) is your only option.
Select Methods#
When run through Jupyter, the select methods select_folder(), select_input(), and select_output() will not work. Consider using IPython widgets instead.
py5bot and py5 magics#
On macOS, the Jupyter py5bot kernel and the py5 magic command %%py5bot cannot use the OpenGL (P2D and P3D) renderers. The %%py5draw magic also cannot use the OpenGL renderers, and the %%py5drawdxf magic is not available.
A future version of py5 will address these issues.
Generic Python Interpreter#
Starting with py5 version 0.7.2, a Sketch can run through the generic Python interpreter (outside of Jupyter). The limitations are that you can only run one Sketch at a time and that exiting the Sketch will terminate the Python process.
The run_sketch() command will always “block”, which means that the method will not return and allow you execute lines of code that appear after it. Since exiting the Sketch will also terminate the Python process, the call to run_sketch() will typically be the last line in your Python script.
Render Helper Tools#
The render helper tools @render(), render_frame(), @render_sequence(), and render_frame_sequence() cannot use the OpenGL (P2D and P3D) renderers.
A future version of py5 will address these issues.
Sketch Exit#
When the Sketch exits you will see the following warning:
NewtNSView::dealloc: softLock still hold @ dealloc!
Ignore that. Windows and Linux users also get odd messages when exiting a Sketch. It’s not a cause for concern.