With major release 0.24, a Python interpreter will be integrated into the application. For evaluation of that feature, an test version is available for download. If you're interested in Python scripting, please try and give feedback.
Here are the download links:
|unix (source package)||0.24-python-eval||klayout-0.24-python-eval.tar.gz|
|Windows 32 bit (binary package)||0.24-python-eval||klayout-0.24-python-eval-win32.zip (binaries)
|Windows 64 bit (binary package)||0.24-python-eval||klayout-0.24-python-eval-win64.zip (binaries)
On Linux, the build script will automatically include Python support if a Python interpreter is present in the path. It will try "python" for the interpreter. You need to have the header files and the library installed before KLayout can be built with Python support. Usually you need to install the "development" packages for Python. On Ubuntu this is "python-dev".
To use a specific Python interpreter, use:
build.sh -python python3.2
To explicitly specifiy the library and path of the include files, use
build.sh -pylib /usr/lib/python/libpython3.2.so -pyinc /usr/include/python3.2
To explicitly disable Python support, use:
The build has been tested with Python 2.7.3 and 3.4. Python 3 and 2 can both be used, but Python 3 is recommended.
Python and Ruby can both be enabled and used together in one executable.
For Windows, the provided binary packages can be used. They are built on Python 3.4 and Ruby 2.1.3. The binary packages are built with Visual Studio Express 2010 which is also the compiler used for the prebuilt Python 3.4 distribution available here: https://www.python.org/downloads/release/python-340
Python extension libraries built for this distribution can be used for KLayout too, but they need to be installed manually. I have not tried to get the disutils running in KLayout's context.
You have not misunderstood the message before: Python and Ruby can both be used together. So it is possible to write one script in Ruby and another one in Python. Just pick your favorite language. Scripts written in different languages share the same KLayout data structures. Naturally they cannot directly share variables or language-specific data. But you can, for example, implement PCell's in Python and Ruby and use those different PCells in the same layout at the same time. Depending on the type of PCell, KLayout will either execute Python or Ruby code.
Python macros are loaded into KLayout using either ".py" files or ".lym" files with the interpreter set to "Python". To create Python macros, a new tab is available in the Macro Development IDE. When creating macros in the "Python" tab, they will use the Python interpreter. Macros created in the "Ruby" tab will use the Ruby interpreter. Files loaded by "import" need to be in plain text format and use the ".py" suffix. The macro folder is called "pymacros" for a clean separation between the two macro worlds. Technically, both Ruby and Python macros are .lym files with a different interpreter specified in these files.
The Python macro folder is in the "sys.path" search path so it is possible to install modules there. To install libraries globally use "%INST_PATH%/lib/python/Lib" and "%INST_PATH%/lib/python/DLLs" on Windows. %INST_PATH% is the installation path (where klayout.exe is located). On Linux, the installation will share the Python interpreter with the system and modules installed there will be available for KLayout too.
"$PYTHONPATH" is supported in the usual way.
A good way is to start with the samples provided when creating new macros on the Python tab. The samples are available at the end of the template list. There is a sample for a PCell implementation, a sample for a Qt dialog, a sample for using Qt's .ui files in Python macros and one sample turning KLayout into a HTTP server using a Python macro.
Apart from a few specialities and the different language of course, Python macros do not look much different from Ruby macros. Ruby's "RBA" namespace is "pya" for Python (lowercase to conform with PEP-8). The class and methods names are the same with very few exceptions and the documentation can be used for Python too. Where necessary, a special remark is made regarding the Python implementation.
Here is a basic Python Macro. It creates a layout with a single cell and single layer and puts one rectangle on that layer:
# Python version: import pya layout = pya.Layout() top = layout.create_cell("TOP") l1 = layout.layer(1, 0) top.shapes(l1).insert(pya.Box(0, 0, 1000, 2000)) layout.write("t.gds")
Here is the Ruby variant to demonstrate the similarity:
# Ruby version: layout = RBA::Layout::new() top = layout.create_cell("TOP") l1 = layout.layer(1, 0) top.shapes(l1).insert(RBA::Box::new(0, 0, 1000, 2000)) layout.write("t.gds")
Of course, not everything can be translated that easily between Ruby and Python. The details are given below. Usually however, it's straightforward to translate Ruby into Python.
There is no clear advantage of one language over the other. The Python community is somewhat stronger, but performance-wise, Ruby is better. In KLayout, the debugger support for Python is a little better, since the guts of the interpreter are well documented in Python. For example, it is possible to evaluate expressions in the context of the current stack frame.
Apart from that, Python and Ruby coexist remarkably well and it was amazing, how easy it was to extend the interfaces from Ruby to Python: not counting the different memory management model (mark and sweep garbage collector in Ruby, reference counting in Python), the concepts are very similar.
Please read the Python specific notes below before you start. Some things need to be considered when going from Ruby to Python.
Please have a look at the PCell sample available in the templates. Pick the PCell sample after you have created a new Python macro.
PCell implementation in Python is very similar to Ruby.
box = pya.Box() box.left = 10 box.right = box.right + 100
If the translation is ambiguous (i.e. because there is more than one getter or setter, the setter will be translated to a method "set_x(value)" where "x" is the attribute name.
# Ruby: edges.is_empty? # Python: edges.is_empty()
edges = pya.Edges() ... for edge in edges.each(): ...
If there is an iterator named "each", it will become the default iterator:
for edge in edges: ...
"x.to_s()" is available as "str(x)" too.
"x.size()" is available as "len(x)" too.
If there is a "" operator and a "size" method, the object implements the sequence protocol too.
Operators are made available through Python operators. For example
box = pya.Box(10, 20, 110, 220) copy_box = box.dup()
action.on_triggered( lambda: action.text += "X" )or to function:
def f(): print "triggered" action.on_triggered(f)
Events have to match precisely - exactly the number of arguments have to be declared.
Tips when developing own modules: