Skip to content

Commit 08ad055

Browse files
authored
Merge pull request #2258 from thewtex/swig-attr
2 parents c00531f + 029dd60 commit 08ad055

File tree

2 files changed

+61
-59
lines changed

2 files changed

+61
-59
lines changed

Wrapping/Generators/Python/itk/support/itkBase.py

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,8 @@ def itk_load_swig_module(name: str, namespace=None):
6868
if hasattr(this_module, "__templates_loaded"):
6969
if namespace is not None:
7070
swig = namespace.setdefault("swig", {})
71-
assert hasattr(this_module, "swig")
72-
swig.update(this_module.swig)
71+
if hasattr(this_module, "swig"):
72+
swig.update(this_module.swig)
7373

7474
# don't worry about overwriting the symbols in namespace -- any
7575
# common symbols should be of type itkTemplate, which is a
@@ -125,10 +125,7 @@ def itk_load_swig_module(name: str, namespace=None):
125125
if not (k.startswith("__") or k.startswith("itk")):
126126
this_module.swig[k] = v
127127
else:
128-
swig = None
129-
if namespace is not None:
130-
swig = namespace.setdefault("swig", {})
131-
assert swig is not None
128+
swig = namespace.setdefault("swig", {})
132129
for k, v in l_module.__dict__.items():
133130
if not (k.startswith("__") or k.startswith("itk")):
134131
this_module.swig[k] = v

Wrapping/Generators/SwigInterface/igenerator.py

Lines changed: 58 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import re
77
from argparse import ArgumentParser
88
from io import StringIO
9+
from pathlib import Path
910

1011

1112
def getType(v):
@@ -20,8 +21,8 @@ class IdxGenerator(object):
2021
"""Generates a the .idx file for an ITK wrapping submodule (which usually
2122
corresponds to a class)."""
2223

23-
def __init__(self, moduleName):
24-
self.moduleName = moduleName
24+
def __init__(self, submoduleName):
25+
self.submoduleName = submoduleName
2526
# the output file
2627
self.outputFile = StringIO()
2728

@@ -33,7 +34,7 @@ def create_idxfile(self, idxFilePath, wrappersNamespace):
3334
# drop the :: prefix - it make swig produce invalid code
3435
if s.startswith("::"):
3536
s = s[2:]
36-
self.outputFile.write("{%s} {%s} {%s}\n" % (s, n, self.moduleName))
37+
self.outputFile.write("{%s} {%s} {%s}\n" % (s, n, self.submoduleName))
3738

3839
content = self.outputFile.getvalue()
3940

@@ -200,8 +201,10 @@ def {class_name}_New():
200201
201202
'''
202203

203-
def __init__(self, moduleName, options):
204-
self.moduleName = moduleName
204+
def __init__(self, submoduleName, options):
205+
self.submoduleName = submoduleName
206+
# The first mdx file is the master index file for this module.
207+
self.moduleName = Path(options.mdx[0]).stem
205208
self.options = options
206209

207210
self.outputFile = StringIO()
@@ -242,12 +245,12 @@ def warn(self, identifier, msg, doWarn=True):
242245
else:
243246
if self.options.warningError:
244247
print(
245-
f"{self.moduleName}: error({str(identifier)}): {msg}",
248+
f"{self.submoduleName}: error({str(identifier)}): {msg}",
246249
file=sys.stderr,
247250
)
248251
else:
249252
print(
250-
f"{self.moduleName}: warning({str(identifier)}): {msg}",
253+
f"{self.submoduleName}: warning({str(identifier)}): {msg}",
251254
file=sys.stderr,
252255
)
253256

@@ -452,7 +455,7 @@ def load_mdx(self, file_name):
452455
pass
453456
elif line_stripped.endswith(".mdx"):
454457
self.load_mdx(os.path.dirname(file_name) + os.sep + line_stripped)
455-
elif line_stripped[:-4] == self.moduleName:
458+
elif line_stripped[:-4] == self.submoduleName:
456459
continue
457460
else:
458461
self.load_idx(os.path.dirname(file_name) + os.sep + line_stripped)
@@ -625,15 +628,17 @@ def {snakeCase}_init_docstring():
625628
from itk.support import itkTemplate
626629
from itk.support import itkHelpers
627630
628-
if isinstance(itk.{processObject}, itkTemplate.itkTemplate):
629-
filter_object = itk.{processObject}.values()[0]
631+
filter_class = itk.{self.moduleName}.{processObject}
632+
is_template = isinstance(filter_class, itkTemplate.itkTemplate)
633+
if is_template:
634+
filter_object = filter_class.values()[0]
630635
else:
631-
filter_object = itk.{processObject}
636+
filter_object = filter_class
632637
633638
{snakeCase}.__doc__ = filter_object.__doc__
634-
{snakeCase}.__doc__ += "\\n Args are Input(s) to the filter.\\n"
635-
{snakeCase}.__doc__ += "\\n Available Keyword Arguments:\\n"
636-
if isinstance(itk.{processObject}, itkTemplate.itkTemplate):
639+
{snakeCase}.__doc__ += "\\n args are input(s) to the filter.\\n\\n"
640+
{snakeCase}.__doc__ += "\\n Available keyword arguments:\\n"
641+
if is_template:
637642
{snakeCase}.__doc__ += itkHelpers.filter_args(filter_object)[0]
638643
{snakeCase}.__doc__ += "\\n"
639644
{snakeCase}.__doc__ += itkHelpers.filter_args(filter_object)[1]
@@ -830,12 +835,12 @@ def generate_headerfile(self, idxFile, wrappersNamespace):
830835
)
831836
# Also, release the GIL
832837
headerFile.write(
833-
f'%module(package="itk",threads="1") {self.moduleName}{lang.title()}\n'
838+
f'%module(package="itk",threads="1") {self.submoduleName}{lang.title()}\n'
834839
)
835840
headerFile.write('%feature("nothreadallow");\n')
836841
headerFile.write('%feature("autodoc","2");\n')
837842
else:
838-
headerFile.write(f"%module {self.moduleName}{lang.title()}\n")
843+
headerFile.write(f"%module {self.submoduleName}{lang.title()}\n")
839844
headerFile.write("#endif\n")
840845
headerFile.write("\n")
841846

@@ -844,7 +849,7 @@ def generate_headerfile(self, idxFile, wrappersNamespace):
844849
s = set()
845850
headerFile.write("%{\n")
846851
# the include files passed in option
847-
include = self.moduleName + "SwigInterface.h"
852+
include = self.submoduleName + "SwigInterface.h"
848853
i = f'#include "{include}"'
849854
if i not in s:
850855
headerFile.write(i + "\n")
@@ -895,7 +900,7 @@ def generate_includefile(self):
895900
includeFile.write("%include itk.i\n")
896901
for f in options.swig_includes:
897902
includeFile.write("%%include %s\n" % f)
898-
includeFile.write("%%include %s\n" % (self.moduleName + "_ext.i"))
903+
includeFile.write("%%include %s\n" % (self.submoduleName + "_ext.i"))
899904
includeFile.write("\n\n")
900905
return includeFile
901906

@@ -918,18 +923,18 @@ def generate_applyfile(self):
918923
def create_typedefheader(self, usedSources):
919924
# create the typedef header
920925
typedefFile = StringIO()
921-
typedefFile.write(f"#ifndef __{self.moduleName}SwigInterface_h\n")
922-
typedefFile.write(f"#define __{self.moduleName}SwigInterface_h\n")
926+
typedefFile.write(f"#ifndef __{self.submoduleName}SwigInterface_h\n")
927+
typedefFile.write(f"#define __{self.submoduleName}SwigInterface_h\n")
923928
typedefInput = os.path.join(
924-
options.library_output_dir, self.moduleName + "SwigInterface.h.in"
929+
options.library_output_dir, self.submoduleName + "SwigInterface.h.in"
925930
)
926931
with open(typedefInput, "r") as f:
927932
typedefFile.write(f.read() + "\n")
928933
for src in usedSources:
929934
typedefFile.write(f'#include "{src}SwigInterface.h"\n')
930935
typedefFile.write("#endif\n")
931936
typedefOutput = os.path.join(
932-
options.interface_output_dir, self.moduleName + "SwigInterface.h"
937+
options.interface_output_dir, self.submoduleName + "SwigInterface.h"
933938
)
934939
with open(typedefOutput, "w") as f:
935940
f.write(typedefFile.getvalue())
@@ -1166,7 +1171,7 @@ def create_interfacefile(self, interfaceFile, idxFile, wrappersNamespace):
11661171
xml_generator_path=options.castxml_path, xml_generator="castxml"
11671172
)
11681173

1169-
moduleNames = []
1174+
submoduleNames = []
11701175
# The first mdx file is the master index file for this module.
11711176
with open(options.mdx[0], "r") as ff:
11721177
for line in ff.readlines():
@@ -1178,14 +1183,14 @@ def create_interfacefile(self, interfaceFile, idxFile, wrappersNamespace):
11781183
elif stripped.endswith(".mdx"):
11791184
pass
11801185
else:
1181-
moduleName = stripped.rsplit(".")[0]
1182-
if moduleName.startswith("(const char*)"):
1183-
moduleName = moduleName[len("(const char*)") :]
1184-
moduleName = moduleName.strip('"')
1185-
moduleNames.append(moduleName)
1186-
1187-
def generate_wrapping_namespace(moduleName):
1188-
xmlFilePath = os.path.join(options.library_output_dir, moduleName + ".xml")
1186+
submoduleName = stripped.rsplit(".")[0]
1187+
if submoduleName.startswith("(const char*)"):
1188+
submoduleName = submoduleName[len("(const char*)") :]
1189+
submoduleName = submoduleName.strip('"')
1190+
submoduleNames.append(submoduleName)
1191+
1192+
def generate_wrapping_namespace(submoduleName):
1193+
xmlFilePath = os.path.join(options.library_output_dir, submoduleName + ".xml")
11891194
pygccxml_reader = pygccxml.parser.source_reader.source_reader_t(pygccxml_config)
11901195
abstractSyntaxTree = pygccxml_reader.read_xml_file(xmlFilePath)
11911196
globalNamespace = pygccxml.declarations.get_global_namespace(abstractSyntaxTree)
@@ -1195,36 +1200,36 @@ def generate_wrapping_namespace(moduleName):
11951200
wrappingNamespaces = dict()
11961201
# Limit the number of cached, parsed abstract syntax trees to avoid very
11971202
# high memory usage
1198-
wrappingCacheLength = min(len(moduleNames), 20)
1203+
wrappingCacheLength = min(len(submoduleNames), 20)
11991204
for ii in range(wrappingCacheLength):
1200-
moduleName = moduleNames[ii]
1201-
wrappingNamespace = generate_wrapping_namespace(moduleName)
1202-
wrappingNamespaces[moduleName] = wrappingNamespace
1205+
submoduleName = submoduleNames[ii]
1206+
wrappingNamespace = generate_wrapping_namespace(submoduleName)
1207+
wrappingNamespaces[submoduleName] = wrappingNamespace
12031208

1204-
for moduleName in moduleNames:
1205-
if moduleName in wrappingNamespaces:
1206-
wrappersNamespace = wrappingNamespaces[moduleName]
1209+
for submoduleName in submoduleNames:
1210+
if submoduleName in wrappingNamespaces:
1211+
wrappersNamespace = wrappingNamespaces[submoduleName]
12071212
else:
1208-
wrappersNamespace = generate_wrapping_namespace(moduleName)
1213+
wrappersNamespace = generate_wrapping_namespace(submoduleName)
12091214

1210-
idxFilePath = os.path.join(options.interface_output_dir, moduleName + ".idx")
1211-
idx_generator = IdxGenerator(moduleName)
1215+
idxFilePath = os.path.join(options.interface_output_dir, submoduleName + ".idx")
1216+
idx_generator = IdxGenerator(submoduleName)
12121217
idx_generator.create_idxfile(idxFilePath, wrappersNamespace)
12131218

12141219
snake_case_process_object_functions = set()
12151220

1216-
def generate_swig_input(moduleName):
1217-
if moduleName in wrappingNamespaces:
1218-
wrappersNamespace = wrappingNamespaces[moduleName]
1221+
def generate_swig_input(submoduleName):
1222+
if submoduleName in wrappingNamespaces:
1223+
wrappersNamespace = wrappingNamespaces[submoduleName]
12191224
else:
1220-
wrappersNamespace = generate_wrapping_namespace(moduleName)
1225+
wrappersNamespace = generate_wrapping_namespace(submoduleName)
12211226

1222-
idxFilePath = os.path.join(options.interface_output_dir, moduleName + ".idx")
1227+
idxFilePath = os.path.join(options.interface_output_dir, submoduleName + ".idx")
12231228
swigInputFilePath = os.path.join(
1224-
options.interface_output_dir, moduleName + ".i"
1229+
options.interface_output_dir, submoduleName + ".i"
12251230
)
12261231

1227-
swig_input_generator = SwigInputGenerator(moduleName, options)
1232+
swig_input_generator = SwigInputGenerator(submoduleName, options)
12281233
swig_input_generator.create_interfacefile(
12291234
swigInputFilePath, idxFilePath, wrappersNamespace
12301235
)
@@ -1233,11 +1238,11 @@ def generate_swig_input(moduleName):
12331238
)
12341239

12351240
if options.submodule_order:
1236-
for moduleName in options.submodule_order.split(";"):
1237-
generate_swig_input(moduleName)
1238-
moduleNames.remove(moduleName)
1239-
for moduleName in moduleNames:
1240-
generate_swig_input(moduleName)
1241+
for submoduleName in options.submodule_order.split(";"):
1242+
generate_swig_input(submoduleName)
1243+
submoduleNames.remove(submoduleName)
1244+
for submoduleName in submoduleNames:
1245+
generate_swig_input(submoduleName)
12411246

12421247
snake_case_file = options.snake_case_file
12431248
if len(snake_case_file) > 1:

0 commit comments

Comments
 (0)