Python weirdness - plotLayer() fails .... but not always

I have a python script which plots a number of separate layers to .svg files. This has been working fine and then, like a fool, I am tempted to try upgrading to a new nightly as I see there is better zoom and scrolling for macOS. I am not working on anything critical and have generally been very happy with nightly builds.

I have had to make a few adjustments to get python scripting to run (following previous advice on the Forum). Out of the box the new nightly causes a
pcbnewInitPythonScripting() failed.""Error importing the wxPython API!” error. I have fixed this by moving
/Applications/Kicad/kicad.app/Contents/Frameworks/python/site-packages/wx-3.0-osx_cocoa to one side. Now the scripting interface runs and, for instance, I can run a number of scripts and the footprint wizards - so far so good.

When I run my script however most of the time it fails with a Segfault 11 when it tries to plotLayer(). However, without making any changes whatsoever if I try running it again and sometimes it is successful - maybe one time in six, it works perfectly.

I am somewhat at loss to understand this and not really sure how or where to start debugging it.

I think have removed anything wx related that I might have installed with Brew but I am reluctant to remove all of Brew stuff as I need it for other things. My feeling is that it is path related but not sure how - the sys.info is a bit of a mess.

MacOS 10.12
Application: kicad
Version: (2017-09-15 revision e2505cb)-master, release build
Libraries:
wxWidgets 3.0.2
libcurl/7.54.0 SecureTransport zlib/1.2.8
Platform: Mac OS X (Darwin 16.7.0 x86_64), 64 bit, Little endian, wxMac
Build Info:
wxWidgets: 3.0.2 (UTF-8,STL containers,compatible with 2.8)
Boost: 1.61.0
Curl: 7.43.0
Compiler: Clang 7.3.0 with C++ ABI 1002

Build settings:
USE_WX_GRAPHICS_CONTEXT=ON
USE_WX_OVERLAY=ON
KICAD_SCRIPTING=ON
KICAD_SCRIPTING_MODULES=ON
KICAD_SCRIPTING_WXPYTHON=ON
KICAD_SCRIPTING_ACTION_MENU=ON
BUILD_GITHUB_PLUGIN=ON
KICAD_USE_OCE=ON
KICAD_SPICE=ON

sys.path

[’/Applications/Kicad/kicad.app/Contents/Frameworks/python/site-packages/wx-3.0-osx_cocoa.old’, ‘/Applications/Kicad/kicad.app/Contents/Frameworks/python/site-packages/wx-3.0-osx_cocoa.old’, ‘/Library/Python/2.7/site-packages/pyserial-3.0.1-py2.7.egg’, ‘/usr/local/lib/python2.7/site-packages/ino-0.3.6-py2.7.egg’, ‘/Library/Python/2.7/site-packages/argparse-1.4.0-py2.7.egg’, ‘/Library/Python/2.7/site-packages/ordereddict-1.1-py2.7.egg’, ‘/Library/Python/2.7/site-packages/configobj-5.0.6-py2.7.egg’, ‘/Library/Python/2.7/site-packages/Jinja2-2.8-py2.7.egg’, ‘/Library/Python/2.7/site-packages/MarkupSafe-0.23-py2.7-macosx-10.11-intel.egg’, ‘/Library/Python/2.7/site-packages/ano-0.4.5-py2.7.egg’, ‘/Library/Python/2.7/site-packages/glob2-0.4.1-py2.7.egg’, ‘/Applications/Kicad/kicad.app/Contents/SharedSupport/scripting’, ‘/Applications/Kicad/kicad.app/Contents/Frameworks/python/site-packages’, ‘/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python27.zip’, ‘/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7’, ‘/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/plat-darwin’, ‘/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/plat-mac’, ‘/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/plat-mac/lib-scriptpackages’, ‘/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-tk’, ‘/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-old’, ‘/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-dynload’, ‘/Users/johnpateman/Library/Python/2.7/lib/python/site-packages’, ‘/usr/local/lib/python2.7/site-packages’, ‘/usr/local/lib/python2.7/site-packages/geos’, ‘/usr/local/lib/python2.7/site-packages/gtk-2.0’, ‘/Library/Python/2.7/site-packages’, ‘/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python’, ‘/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/PyObjC’, ‘.’, ‘/Applications/Kicad/kicad.app/Contents/SharedSupport/scripting’, ‘/Applications/Kicad/kicad.app/Contents/SharedSupport/scripting/plugins’]

My script

#!/Applications/Kicad/kicad.app/Contents/Applications/pcbnew.app/Contents/MacOS/Python

"""
Kicad plot pcb file.
Plot variety of svg files in plot directory
"""

import sys
sys.path.insert(0, "/Applications/Kicad/kicad.app/Contents/Frameworks/python/site-packages")
import pcbnew
from pcbnew import *

boardName = sys.argv[1]
board = LoadBoard(boardName)
pctl = pcbnew.PLOT_CONTROLLER(board)
popt = pctl.GetPlotOptions()
plotDir = "plot/"
popt.SetOutputDirectory(plotDir)
popt.SetPlotFrameRef(False)
popt.SetLineWidth(pcbnew.FromMM(0.15))
popt.SetAutoScale(False)
popt.SetScale(1)
popt.SetMirror(False)
popt.SetUseGerberAttributes(True)
popt.SetExcludeEdgeLayer(False)
popt.SetUseAuxOrigin(True)
pctl.SetColorMode(True)

layers = [
    ("F_Cu", pcbnew.F_Cu, "Top layer"),
    ("B_Cu", pcbnew.B_Cu, "Bottom layer"),
    ("B_Paste", pcbnew.B_Paste, "Paste Bottom"),
    ("F_Paste", pcbnew.F_Paste, "Paste top"),
    ("F_SilkS", pcbnew.F_SilkS, "Silk top"),
    ("B_SilkS", pcbnew.B_SilkS, "Silk top"),
    ("B_Mask", pcbnew.B_Mask, "Mask bottom"),
    ("F_Mask", pcbnew.F_Mask, "Mask top"),
    ("Edge_Cuts", pcbnew.Edge_Cuts, "Edges"),
]

for layer_info in layers:
  pctl.SetLayer(layer_info[1])
  pctl.OpenPlotfile(layer_info[0], pcbnew.PLOT_FORMAT_SVG, layer_info[2])
  pctl.PlotLayer()

pctl.ClosePlot()

I haven’t messed with plotting stuff from python. But the first thing that pops out just reading it:

Are the methods OpenPlotfile and ClosePlot really not symmetrical?

Related: I don’t see a ClosePlotfile().

Granted: maybe this is how plotting works: I do not know.

I mainly wanted you to know that there are other KiCad python programmers here. At least a couple. Sorry I couldn’t be more help.

Thanks for having a look @HiGreg .

I included the ClosePlot() as was suggested by the original author to prevent the plot object from being recycled. I think that is how plotting is supposed to work and I don’t believe there is a ClosePlotfile(). Removing it doesn’t seem to help. :frowning:

As I say, the weird thing is that it used to work and now it still works some of the time - just not every time.

Sticking in some debugging print() lines show that when it fails, it is around the plotLayer() line. Changing the plot format to PLOT_FORMAT_PDF or PLOT_FORMAT_GERBER doesn’t make any difference.

Anyhow, thanks for looking. BTW I really like the look of your work on the Command Stack. Well done!

2 Likes