diff --git a/.et b/.et new file mode 100644 index 0000000000..96ed9287ea --- /dev/null +++ b/.et @@ -0,0 +1,3 @@ +{ "bad_versions" : [ "1.2.1", + "1.2.3"] +} \ No newline at end of file diff --git a/nipype/__init__.py b/nipype/__init__.py index 8d135bf061..821a411009 100644 --- a/nipype/__init__.py +++ b/nipype/__init__.py @@ -22,9 +22,7 @@ config = NipypeConfig() logging = Logging(config) -logger = logging.getLogger('nipype.utils') -INIT_MSG = "Running {packname} version {version} (latest: {latest})".format class NipypeTester(object): def __call__(self, doctests=True, parallel=False): @@ -60,15 +58,46 @@ def get_info(): Rename, Function, Select, Merge) -if config.getboolean('execution', 'check_version'): +def check_latest_version(raise_exception=False): + """Check for the latest version of the library + + parameters: + raise_exception: boolean + Raise a RuntimeError if a bad version is being used + """ import etelemetry + logger = logging.getLogger('nipype.utils') + + INIT_MSG = "Running {packname} version {version} (latest: {latest})".format - latest = {"version": 'Unknown'} + latest = {"version": 'Unknown', "bad_versions": []} + result = None try: - latest = etelemetry.get_project("nipy/nipype") + result = etelemetry.get_project("nipy/nipype") except Exception as e: logger.warning("Could not check for version updates: \n%s", e) finally: - logger.info(INIT_MSG(packname='nipype', - version=__version__, - latest=latest["version"])) + if result: + latest.update(**result) + if LooseVersion(__version__) != LooseVersion(latest["version"]): + logger.info(INIT_MSG(packname='nipype', + version=__version__, + latest=latest["version"])) + if latest["bad_versions"] and \ + any([LooseVersion(__version__) == LooseVersion(ver) + for ver in latest["bad_versions"]]): + message = ('You are using a version of Nipype with a critical ' + 'bug. Please use a different version.') + if raise_exception: + raise RuntimeError(message) + else: + logger.critical(message) + return latest + +# Run telemetry on import for interactive sessions, such as IPython, Jupyter notebooks, Python REPL +if config.getboolean('execution', 'check_version'): + import __main__ + if not hasattr(__main__, '__file__'): + from .interfaces.base import BaseInterface + if BaseInterface._etelemetry_version_data is None: + BaseInterface._etelemetry_version_data = check_latest_version() diff --git a/nipype/interfaces/base/core.py b/nipype/interfaces/base/core.py index 7ba8486082..85cad50045 100644 --- a/nipype/interfaces/base/core.py +++ b/nipype/interfaces/base/core.py @@ -166,9 +166,15 @@ class BaseInterface(Interface): _redirect_x = False references_ = [] resource_monitor = True # Enabled for this interface IFF enabled in the config + _etelemetry_version_data = None def __init__(self, from_file=None, resource_monitor=None, ignore_exception=False, **inputs): + if config.getboolean('execution', 'check_version'): + from ... import check_latest_version + if BaseInterface._etelemetry_version_data is None: + BaseInterface._etelemetry_version_data = check_latest_version() + if not self.input_spec: raise Exception( 'No input_spec in class: %s' % self.__class__.__name__)