Python 3 Introduction
Getting Started
JMRI's Python 3 support is provided, in part, by running on a GraalVM virtual machine instead of the usual Java Runtime Environment. The first step is to install a GraalVM on your computer.To do that, follow the GraalVM install instructions to install a Java 17 or later version. The Java 17 version is recommended. Note that using Java 17 will cause some problems for other JMRI functions, see the description of those.
Next, check that "python" has been installed in your GraalVM using the command
gu list
If the gu command is not available, it's likely that your GraalVM installation
didn't go correctly. If that command doesn't show "python" installed, you have
to install it:
gu install python
then check again with the gu list command.
Once you do all that and start JMRI, a "Python 3" choice should appear in the language selector in the Script Input Window, and the file choosers for running scripts should give you a similar choice.
Our convention is that Python 3 files use a .py3 extension.
Issues and differences from Jython (Python 2.7)
In addition to the syntax differences between the Python 2.7 and Python 3 languages, such as print statements need to have their value enclosed in parentheses
print (123)
there are some scripting-related differences:
- Scripts should start with
import jmri as jmri import java exec( open("jython/jmri_bindings.py3").read() )The third line is the Py3 syntax to read and execute another script file. In this case, it reads and executes the file that defines a number of symbols like `THROWN``, `turnouts`, etc. -
The syntax for getting a class reference has changed. The only
place you're likely to see that is in InstanceManager calls. They become:
manager = jmri.InstanceManager.getNullableDefault('jmri.MyManager')(note quotes). More generally, if you need access to a Java type object for other purposes, you can get it withjava.type('jmri.MyManager')but we've provided a new version of InstanceManager.getDefault and InstanceManager.getNullableDefault that takes the class name as a parameter to make those common operations simpler. -
Constants are not inherited:
You have to reference
DigitalIO.ON, notLight.ON. - Unlike Jython, JMRI's Python 3 can address (almost) any of the Python libraries you have installed on your computer.
-
You can inherit a Python class from a Java class, i.e.
class Automat(AbstractAutomaton) : def init(self) : print ("init in Python 3") def handle(self) : print ("handle in Python 3") return False - The "syntax error" message doesn't tell you where the error was found. This is a real pain.