1# Copyright 2014 The Chromium Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5import importlib
6
7from distutils import version
8
9MODULES = {
10  'cv2': (version.StrictVersion('2.4.8'), version.StrictVersion('3.0.0')),
11  'numpy': (version.StrictVersion('1.6.1'), None),
12  'psutil': (version.StrictVersion('0.5.0'), None),
13}
14
15def ImportRequiredModule(module):
16  """Tries to import the desired module.
17
18  Returns:
19    The module on success, raises error on failure.
20  Raises:
21    ImportError: The import failed."""
22  versions = MODULES.get(module)
23  if versions is None:
24    raise NotImplementedError('Please teach telemetry about module %s.' %
25                              module)
26  min_version, max_version = versions
27
28  module = importlib.import_module(module)
29  try:
30    if ((min_version is not None and
31            version.StrictVersion(module.__version__) < min_version) or
32        (max_version is not None and
33            version.StrictVersion(module.__version__) >= max_version)):
34      raise ImportError(('Incorrect {0} version found, expected {1} <= version '
35                         '< {2}, found version {3}').format(
36          module, min_version, max_version, module.__version__))
37  except ValueError as e:
38    # This error is raised when a module returns and incorrectly formatted
39    # version string. ex. '$build 1456a'
40    if 'invalid version number' in str(e):
41      raise ImportError(('Incorrectly formatted {0} version found, expected '
42                         '{1} <= version < {2}, found version {3}').format(
43          module, min_version, max_version, module.__version__))
44    else:
45      raise
46  return module
47
48def ImportOptionalModule(module):
49  """Tries to import the desired module.
50
51  Returns:
52    The module if successful, None if not."""
53  try:
54    return ImportRequiredModule(module)
55  except ImportError:
56    return None
57