mirror of https://github.com/KLayout/klayout.git
Cherry-picked Python type hint enhancements from master
This commit is contained in:
parent
c9c9d6198b
commit
c012bb846e
|
|
@ -68,3 +68,5 @@ dist/
|
|||
# Macos artifacts
|
||||
*.dmg
|
||||
*.dmg.md5
|
||||
.DS_Store
|
||||
|
||||
|
|
|
|||
634
setup.py
634
setup.py
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
"""
|
||||
|
||||
KLayout standalone Python module setup script
|
||||
|
|
@ -55,6 +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 typing import List
|
||||
from setuptools import setup, Distribution, find_packages
|
||||
from setuptools.extension import Extension, Library
|
||||
import glob
|
||||
|
|
@ -70,17 +70,28 @@ import multiprocessing
|
|||
# for Jenkins we do not want to be greedy
|
||||
multicore = os.getenv("KLAYOUT_SETUP_MULTICORE")
|
||||
if multicore:
|
||||
N_cores = int(multicore)
|
||||
N_cores = int(multicore)
|
||||
else:
|
||||
N_cores = multiprocessing.cpu_count()
|
||||
N_cores = multiprocessing.cpu_count()
|
||||
|
||||
|
||||
# monkey-patch for parallel compilation
|
||||
# from https://stackoverflow.com/questions/11013851/speeding-up-build-process-with-distutils
|
||||
def parallelCCompile(self, sources, output_dir=None, macros=None, include_dirs=None, debug=0, extra_preargs=None, extra_postargs=None, depends=None):
|
||||
def parallelCCompile(
|
||||
self,
|
||||
sources,
|
||||
output_dir=None,
|
||||
macros=None,
|
||||
include_dirs=None,
|
||||
debug=0,
|
||||
extra_preargs=None,
|
||||
extra_postargs=None,
|
||||
depends=None,
|
||||
):
|
||||
# those lines are copied from distutils.ccompiler.CCompiler directly
|
||||
macros, objects, extra_postargs, pp_opts, build = self._setup_compile(
|
||||
output_dir, macros, include_dirs, sources, depends, extra_postargs)
|
||||
output_dir, macros, include_dirs, sources, depends, extra_postargs
|
||||
)
|
||||
cc_args = self._get_cc_args(pp_opts, debug, extra_preargs)
|
||||
# parallel code
|
||||
|
||||
|
|
@ -104,6 +115,7 @@ def parallelCCompile(self, sources, output_dir=None, macros=None, include_dirs=N
|
|||
print("Building", obj, "has failed. Trying again.")
|
||||
else:
|
||||
break
|
||||
|
||||
# convert to list, imap is evaluated on-demand
|
||||
list(multiprocessing.pool.ThreadPool(N).map(_single_compile, objects))
|
||||
return objects
|
||||
|
|
@ -112,6 +124,7 @@ def parallelCCompile(self, sources, output_dir=None, macros=None, include_dirs=N
|
|||
# only if python version > 2.6, somehow the travis compiler hangs in 2.6
|
||||
if sys.version_info[0] * 100 + sys.version_info[1] > 206:
|
||||
import distutils.ccompiler
|
||||
|
||||
distutils.ccompiler.CCompiler.compile = parallelCCompile
|
||||
|
||||
|
||||
|
|
@ -119,7 +132,7 @@ if sys.version_info[0] * 100 + sys.version_info[1] > 206:
|
|||
def quote_path(path):
|
||||
# looks like disutils don't need path quoting in version >= 3.9:
|
||||
if " " in path and sys.version_info[0] * 100 + sys.version_info[1] < 309:
|
||||
return "\"" + path + "\""
|
||||
return '"' + path + '"'
|
||||
else:
|
||||
return path
|
||||
|
||||
|
|
@ -127,6 +140,7 @@ def quote_path(path):
|
|||
# TODO: delete (Obsolete)
|
||||
# patch get_ext_filename
|
||||
from distutils.command.build_ext import build_ext
|
||||
|
||||
_old_get_ext_filename = build_ext.get_ext_filename
|
||||
|
||||
|
||||
|
|
@ -137,8 +151,8 @@ def patched_get_ext_filename(self, ext_name):
|
|||
"""
|
||||
filename = _old_get_ext_filename(self, ext_name)
|
||||
# Making sure this matches qmake's default extension .dylib, instead of .so
|
||||
if platform.system() == "Darwin" and '_dbpi' in ext_name:
|
||||
filename = filename.replace('.so', '.dylib')
|
||||
if platform.system() == "Darwin" and "_dbpi" in ext_name:
|
||||
filename = filename.replace(".so", ".dylib")
|
||||
return filename
|
||||
|
||||
|
||||
|
|
@ -152,15 +166,18 @@ distutils.command.build_ext.build_ext.get_ext_filename = patched_get_ext_filenam
|
|||
# hence the patch
|
||||
|
||||
from distutils.ccompiler import CCompiler
|
||||
|
||||
old_library_filename = CCompiler.library_filename
|
||||
|
||||
|
||||
def patched_library_filename(self, libname, lib_type='static', # or 'shared'
|
||||
strip_dir=0, output_dir=''):
|
||||
if platform.system() == "Darwin" and '_dbpi' in libname:
|
||||
lib_type = 'dylib'
|
||||
return old_library_filename(self, libname, lib_type=lib_type,
|
||||
strip_dir=strip_dir, output_dir=output_dir)
|
||||
def patched_library_filename(
|
||||
self, libname, lib_type="static", strip_dir=0, output_dir="" # or 'shared'
|
||||
):
|
||||
if platform.system() == "Darwin" and "_dbpi" in libname:
|
||||
lib_type = "dylib"
|
||||
return old_library_filename(
|
||||
self, libname, lib_type=lib_type, strip_dir=strip_dir, output_dir=output_dir
|
||||
)
|
||||
|
||||
|
||||
distutils.ccompiler.CCompiler.library_filename = patched_library_filename
|
||||
|
|
@ -172,16 +189,36 @@ distutils.ccompiler.CCompiler.library_filename = patched_library_filename
|
|||
# link a shared object on Linux, but a static library and patches distutils
|
||||
# for this ... We're patching this back now.
|
||||
|
||||
|
||||
def always_link_shared_object(
|
||||
self, objects, output_libname, output_dir=None, libraries=None,
|
||||
library_dirs=None, runtime_library_dirs=None, export_symbols=None,
|
||||
debug=0, extra_preargs=None, extra_postargs=None, build_temp=None,
|
||||
target_lang=None):
|
||||
self,
|
||||
objects,
|
||||
output_libname,
|
||||
output_dir=None,
|
||||
libraries=None,
|
||||
library_dirs=None,
|
||||
runtime_library_dirs=None,
|
||||
export_symbols=None,
|
||||
debug=0,
|
||||
extra_preargs=None,
|
||||
extra_postargs=None,
|
||||
build_temp=None,
|
||||
target_lang=None,
|
||||
):
|
||||
self.link(
|
||||
self.SHARED_LIBRARY, objects, output_libname,
|
||||
output_dir, libraries, library_dirs, runtime_library_dirs,
|
||||
export_symbols, debug, extra_preargs, extra_postargs,
|
||||
build_temp, target_lang
|
||||
self.SHARED_LIBRARY,
|
||||
objects,
|
||||
output_libname,
|
||||
output_dir,
|
||||
libraries,
|
||||
library_dirs,
|
||||
runtime_library_dirs,
|
||||
export_symbols,
|
||||
debug,
|
||||
extra_preargs,
|
||||
extra_postargs,
|
||||
build_temp,
|
||||
target_lang,
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -201,7 +238,7 @@ class Config(object):
|
|||
|
||||
# TODO: is this really how we get the build paths?
|
||||
|
||||
build_cmd = Distribution().get_command_obj('build')
|
||||
build_cmd = Distribution().get_command_obj("build")
|
||||
build_cmd.finalize_options()
|
||||
self.build_platlib = build_cmd.build_platlib
|
||||
self.build_temp = build_cmd.build_temp
|
||||
|
|
@ -212,7 +249,7 @@ class Config(object):
|
|||
else:
|
||||
self.build_temp = os.path.join(self.build_temp, "Release")
|
||||
|
||||
build_ext_cmd = Distribution().get_command_obj('build_ext')
|
||||
build_ext_cmd = Distribution().get_command_obj("build_ext")
|
||||
|
||||
build_ext_cmd.initialize_options()
|
||||
build_ext_cmd.setup_shlib_compiler()
|
||||
|
|
@ -230,7 +267,7 @@ class Config(object):
|
|||
This code was extracted from the source in setuptools.command.build_ext.build_ext
|
||||
"""
|
||||
libtype = setuptools.command.build_ext.libtype
|
||||
full_mod = self.root + '.' + mod
|
||||
full_mod = self.root + "." + mod
|
||||
if is_lib is True:
|
||||
# Here we are guessing it is a library and that the filename
|
||||
# is to be computed by shlib_compiler.
|
||||
|
|
@ -246,8 +283,8 @@ class Config(object):
|
|||
ext_filename = os.path.basename(ext_path)
|
||||
|
||||
# Exception for database plugins, which will always be dylib.
|
||||
if platform.system() == "Darwin" and '_dbpi' in mod:
|
||||
ext_filename = ext_filename.replace('.so', '.dylib')
|
||||
if platform.system() == "Darwin" and "_dbpi" in mod:
|
||||
ext_filename = ext_filename.replace(".so", ".dylib")
|
||||
return ext_filename
|
||||
|
||||
def path_of(self, mod, mod_src_path):
|
||||
|
|
@ -265,20 +302,25 @@ class Config(object):
|
|||
"""
|
||||
Gets additional compiler arguments
|
||||
"""
|
||||
args: List[str]
|
||||
if platform.system() == "Windows":
|
||||
bits = os.getenv("KLAYOUT_BITS")
|
||||
if bits:
|
||||
return [quote_path("-I" + os.path.join(bits, "zlib", "include")),
|
||||
quote_path("-I" + os.path.join(bits, "ptw", "include")),
|
||||
quote_path("-I" + os.path.join(bits, "png", "include")),
|
||||
quote_path("-I" + os.path.join(bits, "expat", "include")),
|
||||
quote_path("-I" + os.path.join(bits, "curl", "include"))]
|
||||
args = [
|
||||
quote_path("-I" + os.path.join(bits, "zlib", "include")),
|
||||
quote_path("-I" + os.path.join(bits, "ptw", "include")),
|
||||
quote_path("-I" + os.path.join(bits, "png", "include")),
|
||||
quote_path("-I" + os.path.join(bits, "expat", "include")),
|
||||
quote_path("-I" + os.path.join(bits, "curl", "include")),
|
||||
]
|
||||
else:
|
||||
return []
|
||||
args = []
|
||||
else:
|
||||
return ["-Wno-strict-aliasing", # Avoids many "type-punned pointer" warnings
|
||||
"-std=c++11", # because we use unordered_map/unordered_set
|
||||
]
|
||||
args = [
|
||||
"-Wno-strict-aliasing", # Avoids many "type-punned pointer" warnings
|
||||
"-std=c++11", # because we use unordered_map/unordered_set
|
||||
]
|
||||
return args
|
||||
|
||||
def libraries(self, mod):
|
||||
"""
|
||||
|
|
@ -286,10 +328,10 @@ class Config(object):
|
|||
"""
|
||||
if platform.system() == "Windows":
|
||||
if mod == "_tl":
|
||||
return [ "libcurl", "expat", "pthreadVCE2", "zlib", "wsock32", "libpng16" ]
|
||||
return ["libcurl", "expat", "pthreadVCE2", "zlib", "wsock32", "libpng16"]
|
||||
else:
|
||||
if mod == "_tl":
|
||||
return [ "curl", "expat", "png" ]
|
||||
return ["curl", "expat", "png"]
|
||||
return []
|
||||
|
||||
def link_args(self, mod):
|
||||
|
|
@ -300,19 +342,24 @@ class Config(object):
|
|||
args = ["/DLL"]
|
||||
bits = os.getenv("KLAYOUT_BITS")
|
||||
if bits:
|
||||
args += [quote_path("/LIBPATH:" + os.path.join(bits, "zlib", "lib")),
|
||||
quote_path("/LIBPATH:" + os.path.join(bits, "ptw", "libraries")),
|
||||
quote_path("/LIBPATH:" + os.path.join(bits, "png", "libraries")),
|
||||
quote_path("/LIBPATH:" + os.path.join(bits, "expat", "libraries")),
|
||||
quote_path("/LIBPATH:" + os.path.join(bits, "curl", "libraries"))]
|
||||
args += [
|
||||
quote_path("/LIBPATH:" + os.path.join(bits, "zlib", "libraries")),
|
||||
quote_path("/LIBPATH:" + os.path.join(bits, "ptw", "libraries")),
|
||||
quote_path("/LIBPATH:" + os.path.join(bits, "png", "libraries")),
|
||||
quote_path("/LIBPATH:" + os.path.join(bits, "expat", "libraries")),
|
||||
quote_path("/LIBPATH:" + os.path.join(bits, "curl", "libraries")),
|
||||
]
|
||||
return args
|
||||
elif platform.system() == "Darwin":
|
||||
# For the dependency modules, make sure we produce a dylib.
|
||||
# We can only link against such, but the bundles produced otherwise.
|
||||
args = []
|
||||
if mod[0] == "_":
|
||||
args += ["-Wl,-dylib", '-Wl,-install_name,@rpath/%s' % self.libname_of(mod, is_lib=True)]
|
||||
args += ['-Wl,-rpath,@loader_path/']
|
||||
args += [
|
||||
"-Wl,-dylib",
|
||||
"-Wl,-install_name,@rpath/%s" % self.libname_of(mod, is_lib=True),
|
||||
]
|
||||
args += ["-Wl,-rpath,@loader_path/"]
|
||||
return args
|
||||
else:
|
||||
# this makes the libraries suitable for linking with a path -
|
||||
|
|
@ -321,23 +368,30 @@ class Config(object):
|
|||
# will look for the path-qualified library. But that's the
|
||||
# build path and the loader will fail.
|
||||
args = []
|
||||
args += ['-Wl,-soname,' + self.libname_of(mod, is_lib=True)]
|
||||
if '_dbpi' not in mod:
|
||||
loader_path = '$ORIGIN'
|
||||
args += ["-Wl,-soname," + self.libname_of(mod, is_lib=True)]
|
||||
if "_dbpi" not in mod:
|
||||
loader_path = "$ORIGIN"
|
||||
else:
|
||||
loader_path = '$ORIGIN/..'
|
||||
args += ['-Wl,-rpath,' + loader_path]
|
||||
loader_path = "$ORIGIN/.."
|
||||
args += ["-Wl,-rpath," + loader_path]
|
||||
# default linux shared object compilation uses the '-g' flag,
|
||||
# which generates unnecessary debug information
|
||||
# removing with strip-all during the linking stage
|
||||
args += ['-Wl,--strip-all']
|
||||
args += ["-Wl,--strip-all"]
|
||||
return args
|
||||
|
||||
def macros(self):
|
||||
"""
|
||||
Returns the macros to use for building
|
||||
"""
|
||||
return [('HAVE_PNG', 1), ('HAVE_CURL', 1), ('HAVE_EXPAT', 1), ('KLAYOUT_MAJOR_VERSION', self.major_version()), ('KLAYOUT_MINOR_VERSION', self.minor_version())]
|
||||
return [
|
||||
("HAVE_PNG", 1),
|
||||
("HAVE_CURL", 1),
|
||||
("HAVE_EXPAT", 1),
|
||||
("KLAYOUT_MAJOR_VERSION", self.major_version()),
|
||||
("KLAYOUT_MINOR_VERSION", self.minor_version()),
|
||||
("GSI_ALIAS_INSPECT", 1),
|
||||
]
|
||||
|
||||
def minor_version(self):
|
||||
"""
|
||||
|
|
@ -349,7 +403,9 @@ class Config(object):
|
|||
version_file = os.path.join(os.path.dirname(__file__), "version.sh")
|
||||
with open(version_file, "r") as file:
|
||||
version_txt = file.read()
|
||||
rm = re.search(r"KLAYOUT_VERSION\s*=\s*\"(.*?)\.(.*?)(\..*)?\".*", version_txt)
|
||||
rm = re.search(
|
||||
r"KLAYOUT_VERSION\s*=\s*\"(.*?)\.(.*?)(\..*)?\".*", version_txt
|
||||
)
|
||||
if rm:
|
||||
version_string = rm.group(2)
|
||||
return version_string
|
||||
|
|
@ -366,7 +422,9 @@ class Config(object):
|
|||
version_file = os.path.join(os.path.dirname(__file__), "version.sh")
|
||||
with open(version_file, "r") as file:
|
||||
version_txt = file.read()
|
||||
rm = re.search(r"KLAYOUT_VERSION\s*=\s*\"(.*?)\.(.*?)(\..*)?\".*", version_txt)
|
||||
rm = re.search(
|
||||
r"KLAYOUT_VERSION\s*=\s*\"(.*?)\.(.*?)(\..*)?\".*", version_txt
|
||||
)
|
||||
if rm:
|
||||
version_string = rm.group(1)
|
||||
return version_string
|
||||
|
|
@ -407,13 +465,15 @@ _tl_sources.discard(os.path.join(_tl_path, "tlHttpStreamNoQt.cc"))
|
|||
_tl_sources.discard(os.path.join(_tl_path, "tlFileSystemWatcher.cc"))
|
||||
_tl_sources.discard(os.path.join(_tl_path, "tlDeferredExecutionQt.cc"))
|
||||
|
||||
_tl = Library(config.root + '._tl',
|
||||
define_macros=config.macros() + [('MAKE_TL_LIBRARY', 1)],
|
||||
language='c++',
|
||||
libraries=config.libraries('_tl'),
|
||||
extra_link_args=config.link_args('_tl'),
|
||||
extra_compile_args=config.compile_args('_tl'),
|
||||
sources=list(_tl_sources))
|
||||
_tl = Library(
|
||||
config.root + "._tl",
|
||||
define_macros=config.macros() + [("MAKE_TL_LIBRARY", 1)],
|
||||
language="c++",
|
||||
libraries=config.libraries("_tl"),
|
||||
extra_link_args=config.link_args("_tl"),
|
||||
extra_compile_args=config.compile_args("_tl"),
|
||||
sources=list(_tl_sources),
|
||||
)
|
||||
|
||||
config.add_extension(_tl)
|
||||
|
||||
|
|
@ -423,15 +483,17 @@ config.add_extension(_tl)
|
|||
_gsi_path = os.path.join("src", "gsi", "gsi")
|
||||
_gsi_sources = set(glob.glob(os.path.join(_gsi_path, "*.cc")))
|
||||
|
||||
_gsi = Library(config.root + '._gsi',
|
||||
define_macros=config.macros() + [('MAKE_GSI_LIBRARY', 1)],
|
||||
include_dirs=[_tl_path],
|
||||
extra_objects=[config.path_of('_tl', _tl_path)],
|
||||
language='c++',
|
||||
libraries=config.libraries('_gsi'),
|
||||
extra_link_args=config.link_args('_gsi'),
|
||||
extra_compile_args=config.compile_args('_gsi'),
|
||||
sources=list(_gsi_sources))
|
||||
_gsi = Library(
|
||||
config.root + "._gsi",
|
||||
define_macros=config.macros() + [("MAKE_GSI_LIBRARY", 1)],
|
||||
include_dirs=[_tl_path],
|
||||
extra_objects=[config.path_of("_tl", _tl_path)],
|
||||
language="c++",
|
||||
libraries=config.libraries('_gsi'),
|
||||
extra_link_args=config.link_args("_gsi"),
|
||||
extra_compile_args=config.compile_args("_gsi"),
|
||||
sources=list(_gsi_sources),
|
||||
)
|
||||
config.add_extension(_gsi)
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
|
|
@ -440,15 +502,17 @@ config.add_extension(_gsi)
|
|||
_pya_path = os.path.join("src", "pya", "pya")
|
||||
_pya_sources = set(glob.glob(os.path.join(_pya_path, "*.cc")))
|
||||
|
||||
_pya = Library(config.root + '._pya',
|
||||
define_macros=config.macros() + [('MAKE_PYA_LIBRARY', 1)],
|
||||
include_dirs=[_tl_path, _gsi_path],
|
||||
extra_objects=[config.path_of('_tl', _tl_path), config.path_of('_gsi', _gsi_path)],
|
||||
language='c++',
|
||||
libraries=config.libraries('_pya'),
|
||||
extra_link_args=config.link_args('_pya'),
|
||||
extra_compile_args=config.compile_args('_pya'),
|
||||
sources=list(_pya_sources))
|
||||
_pya = Library(
|
||||
config.root + "._pya",
|
||||
define_macros=config.macros() + [("MAKE_PYA_LIBRARY", 1)],
|
||||
include_dirs=[_tl_path, _gsi_path],
|
||||
extra_objects=[config.path_of("_tl", _tl_path), config.path_of("_gsi", _gsi_path)],
|
||||
language="c++",
|
||||
libraries=config.libraries('_pya'),
|
||||
extra_link_args=config.link_args("_pya"),
|
||||
extra_compile_args=config.compile_args("_pya"),
|
||||
sources=list(_pya_sources),
|
||||
)
|
||||
config.add_extension(_pya)
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
|
|
@ -457,15 +521,17 @@ config.add_extension(_pya)
|
|||
_rba_path = os.path.join("src", "rbastub")
|
||||
_rba_sources = set(glob.glob(os.path.join(_rba_path, "*.cc")))
|
||||
|
||||
_rba = Library(config.root + '._rba',
|
||||
define_macros=config.macros() + [('MAKE_RBA_LIBRARY', 1)],
|
||||
include_dirs=[_tl_path, _gsi_path],
|
||||
extra_objects=[config.path_of('_tl', _tl_path), config.path_of('_gsi', _gsi_path)],
|
||||
language='c++',
|
||||
libraries=config.libraries('_rba'),
|
||||
extra_link_args=config.link_args('_rba'),
|
||||
extra_compile_args=config.compile_args('_rba'),
|
||||
sources=list(_rba_sources))
|
||||
_rba = Library(
|
||||
config.root + '._rba',
|
||||
define_macros=config.macros() + [('MAKE_RBA_LIBRARY', 1)],
|
||||
include_dirs=[_tl_path, _gsi_path],
|
||||
extra_objects=[config.path_of('_tl', _tl_path), config.path_of('_gsi', _gsi_path)],
|
||||
language='c++',
|
||||
libraries=config.libraries('_rba'),
|
||||
extra_link_args=config.link_args('_rba'),
|
||||
extra_compile_args=config.compile_args('_rba'),
|
||||
sources=list(_rba_sources)
|
||||
)
|
||||
config.add_extension(_rba)
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
|
|
@ -474,15 +540,17 @@ config.add_extension(_rba)
|
|||
_db_path = os.path.join("src", "db", "db")
|
||||
_db_sources = set(glob.glob(os.path.join(_db_path, "*.cc")))
|
||||
|
||||
_db = Library(config.root + '._db',
|
||||
define_macros=config.macros() + [('MAKE_DB_LIBRARY', 1)],
|
||||
include_dirs=[_tl_path, _gsi_path, _db_path],
|
||||
extra_objects=[config.path_of('_tl', _tl_path), config.path_of('_gsi', _gsi_path)],
|
||||
language='c++',
|
||||
libraries=config.libraries('_db'),
|
||||
extra_link_args=config.link_args('_db'),
|
||||
extra_compile_args=config.compile_args('_db'),
|
||||
sources=list(_db_sources))
|
||||
_db = Library(
|
||||
config.root + "._db",
|
||||
define_macros=config.macros() + [("MAKE_DB_LIBRARY", 1)],
|
||||
include_dirs=[_tl_path, _gsi_path, _db_path],
|
||||
extra_objects=[config.path_of("_tl", _tl_path), config.path_of("_gsi", _gsi_path)],
|
||||
language="c++",
|
||||
libraries=config.libraries('_db'),
|
||||
extra_link_args=config.link_args("_db"),
|
||||
extra_compile_args=config.compile_args("_db"),
|
||||
sources=list(_db_sources),
|
||||
)
|
||||
config.add_extension(_db)
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
|
|
@ -491,15 +559,21 @@ config.add_extension(_db)
|
|||
_lib_path = os.path.join("src", "lib", "lib")
|
||||
_lib_sources = set(glob.glob(os.path.join(_lib_path, "*.cc")))
|
||||
|
||||
_lib = Library(config.root + '._lib',
|
||||
define_macros=config.macros() + [('MAKE_LIB_LIBRARY', 1)],
|
||||
include_dirs=[_tl_path, _gsi_path, _db_path, _lib_path],
|
||||
extra_objects=[config.path_of('_tl', _tl_path), config.path_of('_gsi', _gsi_path), config.path_of('_db', _db_path)],
|
||||
language='c++',
|
||||
libraries=config.libraries('_lib'),
|
||||
extra_link_args=config.link_args('_lib'),
|
||||
extra_compile_args=config.compile_args('_lib'),
|
||||
sources=list(_lib_sources))
|
||||
_lib = Library(
|
||||
config.root + "._lib",
|
||||
define_macros=config.macros() + [("MAKE_LIB_LIBRARY", 1)],
|
||||
include_dirs=[_tl_path, _gsi_path, _db_path, _lib_path],
|
||||
extra_objects=[
|
||||
config.path_of("_tl", _tl_path),
|
||||
config.path_of("_gsi", _gsi_path),
|
||||
config.path_of("_db", _db_path),
|
||||
],
|
||||
language="c++",
|
||||
libraries=config.libraries('_lib'),
|
||||
extra_link_args=config.link_args("_lib"),
|
||||
extra_compile_args=config.compile_args("_lib"),
|
||||
sources=list(_lib_sources),
|
||||
)
|
||||
config.add_extension(_lib)
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
|
|
@ -508,15 +582,21 @@ config.add_extension(_lib)
|
|||
_rdb_path = os.path.join("src", "rdb", "rdb")
|
||||
_rdb_sources = set(glob.glob(os.path.join(_rdb_path, "*.cc")))
|
||||
|
||||
_rdb = Library(config.root + '._rdb',
|
||||
define_macros=config.macros() + [('MAKE_RDB_LIBRARY', 1)],
|
||||
include_dirs=[_db_path, _tl_path, _gsi_path],
|
||||
extra_objects=[config.path_of('_tl', _tl_path), config.path_of('_gsi', _gsi_path), config.path_of('_db', _db_path)],
|
||||
language='c++',
|
||||
libraries=config.libraries('_rdb'),
|
||||
extra_link_args=config.link_args('_rdb'),
|
||||
extra_compile_args=config.compile_args('_rdb'),
|
||||
sources=list(_rdb_sources))
|
||||
_rdb = Library(
|
||||
config.root + "._rdb",
|
||||
define_macros=config.macros() + [("MAKE_RDB_LIBRARY", 1)],
|
||||
include_dirs=[_db_path, _tl_path, _gsi_path],
|
||||
extra_objects=[
|
||||
config.path_of("_tl", _tl_path),
|
||||
config.path_of("_gsi", _gsi_path),
|
||||
config.path_of("_db", _db_path),
|
||||
],
|
||||
language="c++",
|
||||
libraries=config.libraries('_rdb'),
|
||||
extra_link_args=config.link_args("_rdb"),
|
||||
extra_compile_args=config.compile_args("_rdb"),
|
||||
sources=list(_rdb_sources),
|
||||
)
|
||||
config.add_extension(_rdb)
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
|
|
@ -525,15 +605,22 @@ config.add_extension(_rdb)
|
|||
_laybasic_path = os.path.join("src", "laybasic", "laybasic")
|
||||
_laybasic_sources = set(glob.glob(os.path.join(_laybasic_path, "*.cc")))
|
||||
|
||||
_laybasic = Library(config.root + '._laybasic',
|
||||
define_macros=config.macros() + [('MAKE_LAYBASIC_LIBRARY', 1)],
|
||||
include_dirs=[_rdb_path, _db_path, _tl_path, _gsi_path],
|
||||
extra_objects=[config.path_of('_rdb', _rdb_path), config.path_of('_tl', _tl_path), config.path_of('_gsi', _gsi_path), config.path_of('_db', _db_path)],
|
||||
language='c++',
|
||||
libraries=config.libraries('_laybasic'),
|
||||
extra_link_args=config.link_args('_laybasic'),
|
||||
extra_compile_args=config.compile_args('_laybasic'),
|
||||
sources=list(_laybasic_sources))
|
||||
_laybasic = Library(
|
||||
config.root + '._laybasic',
|
||||
define_macros=config.macros() + [('MAKE_LAYBASIC_LIBRARY', 1)],
|
||||
include_dirs=[_rdb_path, _db_path, _tl_path, _gsi_path],
|
||||
extra_objects=[
|
||||
config.path_of('_rdb', _rdb_path),
|
||||
config.path_of('_tl', _tl_path),
|
||||
config.path_of('_gsi', _gsi_path),
|
||||
config.path_of('_db', _db_path)
|
||||
],
|
||||
language='c++',
|
||||
libraries=config.libraries('_laybasic'),
|
||||
extra_link_args=config.link_args('_laybasic'),
|
||||
extra_compile_args=config.compile_args('_laybasic'),
|
||||
sources=list(_laybasic_sources)
|
||||
)
|
||||
config.add_extension(_laybasic)
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
|
|
@ -542,15 +629,23 @@ config.add_extension(_laybasic)
|
|||
_layview_path = os.path.join("src", "layview", "layview")
|
||||
_layview_sources = set(glob.glob(os.path.join(_layview_path, "*.cc")))
|
||||
|
||||
_layview = Library(config.root + '._layview',
|
||||
define_macros=config.macros() + [('MAKE_LAYVIEW_LIBRARY', 1)],
|
||||
include_dirs=[_laybasic_path, _rdb_path, _db_path, _tl_path, _gsi_path],
|
||||
extra_objects=[config.path_of('_laybasic', _laybasic_path), config.path_of('_rdb', _rdb_path), config.path_of('_tl', _tl_path), config.path_of('_gsi', _gsi_path), config.path_of('_db', _db_path)],
|
||||
language='c++',
|
||||
libraries=config.libraries('_layview'),
|
||||
extra_link_args=config.link_args('_layview'),
|
||||
extra_compile_args=config.compile_args('_layview'),
|
||||
sources=list(_layview_sources))
|
||||
_layview = Library(
|
||||
config.root + '._layview',
|
||||
define_macros=config.macros() + [('MAKE_LAYVIEW_LIBRARY', 1)],
|
||||
include_dirs=[_laybasic_path, _rdb_path, _db_path, _tl_path, _gsi_path],
|
||||
extra_objects=[
|
||||
config.path_of('_laybasic', _laybasic_path),
|
||||
config.path_of('_rdb', _rdb_path),
|
||||
config.path_of('_tl', _tl_path),
|
||||
config.path_of('_gsi', _gsi_path),
|
||||
config.path_of('_db', _db_path)
|
||||
],
|
||||
language='c++',
|
||||
libraries=config.libraries('_layview'),
|
||||
extra_link_args=config.link_args('_layview'),
|
||||
extra_compile_args=config.compile_args('_layview'),
|
||||
sources=list(_layview_sources)
|
||||
)
|
||||
config.add_extension(_layview)
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
|
|
@ -559,15 +654,22 @@ config.add_extension(_layview)
|
|||
_lym_path = os.path.join("src", "lym", "lym")
|
||||
_lym_sources = set(glob.glob(os.path.join(_lym_path, "*.cc")))
|
||||
|
||||
_lym = Library(config.root + '._lym',
|
||||
define_macros=config.macros() + [('MAKE_LYM_LIBRARY', 1)],
|
||||
include_dirs=[_pya_path, _rba_path, _tl_path, _gsi_path],
|
||||
extra_objects=[config.path_of('_rba', _rba_path), config.path_of('_pya', _pya_path), config.path_of('_tl', _tl_path), config.path_of('_gsi', _gsi_path)],
|
||||
language='c++',
|
||||
libraries=config.libraries('_lym'),
|
||||
extra_link_args=config.link_args('_lym'),
|
||||
extra_compile_args=config.compile_args('_lym'),
|
||||
sources=list(_lym_sources))
|
||||
_lym = Library(
|
||||
config.root + '._lym',
|
||||
define_macros=config.macros() + [('MAKE_LYM_LIBRARY', 1)],
|
||||
include_dirs=[_pya_path, _rba_path, _tl_path, _gsi_path],
|
||||
extra_objects=[
|
||||
config.path_of('_rba', _rba_path),
|
||||
config.path_of('_pya', _pya_path),
|
||||
config.path_of('_tl', _tl_path),
|
||||
config.path_of('_gsi', _gsi_path)
|
||||
],
|
||||
language='c++',
|
||||
libraries=config.libraries('_lym'),
|
||||
extra_link_args=config.link_args('_lym'),
|
||||
extra_compile_args=config.compile_args('_lym'),
|
||||
sources=list(_lym_sources)
|
||||
)
|
||||
config.add_extension(_lym)
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
|
|
@ -576,15 +678,24 @@ config.add_extension(_lym)
|
|||
_ant_path = os.path.join("src", "ant", "ant")
|
||||
_ant_sources = set(glob.glob(os.path.join(_ant_path, "*.cc")))
|
||||
|
||||
_ant = Library(config.root + '._ant',
|
||||
define_macros=config.macros() + [('MAKE_ANT_LIBRARY', 1)],
|
||||
include_dirs=[_laybasic_path, _layview_path, _rdb_path, _db_path, _tl_path, _gsi_path],
|
||||
extra_objects=[config.path_of('_laybasic', _laybasic_path), config.path_of('_layview', _layview_path), config.path_of('_rdb', _rdb_path), config.path_of('_tl', _tl_path), config.path_of('_gsi', _gsi_path), config.path_of('_db', _db_path)],
|
||||
language='c++',
|
||||
libraries=config.libraries('_ant'),
|
||||
extra_link_args=config.link_args('_ant'),
|
||||
extra_compile_args=config.compile_args('_ant'),
|
||||
sources=list(_ant_sources))
|
||||
_ant = Library(
|
||||
config.root + '._ant',
|
||||
define_macros=config.macros() + [('MAKE_ANT_LIBRARY', 1)],
|
||||
include_dirs=[_laybasic_path, _layview_path, _rdb_path, _db_path, _tl_path, _gsi_path],
|
||||
extra_objects=[
|
||||
config.path_of('_laybasic', _laybasic_path),
|
||||
config.path_of('_layview', _layview_path),
|
||||
config.path_of('_rdb', _rdb_path),
|
||||
config.path_of('_tl', _tl_path),
|
||||
config.path_of('_gsi', _gsi_path),
|
||||
config.path_of('_db', _db_path)
|
||||
],
|
||||
language='c++',
|
||||
libraries=config.libraries('_ant'),
|
||||
extra_link_args=config.link_args('_ant'),
|
||||
extra_compile_args=config.compile_args('_ant'),
|
||||
sources=list(_ant_sources)
|
||||
)
|
||||
config.add_extension(_ant)
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
|
|
@ -593,15 +704,24 @@ config.add_extension(_ant)
|
|||
_img_path = os.path.join("src", "img", "img")
|
||||
_img_sources = set(glob.glob(os.path.join(_img_path, "*.cc")))
|
||||
|
||||
_img = Library(config.root + '._img',
|
||||
define_macros=config.macros() + [('MAKE_IMG_LIBRARY', 1)],
|
||||
include_dirs=[_laybasic_path, _layview_path, _rdb_path, _db_path, _tl_path, _gsi_path],
|
||||
extra_objects=[config.path_of('_laybasic', _laybasic_path), config.path_of('_layview', _layview_path), config.path_of('_rdb', _rdb_path), config.path_of('_tl', _tl_path), config.path_of('_gsi', _gsi_path), config.path_of('_db', _db_path)],
|
||||
language='c++',
|
||||
libraries=config.libraries('_img'),
|
||||
extra_link_args=config.link_args('_img'),
|
||||
extra_compile_args=config.compile_args('_img'),
|
||||
sources=list(_img_sources))
|
||||
_img = Library(
|
||||
config.root + '._img',
|
||||
define_macros=config.macros() + [('MAKE_IMG_LIBRARY', 1)],
|
||||
include_dirs=[_laybasic_path, _layview_path, _rdb_path, _db_path, _tl_path, _gsi_path],
|
||||
extra_objects=[
|
||||
config.path_of('_laybasic', _laybasic_path),
|
||||
config.path_of('_layview', _layview_path),
|
||||
config.path_of('_rdb', _rdb_path),
|
||||
config.path_of('_tl', _tl_path),
|
||||
config.path_of('_gsi', _gsi_path),
|
||||
config.path_of('_db', _db_path)
|
||||
],
|
||||
language='c++',
|
||||
libraries=config.libraries('_img'),
|
||||
extra_link_args=config.link_args('_img'),
|
||||
extra_compile_args=config.compile_args('_img'),
|
||||
sources=list(_img_sources)
|
||||
)
|
||||
config.add_extension(_img)
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
|
|
@ -610,15 +730,24 @@ config.add_extension(_img)
|
|||
_edt_path = os.path.join("src", "edt", "edt")
|
||||
_edt_sources = set(glob.glob(os.path.join(_edt_path, "*.cc")))
|
||||
|
||||
_edt = Library(config.root + '._edt',
|
||||
define_macros=config.macros() + [('MAKE_EDT_LIBRARY', 1)],
|
||||
include_dirs=[_laybasic_path, _layview_path, _rdb_path, _db_path, _tl_path, _gsi_path],
|
||||
extra_objects=[config.path_of('_laybasic', _laybasic_path), config.path_of('_layview', _layview_path), config.path_of('_rdb', _rdb_path), config.path_of('_tl', _tl_path), config.path_of('_gsi', _gsi_path), config.path_of('_db', _db_path)],
|
||||
language='c++',
|
||||
libraries=config.libraries('_edt'),
|
||||
extra_link_args=config.link_args('_edt'),
|
||||
extra_compile_args=config.compile_args('_edt'),
|
||||
sources=list(_edt_sources))
|
||||
_edt = Library(
|
||||
config.root + '._edt',
|
||||
define_macros=config.macros() + [('MAKE_EDT_LIBRARY', 1)],
|
||||
include_dirs=[_laybasic_path, _layview_path, _rdb_path, _db_path, _tl_path, _gsi_path],
|
||||
extra_objects=[
|
||||
config.path_of('_laybasic', _laybasic_path),
|
||||
config.path_of('_layview', _layview_path),
|
||||
config.path_of('_rdb', _rdb_path),
|
||||
config.path_of('_tl', _tl_path),
|
||||
config.path_of('_gsi', _gsi_path),
|
||||
config.path_of('_db', _db_path)
|
||||
],
|
||||
language='c++',
|
||||
libraries=config.libraries('_edt'),
|
||||
extra_link_args=config.link_args('_edt'),
|
||||
extra_compile_args=config.compile_args('_edt'),
|
||||
sources=list(_edt_sources)
|
||||
)
|
||||
config.add_extension(_edt)
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
|
|
@ -635,15 +764,25 @@ for pi in dbpi_dirs:
|
|||
|
||||
pi_sources = glob.glob(os.path.join(pi, "*.cc"))
|
||||
|
||||
pi_ext = Library(config.root + '.db_plugins.' + mod_name,
|
||||
define_macros=config.macros() + [('MAKE_DB_PLUGIN_LIBRARY', 1)],
|
||||
include_dirs=[os.path.join("src", "plugins", "common"),
|
||||
_db_path, _tl_path, _gsi_path],
|
||||
extra_objects=[config.path_of('_tl', _tl_path), config.path_of('_gsi', _gsi_path), config.path_of('_db', _db_path)],
|
||||
language='c++',
|
||||
extra_link_args=config.link_args(mod_name),
|
||||
extra_compile_args=config.compile_args(mod_name),
|
||||
sources=pi_sources)
|
||||
pi_ext = Library(
|
||||
config.root + ".db_plugins." + mod_name,
|
||||
define_macros=config.macros() + [("MAKE_DB_PLUGIN_LIBRARY", 1)],
|
||||
include_dirs=[
|
||||
os.path.join("src", "plugins", "common"),
|
||||
_db_path,
|
||||
_tl_path,
|
||||
_gsi_path,
|
||||
],
|
||||
extra_objects=[
|
||||
config.path_of("_tl", _tl_path),
|
||||
config.path_of("_gsi", _gsi_path),
|
||||
config.path_of("_db", _db_path),
|
||||
],
|
||||
language="c++",
|
||||
extra_link_args=config.link_args(mod_name),
|
||||
extra_compile_args=config.compile_args(mod_name),
|
||||
sources=pi_sources,
|
||||
)
|
||||
|
||||
db_plugins.append(pi_ext)
|
||||
config.add_extension(pi_ext)
|
||||
|
|
@ -654,13 +793,19 @@ for pi in dbpi_dirs:
|
|||
tl_path = os.path.join("src", "pymod", "tl")
|
||||
tl_sources = set(glob.glob(os.path.join(tl_path, "*.cc")))
|
||||
|
||||
tl = Extension(config.root + '.tlcore',
|
||||
define_macros=config.macros(),
|
||||
include_dirs=[_tl_path, _gsi_path, _pya_path],
|
||||
extra_objects=[config.path_of('_tl', _tl_path), config.path_of('_gsi', _gsi_path), config.path_of('_pya', _pya_path)],
|
||||
extra_link_args=config.link_args('tlcore'),
|
||||
extra_compile_args=config.compile_args('tlcore'),
|
||||
sources=list(tl_sources))
|
||||
tl = Extension(
|
||||
config.root + ".tlcore",
|
||||
define_macros=config.macros(),
|
||||
include_dirs=[_tl_path, _gsi_path, _pya_path],
|
||||
extra_objects=[
|
||||
config.path_of("_tl", _tl_path),
|
||||
config.path_of("_gsi", _gsi_path),
|
||||
config.path_of("_pya", _pya_path),
|
||||
],
|
||||
extra_link_args=config.link_args("tlcore"),
|
||||
extra_compile_args=config.compile_args("tlcore"),
|
||||
sources=list(tl_sources),
|
||||
)
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# db extension library
|
||||
|
|
@ -668,13 +813,20 @@ tl = Extension(config.root + '.tlcore',
|
|||
db_path = os.path.join("src", "pymod", "db")
|
||||
db_sources = set(glob.glob(os.path.join(db_path, "*.cc")))
|
||||
|
||||
db = Extension(config.root + '.dbcore',
|
||||
define_macros=config.macros(),
|
||||
include_dirs=[_db_path, _tl_path, _gsi_path, _pya_path],
|
||||
extra_objects=[config.path_of('_db', _db_path), config.path_of('_tl', _tl_path), config.path_of('_gsi', _gsi_path), config.path_of('_pya', _pya_path)],
|
||||
extra_link_args=config.link_args('dbcore'),
|
||||
extra_compile_args=config.compile_args('dbcore'),
|
||||
sources=list(db_sources))
|
||||
db = Extension(
|
||||
config.root + ".dbcore",
|
||||
define_macros=config.macros(),
|
||||
include_dirs=[_db_path, _tl_path, _gsi_path, _pya_path],
|
||||
extra_objects=[
|
||||
config.path_of("_db", _db_path),
|
||||
config.path_of("_tl", _tl_path),
|
||||
config.path_of("_gsi", _gsi_path),
|
||||
config.path_of("_pya", _pya_path),
|
||||
],
|
||||
extra_link_args=config.link_args("dbcore"),
|
||||
extra_compile_args=config.compile_args("dbcore"),
|
||||
sources=list(db_sources),
|
||||
)
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# lib extension library
|
||||
|
|
@ -682,13 +834,20 @@ db = Extension(config.root + '.dbcore',
|
|||
lib_path = os.path.join("src", "pymod", "lib")
|
||||
lib_sources = set(glob.glob(os.path.join(lib_path, "*.cc")))
|
||||
|
||||
lib = Extension(config.root + '.libcore',
|
||||
define_macros=config.macros(),
|
||||
include_dirs=[_lib_path, _tl_path, _gsi_path, _pya_path],
|
||||
extra_objects=[config.path_of('_lib', _lib_path), config.path_of('_tl', _tl_path), config.path_of('_gsi', _gsi_path), config.path_of('_pya', _pya_path)],
|
||||
extra_link_args=config.link_args('libcore'),
|
||||
extra_compile_args=config.compile_args('libcore'),
|
||||
sources=list(lib_sources))
|
||||
lib = Extension(
|
||||
config.root + ".libcore",
|
||||
define_macros=config.macros(),
|
||||
include_dirs=[_lib_path, _tl_path, _gsi_path, _pya_path],
|
||||
extra_objects=[
|
||||
config.path_of("_lib", _lib_path),
|
||||
config.path_of("_tl", _tl_path),
|
||||
config.path_of("_gsi", _gsi_path),
|
||||
config.path_of("_pya", _pya_path),
|
||||
],
|
||||
extra_link_args=config.link_args("libcore"),
|
||||
extra_compile_args=config.compile_args("libcore"),
|
||||
sources=list(lib_sources),
|
||||
)
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# rdb extension library
|
||||
|
|
@ -696,13 +855,20 @@ lib = Extension(config.root + '.libcore',
|
|||
rdb_path = os.path.join("src", "pymod", "rdb")
|
||||
rdb_sources = set(glob.glob(os.path.join(rdb_path, "*.cc")))
|
||||
|
||||
rdb = Extension(config.root + '.rdbcore',
|
||||
define_macros=config.macros(),
|
||||
include_dirs=[_rdb_path, _tl_path, _gsi_path, _pya_path],
|
||||
extra_objects=[config.path_of('_rdb', _rdb_path), config.path_of('_tl', _tl_path), config.path_of('_gsi', _gsi_path), config.path_of('_pya', _pya_path)],
|
||||
extra_link_args=config.link_args('rdbcore'),
|
||||
extra_compile_args=config.compile_args('rdbcore'),
|
||||
sources=list(rdb_sources))
|
||||
rdb = Extension(
|
||||
config.root + ".rdbcore",
|
||||
define_macros=config.macros(),
|
||||
include_dirs=[_rdb_path, _tl_path, _gsi_path, _pya_path],
|
||||
extra_objects=[
|
||||
config.path_of("_rdb", _rdb_path),
|
||||
config.path_of("_tl", _tl_path),
|
||||
config.path_of("_gsi", _gsi_path),
|
||||
config.path_of("_pya", _pya_path),
|
||||
],
|
||||
extra_link_args=config.link_args("rdbcore"),
|
||||
extra_compile_args=config.compile_args("rdbcore"),
|
||||
sources=list(rdb_sources),
|
||||
)
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# lay extension library
|
||||
|
|
@ -737,28 +903,34 @@ lay = Extension(config.root + '.laycore',
|
|||
# ------------------------------------------------------------------
|
||||
# Core setup function
|
||||
|
||||
if __name__ == '__main__':
|
||||
setup(name=config.root,
|
||||
version=config.version(),
|
||||
license='GNU GPLv3',
|
||||
description='KLayout standalone Python package',
|
||||
long_description='This package is a standalone distribution of KLayout\'s Python API.\n\nFor more details see here: https://www.klayout.org/klayout-pypi',
|
||||
author='Matthias Koefferlein',
|
||||
author_email='matthias@klayout.de',
|
||||
classifiers=[
|
||||
# Recommended classifiers
|
||||
"Programming Language :: Python :: 2",
|
||||
"Programming Language :: Python :: 3",
|
||||
"License :: OSI Approved :: GNU General Public License v3 (GPLv3)",
|
||||
"Operating System :: MacOS :: MacOS X",
|
||||
"Operating System :: Microsoft :: Windows",
|
||||
"Operating System :: POSIX :: Linux",
|
||||
# Optional classifiers
|
||||
"Topic :: Scientific/Engineering :: Electronic Design Automation (EDA)",
|
||||
],
|
||||
url='https://github.com/klayout/klayout',
|
||||
packages=find_packages('src/pymod/distutils_src'),
|
||||
package_dir={'': 'src/pymod/distutils_src'}, # https://github.com/pypa/setuptools/issues/230
|
||||
package_data={config.root: ["src/pymod/distutils_src/klayout/*.pyi"]},
|
||||
include_package_data=True,
|
||||
ext_modules=[_tl, _gsi, _pya, _rba, _db, _lib, _rdb, _lym, _laybasic, _layview, _ant, _edt, _img] + db_plugins + [tl, db, lib, rdb, lay])
|
||||
if __name__ == "__main__":
|
||||
setup(
|
||||
name=config.root,
|
||||
version=config.version(),
|
||||
license="GNU GPLv3",
|
||||
description="KLayout standalone Python package",
|
||||
long_description="This package is a standalone distribution of KLayout's Python API.\n\nFor more details see here: https://www.klayout.org/klayout-pypi",
|
||||
author="Matthias Koefferlein",
|
||||
author_email="matthias@klayout.de",
|
||||
classifiers=[
|
||||
# Recommended classifiers
|
||||
"Programming Language :: Python :: 2",
|
||||
"Programming Language :: Python :: 3",
|
||||
"License :: OSI Approved :: GNU General Public License v3 (GPLv3)",
|
||||
"Operating System :: MacOS :: MacOS X",
|
||||
"Operating System :: Microsoft :: Windows",
|
||||
"Operating System :: POSIX :: Linux",
|
||||
# Optional classifiers
|
||||
"Topic :: Scientific/Engineering :: Electronic Design Automation (EDA)",
|
||||
],
|
||||
url="https://github.com/klayout/klayout",
|
||||
packages=find_packages("src/pymod/distutils_src"),
|
||||
package_dir={
|
||||
"": "src/pymod/distutils_src"
|
||||
}, # https://github.com/pypa/setuptools/issues/230
|
||||
package_data={config.root: ["src/pymod/distutils_src/klayout/*.pyi"]},
|
||||
include_package_data=True,
|
||||
ext_modules=[_tl, _gsi, _pya, _rba, _db, _lib, _rdb, _lym, _laybasic, _layview, _ant, _edt, _img]
|
||||
+ db_plugins
|
||||
+ [tl, db, lib, rdb, lay])
|
||||
)
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ namespace gsi
|
|||
// db::Library binding
|
||||
|
||||
/**
|
||||
* @brief A basic implementation of the library
|
||||
* @brief A basic implementation of the library
|
||||
*/
|
||||
static db::Library *new_lib ()
|
||||
{
|
||||
|
|
@ -172,15 +172,15 @@ LibraryClass decl_Library ("db", "Library",
|
|||
"\n"
|
||||
"This method has been introduced in version 0.25.\n"
|
||||
) +
|
||||
gsi::method ("name", &db::Library::get_name,
|
||||
gsi::method ("name", &db::Library::get_name,
|
||||
"@brief Returns the libraries' name\n"
|
||||
"The name is set when the library is registered and cannot be changed\n"
|
||||
) +
|
||||
gsi::method ("id", &db::Library::get_id,
|
||||
gsi::method ("id", &db::Library::get_id,
|
||||
"@brief Returns the library's ID\n"
|
||||
"The ID is set when the library is registered and cannot be changed \n"
|
||||
) +
|
||||
gsi::method ("description", &db::Library::get_description,
|
||||
gsi::method ("description", &db::Library::get_description,
|
||||
"@brief Returns the libraries' description text\n"
|
||||
) +
|
||||
gsi::method ("description=", &db::Library::set_description, gsi::arg ("description"),
|
||||
|
|
@ -231,7 +231,7 @@ LibraryClass decl_Library ("db", "Library",
|
|||
gsi::method ("layout_const", (const db::Layout &(db::Library::*)() const) &db::Library::layout,
|
||||
"@brief The layout object where the cells reside that this library defines (const version)\n"
|
||||
) +
|
||||
gsi::method ("layout", (db::Layout &(db::Library::*)()) &db::Library::layout,
|
||||
gsi::method ("layout", (db::Layout &(db::Library::*)()) &db::Library::layout,
|
||||
"@brief The layout object where the cells reside that this library defines\n"
|
||||
) +
|
||||
gsi::method ("refresh", &db::Library::refresh,
|
||||
|
|
@ -303,7 +303,7 @@ class PCellDeclarationImpl
|
|||
: public db::PCellDeclaration
|
||||
{
|
||||
public:
|
||||
// dummy implementation to provide the signature
|
||||
// dummy implementation to provide the signature
|
||||
virtual std::vector<db::LayerProperties> get_layer_declarations_impl (const db::pcell_parameters_type &) const
|
||||
{
|
||||
return std::vector<db::LayerProperties> ();
|
||||
|
|
@ -340,7 +340,7 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
// dummy implementation to provide the signature
|
||||
// dummy implementation to provide the signature
|
||||
virtual db::pcell_parameters_type coerce_parameters_impl (const db::Layout & /*layout*/, const db::pcell_parameters_type &input) const
|
||||
{
|
||||
return input;
|
||||
|
|
@ -472,7 +472,7 @@ Class<PCellDeclarationImpl> decl_PCellDeclaration (decl_PCellDeclaration_Native,
|
|||
"This method receives the PCell parameters which allows it to deduce layers\n"
|
||||
"from the parameters."
|
||||
) +
|
||||
gsi::callback ("get_parameters", &PCellDeclarationImpl::get_parameter_declarations, &PCellDeclarationImpl::cb_get_parameter_declarations,
|
||||
gsi::callback ("get_parameters", &PCellDeclarationImpl::get_parameter_declarations, &PCellDeclarationImpl::cb_get_parameter_declarations,
|
||||
"@brief Returns a list of parameter declarations\n"
|
||||
"Reimplement this method to return a list of parameters used in that PCell \n"
|
||||
"implementation. A parameter declaration is a PCellParameterDeclaration object\n"
|
||||
|
|
@ -691,33 +691,33 @@ Class<db::PCellParameterDeclaration> decl_PCellParameterDeclaration ("db", "PCel
|
|||
"@param default The default (initial) value\n"
|
||||
"@param unit The unit string\n"
|
||||
) +
|
||||
gsi::method ("name", &db::PCellParameterDeclaration::get_name,
|
||||
gsi::method ("name", &db::PCellParameterDeclaration::get_name,
|
||||
"@brief Gets the name\n"
|
||||
) +
|
||||
gsi::method ("name=", &db::PCellParameterDeclaration::set_name, gsi::arg ("value"),
|
||||
"@brief Sets the name\n"
|
||||
) +
|
||||
gsi::method ("unit", &db::PCellParameterDeclaration::get_unit,
|
||||
gsi::method ("unit", &db::PCellParameterDeclaration::get_unit,
|
||||
"@brief Gets the unit string\n"
|
||||
) +
|
||||
gsi::method ("unit=", &db::PCellParameterDeclaration::set_unit, gsi::arg ("unit"),
|
||||
"@brief Sets the unit string\n"
|
||||
"The unit string is shown right to the edit fields for numeric parameters.\n"
|
||||
) +
|
||||
gsi::method_ext ("type", &get_type,
|
||||
gsi::method_ext ("type", &get_type,
|
||||
"@brief Gets the type\n"
|
||||
"The type is one of the T... constants."
|
||||
) +
|
||||
gsi::method_ext ("type=", &set_type, gsi::arg ("type"),
|
||||
"@brief Sets the type\n"
|
||||
) +
|
||||
gsi::method ("description", &db::PCellParameterDeclaration::get_description,
|
||||
gsi::method ("description", &db::PCellParameterDeclaration::get_description,
|
||||
"@brief Gets the description text\n"
|
||||
) +
|
||||
gsi::method ("description=", &db::PCellParameterDeclaration::set_description, gsi::arg ("description"),
|
||||
"@brief Sets the description\n"
|
||||
) +
|
||||
gsi::method ("hidden?", &db::PCellParameterDeclaration::is_hidden,
|
||||
gsi::method ("hidden?", &db::PCellParameterDeclaration::is_hidden,
|
||||
"@brief Returns true, if the parameter is a hidden parameter that should not be shown in the user interface\n"
|
||||
"By making a parameter hidden, it is possible to create internal parameters which cannot be\n"
|
||||
"edited.\n"
|
||||
|
|
@ -725,7 +725,7 @@ Class<db::PCellParameterDeclaration> decl_PCellParameterDeclaration ("db", "PCel
|
|||
gsi::method ("hidden=", &db::PCellParameterDeclaration::set_hidden, gsi::arg ("flag"),
|
||||
"@brief Makes the parameter hidden if this attribute is set to true\n"
|
||||
) +
|
||||
gsi::method ("readonly?", &db::PCellParameterDeclaration::is_readonly,
|
||||
gsi::method ("readonly?", &db::PCellParameterDeclaration::is_readonly,
|
||||
"@brief Returns true, if the parameter is a read-only parameter\n"
|
||||
"By making a parameter read-only, it is shown but cannot be\n"
|
||||
"edited.\n"
|
||||
|
|
@ -733,7 +733,7 @@ Class<db::PCellParameterDeclaration> decl_PCellParameterDeclaration ("db", "PCel
|
|||
gsi::method ("readonly=", &db::PCellParameterDeclaration::set_readonly, gsi::arg ("flag"),
|
||||
"@brief Makes the parameter read-only if this attribute is set to true\n"
|
||||
) +
|
||||
gsi::method_ext ("clear_choices", &clear_choices,
|
||||
gsi::method_ext ("clear_choices", &clear_choices,
|
||||
"@brief Clears the list of choices\n"
|
||||
) +
|
||||
gsi::method_ext ("add_choice", &add_choice, gsi::arg ("description"), gsi::arg ("value"),
|
||||
|
|
@ -742,13 +742,13 @@ Class<db::PCellParameterDeclaration> decl_PCellParameterDeclaration ("db", "PCel
|
|||
"choices. If choices are defined, KLayout will show a drop-down box instead of an\n"
|
||||
"entry field in the parameter user interface.\n"
|
||||
) +
|
||||
gsi::method ("choice_values", &db::PCellParameterDeclaration::get_choices,
|
||||
gsi::method ("choice_values", &db::PCellParameterDeclaration::get_choices,
|
||||
"@brief Returns a list of choice values\n"
|
||||
) +
|
||||
gsi::method ("choice_descriptions", &db::PCellParameterDeclaration::get_choice_descriptions,
|
||||
gsi::method ("choice_descriptions", &db::PCellParameterDeclaration::get_choice_descriptions,
|
||||
"@brief Returns a list of choice descriptions\n"
|
||||
) +
|
||||
gsi::method ("default", &db::PCellParameterDeclaration::get_default,
|
||||
gsi::method ("default", &db::PCellParameterDeclaration::get_default,
|
||||
"@brief Gets the default value\n"
|
||||
) +
|
||||
gsi::method ("default=", &db::PCellParameterDeclaration::set_default, gsi::arg ("value"),
|
||||
|
|
@ -763,7 +763,7 @@ Class<db::PCellParameterDeclaration> decl_PCellParameterDeclaration ("db", "PCel
|
|||
gsi::method ("TypeList", &pd_type_list, "@brief Type code: a list of variants") +
|
||||
gsi::method ("TypeLayer", &pd_type_layer, "@brief Type code: a layer (a \\LayerInfo object)") +
|
||||
gsi::method ("TypeShape", &pd_type_shape, "@brief Type code: a guiding shape (Box, Edge, Point, Polygon or Path)") +
|
||||
gsi::method ("TypeNone", &pd_type_none, "@brief Type code: unspecific type")
|
||||
gsi::method ("TypeNone", &pd_type_none, "@brief Type code: unspecific type")
|
||||
,
|
||||
"@brief A PCell parameter declaration\n"
|
||||
"\n"
|
||||
|
|
@ -776,4 +776,3 @@ Class<db::PCellParameterDeclaration> decl_PCellParameterDeclaration ("db", "PCel
|
|||
);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ namespace gsi
|
|||
// point binding
|
||||
|
||||
template <class C>
|
||||
struct point_defs
|
||||
struct point_defs
|
||||
{
|
||||
typedef typename C::coord_type coord_type;
|
||||
|
||||
|
|
@ -141,6 +141,14 @@ struct point_defs
|
|||
"\n"
|
||||
"Starting with version 0.25, this method renders a vector."
|
||||
) +
|
||||
method ("-", (C (C::*) (const db::vector<coord_type> &) const) &C::subtract, gsi::arg ("v"),
|
||||
"@brief Subtract one vector from a point\n"
|
||||
"\n"
|
||||
"\n"
|
||||
"Subtract vector v from from self by subtracting the coordinates. This renders a point.\n"
|
||||
"\n"
|
||||
"This method has been added in version 0.27."
|
||||
) +
|
||||
method ("<", &C::less, gsi::arg ("p"),
|
||||
"@brief \"less\" comparison operator\n"
|
||||
"\n"
|
||||
|
|
|
|||
|
|
@ -752,7 +752,7 @@ extern Class<db::ShapeCollection> decl_dbShapeCollection;
|
|||
|
||||
|
||||
Class<db::Region> decl_Region (decl_dbShapeCollection, "db", "Region",
|
||||
constructor ("new", &new_v,
|
||||
constructor ("new", &new_v,
|
||||
"@brief Default constructor\n"
|
||||
"\n"
|
||||
"This constructor creates an empty region.\n"
|
||||
|
|
@ -798,8 +798,8 @@ Class<db::Region> decl_Region (decl_dbShapeCollection, "db", "Region",
|
|||
"\n"
|
||||
"@code\n"
|
||||
"layout = ... # a layout\n"
|
||||
"cell = ... # the index of the initial cell\n"
|
||||
"layer = ... # the index of the layer from where to take the shapes from\n"
|
||||
"cell = ... # the index of the initial cell\n"
|
||||
"layer = ... # the index of the layer from where to take the shapes from\n"
|
||||
"r = RBA::Region::new(layout.begin_shapes(cell, layer))\n"
|
||||
"@/code\n"
|
||||
) +
|
||||
|
|
@ -814,8 +814,8 @@ Class<db::Region> decl_Region (decl_dbShapeCollection, "db", "Region",
|
|||
"\n"
|
||||
"@code\n"
|
||||
"layout = ... # a layout\n"
|
||||
"cell = ... # the index of the initial cell\n"
|
||||
"layer = ... # the index of the layer from where to take the shapes from\n"
|
||||
"cell = ... # the index of the initial cell\n"
|
||||
"layer = ... # the index of the layer from where to take the shapes from\n"
|
||||
"dbu = 0.1 # the target database unit\n"
|
||||
"r = RBA::Region::new(layout.begin_shapes(cell, layer), RBA::ICplxTrans::new(layout.dbu / dbu))\n"
|
||||
"@/code\n"
|
||||
|
|
@ -925,11 +925,11 @@ Class<db::Region> decl_Region (decl_dbShapeCollection, "db", "Region",
|
|||
"as single regions and artificial edges such as cut-lines will not be considered.\n"
|
||||
"Merged semantics thus is equivalent to considering coherent areas rather than\n"
|
||||
"single polygons\n"
|
||||
) +
|
||||
) +
|
||||
method ("merged_semantics?", &db::Region::merged_semantics,
|
||||
"@brief Gets a flag indicating whether merged semantics is enabled\n"
|
||||
"See \\merged_semantics= for a description of this attribute.\n"
|
||||
) +
|
||||
) +
|
||||
method ("strict_handling=", &db::Region::set_strict_handling, gsi::arg ("f"),
|
||||
"@brief Enables or disables strict handling\n"
|
||||
"\n"
|
||||
|
|
@ -941,7 +941,7 @@ Class<db::Region> decl_Region (decl_dbShapeCollection, "db", "Region",
|
|||
"Strict handling is disabled by default and optimization is in place.\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.23.2."
|
||||
) +
|
||||
) +
|
||||
method ("strict_handling?", &db::Region::strict_handling,
|
||||
"@brief Gets a flag indicating whether merged semantics is enabled\n"
|
||||
"See \\strict_handling= for a description of this attribute.\n"
|
||||
|
|
@ -957,11 +957,11 @@ Class<db::Region> decl_Region (decl_dbShapeCollection, "db", "Region",
|
|||
"created which touch at a corner).\n"
|
||||
"\n"
|
||||
"The default setting is maximum coherence (min_coherence = false).\n"
|
||||
) +
|
||||
) +
|
||||
method ("min_coherence?", &db::Region::min_coherence,
|
||||
"@brief Gets a flag indicating whether minimum coherence is selected\n"
|
||||
"See \\min_coherence= for a description of this attribute.\n"
|
||||
) +
|
||||
) +
|
||||
method_ext ("complex_op", &complex_op, gsi::arg ("node"),
|
||||
"@brief Executes a complex operation (see \\CompoundRegionOperationNode for details)\n"
|
||||
"\n"
|
||||
|
|
@ -1337,7 +1337,7 @@ Class<db::Region> decl_Region (decl_dbShapeCollection, "db", "Region",
|
|||
"of these boxes for example.\n"
|
||||
"\n"
|
||||
"Merged semantics applies for this method (see \\merged_semantics= for a description of this concept)\n"
|
||||
) +
|
||||
) +
|
||||
method_ext ("extents", &extents1, gsi::arg ("d"),
|
||||
"@brief Returns a region with the enlarged bounding boxes of the polygons\n"
|
||||
"This method will return a region consisting of the bounding boxes of the polygons enlarged by the given distance d.\n"
|
||||
|
|
@ -1346,7 +1346,7 @@ Class<db::Region> decl_Region (decl_dbShapeCollection, "db", "Region",
|
|||
"of these boxes for example.\n"
|
||||
"\n"
|
||||
"Merged semantics applies for this method (see \\merged_semantics= for a description of this concept)\n"
|
||||
) +
|
||||
) +
|
||||
method_ext ("extents", &extents2, gsi::arg ("dx"), gsi::arg ("dy"),
|
||||
"@brief Returns a region with the enlarged bounding boxes of the polygons\n"
|
||||
"This method will return a region consisting of the bounding boxes of the polygons enlarged by the given distance dx in x direction and dy in y direction.\n"
|
||||
|
|
@ -1355,7 +1355,7 @@ Class<db::Region> decl_Region (decl_dbShapeCollection, "db", "Region",
|
|||
"of these boxes for example.\n"
|
||||
"\n"
|
||||
"Merged semantics applies for this method (see \\merged_semantics= for a description of this concept)\n"
|
||||
) +
|
||||
) +
|
||||
method_ext ("extent_refs", &extent_refs,
|
||||
"@hide\n"
|
||||
"This method is provided for DRC implementation.\n"
|
||||
|
|
@ -1589,7 +1589,7 @@ Class<db::Region> decl_Region (decl_dbShapeCollection, "db", "Region",
|
|||
"This method returns the sized region (see \\size), but does not modify self.\n"
|
||||
"\n"
|
||||
"Merged semantics applies for this method (see \\merged_semantics= for a description of this concept)\n"
|
||||
) +
|
||||
) +
|
||||
method_ext ("andnot", &andnot, gsi::arg ("other"),
|
||||
"@brief Returns the boolean AND and NOT between self and the other region\n"
|
||||
"\n"
|
||||
|
|
@ -1607,7 +1607,7 @@ Class<db::Region> decl_Region (decl_dbShapeCollection, "db", "Region",
|
|||
"\n"
|
||||
"This method will compute the boolean AND (intersection) between two regions. "
|
||||
"The result is often but not necessarily always merged.\n"
|
||||
) +
|
||||
) +
|
||||
method ("&=", &db::Region::operator&=, gsi::arg ("other"),
|
||||
"@brief Performs the boolean AND between self and the other region\n"
|
||||
"\n"
|
||||
|
|
@ -1615,7 +1615,7 @@ Class<db::Region> decl_Region (decl_dbShapeCollection, "db", "Region",
|
|||
"\n"
|
||||
"This method will compute the boolean AND (intersection) between two regions. "
|
||||
"The result is often but not necessarily always merged.\n"
|
||||
) +
|
||||
) +
|
||||
method ("-", &db::Region::operator-, gsi::arg ("other"),
|
||||
"@brief Returns the boolean NOT between self and the other region\n"
|
||||
"\n"
|
||||
|
|
@ -1623,7 +1623,7 @@ Class<db::Region> decl_Region (decl_dbShapeCollection, "db", "Region",
|
|||
"\n"
|
||||
"This method will compute the boolean NOT (intersection) between two regions. "
|
||||
"The result is often but not necessarily always merged.\n"
|
||||
) +
|
||||
) +
|
||||
method ("-=", &db::Region::operator-=, gsi::arg ("other"),
|
||||
"@brief Performs the boolean NOT between self and the other region\n"
|
||||
"\n"
|
||||
|
|
@ -1631,15 +1631,15 @@ Class<db::Region> decl_Region (decl_dbShapeCollection, "db", "Region",
|
|||
"\n"
|
||||
"This method will compute the boolean NOT (intersection) between two regions. "
|
||||
"The result is often but not necessarily always merged.\n"
|
||||
) +
|
||||
) +
|
||||
method ("^", &db::Region::operator^, gsi::arg ("other"),
|
||||
"@brief Returns the boolean NOT between self and the other region\n"
|
||||
"@brief Returns the boolean XOR between self and the other region\n"
|
||||
"\n"
|
||||
"@return The result of the boolean XOR operation\n"
|
||||
"\n"
|
||||
"This method will compute the boolean XOR (intersection) between two regions. "
|
||||
"The result is often but not necessarily always merged.\n"
|
||||
) +
|
||||
) +
|
||||
method ("^=", &db::Region::operator^=, gsi::arg ("other"),
|
||||
"@brief Performs the boolean XOR between self and the other region\n"
|
||||
"\n"
|
||||
|
|
@ -1647,7 +1647,7 @@ Class<db::Region> decl_Region (decl_dbShapeCollection, "db", "Region",
|
|||
"\n"
|
||||
"This method will compute the boolean XOR (intersection) between two regions. "
|
||||
"The result is often but not necessarily always merged.\n"
|
||||
) +
|
||||
) +
|
||||
method ("\\|", &db::Region::operator|, gsi::arg ("other"),
|
||||
"@brief Returns the boolean OR between self and the other region\n"
|
||||
"\n"
|
||||
|
|
@ -1655,7 +1655,7 @@ Class<db::Region> decl_Region (decl_dbShapeCollection, "db", "Region",
|
|||
"\n"
|
||||
"The boolean OR is implemented by merging the polygons of both regions. To simply join the regions "
|
||||
"without merging, the + operator is more efficient."
|
||||
) +
|
||||
) +
|
||||
method ("\\|=", &db::Region::operator|=, gsi::arg ("other"),
|
||||
"@brief Performs the boolean OR between self and the other region\n"
|
||||
"\n"
|
||||
|
|
@ -1663,7 +1663,7 @@ Class<db::Region> decl_Region (decl_dbShapeCollection, "db", "Region",
|
|||
"\n"
|
||||
"The boolean OR is implemented by merging the polygons of both regions. To simply join the regions "
|
||||
"without merging, the + operator is more efficient."
|
||||
) +
|
||||
) +
|
||||
method ("+", &db::Region::operator+, gsi::arg ("other"),
|
||||
"@brief Returns the combined region of self and the other region\n"
|
||||
"\n"
|
||||
|
|
@ -1671,7 +1671,7 @@ Class<db::Region> decl_Region (decl_dbShapeCollection, "db", "Region",
|
|||
"\n"
|
||||
"This operator adds the polygons of the other region to self and returns a new combined region. "
|
||||
"This usually creates unmerged regions and polygons may overlap. Use \\merge if you want to ensure the result region is merged.\n"
|
||||
) +
|
||||
) +
|
||||
method ("+=", &db::Region::operator+=, gsi::arg ("other"),
|
||||
"@brief Adds the polygons of the other region to self\n"
|
||||
"\n"
|
||||
|
|
@ -1679,7 +1679,7 @@ Class<db::Region> decl_Region (decl_dbShapeCollection, "db", "Region",
|
|||
"\n"
|
||||
"This operator adds the polygons of the other region to self. "
|
||||
"This usually creates unmerged regions and polygons may overlap. Use \\merge if you want to ensure the result region is merged.\n"
|
||||
) +
|
||||
) +
|
||||
method ("covering", &db::Region::selected_enclosing, gsi::arg ("other"), gsi::arg ("min_count", size_t (1)), gsi::arg ("max_count", size_t (std::numeric_limits<size_t>::max ()), "unlimited"),
|
||||
"@brief Returns the polygons of this region which are completely covering polygons from the other region\n"
|
||||
"\n"
|
||||
|
|
@ -1740,14 +1740,14 @@ Class<db::Region> decl_Region (decl_dbShapeCollection, "db", "Region",
|
|||
"@return A new region containing the polygons which are inside polygons from the other region\n"
|
||||
"\n"
|
||||
"Merged semantics applies for this method (see \\merged_semantics= for a description of this concept)\n"
|
||||
) +
|
||||
) +
|
||||
method ("not_inside", &db::Region::selected_not_inside, gsi::arg ("other"),
|
||||
"@brief Returns the polygons of this region which are not completely inside polygons from the other region\n"
|
||||
"\n"
|
||||
"@return A new region containing the polygons which are not inside polygons from the other region\n"
|
||||
"\n"
|
||||
"Merged semantics applies for this method (see \\merged_semantics= for a description of this concept)\n"
|
||||
) +
|
||||
) +
|
||||
method_ext ("split_inside", &split_inside, gsi::arg ("other"),
|
||||
"@brief Returns the polygons of this region which are completely inside polygons from the other region and the ones which are not at the same time\n"
|
||||
"\n"
|
||||
|
|
@ -1764,28 +1764,28 @@ Class<db::Region> decl_Region (decl_dbShapeCollection, "db", "Region",
|
|||
"@return The region after the polygons have been selected (self)\n"
|
||||
"\n"
|
||||
"Merged semantics applies for this method (see \\merged_semantics= for a description of this concept)\n"
|
||||
) +
|
||||
) +
|
||||
method ("select_not_inside", &db::Region::select_not_inside, gsi::arg ("other"),
|
||||
"@brief Selects the polygons of this region which are not completely inside polygons from the other region\n"
|
||||
"\n"
|
||||
"@return The region after the polygons have been selected (self)\n"
|
||||
"\n"
|
||||
"Merged semantics applies for this method (see \\merged_semantics= for a description of this concept)\n"
|
||||
) +
|
||||
) +
|
||||
method ("outside", &db::Region::selected_outside, gsi::arg ("other"),
|
||||
"@brief Returns the polygons of this region which are completely outside polygons from the other region\n"
|
||||
"\n"
|
||||
"@return A new region containing the polygons which are outside polygons from the other region\n"
|
||||
"\n"
|
||||
"Merged semantics applies for this method (see \\merged_semantics= for a description of this concept)\n"
|
||||
) +
|
||||
) +
|
||||
method ("not_outside", &db::Region::selected_not_outside, gsi::arg ("other"),
|
||||
"@brief Returns the polygons of this region which are not completely outside polygons from the other region\n"
|
||||
"\n"
|
||||
"@return A new region containing the polygons which are not outside polygons from the other region\n"
|
||||
"\n"
|
||||
"Merged semantics applies for this method (see \\merged_semantics= for a description of this concept)\n"
|
||||
) +
|
||||
) +
|
||||
method_ext ("split_outside", &split_outside, gsi::arg ("other"),
|
||||
"@brief Returns the polygons of this region which are completely outside polygons from the other region and the ones which are not at the same time\n"
|
||||
"\n"
|
||||
|
|
@ -1802,14 +1802,14 @@ Class<db::Region> decl_Region (decl_dbShapeCollection, "db", "Region",
|
|||
"@return The region after the polygons have been selected (self)\n"
|
||||
"\n"
|
||||
"Merged semantics applies for this method (see \\merged_semantics= for a description of this concept)\n"
|
||||
) +
|
||||
) +
|
||||
method ("select_not_outside", &db::Region::select_not_outside, gsi::arg ("other"),
|
||||
"@brief Selects the polygons of this region which are not completely outside polygons from the other region\n"
|
||||
"\n"
|
||||
"@return The region after the polygons have been selected (self)\n"
|
||||
"\n"
|
||||
"Merged semantics applies for this method (see \\merged_semantics= for a description of this concept)\n"
|
||||
) +
|
||||
) +
|
||||
method ("interacting", (db::Region (db::Region::*) (const db::Region &, size_t, size_t) const) &db::Region::selected_interacting, gsi::arg ("other"), gsi::arg ("min_count", size_t (1)), gsi::arg ("max_count", size_t (std::numeric_limits<size_t>::max ()), "unlimited"),
|
||||
"@brief Returns the polygons of this region which overlap or touch polygons from the other region\n"
|
||||
"\n"
|
||||
|
|
@ -2020,7 +2020,7 @@ Class<db::Region> decl_Region (decl_dbShapeCollection, "db", "Region",
|
|||
"Merged semantics applies for this method (see \\merged_semantics= for a description of this concept)\n"
|
||||
"\n"
|
||||
"The count options have been introduced in version 0.27."
|
||||
) +
|
||||
) +
|
||||
method ("not_overlapping", &db::Region::selected_not_overlapping, gsi::arg ("other"), gsi::arg ("min_count", size_t (1)), gsi::arg ("max_count", size_t (std::numeric_limits<size_t>::max ()), "unlimited"),
|
||||
"@brief Returns the polygons of this region which do not overlap polygons from the other region\n"
|
||||
"\n"
|
||||
|
|
@ -2129,7 +2129,7 @@ Class<db::Region> decl_Region (decl_dbShapeCollection, "db", "Region",
|
|||
"possibilities of the edge collection.\n"
|
||||
"\n"
|
||||
"Merged semantics applies for this method (see \\merged_semantics= for a description of this concept)\n"
|
||||
) +
|
||||
) +
|
||||
factory_ext ("decompose_convex", &decompose_convex<db::Shapes>, gsi::arg ("preferred_orientation", po_any (), "\\Polygon#PO_any"),
|
||||
"@brief Decomposes the region into convex pieces.\n"
|
||||
"\n"
|
||||
|
|
@ -2166,7 +2166,7 @@ Class<db::Region> decl_Region (decl_dbShapeCollection, "db", "Region",
|
|||
method ("swap", &db::Region::swap, gsi::arg ("other"),
|
||||
"@brief Swap the contents of this region with the contents of another region\n"
|
||||
"This method is useful to avoid excessive memory allocation in some cases. "
|
||||
"For managed memory languages such as Ruby, those cases will be rare. "
|
||||
"For managed memory languages such as Ruby, those cases will be rare. "
|
||||
) +
|
||||
method ("holes", &db::Region::holes,
|
||||
"@brief Returns the holes of the region\n"
|
||||
|
|
@ -3099,4 +3099,3 @@ gsi::EnumIn<db::Region, db::OppositeFilter> decl_Region_OppositeFilter ("db", "O
|
|||
gsi::ClassExt<db::Region> inject_OppositeFilter_in_parent (decl_Region_OppositeFilter.defs ());
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -246,6 +246,12 @@ struct vector_defs
|
|||
"\n"
|
||||
"The scalar product of a and b is defined as: vp = ax*bx+ay*by.\n"
|
||||
) +
|
||||
method_ext ("*", &sprod, gsi::arg ("v"),
|
||||
"@brief Computes the scalar product between self and the given vector\n"
|
||||
"\n"
|
||||
"\n"
|
||||
"The scalar product of a and b is defined as: vp = ax*bx+ay*by.\n"
|
||||
) +
|
||||
method_ext ("sprod_sign", &sprod_sign, gsi::arg ("v"),
|
||||
"@brief Computes the scalar product between self and the given vector and returns a value indicating the sign of the product\n"
|
||||
"\n"
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ namespace pya
|
|||
} catch (...) { \
|
||||
if (PythonInterpreter::instance ()) { PythonInterpreter::instance ()->end_execution (); } \
|
||||
throw; \
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief A class encapsulating a python exception
|
||||
|
|
@ -92,7 +92,7 @@ class PYA_PUBLIC PythonInterpreter
|
|||
{
|
||||
public:
|
||||
/**
|
||||
* @brief The constructor
|
||||
* @brief The constructor
|
||||
*
|
||||
* If embedded is true, the interpreter is an embedded one. Only in this case, the
|
||||
* Python interpreter is initialized. Otherwise, it is assumed the interpreter
|
||||
|
|
@ -101,7 +101,7 @@ public:
|
|||
PythonInterpreter (bool embedded = true);
|
||||
|
||||
/**
|
||||
* @brief The destructor
|
||||
* @brief The destructor
|
||||
*/
|
||||
~PythonInterpreter ();
|
||||
|
||||
|
|
@ -160,10 +160,10 @@ public:
|
|||
* @brief Implementation of gsi::Interpreter::eval_expr
|
||||
*/
|
||||
tl::Variant eval_expr (const char *string, const char *filename = 0, int line = 1, int context = -1);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Implementation of gsi::Interpreter::eval_string_and_print
|
||||
*/
|
||||
*/
|
||||
void eval_string_and_print (const char *string, const char *filename = 0, int line = 1, int context = -1);
|
||||
|
||||
/**
|
||||
|
|
@ -172,7 +172,7 @@ public:
|
|||
virtual gsi::Inspector *inspector (int context = -1);
|
||||
|
||||
/**
|
||||
* @brief Defines a global variable with the given name and value
|
||||
* @brief Defines a global variable with the given name and value
|
||||
*/
|
||||
void define_variable (const std::string &name, const tl::Variant &value);
|
||||
|
||||
|
|
@ -284,4 +284,3 @@ private:
|
|||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -45,14 +45,14 @@ long python2c_func<long>::operator() (PyObject *rval)
|
|||
#if PY_MAJOR_VERSION < 3
|
||||
if (PyInt_Check (rval)) {
|
||||
return PyInt_AsLong (rval);
|
||||
} else
|
||||
} else
|
||||
#endif
|
||||
if (PyLong_Check (rval)) {
|
||||
return PyLong_AsLong (rval);
|
||||
} else if (PyFloat_Check (rval)) {
|
||||
return (long) (PyFloat_AsDouble (rval));
|
||||
} else {
|
||||
throw tl::Exception (tl::to_string (tr ("Value cannot be converted to an integer")));
|
||||
throw tl::TypeError (tl::to_string (tr ("Value cannot be converted to an integer")));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -68,14 +68,14 @@ char python2c_func<char>::operator() (PyObject *rval)
|
|||
#if PY_MAJOR_VERSION < 3
|
||||
if (PyInt_Check (rval)) {
|
||||
return char (PyInt_AsLong (rval));
|
||||
} else
|
||||
} else
|
||||
#endif
|
||||
if (PyLong_Check (rval)) {
|
||||
return char (PyLong_AsLong (rval));
|
||||
} else if (PyFloat_Check (rval)) {
|
||||
return char (PyFloat_AsDouble (rval));
|
||||
} else {
|
||||
throw tl::Exception (tl::to_string (tr ("Value cannot be converted to a character")));
|
||||
throw tl::TypeError (tl::to_string (tr ("Value cannot be converted to a character")));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -85,14 +85,14 @@ unsigned long python2c_func<unsigned long>::operator() (PyObject *rval)
|
|||
#if PY_MAJOR_VERSION < 3
|
||||
if (PyInt_Check (rval)) {
|
||||
return PyInt_AsUnsignedLongMask (rval);
|
||||
} else
|
||||
} else
|
||||
#endif
|
||||
if (PyLong_Check (rval)) {
|
||||
return PyLong_AsUnsignedLongMask (rval);
|
||||
} else if (PyFloat_Check (rval)) {
|
||||
return (unsigned long) (PyFloat_AsDouble (rval));
|
||||
} else {
|
||||
throw tl::Exception (tl::to_string (tr ("Value cannot be converted to an integer")));
|
||||
throw tl::TypeError (tl::to_string (tr ("Value cannot be converted to an integer")));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -102,14 +102,14 @@ long long python2c_func<long long>::operator() (PyObject *rval)
|
|||
#if PY_MAJOR_VERSION < 3
|
||||
if (PyInt_Check (rval)) {
|
||||
return PyInt_AsLong (rval);
|
||||
} else
|
||||
} else
|
||||
#endif
|
||||
if (PyLong_Check (rval)) {
|
||||
return PyLong_AsLongLong (rval);
|
||||
} else if (PyFloat_Check (rval)) {
|
||||
return (long long) (PyFloat_AsDouble (rval));
|
||||
} else {
|
||||
throw tl::Exception (tl::to_string (tr ("Value cannot be converted to an integer")));
|
||||
throw tl::TypeError (tl::to_string (tr ("Value cannot be converted to an integer")));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -119,14 +119,14 @@ unsigned long long python2c_func<unsigned long long>::operator() (PyObject *rval
|
|||
#if PY_MAJOR_VERSION < 3
|
||||
if (PyInt_Check (rval)) {
|
||||
return PyInt_AsUnsignedLongMask (rval);
|
||||
} else
|
||||
} else
|
||||
#endif
|
||||
if (PyLong_Check (rval)) {
|
||||
return PyLong_AsUnsignedLongLongMask (rval);
|
||||
} else if (PyFloat_Check (rval)) {
|
||||
return (unsigned long long) (PyFloat_AsDouble (rval));
|
||||
} else {
|
||||
throw tl::Exception (tl::to_string (tr ("Value cannot be converted to an integer")));
|
||||
throw tl::TypeError (tl::to_string (tr ("Value cannot be converted to an integer")));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -138,14 +138,14 @@ __int128 python2c_func<__int128>::operator() (PyObject *rval)
|
|||
#if PY_MAJOR_VERSION < 3
|
||||
if (PyInt_Check (rval)) {
|
||||
return PyInt_AsLong (rval);
|
||||
} else
|
||||
} else
|
||||
#endif
|
||||
if (PyLong_Check (rval)) {
|
||||
return PyLong_AsLongLong (rval);
|
||||
} else if (PyFloat_Check (rval)) {
|
||||
return PyFloat_AsDouble (rval);
|
||||
} else {
|
||||
throw tl::Exception (tl::to_string (tr ("Value cannot be converted to an integer")));
|
||||
throw tl::TypeError (tl::to_string (tr ("Value cannot be converted to an integer")));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
@ -156,14 +156,14 @@ double python2c_func<double>::operator() (PyObject *rval)
|
|||
#if PY_MAJOR_VERSION < 3
|
||||
if (PyInt_Check (rval)) {
|
||||
return PyInt_AsLong (rval);
|
||||
} else
|
||||
} else
|
||||
#endif
|
||||
if (PyLong_Check (rval)) {
|
||||
return PyLong_AsLongLong (rval);
|
||||
} else if (PyFloat_Check (rval)) {
|
||||
return PyFloat_AsDouble (rval);
|
||||
} else {
|
||||
throw tl::Exception (tl::to_string (tr ("Value cannot be converted to a floating-point value")));
|
||||
throw tl::TypeError (tl::to_string (tr ("Value cannot be converted to a floating-point value")));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -173,11 +173,11 @@ std::string python2c_func<std::string>::operator() (PyObject *rval)
|
|||
#if PY_MAJOR_VERSION < 3
|
||||
if (PyString_Check (rval)) {
|
||||
return std::string (PyString_AsString (rval), PyString_Size (rval));
|
||||
} else
|
||||
} else
|
||||
#else
|
||||
if (PyBytes_Check (rval)) {
|
||||
return std::string (PyBytes_AsString (rval), PyBytes_Size (rval));
|
||||
} else
|
||||
} else
|
||||
#endif
|
||||
if (PyUnicode_Check (rval)) {
|
||||
PythonRef ba (PyUnicode_AsUTF8String (rval));
|
||||
|
|
@ -188,7 +188,7 @@ std::string python2c_func<std::string>::operator() (PyObject *rval)
|
|||
} else if (PyByteArray_Check (rval)) {
|
||||
return std::string (PyByteArray_AsString (rval), PyByteArray_Size (rval));
|
||||
} else {
|
||||
throw tl::Exception (tl::to_string (tr ("Value cannot be converted to a string")));
|
||||
throw tl::TypeError (tl::to_string (tr ("Value cannot be converted to a string")));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -224,7 +224,7 @@ std::vector<char> python2c_func<std::vector<char> >::operator() (PyObject *rval)
|
|||
Py_ssize_t sz = PyByteArray_Size (rval);
|
||||
return std::vector<char> (cp, cp + sz);
|
||||
} else {
|
||||
throw tl::Exception (tl::to_string (tr ("Value cannot be converted to a byte array")));
|
||||
throw tl::TypeError (tl::to_string (tr ("Value cannot be converted to a byte array")));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -235,11 +235,11 @@ QByteArray python2c_func<QByteArray>::operator() (PyObject *rval)
|
|||
#if PY_MAJOR_VERSION < 3
|
||||
if (PyString_Check (rval)) {
|
||||
return QByteArray (PyString_AsString (rval), PyString_Size (rval));
|
||||
} else
|
||||
} else
|
||||
#else
|
||||
if (PyBytes_Check (rval)) {
|
||||
return QByteArray (PyBytes_AsString (rval), PyBytes_Size (rval));
|
||||
} else
|
||||
} else
|
||||
#endif
|
||||
if (PyUnicode_Check (rval)) {
|
||||
PythonRef ba (PyUnicode_AsUTF8String (rval));
|
||||
|
|
@ -250,7 +250,7 @@ QByteArray python2c_func<QByteArray>::operator() (PyObject *rval)
|
|||
} else if (PyByteArray_Check (rval)) {
|
||||
return QByteArray (PyByteArray_AsString (rval), PyByteArray_Size (rval));
|
||||
} else {
|
||||
throw tl::Exception (tl::to_string (tr ("Value cannot be converted to a byte array")));
|
||||
throw tl::TypeError (tl::to_string (tr ("Value cannot be converted to a byte array")));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -325,13 +325,13 @@ tl::Variant python2c_func<tl::Variant>::operator() (PyObject *rval)
|
|||
return r;
|
||||
|
||||
} else {
|
||||
|
||||
|
||||
const gsi::ClassBase *cls = PythonModule::cls_for_type (Py_TYPE (rval));
|
||||
if (cls) {
|
||||
|
||||
PYAObjectBase *p = PYAObjectBase::from_pyobject (rval);
|
||||
|
||||
// employ the tl::Variant binding capabilities of the Expression binding to derive the
|
||||
// employ the tl::Variant binding capabilities of the Expression binding to derive the
|
||||
// variant value.
|
||||
|
||||
void *obj = p->obj ();
|
||||
|
|
@ -519,7 +519,7 @@ PyObject *c2python_func<const tl::Variant &>::operator() (const tl::Variant &c)
|
|||
PyDict_SetItem (ret, c2python (i->first), c2python (i->second));
|
||||
}
|
||||
return ret;
|
||||
|
||||
|
||||
} else if (c.is_list ()) {
|
||||
|
||||
PyObject *ret = PyList_New (c.get_list ().size ());
|
||||
|
|
@ -619,4 +619,3 @@ PyObject *c2python_func<const QString &>::operator() (const QString &qs)
|
|||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -469,7 +469,7 @@ struct writer<gsi::ObjectType>
|
|||
|
||||
const gsi::ClassBase *cls_decl = PythonModule::cls_for_type (Py_TYPE (arg));
|
||||
if (! cls_decl) {
|
||||
throw tl::Exception (tl::sprintf (tl::to_string (tr ("Unexpected object type (expected argument of class %s, got %s)")), atype.cls ()->name (), Py_TYPE (arg)->tp_name));
|
||||
throw tl::TypeError (tl::sprintf (tl::to_string (tr ("Unexpected object type (expected argument of class %s, got %s)")), atype.cls ()->name (), Py_TYPE (arg)->tp_name));
|
||||
}
|
||||
|
||||
if (cls_decl->is_derived_from (atype.cls ())) {
|
||||
|
|
@ -494,14 +494,14 @@ struct writer<gsi::ObjectType>
|
|||
aa->write<void *> (new_obj);
|
||||
|
||||
} else {
|
||||
throw tl::Exception (tl::sprintf (tl::to_string (tr ("Unexpected object type (expected argument of class %s, got %s)")), atype.cls ()->name (), cls_decl->name ()));
|
||||
throw tl::TypeError (tl::sprintf (tl::to_string (tr ("Unexpected object type (expected argument of class %s, got %s)")), atype.cls ()->name (), cls_decl->name ()));
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
const gsi::ClassBase *cls_decl = PythonModule::cls_for_type (Py_TYPE (arg));
|
||||
if (! cls_decl) {
|
||||
throw tl::Exception (tl::sprintf (tl::to_string (tr ("Unexpected object type (expected argument of class %s, got %s)")), atype.cls ()->name (), Py_TYPE (arg)->tp_name));
|
||||
throw tl::TypeError (tl::sprintf (tl::to_string (tr ("Unexpected object type (expected argument of class %s, got %s)")), atype.cls ()->name (), Py_TYPE (arg)->tp_name));
|
||||
}
|
||||
|
||||
if (cls_decl->is_derived_from (atype.cls ())) {
|
||||
|
|
@ -521,7 +521,7 @@ struct writer<gsi::ObjectType>
|
|||
aa->write<void *> (atype.cls ()->create_obj_from (cls_decl, p->obj ()));
|
||||
|
||||
} else {
|
||||
throw tl::Exception (tl::sprintf (tl::to_string (tr ("Unexpected object type (expected argument of class %s, got %s)")), atype.cls ()->name (), cls_decl->name ()));
|
||||
throw tl::TypeError (tl::sprintf (tl::to_string (tr ("Unexpected object type (expected argument of class %s, got %s)")), atype.cls ()->name (), cls_decl->name ()));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ class PYAObjectBase;
|
|||
* @param arg The argument to serialize (a Python object)
|
||||
* @param heap A heap for temporary objects
|
||||
*
|
||||
* The heap collects objects created while filling the buffer.
|
||||
* The heap collects objects created while filling the buffer.
|
||||
* The stack must persist as long as the serial buffer is used.
|
||||
*/
|
||||
void
|
||||
|
|
@ -84,4 +84,3 @@ void correct_constness (PyObject *obj, bool const_required);
|
|||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -920,7 +920,7 @@ match_method (int mid, PyObject *self, PyObject *args, bool strict)
|
|||
if (! strict) {
|
||||
return 0;
|
||||
} else {
|
||||
throw tl::Exception (tl::to_string (tr ("No overload with matching arguments")));
|
||||
throw tl::TypeError (tl::to_string (tr ("No overload with matching arguments")));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -928,7 +928,7 @@ match_method (int mid, PyObject *self, PyObject *args, bool strict)
|
|||
if (! strict) {
|
||||
return 0;
|
||||
} else {
|
||||
throw tl::Exception (tl::to_string (tr ("Ambiguous overload variants - multiple method declarations match arguments")));
|
||||
throw tl::TypeError (tl::to_string (tr ("Ambiguous overload variants - multiple method declarations match arguments")));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2734,10 +2734,26 @@ public:
|
|||
alt_names.push_back ("__iter__");
|
||||
|
||||
} else if (name == "__mul__") {
|
||||
// Adding right multiplication
|
||||
// Rationale: if pyaObj * x works, so should x * pyaObj
|
||||
mp_module->add_python_doc (*cls, mt, int (mid), tl::to_string (tr ("This method is also available as '__mul__'")));
|
||||
alt_names.push_back ("__rmul__");
|
||||
|
||||
// Adding right multiplication
|
||||
// Rationale: if pyaObj * x works, so should x * pyaObj
|
||||
// But this should only apply if the multiplication is commutative
|
||||
// There are a few exceptions like Trans * Trans, so we support this case only if
|
||||
// the second argument is double (scaling).
|
||||
gsi::ArgType double_argtype;
|
||||
double_argtype.template init<double> ();
|
||||
if (m_first->arg (0) == double_argtype) {
|
||||
add_python_doc (**c, mt, int (mid), tl::to_string (tr ("This method is also available as '__rmul__'")));
|
||||
alt_names.push_back ("__rmul__");
|
||||
}
|
||||
|
||||
} else if (name == "dup" && m_first->compatible_with_num_args (0) ) {
|
||||
|
||||
// If the object supports the dup method, then it is a good
|
||||
// idea to define the __copy__ method.
|
||||
add_python_doc (**c, mt, int (mid), tl::to_string (tr ("This method also implements '__copy__'")));
|
||||
alt_names.push_back ("__copy__");
|
||||
|
||||
}
|
||||
|
||||
for (std::vector <std::string>::const_iterator an = alt_names.begin (); an != alt_names.end (); ++an) {
|
||||
|
|
@ -2901,11 +2917,13 @@ public:
|
|||
PyObject *attr_class = PyObject_GetAttrString ((PyObject *) type, ("_class_" + *a).c_str ());
|
||||
if (attr_inst == NULL || attr_class == NULL) {
|
||||
|
||||
// some error or disambiguator is not required -> don't install it
|
||||
// some error -> don't install the disambiguator
|
||||
Py_XDECREF (attr_inst);
|
||||
Py_XDECREF (attr_class);
|
||||
PyErr_Clear ();
|
||||
|
||||
tl::warn << "Unable to install a static/non-static disambiguator for " << *a << " in class " << (*c)->name ();
|
||||
|
||||
} else {
|
||||
|
||||
PyObject *desc = PYAAmbiguousMethodDispatcher::create (attr_inst, attr_class);
|
||||
|
|
|
|||
|
|
@ -43,6 +43,10 @@ namespace pya
|
|||
} catch (std::exception &ex) { \
|
||||
std::string msg = std::string(ex.what ()) + tl::to_string (tr (" in ")) + (where); \
|
||||
PyErr_SetString (PyExc_RuntimeError, msg.c_str ()); \
|
||||
} catch (tl::TypeError &ex) { \
|
||||
std::string msg; \
|
||||
msg = ex.msg () + tl::to_string (tr (" in ")) + (where); \
|
||||
PyErr_SetString (PyExc_TypeError, msg.c_str ()); \
|
||||
} catch (tl::Exception &ex) { \
|
||||
std::string msg; \
|
||||
msg = ex.msg () + tl::to_string (tr (" in ")) + (where); \
|
||||
|
|
@ -73,4 +77,3 @@ void check_error ();
|
|||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,79 @@
|
|||
import functools
|
||||
from typing import Type
|
||||
import klayout.dbcore
|
||||
from klayout.dbcore import *
|
||||
|
||||
from klayout.db.pcell_declaration_helper import PCellDeclarationHelper
|
||||
|
||||
__all__ = klayout.dbcore.__all__ + ['PCellDeclarationHelper']
|
||||
__all__ = klayout.dbcore.__all__ + ["PCellDeclarationHelper"] # type: ignore
|
||||
|
||||
# Implementing deepcopy of common objects
|
||||
# Point-like classes
|
||||
PointLike = (Point, DPoint, DVector, Vector)
|
||||
|
||||
|
||||
def pyaPoint__deepcopy__(self, memo):
|
||||
return self.dup()
|
||||
|
||||
|
||||
def convert_type_error_to_not_implemented(cls, method):
|
||||
"""If cls.method exists raises a TypeError, patch it so
|
||||
it returns a NotImplemented error instead.
|
||||
|
||||
|
||||
"""
|
||||
if not hasattr(cls, method):
|
||||
return
|
||||
|
||||
old_func = getattr(cls, method)
|
||||
|
||||
@functools.wraps(old_func)
|
||||
def new_func(*args, **kwargs):
|
||||
try:
|
||||
return old_func(*args, **kwargs)
|
||||
except TypeError:
|
||||
return NotImplemented
|
||||
try:
|
||||
setattr(cls, method, new_func)
|
||||
except TypeError:
|
||||
# Some classes are immutable and cannot be changed.
|
||||
# At the time of writing, this happens to (_StaticAttribute, _AmbiguousMethodDispatcher, _Iterator, _Signal).__or__
|
||||
return
|
||||
|
||||
for PClass in PointLike:
|
||||
PClass.__deepcopy__ = pyaPoint__deepcopy__ # type: ignore
|
||||
|
||||
for cls in klayout.dbcore.__dict__.values():
|
||||
if not isinstance(cls, type): # skip if not a class
|
||||
continue
|
||||
for method in (
|
||||
"__add__",
|
||||
"__sub__",
|
||||
"__mul__",
|
||||
"__matmul__",
|
||||
"__truediv__",
|
||||
"__floordiv__",
|
||||
"__mod__",
|
||||
"__divmod__",
|
||||
"__pow__",
|
||||
"__lshift__",
|
||||
"__rshift__",
|
||||
"__and__",
|
||||
"__xor__",
|
||||
"__or__",
|
||||
):
|
||||
# list of methods extracted from https://docs.python.org/3.7/reference/datamodel.html#emulating-numeric-types
|
||||
convert_type_error_to_not_implemented(cls, method)
|
||||
|
||||
|
||||
# If class has from_s, to_s, and assign, use them to
|
||||
# enable serialization.
|
||||
for name, cls in klayout.dbcore.__dict__.items():
|
||||
if not isinstance(cls, type):
|
||||
continue
|
||||
if hasattr(cls, 'from_s') and hasattr(cls, 'to_s') and hasattr(cls, 'assign'):
|
||||
cls.__getstate__ = cls.to_s # type: ignore
|
||||
def _setstate(self, str):
|
||||
cls = self.__class__
|
||||
self.assign(cls.from_s(str))
|
||||
cls.__setstate__ = _setstate # type: ignore
|
||||
|
|
|
|||
|
|
@ -63,7 +63,17 @@ class _PCellDeclarationHelper(PCellDeclaration):
|
|||
self.layer = None
|
||||
self.cell = None
|
||||
|
||||
def param(self, name, value_type, description, hidden=False, readonly=False, unit=None, default=None, choices=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
|
||||
|
|
@ -84,11 +94,16 @@ class _PCellDeclarationHelper(PCellDeclaration):
|
|||
|
||||
# create accessor methods for the parameters
|
||||
param_index = len(self._param_decls)
|
||||
setattr(type(self), name, _PCellDeclarationHelperParameterDescriptor(param_index))
|
||||
setattr(
|
||||
type(self), name, _PCellDeclarationHelperParameterDescriptor(param_index)
|
||||
)
|
||||
|
||||
if value_type == type(self).TypeLayer:
|
||||
setattr(type(self), name + "_layer",
|
||||
_PCellDeclarationHelperLayerDescriptor(len(self._layer_param_index)))
|
||||
setattr(
|
||||
type(self),
|
||||
name + "_layer",
|
||||
_PCellDeclarationHelperLayerDescriptor(len(self._layer_param_index)),
|
||||
)
|
||||
self._layer_param_index.append(param_index)
|
||||
|
||||
# store the parameter declarations
|
||||
|
|
@ -104,10 +119,16 @@ class _PCellDeclarationHelper(PCellDeclaration):
|
|||
pdecl.unit = unit
|
||||
if not (choices is None):
|
||||
if not isinstance(choices, list) and not isinstance(choices, tuple):
|
||||
raise Exception("choices value must be an list/tuple of two-element arrays (description, value)")
|
||||
raise Exception(
|
||||
"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 Exception("choices value must be an list/tuple of two-element arrays (description, value)")
|
||||
if (
|
||||
not isinstance(choices, list) and not isinstance(choices, tuple)
|
||||
) or len(c) != 2:
|
||||
raise Exception(
|
||||
"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
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,4 +1,4 @@
|
|||
from typing import Any, ClassVar, Dict, Iterable, Optional
|
||||
from typing import Any, ClassVar, Dict, Sequence, List, Iterator, Optional
|
||||
from typing import overload
|
||||
import klayout.db as db
|
||||
class RdbReference:
|
||||
|
|
@ -19,6 +19,10 @@ class RdbReference:
|
|||
@return The transformation
|
||||
@brief Sets the transformation for this reference
|
||||
"""
|
||||
def __copy__(self) -> RdbReference:
|
||||
r"""
|
||||
@brief Creates a copy of self
|
||||
"""
|
||||
def __init__(self, trans: db.DCplxTrans, parent_cell_id: int) -> None:
|
||||
r"""
|
||||
@brief Creates a reference with a given transformation and parent cell ID
|
||||
|
|
@ -136,13 +140,13 @@ class RdbCell:
|
|||
|
||||
This method has been introduced in version 0.23.
|
||||
"""
|
||||
def each_item(self) -> Iterable[RdbItem]:
|
||||
def each_item(self) -> Iterator[RdbItem]:
|
||||
r"""
|
||||
@brief Iterates over all items inside the database which are associated with this cell
|
||||
|
||||
This method has been introduced in version 0.23.
|
||||
"""
|
||||
def each_reference(self) -> Iterable[RdbReference]:
|
||||
def each_reference(self) -> Iterator[RdbReference]:
|
||||
r"""
|
||||
@brief Iterates over all references
|
||||
"""
|
||||
|
|
@ -236,13 +240,13 @@ class RdbCategory:
|
|||
|
||||
This method has been introduced in version 0.23.
|
||||
"""
|
||||
def each_item(self) -> Iterable[RdbItem]:
|
||||
def each_item(self) -> Iterator[RdbItem]:
|
||||
r"""
|
||||
@brief Iterates over all items inside the database which are associated with this category
|
||||
|
||||
This method has been introduced in version 0.23.
|
||||
"""
|
||||
def each_sub_category(self) -> Iterable[RdbCategory]:
|
||||
def each_sub_category(self) -> Iterator[RdbCategory]:
|
||||
r"""
|
||||
@brief Iterates over all sub-categories
|
||||
"""
|
||||
|
|
@ -368,6 +372,10 @@ class RdbItemValue:
|
|||
|
||||
This variant has been introduced in version 0.24
|
||||
"""
|
||||
def __copy__(self) -> RdbItemValue:
|
||||
r"""
|
||||
@brief Creates a copy of self
|
||||
"""
|
||||
@overload
|
||||
def __init__(self, b: db.DBox) -> None:
|
||||
r"""
|
||||
|
|
@ -414,6 +422,12 @@ class RdbItemValue:
|
|||
|
||||
This method has been introduced in version 0.22.
|
||||
"""
|
||||
def __repr__(self) -> str:
|
||||
r"""
|
||||
@brief Converts a value to a string
|
||||
The string can be used by the string constructor to create another object from it.
|
||||
@return The string
|
||||
"""
|
||||
def __str__(self) -> str:
|
||||
r"""
|
||||
@brief Converts a value to a string
|
||||
|
|
@ -696,7 +710,7 @@ class RdbItem:
|
|||
|
||||
This method has been introduced in version 0.23.
|
||||
"""
|
||||
def each_value(self) -> Iterable[RdbItemValue]:
|
||||
def each_value(self) -> Iterator[RdbItemValue]:
|
||||
r"""
|
||||
@brief Iterates over all values
|
||||
"""
|
||||
|
|
@ -892,7 +906,7 @@ class ReportDatabase:
|
|||
@param iter The iterator (a \RecursiveShapeIterator object) from which to take the items
|
||||
"""
|
||||
@overload
|
||||
def create_items(self, cell_id: int, category_id: int, trans: db.CplxTrans, array: Iterable[db.EdgePair]) -> None:
|
||||
def create_items(self, cell_id: int, category_id: int, trans: db.CplxTrans, array: Sequence[db.EdgePair]) -> None:
|
||||
r"""
|
||||
@brief Creates new edge pair items for the given cell/category combination
|
||||
For each edge pair a single item will be created. The value of the item will be this edge pair.
|
||||
|
|
@ -906,7 +920,7 @@ class ReportDatabase:
|
|||
@param edge_pairs The list of edge_pairs for which the items are created
|
||||
"""
|
||||
@overload
|
||||
def create_items(self, cell_id: int, category_id: int, trans: db.CplxTrans, array: Iterable[db.Edge]) -> None:
|
||||
def create_items(self, cell_id: int, category_id: int, trans: db.CplxTrans, array: Sequence[db.Edge]) -> None:
|
||||
r"""
|
||||
@brief Creates new edge items for the given cell/category combination
|
||||
For each edge a single item will be created. The value of the item will be this edge.
|
||||
|
|
@ -920,7 +934,7 @@ class ReportDatabase:
|
|||
@param edges The list of edges for which the items are created
|
||||
"""
|
||||
@overload
|
||||
def create_items(self, cell_id: int, category_id: int, trans: db.CplxTrans, array: Iterable[db.Polygon]) -> None:
|
||||
def create_items(self, cell_id: int, category_id: int, trans: db.CplxTrans, array: Sequence[db.Polygon]) -> None:
|
||||
r"""
|
||||
@brief Creates new polygon items for the given cell/category combination
|
||||
For each polygon a single item will be created. The value of the item will be this polygon.
|
||||
|
|
@ -995,29 +1009,29 @@ class ReportDatabase:
|
|||
@param shapes The shape container from which to take the items
|
||||
@param trans The transformation to apply
|
||||
"""
|
||||
def each_category(self) -> Iterable[RdbCategory]:
|
||||
def each_category(self) -> Iterator[RdbCategory]:
|
||||
r"""
|
||||
@brief Iterates over all top-level categories
|
||||
"""
|
||||
def each_cell(self) -> Iterable[RdbCell]:
|
||||
def each_cell(self) -> Iterator[RdbCell]:
|
||||
r"""
|
||||
@brief Iterates over all cells
|
||||
"""
|
||||
def each_item(self) -> Iterable[RdbItem]:
|
||||
def each_item(self) -> Iterator[RdbItem]:
|
||||
r"""
|
||||
@brief Iterates over all items inside the database
|
||||
"""
|
||||
def each_item_per_category(self, category_id: int) -> Iterable[RdbItem]:
|
||||
def each_item_per_category(self, category_id: int) -> Iterator[RdbItem]:
|
||||
r"""
|
||||
@brief Iterates over all items inside the database which are associated with the given category
|
||||
@param category_id The ID of the category for which all associated items should be retrieved
|
||||
"""
|
||||
def each_item_per_cell(self, cell_id: int) -> Iterable[RdbItem]:
|
||||
def each_item_per_cell(self, cell_id: int) -> Iterator[RdbItem]:
|
||||
r"""
|
||||
@brief Iterates over all items inside the database which are associated with the given cell
|
||||
@param cell_id The ID of the cell for which all associated items should be retrieved
|
||||
"""
|
||||
def each_item_per_cell_and_category(self, cell_id: int, category_id: int) -> Iterable[RdbItem]:
|
||||
def each_item_per_cell_and_category(self, cell_id: int, category_id: int) -> Iterator[RdbItem]:
|
||||
r"""
|
||||
@brief Iterates over all items inside the database which are associated with the given cell and category
|
||||
@param cell_id The ID of the cell for which all associated items should be retrieved
|
||||
|
|
@ -1129,7 +1143,7 @@ class ReportDatabase:
|
|||
|
||||
This method has been added in version 0.24.
|
||||
"""
|
||||
def variants(self, name: str) -> Iterable[int]:
|
||||
def variants(self, name: str) -> List[int]:
|
||||
r"""
|
||||
@brief Gets the variants for a given cell name
|
||||
@param name The basic name of the cell
|
||||
|
|
|
|||
|
|
@ -1,8 +1,12 @@
|
|||
from typing import Any, ClassVar, Dict, Iterable, Optional
|
||||
from typing import Any, ClassVar, Dict, Sequence, List, Iterator, Optional
|
||||
from typing import overload
|
||||
class EmptyClass:
|
||||
r"""
|
||||
"""
|
||||
def __copy__(self) -> EmptyClass:
|
||||
r"""
|
||||
@brief Creates a copy of self
|
||||
"""
|
||||
def __init__(self) -> None:
|
||||
r"""
|
||||
@brief Creates a new object of this class
|
||||
|
|
@ -64,6 +68,10 @@ class Value:
|
|||
@brief Gets the actual value.
|
||||
@brief Set the actual value.
|
||||
"""
|
||||
def __copy__(self) -> Value:
|
||||
r"""
|
||||
@brief Creates a copy of self
|
||||
"""
|
||||
@overload
|
||||
def __init__(self) -> None:
|
||||
r"""
|
||||
|
|
@ -75,6 +83,10 @@ class Value:
|
|||
@brief Constructs a non-nil object with the given value.
|
||||
This constructor has been introduced in version 0.22.
|
||||
"""
|
||||
def __repr__(self) -> str:
|
||||
r"""
|
||||
@brief Convert this object to a string
|
||||
"""
|
||||
def __str__(self) -> str:
|
||||
r"""
|
||||
@brief Convert this object to a string
|
||||
|
|
@ -148,14 +160,16 @@ class Interpreter:
|
|||
|
||||
This class was introduced in version 0.27.5.
|
||||
"""
|
||||
python_interpreter: ClassVar[Interpreter]
|
||||
r"""
|
||||
@brief Gets the instance of the Python interpreter
|
||||
"""
|
||||
ruby_interpreter: ClassVar[Interpreter]
|
||||
r"""
|
||||
@brief Gets the instance of the Ruby interpreter
|
||||
"""
|
||||
@classmethod
|
||||
def python_interpreter(cls) -> Interpreter:
|
||||
r"""
|
||||
@brief Gets the instance of the Python interpreter
|
||||
"""
|
||||
@classmethod
|
||||
def ruby_interpreter(cls) -> Interpreter:
|
||||
r"""
|
||||
@brief Gets the instance of the Ruby interpreter
|
||||
"""
|
||||
def __init__(self) -> None:
|
||||
r"""
|
||||
@brief Creates a new object of this class
|
||||
|
|
@ -279,6 +293,10 @@ class ArgType:
|
|||
TypeVoidPtr: ClassVar[int]
|
||||
r"""
|
||||
"""
|
||||
def __copy__(self) -> ArgType:
|
||||
r"""
|
||||
@brief Creates a copy of self
|
||||
"""
|
||||
def __eq__(self, arg0: object) -> bool:
|
||||
r"""
|
||||
@brief Equality of two types
|
||||
|
|
@ -291,6 +309,10 @@ class ArgType:
|
|||
r"""
|
||||
@brief Inequality of two types
|
||||
"""
|
||||
def __repr__(self) -> str:
|
||||
r"""
|
||||
@brief Convert to a string
|
||||
"""
|
||||
def __str__(self) -> str:
|
||||
r"""
|
||||
@brief Convert to a string
|
||||
|
|
@ -413,6 +435,10 @@ class MethodOverload:
|
|||
r"""
|
||||
@hide
|
||||
"""
|
||||
def __copy__(self) -> MethodOverload:
|
||||
r"""
|
||||
@brief Creates a copy of self
|
||||
"""
|
||||
def __init__(self) -> None:
|
||||
r"""
|
||||
@brief Creates a new object of this class
|
||||
|
|
@ -539,11 +565,11 @@ class Method:
|
|||
r"""
|
||||
@brief The documentation string for this method
|
||||
"""
|
||||
def each_argument(self) -> Iterable[ArgType]:
|
||||
def each_argument(self) -> Iterator[ArgType]:
|
||||
r"""
|
||||
@brief Iterate over all arguments of this method
|
||||
"""
|
||||
def each_overload(self) -> Iterable[MethodOverload]:
|
||||
def each_overload(self) -> Iterator[MethodOverload]:
|
||||
r"""
|
||||
@brief This iterator delivers the synonyms (overloads).
|
||||
|
||||
|
|
@ -608,10 +634,11 @@ class Class:
|
|||
r"""
|
||||
@hide
|
||||
"""
|
||||
each_class: ClassVar[Iterable[Class]]
|
||||
r"""
|
||||
@brief Iterate over all classes
|
||||
"""
|
||||
@classmethod
|
||||
def each_class(cls) -> Iterator[Class]:
|
||||
r"""
|
||||
@brief Iterate over all classes
|
||||
"""
|
||||
def __init__(self) -> None:
|
||||
r"""
|
||||
@brief Creates a new object of this class
|
||||
|
|
@ -673,11 +700,11 @@ class Class:
|
|||
r"""
|
||||
@brief The documentation string for this class
|
||||
"""
|
||||
def each_child_class(self) -> Iterable[Class]:
|
||||
def each_child_class(self) -> Iterator[Class]:
|
||||
r"""
|
||||
@brief Iterate over all child classes defined within this class
|
||||
"""
|
||||
def each_method(self) -> Iterable[Method]:
|
||||
def each_method(self) -> Iterator[Method]:
|
||||
r"""
|
||||
@brief Iterate over all methods of this class
|
||||
"""
|
||||
|
|
@ -801,16 +828,25 @@ class Timer:
|
|||
|
||||
This class has been introduced in version 0.23.
|
||||
"""
|
||||
memory_size: ClassVar[int]
|
||||
r"""
|
||||
@brief Gets the current memory usage of the process in Bytes
|
||||
@classmethod
|
||||
def memory_size(cls) -> int:
|
||||
r"""
|
||||
@brief Gets the current memory usage of the process in Bytes
|
||||
|
||||
This method has been introduced in version 0.27.
|
||||
"""
|
||||
This method has been introduced in version 0.27.
|
||||
"""
|
||||
def __copy__(self) -> Timer:
|
||||
r"""
|
||||
@brief Creates a copy of self
|
||||
"""
|
||||
def __init__(self) -> None:
|
||||
r"""
|
||||
@brief Creates a new object of this class
|
||||
"""
|
||||
def __repr__(self) -> str:
|
||||
r"""
|
||||
@brief Produces a string with the currently elapsed times
|
||||
"""
|
||||
def __str__(self) -> str:
|
||||
r"""
|
||||
@brief Produces a string with the currently elapsed times
|
||||
|
|
@ -1229,6 +1265,10 @@ class ExpressionContext:
|
|||
|
||||
This class has been introduced in version 0.26 when \Expression was separated into the execution and context part.
|
||||
"""
|
||||
def __copy__(self) -> ExpressionContext:
|
||||
r"""
|
||||
@brief Creates a copy of self
|
||||
"""
|
||||
def __init__(self) -> None:
|
||||
r"""
|
||||
@brief Creates a new object of this class
|
||||
|
|
@ -1384,6 +1424,10 @@ class GlobPattern:
|
|||
@brief Sets a value indicating whether trailing characters are allowed.
|
||||
If this predicate is false, the glob pattern needs to match the full subject string. If true, the match function will ignore trailing characters and return true if the front part of the subject string matches.
|
||||
"""
|
||||
def __copy__(self) -> GlobPattern:
|
||||
r"""
|
||||
@brief Creates a copy of self
|
||||
"""
|
||||
def __init__(self, pattern: str) -> None:
|
||||
r"""
|
||||
@brief Creates a new glob pattern match object
|
||||
|
|
@ -1444,6 +1488,10 @@ class ExecutableBase:
|
|||
@hide
|
||||
@alias Executable
|
||||
"""
|
||||
def __copy__(self) -> ExecutableBase:
|
||||
r"""
|
||||
@brief Creates a copy of self
|
||||
"""
|
||||
def __init__(self) -> None:
|
||||
r"""
|
||||
@brief Creates a new object of this class
|
||||
|
|
|
|||
|
|
@ -192,7 +192,9 @@ _type_dict[ktl.ArgType.TypeVoid] = "None"
|
|||
_type_dict[ktl.ArgType.TypeVoidPtr] = "None"
|
||||
|
||||
|
||||
def _translate_type(arg_type: ktl.ArgType, within_class: ktl.Class) -> str:
|
||||
def _translate_type(
|
||||
arg_type: ktl.ArgType, within_class: ktl.Class, is_return=False
|
||||
) -> str:
|
||||
"""Translates klayout's C-type to a type in Python.
|
||||
|
||||
This function is equivalent to the `type_to_s` in `pyaModule.cc`.
|
||||
|
|
@ -205,16 +207,19 @@ def _translate_type(arg_type: ktl.ArgType, within_class: ktl.Class) -> str:
|
|||
else:
|
||||
py_str = qualified_name(arg_type.cls())
|
||||
elif arg_type.type() == ktl.ArgType.TypeMap:
|
||||
inner_key = _translate_type(arg_type.inner_k(), within_class)
|
||||
inner_val = _translate_type(arg_type.inner(), within_class)
|
||||
inner_key = _translate_type(arg_type.inner_k(), within_class, is_return)
|
||||
inner_val = _translate_type(arg_type.inner(), within_class, is_return)
|
||||
py_str = f"Dict[{inner_key}, {inner_val}]"
|
||||
elif arg_type.type() == ktl.ArgType.TypeVector:
|
||||
py_str = f"Iterable[{_translate_type(arg_type.inner(), within_class)}]"
|
||||
if is_return:
|
||||
py_str = f"List[{_translate_type(arg_type.inner(), within_class, is_return)}]"
|
||||
else:
|
||||
py_str = f"Sequence[{_translate_type(arg_type.inner(), within_class, is_return)}]"
|
||||
else:
|
||||
py_str = _type_dict[arg_type.type()]
|
||||
|
||||
if arg_type.is_iter():
|
||||
py_str = f"Iterable[{py_str}]"
|
||||
py_str = f"Iterator[{py_str}]"
|
||||
if arg_type.has_default():
|
||||
py_str = f"Optional[{py_str}] = ..."
|
||||
return py_str
|
||||
|
|
@ -324,7 +329,7 @@ def get_c_methods(c: ktl.Class) -> List[_Method]:
|
|||
for ms in m.each_overload():
|
||||
if ms.name() == m.primary_name():
|
||||
return ms
|
||||
raise ("Primary synonym not found for method " + m.name())
|
||||
raise RuntimeError("Primary synonym not found for method " + m.name())
|
||||
|
||||
for m in c.each_method():
|
||||
if m.is_signal():
|
||||
|
|
@ -346,17 +351,35 @@ def get_c_methods(c: ktl.Class) -> List[_Method]:
|
|||
)
|
||||
is_setter = (num_args == 1) and method_def.is_setter()
|
||||
is_classvar = (num_args == 0) and (m.is_static() and not m.is_constructor())
|
||||
method_list.append(
|
||||
_Method(
|
||||
name=method_def.name(),
|
||||
is_setter=is_setter,
|
||||
is_getter=is_getter or is_classvar,
|
||||
is_classmethod=m.is_constructor(),
|
||||
is_classvar=is_classvar,
|
||||
doc=m.doc(),
|
||||
m=m,
|
||||
is_const = m.is_const()
|
||||
|
||||
# static methods without arguments which start with a capital letter are treated as constants
|
||||
# (rule from pyaModule.cc)
|
||||
if is_classvar and m.name()[0].isupper():
|
||||
is_getter = True
|
||||
|
||||
for method_synonym in m.each_overload():
|
||||
if method_synonym.deprecated():
|
||||
# method synonyms that start with # (pound) sign
|
||||
continue
|
||||
if method_synonym.name() == method_def.name():
|
||||
doc = m.doc()
|
||||
else:
|
||||
doc = (
|
||||
f"Note: This is an alias of '{translate_methodname(method_def.name())}'.\n"
|
||||
+ m.doc()
|
||||
)
|
||||
method_list.append(
|
||||
_Method(
|
||||
name=method_synonym.name(),
|
||||
is_setter=is_setter,
|
||||
is_getter=is_getter,
|
||||
is_classmethod=m.is_constructor() or is_classvar,
|
||||
is_classvar=is_classvar,
|
||||
doc=doc,
|
||||
m=m,
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
# print(f"{m.name()}: {m.is_static()=}, {m.is_constructor()=}, {m.is_const_object()=}")
|
||||
return method_list
|
||||
|
|
@ -364,7 +387,7 @@ def get_c_methods(c: ktl.Class) -> List[_Method]:
|
|||
|
||||
def get_py_child_classes(c: ktl.Class):
|
||||
for c_child in c.each_child_class():
|
||||
return c_child
|
||||
yield c_child
|
||||
|
||||
|
||||
def get_py_methods(
|
||||
|
|
@ -390,10 +413,13 @@ def get_py_methods(
|
|||
return m
|
||||
return None
|
||||
|
||||
translate_type = functools.partial(_translate_type, within_class=c)
|
||||
translate_arg_type = functools.partial(_translate_type, within_class=c, is_return=False)
|
||||
translate_ret_type = functools.partial(_translate_type, within_class=c, is_return=True)
|
||||
|
||||
def _get_arglist(m: ktl.Method, self_str) -> List[Tuple[str, ktl.ArgType]]:
|
||||
args = [(self_str, None)]
|
||||
def _get_arglist(
|
||||
m: ktl.Method, self_str: str
|
||||
) -> List[Tuple[str, Optional[ktl.ArgType]]]:
|
||||
args: List[Tuple[str, Optional[ktl.ArgType]]] = [(self_str, None)]
|
||||
for i, a in enumerate(m.each_argument()):
|
||||
argname = a.name()
|
||||
if is_reserved_word(argname):
|
||||
|
|
@ -417,7 +443,7 @@ def get_py_methods(
|
|||
new_arglist: List[Tuple[str, Optional[str]]] = []
|
||||
for argname, a in arg_list:
|
||||
if a:
|
||||
new_arglist.append((argname, translate_type(a)))
|
||||
new_arglist.append((argname, translate_arg_type(a)))
|
||||
else:
|
||||
new_arglist.append((argname, None))
|
||||
return _format_args(new_arglist)
|
||||
|
|
@ -425,7 +451,7 @@ def get_py_methods(
|
|||
# Extract all properties (methods that have getters and/or setters)
|
||||
properties: List[Stub] = list()
|
||||
for m in copy(_c_methods):
|
||||
ret_type = translate_type(m.m.ret_type())
|
||||
ret_type = translate_ret_type(m.m.ret_type())
|
||||
if m.is_getter:
|
||||
m_setter = find_setter(c_methods, m.name)
|
||||
if m_setter is not None: # full property
|
||||
|
|
@ -476,10 +502,27 @@ def get_py_methods(
|
|||
if m.is_setter:
|
||||
_c_methods.remove(m)
|
||||
|
||||
def get_altnames(c_name: str):
|
||||
def get_altnames(c_name: str, m: _Method):
|
||||
args = list(m.m.each_argument())
|
||||
ret = m.m.ret_type()
|
||||
num_args = len(args)
|
||||
names = [c_name]
|
||||
if c_name == "to_s":
|
||||
if c_name == "to_s" and num_args == 0:
|
||||
names.append("__str__")
|
||||
# Only works if GSI_ALIAS_INSPECT is activated
|
||||
names.append("__repr__")
|
||||
elif c_name == "hash" and num_args == 0:
|
||||
names.append("__hash__")
|
||||
elif c_name == "inspect" and num_args == 0:
|
||||
names.append("__repr__")
|
||||
elif c_name == "size" and num_args == 0:
|
||||
names.append("__len__")
|
||||
elif c_name == "each" and num_args == 0 and ret.is_iter():
|
||||
names.append("__iter__")
|
||||
elif c_name == "__mul__" and "Trans" not in c_name:
|
||||
names.append("__rmul__")
|
||||
elif c_name == "dup" and num_args == 0:
|
||||
names.append("__copy__")
|
||||
return names
|
||||
|
||||
# Extract all classmethods
|
||||
|
|
@ -491,8 +534,8 @@ def get_py_methods(
|
|||
if translate_methodname(m.name) == "__init__":
|
||||
continue
|
||||
decorator = "@classmethod"
|
||||
ret_type = translate_type(m.m.ret_type())
|
||||
for name in get_altnames(m.name):
|
||||
ret_type = translate_ret_type(m.m.ret_type())
|
||||
for name in get_altnames(m.name, m):
|
||||
classmethods.append(
|
||||
MethodStub(
|
||||
decorator=decorator,
|
||||
|
|
@ -515,9 +558,10 @@ def get_py_methods(
|
|||
if translated_name == "__init__":
|
||||
ret_type = "None"
|
||||
else:
|
||||
ret_type = translate_type(m.m.ret_type())
|
||||
ret_type = translate_ret_type(m.m.ret_type())
|
||||
|
||||
arg_list = _get_arglist(m.m, "self")
|
||||
# TODO: fix type errors
|
||||
# Exceptions:
|
||||
# For X.__eq__(self, a:X), treat second argument as type object instead of X
|
||||
if translated_name in ("__eq__", "__ne__"):
|
||||
|
|
@ -525,19 +569,20 @@ def get_py_methods(
|
|||
# X._assign(self, other:X), mypy complains if _assign is defined at base class.
|
||||
# We can't specialize other in this case.
|
||||
elif translated_name in ("_assign", "assign"):
|
||||
assert arg_list[1][1] is not None
|
||||
assert arg_list[1][1].type() == ktl.ArgType.TypeObject
|
||||
arg_list[1] = arg_list[1][0], superclass(arg_list[1][1].cls())
|
||||
else:
|
||||
new_arg_list = []
|
||||
for argname, a in arg_list:
|
||||
if a:
|
||||
new_arg_list.append((argname, translate_type(a)))
|
||||
new_arg_list.append((argname, translate_arg_type(a)))
|
||||
else:
|
||||
new_arg_list.append((argname, a))
|
||||
arg_list = new_arg_list
|
||||
formatted_args = _format_args(arg_list)
|
||||
|
||||
for name in get_altnames(translated_name):
|
||||
for name in get_altnames(translated_name, m):
|
||||
boundmethods.append(
|
||||
MethodStub(
|
||||
decorator=decorator,
|
||||
|
|
@ -595,6 +640,7 @@ def get_class_stub(
|
|||
_cstub.child_stubs.append(stub)
|
||||
return _cstub
|
||||
|
||||
|
||||
def get_classes(module: str) -> List[ktl.Class]:
|
||||
_classes = []
|
||||
for c in ktl.Class.each_class():
|
||||
|
|
@ -603,7 +649,8 @@ def get_classes(module: str) -> List[ktl.Class]:
|
|||
_classes.append(c)
|
||||
return _classes
|
||||
|
||||
def get_module_stubs(module:str) -> List[ClassStub]:
|
||||
|
||||
def get_module_stubs(module: str) -> List[ClassStub]:
|
||||
_stubs = []
|
||||
_classes = get_classes(module)
|
||||
for c in _classes:
|
||||
|
|
@ -613,7 +660,7 @@ def get_module_stubs(module:str) -> List[ClassStub]:
|
|||
|
||||
|
||||
def print_db():
|
||||
print("from typing import Any, ClassVar, Dict, Iterable, Optional")
|
||||
print("from typing import Any, ClassVar, Dict, Sequence, List, Iterator, Optional")
|
||||
print("from typing import overload")
|
||||
print("import klayout.rdb as rdb")
|
||||
print("import klayout.tl as tl")
|
||||
|
|
@ -622,14 +669,15 @@ def print_db():
|
|||
|
||||
|
||||
def print_rdb():
|
||||
print("from typing import Any, ClassVar, Dict, Iterable, Optional")
|
||||
print("from typing import Any, ClassVar, Dict, Sequence, List, Iterator, Optional")
|
||||
print("from typing import overload")
|
||||
print("import klayout.db as db")
|
||||
for stub in get_module_stubs("rdb"):
|
||||
print(stub.format_stub(include_docstring=True) + "\n")
|
||||
|
||||
|
||||
def print_tl():
|
||||
print("from typing import Any, ClassVar, Dict, Iterable, Optional")
|
||||
print("from typing import Any, ClassVar, Dict, Sequence, List, Iterator, Optional")
|
||||
print("from typing import overload")
|
||||
for stub in get_module_stubs("tl"):
|
||||
print(stub.format_stub(include_docstring=True) + "\n")
|
||||
|
|
|
|||
|
|
@ -36,13 +36,13 @@ namespace tl
|
|||
/**
|
||||
* @brief The unspecific exception class
|
||||
*
|
||||
* This class is the base class for all exceptions in this
|
||||
* framework. It does not carry further information except
|
||||
* a message string that can be created through different
|
||||
* This class is the base class for all exceptions in this
|
||||
* framework. It does not carry further information except
|
||||
* a message string that can be created through different
|
||||
* constructor methods.
|
||||
*/
|
||||
|
||||
class TL_PUBLIC Exception
|
||||
class TL_PUBLIC Exception
|
||||
{
|
||||
public:
|
||||
Exception (const std::string &msg)
|
||||
|
|
@ -169,6 +169,15 @@ private:
|
|||
void init (const std::string &fmt, const std::vector<tl::Variant> &a);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief An exception thrown when the wrong type is provided as argument.
|
||||
*/
|
||||
struct TL_PUBLIC TypeError
|
||||
: public Exception
|
||||
{
|
||||
using Exception::Exception;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A "neutral" exception thrown to terminate some operation
|
||||
* This exception is not shown.
|
||||
|
|
@ -195,4 +204,3 @@ struct TL_PUBLIC InternalException
|
|||
} // namespace tl
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -41,6 +41,19 @@ class BasicTest(unittest.TestCase):
|
|||
v.read(os.path.join(os.path.dirname(__file__), "..", "gds", "t10.gds"))
|
||||
self.assertEqual(v.top_cell().name, "RINGO")
|
||||
|
||||
def test_4(self):
|
||||
class RMulObject:
|
||||
def __init__(self, factor):
|
||||
self.factor = factor
|
||||
def __rmul__(self, point):
|
||||
return point * self.factor
|
||||
def __radd__(self, point):
|
||||
return point + db.Vector(1,1) * self.factor
|
||||
|
||||
p = db.Point(1, 0)
|
||||
fac2 = RMulObject(2)
|
||||
self.assertEqual(p * 2, p * fac2) # p.__mul__(fac2) should return NotImplemented, which will call fac2.__rmul__(p)
|
||||
self.assertEqual(db.Point(3,2), p + fac2)
|
||||
# run unit tests
|
||||
if __name__ == '__main__':
|
||||
suite = unittest.TestSuite()
|
||||
|
|
@ -48,5 +61,3 @@ if __name__ == '__main__':
|
|||
|
||||
if not unittest.TextTestRunner(verbosity = 1).run(suite).wasSuccessful():
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue