From d3fa4465f66aac823d6b10f8bbd088332cbe8d24 Mon Sep 17 00:00:00 2001 From: Thomas Ferreira de Lima Date: Fri, 19 Oct 2018 17:53:10 -0400 Subject: [PATCH 1/4] Renaming core modules to klayout.dbcore, klayout.rdbcore and klayout.tlcore --- setup.py | 14 +++++++------- src/pymod/db/dbMain.cc | 2 +- src/pymod/distutils_src/__init__.py | 3 +-- src/pymod/distutils_src/db.py | 1 + src/pymod/distutils_src/rdb.py | 1 + src/pymod/distutils_src/tl.py | 1 + src/pymod/rdb/rdbMain.cc | 2 +- src/pymod/tl/tlMain.cc | 2 +- 8 files changed, 14 insertions(+), 12 deletions(-) create mode 100644 src/pymod/distutils_src/db.py create mode 100644 src/pymod/distutils_src/rdb.py create mode 100644 src/pymod/distutils_src/tl.py diff --git a/setup.py b/setup.py index 78cc876c2..6c9dc2e17 100644 --- a/setup.py +++ b/setup.py @@ -213,7 +213,7 @@ class Config(object): """ Gets the version string """ - return "0.26.0.dev4" + return "0.26.0.dev5" config = Config() @@ -333,12 +333,12 @@ for pi in glob.glob("src/plugins/*/db_plugin") + glob.glob("src/plugins/*/*/db_p tl_sources = glob.glob("src/pymod/tl/*.cc") -tl = Extension(config.root + '.tl', +tl = Extension(config.root + '.tlcore', define_macros=config.macros(), include_dirs=['src/tl/tl', 'src/gsi/gsi', 'src/pya/pya'], extra_objects=[config.path_of('_tl'), config.path_of( '_gsi'), config.path_of('_pya')], - extra_link_args=config.link_args('tl'), + extra_link_args=config.link_args('tlcore'), sources=tl_sources) # ------------------------------------------------------------------ @@ -346,12 +346,12 @@ tl = Extension(config.root + '.tl', db_sources = glob.glob("src/pymod/db/*.cc") -db = Extension(config.root + '.db', +db = Extension(config.root + '.dbcore', define_macros=config.macros(), include_dirs=['src/db/db', 'src/tl/tl', 'src/gsi/gsi', 'src/pya/pya'], extra_objects=[config.path_of('_db'), config.path_of( '_tl'), config.path_of('_gsi'), config.path_of('_pya')], - extra_link_args=config.link_args('db'), + extra_link_args=config.link_args('dbcore'), sources=db_sources) # ------------------------------------------------------------------ @@ -359,13 +359,13 @@ db = Extension(config.root + '.db', rdb_sources = glob.glob("src/pymod/rdb/*.cc") -rdb = Extension(config.root + '.rdb', +rdb = Extension(config.root + '.rdbcore', define_macros=config.macros(), include_dirs=['src/rdb/rdb', 'src/db/db', 'src/tl/tl', 'src/gsi/gsi', 'src/pya/pya'], extra_objects=[config.path_of('_rdb'), config.path_of( '_gsi'), config.path_of('_pya')], - extra_link_args=config.link_args('rdb'), + extra_link_args=config.link_args('rdbcore'), sources=rdb_sources) # ------------------------------------------------------------------ diff --git a/src/pymod/db/dbMain.cc b/src/pymod/db/dbMain.cc index 9a773e0e6..81a2b9421 100644 --- a/src/pymod/db/dbMain.cc +++ b/src/pymod/db/dbMain.cc @@ -33,4 +33,4 @@ static PyObject *db_module_init (const char *mod_name, const char *mod_descripti return module_init (mod_name, mod_description); } -DEFINE_PYMOD_WITH_INIT(db, "db", "KLayout core module 'db'", db_module_init) +DEFINE_PYMOD_WITH_INIT(dbcore, "dbcore", "KLayout core module 'dbcore'", db_module_init) diff --git a/src/pymod/distutils_src/__init__.py b/src/pymod/distutils_src/__init__.py index dce96f8e4..51c551f9b 100644 --- a/src/pymod/distutils_src/__init__.py +++ b/src/pymod/distutils_src/__init__.py @@ -1,5 +1,4 @@ # klayout library definition file -__all__ = [ "tl", "db", "lay", "rdb" ] - +__all__ = ["tl", "db", "rdb"] diff --git a/src/pymod/distutils_src/db.py b/src/pymod/distutils_src/db.py new file mode 100644 index 000000000..2b4ae260c --- /dev/null +++ b/src/pymod/distutils_src/db.py @@ -0,0 +1 @@ +from dbcore import * diff --git a/src/pymod/distutils_src/rdb.py b/src/pymod/distutils_src/rdb.py new file mode 100644 index 000000000..6dd00e138 --- /dev/null +++ b/src/pymod/distutils_src/rdb.py @@ -0,0 +1 @@ +from rdbcore import * diff --git a/src/pymod/distutils_src/tl.py b/src/pymod/distutils_src/tl.py new file mode 100644 index 000000000..cd1abfb00 --- /dev/null +++ b/src/pymod/distutils_src/tl.py @@ -0,0 +1 @@ +from tlcore import * diff --git a/src/pymod/rdb/rdbMain.cc b/src/pymod/rdb/rdbMain.cc index e0008b22a..0da6e19c6 100644 --- a/src/pymod/rdb/rdbMain.cc +++ b/src/pymod/rdb/rdbMain.cc @@ -25,4 +25,4 @@ // to force linking of the rdb module #include "../../rdb/rdb/rdbForceLink.h" -DEFINE_PYMOD(rdb, "rdb", "KLayout core module 'rdb'") +DEFINE_PYMOD(rdbcore, "rdbcore", "KLayout core module 'rdbcore'") diff --git a/src/pymod/tl/tlMain.cc b/src/pymod/tl/tlMain.cc index db6a278fb..cc75be08b 100644 --- a/src/pymod/tl/tlMain.cc +++ b/src/pymod/tl/tlMain.cc @@ -22,4 +22,4 @@ #include "../pymodHelper.h" -DEFINE_PYMOD(tl, "tl", "KLayout core module 'tl'") +DEFINE_PYMOD(tlcore, "tlcore", "KLayout core module 'tlcore'") From 87a49007ff1ebbd7da515fb17b87f96a4c1cae0c Mon Sep 17 00:00:00 2001 From: Thomas Ferreira de Lima Date: Fri, 19 Oct 2018 18:53:37 -0400 Subject: [PATCH 2/4] Fixing distutils_src folder structure due to setuptools bug Also: adding PCellDeclarationHelper to klayout.db --- setup.py | 6 +- src/pymod/db/dbMain.cc | 2 +- src/pymod/distutils_src/db.py | 1 - .../distutils_src/{ => klayout}/__init__.py | 3 - .../distutils_src/klayout/db/__init__.py | 3 + .../klayout/db/pcell_declaration_helper.py | 280 ++++++++++++++++++ src/pymod/distutils_src/klayout/rdb.py | 1 + src/pymod/distutils_src/klayout/tl.py | 1 + src/pymod/distutils_src/rdb.py | 1 - src/pymod/distutils_src/tl.py | 1 - src/pymod/rdb/rdbMain.cc | 2 +- src/pymod/tl/tlMain.cc | 2 +- 12 files changed, 291 insertions(+), 12 deletions(-) delete mode 100644 src/pymod/distutils_src/db.py rename src/pymod/distutils_src/{ => klayout}/__init__.py (51%) create mode 100644 src/pymod/distutils_src/klayout/db/__init__.py create mode 100644 src/pymod/distutils_src/klayout/db/pcell_declaration_helper.py create mode 100644 src/pymod/distutils_src/klayout/rdb.py create mode 100644 src/pymod/distutils_src/klayout/tl.py delete mode 100644 src/pymod/distutils_src/rdb.py delete mode 100644 src/pymod/distutils_src/tl.py diff --git a/setup.py b/setup.py index 6c9dc2e17..ccb1caad3 100644 --- a/setup.py +++ b/setup.py @@ -54,7 +54,7 @@ and won't find them. So we need to take away the path with "-Wl,-soname" on Linux (see Config.link_args). """ -from setuptools import setup, Extension, Distribution +from setuptools import setup, Extension, Distribution, find_packages import glob import os import platform @@ -380,6 +380,6 @@ if __name__ == '__main__': author='Matthias Koefferlein', author_email='matthias@klayout.de', url='https://github.com/klayoutmatthias/klayout', - packages=[config.root], - package_dir={config.root: 'src/pymod/distutils_src'}, + packages=find_packages('src/pymod/distutils_src'), + package_dir={'': 'src/pymod/distutils_src'}, # https://github.com/pypa/setuptools/issues/230 ext_modules=[_tl, _gsi, _pya, _db, _rdb] + db_plugins + [tl, db, rdb]) diff --git a/src/pymod/db/dbMain.cc b/src/pymod/db/dbMain.cc index 81a2b9421..97c6388df 100644 --- a/src/pymod/db/dbMain.cc +++ b/src/pymod/db/dbMain.cc @@ -33,4 +33,4 @@ static PyObject *db_module_init (const char *mod_name, const char *mod_descripti return module_init (mod_name, mod_description); } -DEFINE_PYMOD_WITH_INIT(dbcore, "dbcore", "KLayout core module 'dbcore'", db_module_init) +DEFINE_PYMOD_WITH_INIT(dbcore, "db", "KLayout core module 'db'", db_module_init) diff --git a/src/pymod/distutils_src/db.py b/src/pymod/distutils_src/db.py deleted file mode 100644 index 2b4ae260c..000000000 --- a/src/pymod/distutils_src/db.py +++ /dev/null @@ -1 +0,0 @@ -from dbcore import * diff --git a/src/pymod/distutils_src/__init__.py b/src/pymod/distutils_src/klayout/__init__.py similarity index 51% rename from src/pymod/distutils_src/__init__.py rename to src/pymod/distutils_src/klayout/__init__.py index 51c551f9b..a01e9cdd4 100644 --- a/src/pymod/distutils_src/__init__.py +++ b/src/pymod/distutils_src/klayout/__init__.py @@ -1,4 +1 @@ - # klayout library definition file - -__all__ = ["tl", "db", "rdb"] diff --git a/src/pymod/distutils_src/klayout/db/__init__.py b/src/pymod/distutils_src/klayout/db/__init__.py new file mode 100644 index 000000000..c3270bfb8 --- /dev/null +++ b/src/pymod/distutils_src/klayout/db/__init__.py @@ -0,0 +1,3 @@ +from klayout.dbcore import * + +from klayout.db.pcell_declaration_helper import PCellDeclarationHelper diff --git a/src/pymod/distutils_src/klayout/db/pcell_declaration_helper.py b/src/pymod/distutils_src/klayout/db/pcell_declaration_helper.py new file mode 100644 index 000000000..9367f787f --- /dev/null +++ b/src/pymod/distutils_src/klayout/db/pcell_declaration_helper.py @@ -0,0 +1,280 @@ +from klayout.db import Trans, PCellDeclaration, PCellParameterDeclaration + + +class _PCellDeclarationHelperLayerDescriptor(object): + """ + A descriptor object which translates the PCell parameters into class attributes + """ + + def __init__(self, param_index): + self.param_index = param_index + + def __get__(self, obj, type=None): + return obj._layers[self.param_index] + + def __set__(self, obj, value): + raise AttributeError("can't change layer attribute") + + +class _PCellDeclarationHelperParameterDescriptor(object): + """ + A descriptor object which translates the PCell parameters into class attributes + + In some cases (i.e. can_convert_from_shape), these placeholders are not + connected to real parameters (obj._param_values is None). In this case, + the descriptor acts as a value holder (self.value) + """ + + def __init__(self, param_index): + self.param_index = param_index + self.value = None + + def __get__(self, obj, type=None): + if obj._param_values: + return obj._param_values[self.param_index] + else: + return self.value + + def __set__(self, obj, value): + if obj._param_values: + obj._param_values[self.param_index] = value + else: + self.value = value + + +class _PCellDeclarationHelper(PCellDeclaration): + """ + A helper class that somewhat simplifies the implementation + of a PCell + """ + + def __init__(self): + """ + initialize this instance + """ + # "private" attributes + self._param_decls = [] + self._param_values = None + self._layer_param_index = [] + self._layers = [] + # public attributes + self.layout = None + self.shape = None + self.layer = None + self.cell = None + + def param(self, name, value_type, description, hidden=False, readonly=False, unit=None, default=None, choices=None): + """ + Defines a parameter + name -> the short name of the parameter + type -> the type of the parameter + description -> the description text + named parameters + hidden -> (boolean) true, if the parameter is not shown in the dialog + readonly -> (boolean) true, if the parameter cannot be edited + unit -> the unit string + default -> the default value + choices -> ([ [ d, v ], ...) choice descriptions/value for choice type + this method defines accessor methods for the parameters + {name} -> read accessor + set_{name} -> write accessor ({name}= does not work because the + Ruby confuses that method with variables) + {name}_layer -> read accessor for the layer index for TypeLayer parameters + """ + + # create accessor methods for the parameters + param_index = len(self._param_decls) + setattr(type(self), name, _PCellDeclarationHelperParameterDescriptor(param_index)) + + if value_type == type(self).TypeLayer: + setattr(type(self), name + "_layer", + _PCellDeclarationHelperLayerDescriptor(len(self._layer_param_index))) + self._layer_param_index.append(param_index) + + # store the parameter declarations + pdecl = PCellParameterDeclaration(name, value_type, description) + self._param_decls.append(pdecl) + + # set additional attributes of the parameters + pdecl.hidden = hidden + pdecl.readonly = readonly + if not (default is None): + pdecl.default = default + if not (unit is None): + pdecl.unit = unit + if not (choices is None): + if not isinstance(choices, list) and not isinstance(choices, tuple): + raise "choices value must be an list/tuple of two-element arrays (description, value)" + for c in choices: + if (not isinstance(choices, list) and not isinstance(choices, tuple)) or len(c) != 2: + raise "choices value must be an list/tuple of two-element arrays (description, value)" + pdecl.add_choice(c[0], c[1]) + + # return the declaration object for further operations + return pdecl + + def display_text(self, parameters): + """ + implementation of display_text + """ + self._param_values = parameters + text = self.display_text_impl() + self._param_values = None + return text + + def get_parameters(self): + """ + gets the parameters + """ + return self._param_decls + + def get_values(self): + """ + gets the temporary parameter values + """ + v = self._param_values + self._param_values = None + return v + + def init_values(self, values=None, layers=None): + """ + initializes the temporary parameter values + "values" are the original values. If "None" is given, the + default values will be used. + "layers" are the layer indexes corresponding to the layer + parameters. + """ + if not values: + self._param_values = [] + for pd in self._param_decls: + self._param_values.append(pd.default) + else: + self._param_values = values + self._layers = layers + + def finish(self): + """ + Needs to be called at the end of produce() after init_values was used + """ + self._param_values = None + self._layers = None + + def get_layers(self, parameters): + """ + get the layer definitions + """ + layers = [] + for i in self._layer_param_index: + layers.append(parameters[i]) + return layers + + def coerce_parameters(self, layout, parameters): + """ + coerce parameters (make consistent) + """ + self.init_values(parameters) + self.layout = layout + self.coerce_parameters_impl() + self.layout = None + return self.get_values() + + def produce(self, layout, layers, parameters, cell): + """ + coerce parameters (make consistent) + """ + self.init_values(parameters, layers) + self.cell = cell + self.layout = layout + self.produce_impl() + self.cell = None + self.layout = None + self.finish() + + def can_create_from_shape(self, layout, shape, layer): + """ + produce a helper for can_create_from_shape + """ + self.layout = layout + self.shape = shape + self.layer = layer + ret = self.can_create_from_shape_impl() + self.layout = None + self.shape = None + self.layer = None + return ret + + def transformation_from_shape(self, layout, shape, layer): + """ + produce a helper for parameters_from_shape + """ + self.layout = layout + self.shape = shape + self.layer = layer + t = self.transformation_from_shape_impl() + self.layout = None + self.shape = None + self.layer = None + return t + + def parameters_from_shape(self, layout, shape, layer): + """ + produce a helper for parameters_from_shape + with this helper, the implementation can use the parameter setters + """ + self.init_values() + self.layout = layout + self.shape = shape + self.layer = layer + self.parameters_from_shape_impl() + param = self.get_values() + self.layout = None + self.shape = None + self.layer = None + return param + + def display_text_impl(self): + """ + default implementation + """ + return "" + + def coerce_parameters_impl(self): + """ + default implementation + """ + pass + + def produce_impl(self): + """ + default implementation + """ + pass + + def can_create_from_shape_impl(self): + """ + default implementation + """ + return False + + def parameters_from_shape_impl(self): + """ + default implementation + """ + pass + + def transformation_from_shape_impl(self): + """ + default implementation + """ + return Trans() + + +# import the Type... constants from PCellParameterDeclaration +for k in dir(PCellParameterDeclaration): + if k.startswith("Type"): + setattr(_PCellDeclarationHelper, k, getattr(PCellParameterDeclaration, k)) + +# Inject the PCellDeclarationHelper into pya module for consistency: +PCellDeclarationHelper = _PCellDeclarationHelper + +__all__ = ['PCellDeclarationHelper'] diff --git a/src/pymod/distutils_src/klayout/rdb.py b/src/pymod/distutils_src/klayout/rdb.py new file mode 100644 index 000000000..217207310 --- /dev/null +++ b/src/pymod/distutils_src/klayout/rdb.py @@ -0,0 +1 @@ +from klayout.rdbcore import * diff --git a/src/pymod/distutils_src/klayout/tl.py b/src/pymod/distutils_src/klayout/tl.py new file mode 100644 index 000000000..0645f506f --- /dev/null +++ b/src/pymod/distutils_src/klayout/tl.py @@ -0,0 +1 @@ +from klayout.tlcore import * diff --git a/src/pymod/distutils_src/rdb.py b/src/pymod/distutils_src/rdb.py deleted file mode 100644 index 6dd00e138..000000000 --- a/src/pymod/distutils_src/rdb.py +++ /dev/null @@ -1 +0,0 @@ -from rdbcore import * diff --git a/src/pymod/distutils_src/tl.py b/src/pymod/distutils_src/tl.py deleted file mode 100644 index cd1abfb00..000000000 --- a/src/pymod/distutils_src/tl.py +++ /dev/null @@ -1 +0,0 @@ -from tlcore import * diff --git a/src/pymod/rdb/rdbMain.cc b/src/pymod/rdb/rdbMain.cc index 0da6e19c6..ba085fe97 100644 --- a/src/pymod/rdb/rdbMain.cc +++ b/src/pymod/rdb/rdbMain.cc @@ -25,4 +25,4 @@ // to force linking of the rdb module #include "../../rdb/rdb/rdbForceLink.h" -DEFINE_PYMOD(rdbcore, "rdbcore", "KLayout core module 'rdbcore'") +DEFINE_PYMOD(rdbcore, "rdb", "KLayout core module 'rdb'") diff --git a/src/pymod/tl/tlMain.cc b/src/pymod/tl/tlMain.cc index cc75be08b..42c21c630 100644 --- a/src/pymod/tl/tlMain.cc +++ b/src/pymod/tl/tlMain.cc @@ -22,4 +22,4 @@ #include "../pymodHelper.h" -DEFINE_PYMOD(tlcore, "tlcore", "KLayout core module 'tlcore'") +DEFINE_PYMOD(tlcore, "tl", "KLayout core module 'tl'") From c3ab951c8a86e137f523305ffb35d44deb111442 Mon Sep 17 00:00:00 2001 From: Thomas Ferreira de Lima Date: Fri, 19 Oct 2018 19:02:38 -0400 Subject: [PATCH 3/4] passing python unit tests --- src/pymod/distutils_src/klayout/db/__init__.py | 3 +++ src/pymod/distutils_src/klayout/db/pcell_declaration_helper.py | 2 -- src/pymod/distutils_src/klayout/rdb.py | 3 +++ src/pymod/distutils_src/klayout/tl.py | 3 +++ 4 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/pymod/distutils_src/klayout/db/__init__.py b/src/pymod/distutils_src/klayout/db/__init__.py index c3270bfb8..ed86dcf86 100644 --- a/src/pymod/distutils_src/klayout/db/__init__.py +++ b/src/pymod/distutils_src/klayout/db/__init__.py @@ -1,3 +1,6 @@ +import klayout.dbcore from klayout.dbcore import * from klayout.db.pcell_declaration_helper import PCellDeclarationHelper + +__all__ = klayout.dbcore.__all__ + ['PCellDeclarationHelper'] diff --git a/src/pymod/distutils_src/klayout/db/pcell_declaration_helper.py b/src/pymod/distutils_src/klayout/db/pcell_declaration_helper.py index 9367f787f..e351a818b 100644 --- a/src/pymod/distutils_src/klayout/db/pcell_declaration_helper.py +++ b/src/pymod/distutils_src/klayout/db/pcell_declaration_helper.py @@ -276,5 +276,3 @@ for k in dir(PCellParameterDeclaration): # Inject the PCellDeclarationHelper into pya module for consistency: PCellDeclarationHelper = _PCellDeclarationHelper - -__all__ = ['PCellDeclarationHelper'] diff --git a/src/pymod/distutils_src/klayout/rdb.py b/src/pymod/distutils_src/klayout/rdb.py index 217207310..eb48ea888 100644 --- a/src/pymod/distutils_src/klayout/rdb.py +++ b/src/pymod/distutils_src/klayout/rdb.py @@ -1 +1,4 @@ +import klayout.rdbcore from klayout.rdbcore import * + +__all__ = klayout.rdbcore.__all__ diff --git a/src/pymod/distutils_src/klayout/tl.py b/src/pymod/distutils_src/klayout/tl.py index 0645f506f..a4c4287e9 100644 --- a/src/pymod/distutils_src/klayout/tl.py +++ b/src/pymod/distutils_src/klayout/tl.py @@ -1 +1,4 @@ +import klayout.tlcore from klayout.tlcore import * + +__all__ = klayout.tlcore.__all__ From c1dbb023ae8f70259e8e67991b9c0e5dc8ee1db1 Mon Sep 17 00:00:00 2001 From: Thomas Ferreira de Lima Date: Fri, 19 Oct 2018 19:09:20 -0400 Subject: [PATCH 4/4] fixing editable install 'python setup.py develop' --- src/pymod/distutils_src/klayout/.gitignore | 9 +++++++++ src/pymod/distutils_src/klayout/db_plugins/.keep | 0 2 files changed, 9 insertions(+) create mode 100644 src/pymod/distutils_src/klayout/.gitignore create mode 100644 src/pymod/distutils_src/klayout/db_plugins/.keep diff --git a/src/pymod/distutils_src/klayout/.gitignore b/src/pymod/distutils_src/klayout/.gitignore new file mode 100644 index 000000000..4b1a6f02b --- /dev/null +++ b/src/pymod/distutils_src/klayout/.gitignore @@ -0,0 +1,9 @@ +### Python ### +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so +*.dylib diff --git a/src/pymod/distutils_src/klayout/db_plugins/.keep b/src/pymod/distutils_src/klayout/db_plugins/.keep new file mode 100644 index 000000000..e69de29bb