On Python projects unrelated to Ignition, I’ve been starting to use type annotations and static type checking tools like mypy. I find the type annotations very helpful as reminders of what function parameters are supposed to be, and mypy helps find corner cases that would’ve lead to exceptions.
If you’ve never seen type annotations in Python, the mypy cheat sheets are the simplest demonstration and practical explanation I’ve found. Annotations used to be stored as comments in Python2, but Python3 made it part of the language. Reading the official Python PEP on typing is a steep learning curve, but does cover more difficult concepts.
Coincidentally, I was trying to setup @thecesrom.git’s excellent
ignition-api library in my editing environment, and noticed it had annotations for everything it stubbed.
For better or worse, I decided to try annotating and type-checking some of my Ignition scripts. Yeah, I knew that the Jython environment, Java libraries, and wonky namespace setup were going to make it all likely to fail, but that’s half the fun.
I setup a Python2.7 virtualenv, loaded it with ignition-api and the modules needed for mypy to run, and then pointed mypy at a code.py file I had annotated. I had to add a lot of imports at the beginning for everything in
system.*, all the other script libraries from my Ignition project, and
typing to make mypy happy. It still complained a lot about unknown libraries, but mostly worked.
The biggest sticking points to using this on a regular basis is that I can’t leave all those
import lines that mypy wants to see in the script file without messing up Ignition, and I don’t have any sane way for mypy to understand script libraries importing each other. I’ve been pondering making some sort of utility that scans a project directory and copy/renames all of the files out into normal Python module hierarchy filenames and pre-pends the hidden
import lines to the front of the scripts, but that’s a heck of a lot of work…
I also noticed that both ignition-api and mypy try to bring in slightly different libraries named
typing. I can’t remember how I resolved that in my virtualenv, but I got around it somehow…
Has anyone else ever played with this and gotten anywhere? Do you have any tricks for running mypy easily without pre-processing the Ignition script files every time?
This whole experiment has convinced me to start annotating all of my Ignition scripts, even if I can’t run mypy, because I found myself instinctively reading the hints to understand functions. Plus, if I keep annotating things, it’ll be less work if I ever find a way to easily run mypy.