99Requires Packages to be installed
1010"""
1111from __future__ import print_function , division , unicode_literals , absolute_import
12- from future import standard_library
13- standard_library . install_aliases ()
12+ import gc
13+
1414from builtins import range , object , open , str , bytes
1515
16- from configparser import NoOptionError
1716from copy import deepcopy
1817import datetime
1918from datetime import datetime as dt
2625import select
2726import subprocess as sp
2827import sys
29- import time
3028from textwrap import wrap
3129from warnings import warn
3230import simplejson as json
4341 traits , Undefined , TraitDictObject , TraitListObject , TraitError , isdefined ,
4442 File , Directory , DictStrStr , has_metadata , ImageFile )
4543from ..external .due import due
44+ from future import standard_library
45+ standard_library .install_aliases ()
4646
4747nipype_version = Version (__version__ )
4848iflogger = logging .getLogger ('interface' )
5858class Str (traits .Unicode ):
5959 """Replacement for the default traits.Str based in bytes"""
6060
61+
6162traits .Str = Str
6263
6364
@@ -1260,6 +1261,7 @@ class SimpleInterface(BaseInterface):
12601261 >>> os.chdir(old.strpath)
12611262
12621263 """
1264+
12631265 def __init__ (self , from_file = None , resource_monitor = None , ** inputs ):
12641266 super (SimpleInterface , self ).__init__ (
12651267 from_file = from_file , resource_monitor = resource_monitor , ** inputs )
@@ -1387,8 +1389,7 @@ def run_command(runtime, output=None, timeout=0.01):
13871389 shell = True ,
13881390 cwd = runtime .cwd ,
13891391 env = env ,
1390- close_fds = True ,
1391- )
1392+ close_fds = True )
13921393 result = {
13931394 'stdout' : [],
13941395 'stderr' : [],
@@ -1427,37 +1428,50 @@ def _process(drain=0):
14271428 temp .sort ()
14281429 result ['merged' ] = [r [1 ] for r in temp ]
14291430
1430- if output == 'allatonce' :
1431- stdout , stderr = proc .communicate ()
1432- result ['stdout' ] = read_stream (stdout , logger = iflogger )
1433- result ['stderr' ] = read_stream (stderr , logger = iflogger )
1434-
1435- elif output .startswith ('file' ):
1431+ if output .startswith ('file' ):
14361432 proc .wait ()
14371433 if outfile is not None :
14381434 stdout .flush ()
14391435 stdout .close ()
14401436 with open (outfile , 'rb' ) as ofh :
14411437 stdoutstr = ofh .read ()
14421438 result ['stdout' ] = read_stream (stdoutstr , logger = iflogger )
1439+ del stdoutstr
14431440
14441441 if errfile is not None :
14451442 stderr .flush ()
14461443 stderr .close ()
14471444 with open (errfile , 'rb' ) as efh :
14481445 stderrstr = efh .read ()
14491446 result ['stderr' ] = read_stream (stderrstr , logger = iflogger )
1447+ del stderrstr
14501448
14511449 if output == 'file' :
14521450 result ['merged' ] = result ['stdout' ]
14531451 result ['stdout' ] = []
14541452 else :
1455- proc .communicate () # Discard stdout and stderr
1453+ stdout , stderr = proc .communicate ()
1454+ if output == 'allatonce' : # Discard stdout and stderr otherwise
1455+ result ['stdout' ] = read_stream (stdout , logger = iflogger )
1456+ result ['stderr' ] = read_stream (stderr , logger = iflogger )
1457+
1458+ runtime .returncode = proc .returncode
1459+ try :
1460+ proc .terminate () # Ensure we are done
1461+ except OSError as error :
1462+ # Python 2 raises when the process is already gone
1463+ if error .errno != errno .ESRCH :
1464+ raise
1465+
1466+ # Dereference & force GC for a cleanup
1467+ del proc
1468+ del stdout
1469+ del stderr
1470+ gc .collect ()
14561471
14571472 runtime .stderr = '\n ' .join (result ['stderr' ])
14581473 runtime .stdout = '\n ' .join (result ['stdout' ])
14591474 runtime .merged = '\n ' .join (result ['merged' ])
1460- runtime .returncode = proc .returncode
14611475 return runtime
14621476
14631477
@@ -1467,21 +1481,26 @@ def get_dependencies(name, environ):
14671481 Uses otool on darwin, ldd on linux. Currently doesn't support windows.
14681482
14691483 """
1484+ cmd = None
14701485 if sys .platform == 'darwin' :
1471- proc = sp .Popen ('otool -L `which %s`' % name ,
1472- stdout = sp .PIPE ,
1473- stderr = sp .PIPE ,
1474- shell = True ,
1475- env = environ )
1486+ cmd = 'otool -L `which {}`' .format
14761487 elif 'linux' in sys .platform :
1477- proc = sp .Popen ('ldd `which %s`' % name ,
1478- stdout = sp .PIPE ,
1479- stderr = sp .PIPE ,
1480- shell = True ,
1481- env = environ )
1482- else :
1488+ cmd = 'ldd -L `which {}`' .format
1489+
1490+ if cmd is None :
14831491 return 'Platform %s not supported' % sys .platform
1484- o , e = proc .communicate ()
1492+
1493+ try :
1494+ proc = sp .Popen (
1495+ cmd (name ), stdout = sp .PIPE , stderr = sp .PIPE , shell = True ,
1496+ env = environ , close_fds = True )
1497+ o , _ = proc .communicate ()
1498+ proc .terminate ()
1499+ gc .collect ()
1500+ except :
1501+ iflogger .warning (
1502+ 'Could not get linked libraries for "%s".' , name )
1503+ return 'Failed collecting dependencies'
14851504 return o .rstrip ()
14861505
14871506
@@ -1572,6 +1591,9 @@ def __init__(self, command=None, terminal_output=None, **inputs):
15721591 # Set command. Input argument takes precedence
15731592 self ._cmd = command or getattr (self , '_cmd' , None )
15741593
1594+ # Store dependencies in runtime object
1595+ self ._ldd = str2bool (config .get ('execution' , 'get_linked_libs' , 'true' ))
1596+
15751597 if self ._cmd is None :
15761598 raise Exception ("Missing command" )
15771599
@@ -1620,6 +1642,8 @@ def _get_environ(self):
16201642 return getattr (self .inputs , 'environ' , {})
16211643
16221644 def version_from_command (self , flag = '-v' ):
1645+ iflogger .warning ('version_from_command member of CommandLine was '
1646+ 'Deprecated in nipype-1.0.0 and deleted in 1.1.0' )
16231647 cmdname = self .cmd .split ()[0 ]
16241648 env = dict (os .environ )
16251649 if _exists_in_path (cmdname , env ):
@@ -1664,7 +1688,8 @@ def _run_interface(self, runtime, correct_return_codes=(0,)):
16641688 (self .cmd .split ()[0 ], runtime .hostname ))
16651689
16661690 runtime .command_path = cmd_path
1667- runtime .dependencies = get_dependencies (executable_name , runtime .environ )
1691+ runtime .dependencies = (get_dependencies (executable_name , runtime .environ )
1692+ if self ._ldd else '<skipped>' )
16681693 runtime = run_command (runtime , output = self .terminal_output )
16691694 if runtime .returncode is None or \
16701695 runtime .returncode not in correct_return_codes :
0 commit comments