handle unavailable traits due to version differences
Showing 1 of 3 files from the diff.
nipype/interfaces/base/core.py
changed.
Other files ignored by Codecov
nipype/interfaces/tests/test_io.py
has changed.
nipype/interfaces/base/tests/test_core.py
has changed.
@@ -31,7 +31,7 @@
Loading
31 | 31 | ||
32 | 32 | from ...external.due import due |
|
33 | 33 | ||
34 | - | from .traits_extension import traits, isdefined |
|
34 | + | from .traits_extension import traits, isdefined, Undefined |
|
35 | 35 | from .specs import ( |
|
36 | 36 | BaseInterfaceInputSpec, |
|
37 | 37 | CommandLineInputSpec, |
@@ -180,7 +180,16 @@
Loading
180 | 180 | if not self.input_spec: |
|
181 | 181 | raise Exception("No input_spec in class: %s" % self.__class__.__name__) |
|
182 | 182 | ||
183 | - | self.inputs = self.input_spec(**inputs) |
|
183 | + | # Create input spec, disable any defaults that are unavailable due to |
|
184 | + | # version, and then apply the inputs that were passed. |
|
185 | + | self.inputs = self.input_spec() |
|
186 | + | unavailable_traits = self._check_version_requirements( |
|
187 | + | self.inputs, permissive=True |
|
188 | + | ) |
|
189 | + | if unavailable_traits: |
|
190 | + | self.inputs.trait_set(**{k: Undefined for k in unavailable_traits}) |
|
191 | + | self.inputs.trait_set(**inputs) |
|
192 | + | ||
184 | 193 | self.ignore_exception = ignore_exception |
|
185 | 194 | ||
186 | 195 | if resource_monitor is not None: |
@@ -264,8 +273,12 @@
Loading
264 | 273 | ): |
|
265 | 274 | self._check_requires(spec, name, getattr(self.inputs, name)) |
|
266 | 275 | ||
267 | - | def _check_version_requirements(self, trait_object, raise_exception=True): |
|
276 | + | def _check_version_requirements(self, trait_object, permissive=False): |
|
268 | 277 | """ Raises an exception on version mismatch |
|
278 | + | ||
279 | + | Set the ``permissive`` attribute to True to suppress warnings and exceptions. |
|
280 | + | This is currently only used in __init__ to silently identify unavailable |
|
281 | + | traits. |
|
269 | 282 | """ |
|
270 | 283 | unavailable_traits = [] |
|
271 | 284 | # check minimum version |
@@ -283,7 +296,8 @@
Loading
283 | 296 | f"Nipype cannot validate the package version {version!r} for " |
|
284 | 297 | f"{self.__class__.__name__}. Trait {name} requires version >={min_ver}." |
|
285 | 298 | ) |
|
286 | - | iflogger.warning(f"{msg}. Please verify validity.") |
|
299 | + | if not permissive: |
|
300 | + | iflogger.warning(f"{msg}. Please verify validity.") |
|
287 | 301 | if config.getboolean("execution", "stop_on_unknown_version"): |
|
288 | 302 | raise ValueError(msg) from err |
|
289 | 303 | continue |
@@ -291,7 +305,7 @@
Loading
291 | 305 | unavailable_traits.append(name) |
|
292 | 306 | if not isdefined(getattr(trait_object, name)): |
|
293 | 307 | continue |
|
294 | - | if raise_exception: |
|
308 | + | if not permissive: |
|
295 | 309 | raise Exception( |
|
296 | 310 | "Trait %s (%s) (version %s < required %s)" |
|
297 | 311 | % (name, self.__class__.__name__, version, min_ver) |
@@ -311,7 +325,8 @@
Loading
311 | 325 | f"Nipype cannot validate the package version {version!r} for " |
|
312 | 326 | f"{self.__class__.__name__}. Trait {name} requires version <={max_ver}." |
|
313 | 327 | ) |
|
314 | - | iflogger.warning(f"{msg}. Please verify validity.") |
|
328 | + | if not permissive: |
|
329 | + | iflogger.warning(f"{msg}. Please verify validity.") |
|
315 | 330 | if config.getboolean("execution", "stop_on_unknown_version"): |
|
316 | 331 | raise ValueError(msg) from err |
|
317 | 332 | continue |
@@ -319,7 +334,7 @@
Loading
319 | 334 | unavailable_traits.append(name) |
|
320 | 335 | if not isdefined(getattr(trait_object, name)): |
|
321 | 336 | continue |
|
322 | - | if raise_exception: |
|
337 | + | if not permissive: |
|
323 | 338 | raise Exception( |
|
324 | 339 | "Trait %s (%s) (version %s > required %s)" |
|
325 | 340 | % (name, self.__class__.__name__, version, max_ver) |
Files | Coverage |
---|---|
nipype | 64.70% |
Project Totals (302 files) | 64.70% |
1 |
coverage: |
2 |
range: "0...100" |
3 |
status: |
4 |
patch: |
5 |
default: |
6 |
target: 0 |
7 |
threshold: 100 |
8 |
project: |
9 |
default: |
10 |
target: 0 |
11 |
threshold: 100 |
12 |
patch: |
13 |
target: 0 |
14 |
threshold: 100 |
15 |
unittests: |
16 |
target: 0 |
17 |
threshold: 100 |
18 |
flags: |
19 |
- "unittests" |
20 |
smoketests: |
21 |
target: 0 |
22 |
threshold: 100 |
23 |
flags: |
24 |
- "smoketests" |
25 |
ignore: # files and folders that will be removed during processing |
26 |
- "nipype/external" |
27 |
- "tools" |
28 |
- "doc" |
29 |
- "**/tests" |
30 |
- "examples" |
Sunburst
The inner-most circle is the entire project, moving away from the center are folders then, finally, a single file.
The size and color of each slice is representing the number of statements and the coverage, respectively.
Icicle
The top section represents the entire project. Proceeding with folders and finally individual files.
The size and color of each slice is representing the number of statements and the coverage, respectively.