After being teased with some graphics improvements coming in Dynamo, I was excited to find on returning from my recent holiday to find a new release of Dynamo Sandbox was available for testing. There are a number of notable features available in Dynamo 2.7, whether the ability to run CPython3 code – rather than using IronPython, which is based on Python2 – or improved graphics preview performance thanks to an upgrade to Helix.
I started by just loading v2 of the MaRS graph, without changing any of the code blocks to use CPython. Straightaway I found that the graphics performance when zooming and panning was improved when compared with earlier versions of Dynamo, so I was immediately sold on the upgrade. Here’s a little zooming and panning of the MaRS graph’s graphical output. It’s still slow to navigate the node view, but this is a helpful improvement for the graphics preview.
For fun I started fooling around with changing the various Python nodes to use CPython3 instead of IronPython2. Here are some notes I made regarding the issues I needed to fix in the various code blocks.
- TypeError : No method matches given arguments for method
- This usually seems to be due to a mismatch between ints and floats, something that is presumably done implicitly in IronPython. This is apparently a known issue and will be fixed in Dynamo 2.8, so I suggest waiting for that release before attempting major Python upgrades – otherwise you may find that you need to add a “.0” suffix to integer constants in your code.
- TabError : inconsistent use of tabs and spaces in indentation
- IronPython seems more tolerant of mixing spaces and tabs in your Python code. In reality it’s not that simple, though: when this was reported and I replaced all remaining tabs with spaces, the logic changed in one of our metrics: we were accumulating values in a nested loop, and the resultant value was actually wrong! You can see this in the “fixed” graphics above, where the congestion map is much darker. Moving to CPython should help identify and fix this class of lurking bug!
- SynchronizationLockException : Object synchronization method was called from an unsynchronized block of code
- We’d introduced a number of Parallel.For calls into the graph (via an optional “Parallelize” flag that is set to false by default). Because of this we had a critical section where shared data was protected via Monitor.Enter and Monitor.Exit. For simplicity I removed all use of Parallel.For and the Monitor object, too.
- TypeError : '>' not supported between instances of 'list' and 'int'
- This highlighted a bug in our code where we were incorrectly comparing a list of floats with a numeric value. I have no idea how this didn’t cause an issue before, but summing the list first seemed to be the answer to this one.
- TypeError : No method matches given arguments for Flatten
- List.Flatten could not be found for love nor money. This one drove me completely potty. In the end I flattened the lists outside the code block using Dynamo nodes and passed them in as additional arguments.
- AttributeError : 'zip' object has no attribute 'sort'
- I had to call list() on the results of a zip(), to make sure I could then sort() it. It’s possible that zip() returns an enumerable object that isn’t strictly a list, so CPython apparently requires this additional step.
Overall I will say that the effort required wasn’t enormous for this particular graph, which does contain quite a lot of Python code. I would recommend holding off porting major graphs until at least Dynamo 2.8 (given the fact the first category of migration problem above will not need to be fixed in that release). Hopefully this list will be of use to you when you do embark on any migration to CPython3.