1 |
bicatali 13/08/27 18:29:10 |
2 |
|
3 |
Added: numpy-1.7.1-distutils-python33.patch |
4 |
Log: |
5 |
Remove trailing spaces from pkg-config calls (bug #444104), fix shared lib extension (upstream patch) for python-3 (bug #470946), remove old |
6 |
|
7 |
(Portage version: 2.2.01.22288-prefix/cvs/Linux x86_64, signed Manifest commit with key 0x13CB1360) |
8 |
|
9 |
Revision Changes Path |
10 |
1.1 dev-python/numpy/files/numpy-1.7.1-distutils-python33.patch |
11 |
|
12 |
file : http://sources.gentoo.org/viewvc.cgi/gentoo-x86/dev-python/numpy/files/numpy-1.7.1-distutils-python33.patch?rev=1.1&view=markup |
13 |
plain: http://sources.gentoo.org/viewvc.cgi/gentoo-x86/dev-python/numpy/files/numpy-1.7.1-distutils-python33.patch?rev=1.1&content-type=text/plain |
14 |
|
15 |
Index: numpy-1.7.1-distutils-python33.patch |
16 |
=================================================================== |
17 |
--- numpy/distutils/misc_util.py.orig 2013-04-06 22:04:05.000000000 -0700 |
18 |
+++ numpy/distutils/misc_util.py 2013-08-27 11:11:50.970945380 -0700 |
19 |
@@ -1,3 +1,5 @@ |
20 |
+from __future__ import division, absolute_import, print_function |
21 |
+ |
22 |
import os |
23 |
import re |
24 |
import sys |
25 |
@@ -165,7 +167,7 @@ |
26 |
fid = open(config_file) |
27 |
mathlibs = [] |
28 |
s = '#define MATHLIB' |
29 |
- for line in fid.readlines(): |
30 |
+ for line in fid: |
31 |
if line.startswith(s): |
32 |
value = line[len(s):].strip() |
33 |
if value: |
34 |
@@ -218,8 +220,8 @@ |
35 |
else: |
36 |
if include_non_existing: |
37 |
new_paths.append(n) |
38 |
- print('could not resolve pattern in %r: %r' \ |
39 |
- % (local_path,n)) |
40 |
+ print('could not resolve pattern in %r: %r' % |
41 |
+ (local_path,n)) |
42 |
else: |
43 |
n2 = njoin(local_path,n) |
44 |
if os.path.exists(n2): |
45 |
@@ -230,8 +232,8 @@ |
46 |
elif include_non_existing: |
47 |
new_paths.append(n) |
48 |
if not os.path.exists(n): |
49 |
- print('non-existing path in %r: %r' \ |
50 |
- % (local_path,n)) |
51 |
+ print('non-existing path in %r: %r' % |
52 |
+ (local_path,n)) |
53 |
|
54 |
elif is_sequence(n): |
55 |
new_paths.extend(_fix_paths(n,local_path,include_non_existing)) |
56 |
@@ -249,11 +251,9 @@ |
57 |
|
58 |
_temporary_directory = None |
59 |
def clean_up_temporary_directory(): |
60 |
- from numpy.distutils import log |
61 |
global _temporary_directory |
62 |
if not _temporary_directory: |
63 |
return |
64 |
- log.debug('removing %s', _temporary_directory) |
65 |
try: |
66 |
shutil.rmtree(_temporary_directory) |
67 |
except OSError: |
68 |
@@ -394,8 +394,7 @@ |
69 |
return [] |
70 |
modules = [] |
71 |
f = open(source,'r') |
72 |
- f_readlines = getattr(f,'xreadlines',f.readlines) |
73 |
- for line in f_readlines(): |
74 |
+ for line in f: |
75 |
m = f90_module_name_match(line) |
76 |
if m: |
77 |
name = m.group('name') |
78 |
@@ -557,7 +556,7 @@ |
79 |
def get_ext_source_files(ext): |
80 |
# Get sources and any include files in the same directory. |
81 |
filenames = [] |
82 |
- sources = filter(is_string, ext.sources) |
83 |
+ sources = [_m for _m in ext.sources if is_string(_m)] |
84 |
filenames.extend(sources) |
85 |
filenames.extend(get_dependencies(sources)) |
86 |
for d in ext.depends: |
87 |
@@ -568,13 +567,13 @@ |
88 |
return filenames |
89 |
|
90 |
def get_script_files(scripts): |
91 |
- scripts = filter(is_string, scripts) |
92 |
+ scripts = [_m for _m in scripts if is_string(_m)] |
93 |
return scripts |
94 |
|
95 |
def get_lib_source_files(lib): |
96 |
filenames = [] |
97 |
sources = lib[1].get('sources',[]) |
98 |
- sources = filter(is_string, sources) |
99 |
+ sources = [_m for _m in sources if is_string(_m)] |
100 |
filenames.extend(sources) |
101 |
filenames.extend(get_dependencies(sources)) |
102 |
depends = lib[1].get('depends',[]) |
103 |
@@ -606,11 +605,29 @@ |
104 |
Linux, but not on OS X. |
105 |
|
106 |
""" |
107 |
- so_ext = distutils.sysconfig.get_config_var('SO') or '' |
108 |
- # fix long extension for Python >=3.2, see PEP 3149. |
109 |
- if (not is_python_ext) and 'SOABI' in distutils.sysconfig.get_config_vars(): |
110 |
- # Does nothing unless SOABI config var exists |
111 |
- so_ext = so_ext.replace('.' + distutils.sysconfig.get_config_var('SOABI'), '', 1) |
112 |
+ confvars = distutils.sysconfig.get_config_vars() |
113 |
+ # SO is deprecated in 3.3.1, use EXT_SUFFIX instead |
114 |
+ so_ext = confvars.get('EXT_SUFFIX', None) |
115 |
+ if so_ext is None: |
116 |
+ so_ext = confvars.get('SO', '') |
117 |
+ |
118 |
+ if not is_python_ext: |
119 |
+ # hardcode known values, config vars (including SHLIB_SUFFIX) are |
120 |
+ # unreliable (see #3182) |
121 |
+ # darwin, windows and debug linux are wrong in 3.3.1 and older |
122 |
+ if (sys.platform.startswith('linux') or |
123 |
+ sys.platform.startswith('gnukfreebsd')): |
124 |
+ so_ext = '.so' |
125 |
+ elif sys.platform.startswith('darwin'): |
126 |
+ so_ext = '.dylib' |
127 |
+ elif sys.platform.startswith('win'): |
128 |
+ so_ext = '.dll' |
129 |
+ else: |
130 |
+ # fall back to config vars for unknown platforms |
131 |
+ # fix long extension for Python >=3.2, see PEP 3149. |
132 |
+ if 'SOABI' in confvars: |
133 |
+ # Does nothing unless SOABI config var exists |
134 |
+ so_ext = so_ext.replace('.' + confvars.get('SOABI'), '', 1) |
135 |
|
136 |
return so_ext |
137 |
|
138 |
@@ -628,7 +645,7 @@ |
139 |
if os.path.isfile(s): |
140 |
filenames.append(s) |
141 |
else: |
142 |
- print('Not existing data file:',s) |
143 |
+ print('Not existing data file:', s) |
144 |
else: |
145 |
raise TypeError(repr(s)) |
146 |
return filenames |
147 |
@@ -647,56 +664,13 @@ |
148 |
frame = frame.f_back |
149 |
return frame |
150 |
|
151 |
-class SconsInfo(object): |
152 |
- """ |
153 |
- Container object holding build info for building a package with scons. |
154 |
- |
155 |
- Parameters |
156 |
- ---------- |
157 |
- scons_path : str or None |
158 |
- Path to scons script, relative to the directory of setup.py. |
159 |
- If None, no scons script is specified. This can be useful to add only |
160 |
- pre- and post-hooks to a configuration. |
161 |
- parent_name : str or None |
162 |
- Name of the parent package (for example "numpy"). |
163 |
- pre_hook : sequence of callables or None |
164 |
- Callables that are executed before scons is invoked. |
165 |
- Each callable should be defined as ``callable(*args, **kw)``. |
166 |
- post_hook : sequence of callables or None |
167 |
- Callables that are executed after scons is invoked. |
168 |
- Each callable should be defined as ``callable(*args, **kw)``. |
169 |
- source_files : list of str or None |
170 |
- List of paths to source files, relative to the directory of setup.py. |
171 |
- pkg_path : str or None |
172 |
- Path to the package for which the `SconsInfo` instance holds the |
173 |
- build info, relative to the directory of setup.py. |
174 |
- |
175 |
- Notes |
176 |
- ----- |
177 |
- All parameters are available as attributes of a `SconsInfo` instance. |
178 |
- |
179 |
- """ |
180 |
- def __init__(self, scons_path, parent_name, pre_hook, |
181 |
- post_hook, source_files, pkg_path): |
182 |
- self.scons_path = scons_path |
183 |
- self.parent_name = parent_name |
184 |
- self.pre_hook = pre_hook |
185 |
- self.post_hook = post_hook |
186 |
- self.source_files = source_files |
187 |
- if pkg_path: |
188 |
- self.pkg_path = pkg_path |
189 |
- else: |
190 |
- if scons_path: |
191 |
- self.pkg_path = os.path.dirname(scons_path) |
192 |
- else: |
193 |
- self.pkg_path = '' |
194 |
|
195 |
###################### |
196 |
|
197 |
class Configuration(object): |
198 |
|
199 |
_list_keys = ['packages', 'ext_modules', 'data_files', 'include_dirs', |
200 |
- 'libraries', 'headers', 'scripts', 'py_modules', 'scons_data', |
201 |
+ 'libraries', 'headers', 'scripts', 'py_modules', |
202 |
'installed_libraries'] |
203 |
_dict_keys = ['package_dir', 'installed_pkg_config'] |
204 |
_extra_keys = ['name', 'version'] |
205 |
@@ -853,7 +827,7 @@ |
206 |
caller_level = 1): |
207 |
l = subpackage_name.split('.') |
208 |
subpackage_path = njoin([self.local_path]+l) |
209 |
- dirs = filter(os.path.isdir,glob.glob(subpackage_path)) |
210 |
+ dirs = [_m for _m in glob.glob(subpackage_path) if os.path.isdir(_m)] |
211 |
config_list = [] |
212 |
for d in dirs: |
213 |
if not os.path.isfile(njoin(d,'__init__.py')): |
214 |
@@ -895,7 +869,7 @@ |
215 |
pn = dot_join(*([parent_name] + subpackage_name.split('.')[:-1])) |
216 |
args = (pn,) |
217 |
def fix_args_py2(args): |
218 |
- if setup_module.configuration.func_code.co_argcount > 1: |
219 |
+ if setup_module.configuration.__code__.co_argcount > 1: |
220 |
args = args + (self.top_path,) |
221 |
return args |
222 |
def fix_args_py3(args): |
223 |
@@ -922,14 +896,14 @@ |
224 |
|
225 |
Parameters |
226 |
---------- |
227 |
- subpackage_name: str,None |
228 |
+ subpackage_name : str or None |
229 |
Name of the subpackage to get the configuration. '*' in |
230 |
subpackage_name is handled as a wildcard. |
231 |
- subpackage_path: str |
232 |
+ subpackage_path : str |
233 |
If None, then the path is assumed to be the local path plus the |
234 |
subpackage_name. If a setup.py file is not found in the |
235 |
subpackage_path, then a default configuration is used. |
236 |
- parent_name: str |
237 |
+ parent_name : str |
238 |
Parent name. |
239 |
""" |
240 |
if subpackage_name is None: |
241 |
@@ -985,13 +959,13 @@ |
242 |
|
243 |
Parameters |
244 |
---------- |
245 |
- subpackage_name: str |
246 |
+ subpackage_name : str |
247 |
name of the subpackage |
248 |
- subpackage_path: str |
249 |
+ subpackage_path : str |
250 |
if given, the subpackage path such as the subpackage is in |
251 |
subpackage_path / subpackage_name. If None,the subpackage is |
252 |
assumed to be located in the local path / subpackage_name. |
253 |
- standalone: bool |
254 |
+ standalone : bool |
255 |
""" |
256 |
|
257 |
if standalone: |
258 |
@@ -1029,10 +1003,10 @@ |
259 |
|
260 |
Parameters |
261 |
---------- |
262 |
- data_path: seq,str |
263 |
+ data_path : seq or str |
264 |
Argument can be either |
265 |
|
266 |
- * 2-sequence (<datadir suffix>,<path to data directory>) |
267 |
+ * 2-sequence (<datadir suffix>, <path to data directory>) |
268 |
* path to data directory where python datadir suffix defaults |
269 |
to package dir. |
270 |
|
271 |
@@ -1091,14 +1065,14 @@ |
272 |
pattern_list = allpath(d).split(os.sep) |
273 |
pattern_list.reverse() |
274 |
# /a/*//b/ -> /a/*/b |
275 |
- rl = range(len(pattern_list)-1); rl.reverse() |
276 |
+ rl = list(range(len(pattern_list)-1)); rl.reverse() |
277 |
for i in rl: |
278 |
if not pattern_list[i]: |
279 |
del pattern_list[i] |
280 |
# |
281 |
for path in paths: |
282 |
if not os.path.isdir(path): |
283 |
- print('Not a directory, skipping',path) |
284 |
+ print('Not a directory, skipping', path) |
285 |
continue |
286 |
rpath = rel_path(path, self.local_path) |
287 |
path_list = rpath.split(os.sep) |
288 |
@@ -1151,7 +1125,7 @@ |
289 |
|
290 |
Parameters |
291 |
---------- |
292 |
- files: sequence |
293 |
+ files : sequence |
294 |
Argument(s) can be either |
295 |
|
296 |
* 2-sequence (<datadir prefix>,<path to data file(s)>) |
297 |
@@ -1330,7 +1304,7 @@ |
298 |
|
299 |
Parameters |
300 |
---------- |
301 |
- files: str, seq |
302 |
+ files : str or seq |
303 |
Argument(s) can be either: |
304 |
|
305 |
* 2-sequence (<includedir suffix>,<path to header file(s)>) |
306 |
@@ -1385,9 +1359,9 @@ |
307 |
|
308 |
Parameters |
309 |
---------- |
310 |
- name: str |
311 |
+ name : str |
312 |
name of the extension |
313 |
- sources: seq |
314 |
+ sources : seq |
315 |
list of the sources. The list of sources may contain functions |
316 |
(called source generators) which must take an extension instance |
317 |
and a build directory as inputs and return a source file or list of |
318 |
@@ -1395,28 +1369,28 @@ |
319 |
generated. If the Extension instance has no sources after |
320 |
processing all source generators, then no extension module is |
321 |
built. |
322 |
- include_dirs: |
323 |
- define_macros: |
324 |
- undef_macros: |
325 |
- library_dirs: |
326 |
- libraries: |
327 |
- runtime_library_dirs: |
328 |
- extra_objects: |
329 |
- extra_compile_args: |
330 |
- extra_link_args: |
331 |
- extra_f77_compile_args: |
332 |
- extra_f90_compile_args: |
333 |
- export_symbols: |
334 |
- swig_opts: |
335 |
- depends: |
336 |
+ include_dirs : |
337 |
+ define_macros : |
338 |
+ undef_macros : |
339 |
+ library_dirs : |
340 |
+ libraries : |
341 |
+ runtime_library_dirs : |
342 |
+ extra_objects : |
343 |
+ extra_compile_args : |
344 |
+ extra_link_args : |
345 |
+ extra_f77_compile_args : |
346 |
+ extra_f90_compile_args : |
347 |
+ export_symbols : |
348 |
+ swig_opts : |
349 |
+ depends : |
350 |
The depends list contains paths to files or directories that the |
351 |
sources of the extension module depend on. If any path in the |
352 |
depends list is newer than the extension module, then the module |
353 |
will be rebuilt. |
354 |
- language: |
355 |
- f2py_options: |
356 |
- module_dirs: |
357 |
- extra_info: dict,list |
358 |
+ language : |
359 |
+ f2py_options : |
360 |
+ module_dirs : |
361 |
+ extra_info : dict or list |
362 |
dict or list of dict of keywords to be appended to keywords. |
363 |
|
364 |
Notes |
365 |
@@ -1653,65 +1627,6 @@ |
366 |
self.installed_pkg_config[self.name] = [(template, install_dir, |
367 |
subst_dict)] |
368 |
|
369 |
- def add_scons_installed_library(self, name, install_dir): |
370 |
- """ |
371 |
- Add a scons-built installable library to distutils. |
372 |
- |
373 |
- Parameters |
374 |
- ---------- |
375 |
- name : str |
376 |
- The name of the library. |
377 |
- install_dir : str |
378 |
- Path to install the library, relative to the current sub-package. |
379 |
- |
380 |
- """ |
381 |
- install_dir = os.path.join(self.package_path, install_dir) |
382 |
- self.installed_libraries.append(InstallableLib(name, {}, install_dir)) |
383 |
- |
384 |
- def add_sconscript(self, sconscript, subpackage_path=None, |
385 |
- standalone = False, pre_hook = None, |
386 |
- post_hook = None, source_files = None, package_path=None): |
387 |
- """Add a sconscript to configuration. |
388 |
- |
389 |
- pre_hook and post hook should be sequences of callable, which will be |
390 |
- use before and after executing scons. The callable should be defined as |
391 |
- callable(*args, **kw). It is ugly, but well, hooks are ugly anyway... |
392 |
- |
393 |
- sconscript can be None, which can be useful to add only post/pre |
394 |
- hooks.""" |
395 |
- if standalone: |
396 |
- parent_name = None |
397 |
- else: |
398 |
- parent_name = self.name |
399 |
- |
400 |
- dist = self.get_distribution() |
401 |
- # Convert the sconscript name to a relative filename (relative from top |
402 |
- # setup.py's directory) |
403 |
- fullsconsname = self.paths(sconscript)[0] |
404 |
- |
405 |
- # XXX: Think about a way to automatically register source files from |
406 |
- # scons... |
407 |
- full_source_files = [] |
408 |
- if source_files: |
409 |
- full_source_files.extend([self.paths(i)[0] for i in source_files]) |
410 |
- |
411 |
- scons_info = SconsInfo(fullsconsname, parent_name, |
412 |
- pre_hook, post_hook, |
413 |
- full_source_files, package_path) |
414 |
- if dist is not None: |
415 |
- if dist.scons_data is None: |
416 |
- dist.scons_data = [] |
417 |
- dist.scons_data.append(scons_info) |
418 |
- self.warn('distutils distribution has been initialized,'\ |
419 |
- ' it may be too late to add a subpackage '+ subpackage_name) |
420 |
- # XXX: we add a fake extension, to correctly initialize some |
421 |
- # options in distutils command. |
422 |
- dist.add_extension('', sources = []) |
423 |
- else: |
424 |
- self.scons_data.append(scons_info) |
425 |
- # XXX: we add a fake extension, to correctly initialize some |
426 |
- # options in distutils command. |
427 |
- self.add_extension('', sources = []) |
428 |
|
429 |
def add_scripts(self,*files): |
430 |
"""Add scripts to configuration. |
431 |
@@ -2086,11 +2001,6 @@ |
432 |
""" |
433 |
self.py_modules.append((self.name,name,generate_config_py)) |
434 |
|
435 |
- def scons_make_config_py(self, name = '__config__'): |
436 |
- """Generate package __config__.py file containing system_info |
437 |
- information used during building the package. |
438 |
- """ |
439 |
- self.py_modules.append((self.name, name, scons_generate_config_py)) |
440 |
|
441 |
def get_info(self,*names): |
442 |
"""Get resources information. |
443 |
@@ -2098,7 +2008,7 @@ |
444 |
Return information (from system_info.get_info) for all of the names in |
445 |
the argument list in a single dictionary. |
446 |
""" |
447 |
- from system_info import get_info, dict_append |
448 |
+ from .system_info import get_info, dict_append |
449 |
info_dict = {} |
450 |
for a in names: |
451 |
dict_append(info_dict,**get_info(a)) |
452 |
@@ -2233,57 +2143,18 @@ |
453 |
return info |
454 |
|
455 |
def is_bootstrapping(): |
456 |
- import __builtin__ |
457 |
+ if sys.version_info[0] >= 3: |
458 |
+ import builtins |
459 |
+ else: |
460 |
+ import __builtin__ as builtins |
461 |
+ |
462 |
try: |
463 |
- __builtin__.__NUMPY_SETUP__ |
464 |
+ builtins.__NUMPY_SETUP__ |
465 |
return True |
466 |
except AttributeError: |
467 |
return False |
468 |
__NUMPY_SETUP__ = False |
469 |
|
470 |
-def scons_generate_config_py(target): |
471 |
- """generate config.py file containing system_info information |
472 |
- used during building the package. |
473 |
- |
474 |
- usage: |
475 |
- config['py_modules'].append((packagename, '__config__',generate_config_py)) |
476 |
- """ |
477 |
- from distutils.dir_util import mkpath |
478 |
- from numscons import get_scons_configres_dir, get_scons_configres_filename |
479 |
- d = {} |
480 |
- mkpath(os.path.dirname(target)) |
481 |
- f = open(target, 'w') |
482 |
- f.write('# this file is generated by %s\n' % (os.path.abspath(sys.argv[0]))) |
483 |
- f.write('# it contains system_info results at the time of building this package.\n') |
484 |
- f.write('__all__ = ["show"]\n\n') |
485 |
- confdir = get_scons_configres_dir() |
486 |
- confilename = get_scons_configres_filename() |
487 |
- for root, dirs, files in os.walk(confdir): |
488 |
- if files: |
489 |
- file = os.path.join(root, confilename) |
490 |
- assert root.startswith(confdir) |
491 |
- pkg_name = '.'.join(root[len(confdir)+1:].split(os.sep)) |
492 |
- fid = open(file, 'r') |
493 |
- try: |
494 |
- cnt = fid.read() |
495 |
- d[pkg_name] = eval(cnt) |
496 |
- finally: |
497 |
- fid.close() |
498 |
- # d is a dictionary whose keys are package names, and values the |
499 |
- # corresponding configuration. Each configuration is itself a dictionary |
500 |
- # (lib : libinfo) |
501 |
- f.write('_config = %s\n' % d) |
502 |
- f.write(r''' |
503 |
-def show(): |
504 |
- for pkg, config in _config.items(): |
505 |
- print("package %s configuration:" % pkg) |
506 |
- for lib, libc in config.items(): |
507 |
- print(' %s' % lib) |
508 |
- for line in libc.split('\n'): |
509 |
- print('\t%s' % line) |
510 |
- ''') |
511 |
- f.close() |
512 |
- return target |
513 |
|
514 |
######################### |
515 |
|
516 |
--- numpy/distutils/tests/test_misc_util.py.orig 2013-04-06 22:04:05.000000000 -0700 |
517 |
+++ numpy/distutils/tests/test_misc_util.py 2013-08-27 11:14:23.438843136 -0700 |
518 |
@@ -1,7 +1,9 @@ |
519 |
#!/usr/bin/env python |
520 |
+from __future__ import division, absolute_import, print_function |
521 |
|
522 |
from numpy.testing import * |
523 |
-from numpy.distutils.misc_util import appendpath, minrelpath, gpaths, rel_path |
524 |
+from numpy.distutils.misc_util import appendpath, minrelpath, \ |
525 |
+ gpaths, get_shared_lib_extension |
526 |
from os.path import join, sep, dirname |
527 |
|
528 |
ajoin = lambda *paths: join(*((sep,)+paths)) |
529 |
@@ -49,10 +51,25 @@ |
530 |
def test_gpaths(self): |
531 |
local_path = minrelpath(join(dirname(__file__),'..')) |
532 |
ls = gpaths('command/*.py', local_path) |
533 |
- assert_(join(local_path,'command','build_src.py') in ls,`ls`) |
534 |
+ assert_(join(local_path,'command','build_src.py') in ls,repr(ls)) |
535 |
f = gpaths('system_info.py', local_path) |
536 |
- assert_(join(local_path,'system_info.py')==f[0],`f`) |
537 |
+ assert_(join(local_path,'system_info.py')==f[0],repr(f)) |
538 |
|
539 |
+class TestSharedExtension(TestCase): |
540 |
+ |
541 |
+ def test_get_shared_lib_extension(self): |
542 |
+ import sys |
543 |
+ ext = get_shared_lib_extension(is_python_ext=False) |
544 |
+ if sys.platform.startswith('linux'): |
545 |
+ assert_equal(ext, '.so') |
546 |
+ elif sys.platform.startswith('gnukfreebsd'): |
547 |
+ assert_equal(ext, '.so') |
548 |
+ elif sys.platform.startswith('darwin'): |
549 |
+ assert_equal(ext, '.dylib') |
550 |
+ elif sys.platform.startswith('win'): |
551 |
+ assert_equal(ext, '.dll') |
552 |
+ # just check for no crash |
553 |
+ assert_(get_shared_lib_extension(is_python_ext=True)) |
554 |
|
555 |
if __name__ == "__main__": |
556 |
run_module_suite() |