Skip to content

Commit 4606fb5

Browse files
committed
ENH: Remove circular module dependancy
The itk/__init.py__ depends on itkExtras.py which in turn depends on itk/__init.py. Remove those circular dependancies by directly importing from primary modules. Introduce new file to more cleanly break circular dependencies The itkInitHelpers.py is dedicated to functions needed during the initialization of the itk module.
1 parent 92f4c11 commit 4606fb5

File tree

7 files changed

+126
-110
lines changed

7 files changed

+126
-110
lines changed

Wrapping/Generators/Python/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ if(NOT EXTERNAL_WRAP_ITK_PROJECT)
150150
itkLazy
151151
itkHelpers
152152
itk/__init__
153+
itk/itkInitHelpers
153154
)
154155
# Done listing files.
155156

Wrapping/Generators/Python/itk/__init__.py

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,7 @@ def _get_lazy_attributes(local_lazy_attributes, l_module, l_data):
4848
import itkBase
4949
import itkConfig
5050
import itkLazy
51-
import itkTypes
52-
import itkExtras
51+
import itkInitHelpers
5352
import os
5453
import sys
5554

@@ -76,17 +75,27 @@ def _get_lazy_attributes(local_lazy_attributes, l_module, l_data):
7675
else:
7776
# We're not lazy-loading. Just load the modules in the order specified in
7877
# the known_modules list for consistency.
79-
for module in itkBase.itk_base_global_known_modules:
78+
for module in itkBase.itk_base_global_module_data.keys():
8079
itkBase.itk_load_swig_module(module, this_module.__dict__)
8180

8281
# Regardless of how it was loaded, fill up the itk module with the ITK types
8382
# and extras.
83+
import itkTypes
84+
8485
for k, v in itkTypes.__dict__.items():
8586
if k != "itkCType" and not k.startswith("_"):
8687
setattr(this_module, k, v)
88+
del itkTypes
89+
for k, v in itkInitHelpers.__dict__.items():
90+
if not k.startswith("_"):
91+
setattr(this_module, k, v)
92+
93+
import itkExtras
94+
8795
for k, v in itkExtras.__dict__.items():
8896
if not k.startswith("_"):
8997
setattr(this_module, k, v)
98+
del itkExtras
9099

91100
# --
92101
# Needed to propagate symbol to itk.image from itkTemplate.image
@@ -116,7 +125,7 @@ def _get_lazy_attributes(local_lazy_attributes, l_module, l_data):
116125
else:
117126
# do some cleanup
118127
del module, this_module, itk_module
119-
del itkBase, itkConfig, itkLazy, itkTypes, itkExtras, os, sys
128+
del itkBase, itkConfig, itkLazy, itkInitHelpers, os, sys
120129

121130

122131
# Now do the initialization
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
from sys import stderr as _system_error_stream
2+
3+
# The following line defines an ascii string used for dynamically refreshing
4+
# the import and progress callbacks on the same terminal line.
5+
# See http://www.termsys.demon.co.uk/vtansi.htm
6+
# \033 is the C-style octal code for an escape character
7+
# [2000D moves the cursor back 2000 columns, this is a brute force way of
8+
# getting to the start of the line.
9+
# [K erases the end of the line
10+
clrLine = "\033[2000D\033[K"
11+
12+
13+
def auto_not_in_place(v=True):
14+
"""Force it to not run in place"""
15+
import itkConfig
16+
17+
itkConfig.NotInPlace = v
18+
19+
20+
def auto_progress(progress_type=1):
21+
"""Set up auto progress report
22+
23+
progress_type:
24+
1 or True -> auto progress be used in a terminal
25+
2 -> simple auto progress (without special characters)
26+
0 or False -> disable auto progress
27+
"""
28+
import itkConfig
29+
30+
if progress_type is True or progress_type == 1:
31+
itkConfig.ImportCallback = terminal_import_callback
32+
itkConfig.ProgressCallback = terminal_progress_callback
33+
34+
elif progress_type == 2:
35+
itkConfig.ImportCallback = simple_import_callback
36+
itkConfig.ProgressCallback = simple_progress_callback
37+
38+
elif progress_type is False or progress_type == 0:
39+
itkConfig.ImportCallback = None
40+
itkConfig.ProgressCallback = None
41+
42+
else:
43+
raise ValueError("Invalid auto progress type: " + repr(progress_type))
44+
45+
46+
def terminal_progress_callback(name, p):
47+
"""Display the progress of an object and clean the display once complete
48+
49+
This function can be used with itkConfig.ProgressCallback
50+
"""
51+
print(clrLine + "%s: %f" % (name, p), file=_system_error_stream, end="")
52+
if p == 1:
53+
print(clrLine, file=_system_error_stream, end="")
54+
55+
56+
def terminal_import_callback(name, p):
57+
"""Display the loading of a module and clean the display once complete
58+
59+
This function can be used with itkConfig.ImportCallback
60+
"""
61+
print(clrLine + "Loading %s... " % name, file=_system_error_stream, end="")
62+
if p == 1:
63+
print(clrLine, file=_system_error_stream, end="")
64+
65+
66+
def simple_import_callback(name, p):
67+
"""Print a message when a module is loading
68+
69+
This function can be used with itkConfig.ImportCallback
70+
"""
71+
if p == 0:
72+
print("Loading %s... " % name, file=_system_error_stream, end="")
73+
elif p == 1:
74+
print("done", file=_system_error_stream)
75+
76+
77+
def simple_progress_callback(name, p):
78+
"""Print a message when an object is running
79+
80+
This function can be used with itkConfig.ProgressCallback
81+
"""
82+
if p == 0:
83+
print("Running %s... " % name, file=_system_error_stream, end="")
84+
elif p == 1:
85+
print("done", file=_system_error_stream)
86+
87+
88+
def force_load():
89+
"""force itk to load all the submodules"""
90+
import itk
91+
92+
for k in dir(itk):
93+
getattr(itk, k)

Wrapping/Generators/Python/itkBase.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,6 @@ def _initialize(l_module_data):
293293

294294

295295
itk_base_global_lazy_attributes = {}
296-
itk_base_global_known_modules = []
297296
itk_base_global_module_data = {}
298297
_initialize(itk_base_global_module_data)
299298
del _initialize

Wrapping/Generators/Python/itkExtras.py

Lines changed: 5 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,7 @@
2424

2525
from itkTemplate import output
2626

27-
# The following line defines an ascii string used for dynamically refreshing
28-
# the import and progress callbacks on the same terminal line.
29-
# See http://www.termsys.demon.co.uk/vtansi.htm
30-
# \033 is the C-style octal code for an escape character
31-
# [2000D moves the cursor back 2000 columns, this is a brute force way of
32-
# getting to the start of the line.
33-
# [K erases the end of the line
34-
clrLine = "\033[2000D\033[K"
27+
from sys import stderr as system_error_stream
3528

3629

3730
def set_nthreads(number_of_threads):
@@ -61,90 +54,6 @@ def get_nthreads():
6154
return threader.GetGlobalDefaultNumberOfThreads()
6255

6356

64-
def auto_not_in_place(v=True):
65-
"""Force it to not run in place
66-
"""
67-
import itkConfig
68-
69-
itkConfig.NotInPlace = v
70-
71-
72-
def auto_progress(progress_type=1):
73-
"""Set up auto progress report
74-
75-
progress_type:
76-
1 or True -> auto progress be used in a terminal
77-
2 -> simple auto progress (without special characters)
78-
0 or False -> disable auto progress
79-
"""
80-
import itkConfig
81-
82-
if progress_type is True or progress_type == 1:
83-
itkConfig.ImportCallback = terminal_import_callback
84-
itkConfig.ProgressCallback = terminal_progress_callback
85-
86-
elif progress_type == 2:
87-
itkConfig.ImportCallback = simple_import_callback
88-
itkConfig.ProgressCallback = simple_progress_callback
89-
90-
elif progress_type is False or progress_type == 0:
91-
itkConfig.ImportCallback = None
92-
itkConfig.ProgressCallback = None
93-
94-
else:
95-
raise ValueError("Invalid auto progress type: " + repr(progress_type))
96-
97-
98-
def terminal_progress_callback(name, p):
99-
"""Display the progress of an object and clean the display once complete
100-
101-
This function can be used with itkConfig.ProgressCallback
102-
"""
103-
print(clrLine + "%s: %f" % (name, p), file=system_error_stream, end="")
104-
if p == 1:
105-
print(clrLine, file=system_error_stream, end="")
106-
107-
108-
def terminal_import_callback(name, p):
109-
"""Display the loading of a module and clean the display once complete
110-
111-
This function can be used with itkConfig.ImportCallback
112-
"""
113-
print(clrLine + "Loading %s... " % name, file=system_error_stream, end="")
114-
if p == 1:
115-
print(clrLine, file=system_error_stream, end="")
116-
117-
118-
def simple_import_callback(name, p):
119-
"""Print a message when a module is loading
120-
121-
This function can be used with itkConfig.ImportCallback
122-
"""
123-
if p == 0:
124-
print("Loading %s... " % name, file=system_error_stream, end="")
125-
elif p == 1:
126-
print("done", file=system_error_stream)
127-
128-
129-
def simple_progress_callback(name, p):
130-
"""Print a message when an object is running
131-
132-
This function can be used with itkConfig.ProgressCallback
133-
"""
134-
if p == 0:
135-
print("Running %s... " % name, file=system_error_stream, end="")
136-
elif p == 1:
137-
print("done", file=system_error_stream)
138-
139-
140-
def force_load():
141-
"""force itk to load all the submodules"""
142-
import itk
143-
144-
for k in dir(itk):
145-
getattr(itk, k)
146-
147-
14857
def echo(obj, f=system_error_stream):
14958
"""Print an object to stream
15059
@@ -255,8 +164,7 @@ def _get_itk_pixelid(numpy_array_type):
255164

256165

257166
def _GetArrayFromImage(image_or_filter, function, keep_axes, update):
258-
"""Get an Array with the content of the image buffer
259-
"""
167+
"""Get an Array with the content of the image buffer"""
260168
# Finds the image type
261169
import itk
262170

@@ -269,17 +177,15 @@ def _GetArrayFromImage(image_or_filter, function, keep_axes, update):
269177

270178

271179
def GetArrayFromImage(image_or_filter, keep_axes=False, update=True):
272-
"""Get an array with the content of the image buffer
273-
"""
180+
"""Get an array with the content of the image buffer"""
274181
return _GetArrayFromImage(image_or_filter, "GetArrayFromImage", keep_axes, update)
275182

276183

277184
array_from_image = GetArrayFromImage
278185

279186

280187
def GetArrayViewFromImage(image_or_filter, keep_axes=False, update=True):
281-
"""Get an array view with the content of the image buffer
282-
"""
188+
"""Get an array view with the content of the image buffer"""
283189
return _GetArrayFromImage(
284190
image_or_filter, "GetArrayViewFromImage", keep_axes, update
285191
)
@@ -1038,7 +944,7 @@ def New(self, *args, **kargs):
1038944
# extract the types from the arguments to instantiate the class
1039945
import itk
1040946

1041-
types = tuple(itk.class_(o) for o in args)
947+
types = tuple(class_(o) for o in args)
1042948
return self[types].New(*args, **kargs)
1043949

1044950
def __getitem__(self, template_parameters):

Wrapping/Generators/Python/itkTemplate.py

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ def normalizeName(name):
4545
"""Normalize the class name to remove ambiguity
4646
4747
This function removes the white spaces in the name, and also
48-
remove the pointer declaration "*" (it have no sense in python) """
48+
remove the pointer declaration "*" (it have no sense in python)"""
4949

5050
name = name.replace(" ", "")
5151
name = name.replace("*", "")
@@ -55,11 +55,13 @@ def normalizeName(name):
5555

5656
class TemplateTypeError(TypeError):
5757
def __init__(self, template_type, input_type):
58+
import itkExtras
59+
5860
def tuple_to_string_type(t):
5961
if type(t) == tuple:
60-
return ", ".join(itk.python_type(x) for x in t)
62+
return ", ".join(itkExtras.python_type(x) for x in t)
6163
else:
62-
itk.python_type(t)
64+
itkExtras.python_type(t)
6365

6466
import itk
6567

@@ -77,10 +79,14 @@ def tuple_to_string_type(t):
7779
e.g.: image = itk.imread(my_input_filename, itk.F)
7880
"""
7981

80-
python_template_type = itk.python_type(template_type)
82+
python_template_type = itkExtras.python_type(template_type)
8183
python_input_type = tuple_to_string_type(input_type)
82-
type_list = "\n".join([itk.python_type(x[0]) for x in template_type.keys()])
83-
eg_type = ", ".join([itk.python_type(x) for x in list(template_type.keys())[0]])
84+
type_list = "\n".join(
85+
[itkExtras.python_type(x[0]) for x in template_type.keys()]
86+
)
87+
eg_type = ", ".join(
88+
[itkExtras.python_type(x) for x in list(template_type.keys())[0]]
89+
)
8490
msg = """{template_type} is not wrapped for input type `{input_type}`.
8591
8692
To limit the size of the package, only a limited number of

Wrapping/Generators/Python/itkTypes.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,3 +111,5 @@ def initialize_c_types_once():
111111
SLL,
112112
B,
113113
) = itkCType.initialize_c_types_once()
114+
115+
del Dict, Any

0 commit comments

Comments
 (0)