|
14 | 14 |
|
15 | 15 | """Compatibility interfaces for TensorBoard. |
16 | 16 |
|
17 | | -This module provides logic for importing variations on the TensorFlow APIs. |
18 | | -
|
19 | | -The alias `tf` is for the main TF API used by TensorBoard. By default this will |
20 | | -be the result of `import tensorflow as tf`, or undefined if that fails. This |
21 | | -can be used in combination with //tensorboard/compat:tensorflow (to fall back to |
22 | | -a stub TF API implementation if the real one is not available) and |
23 | | -//tensorboard/compat:no_tensorflow (to use the stub TF API unconditionally). |
24 | | -
|
25 | | -The function `import_tf_v2` provides common logic for importing the TF 2.0 API, |
26 | | -and returns the root module of the API if found, or else raises ImportError. |
27 | | -This is a function instead of a direct alias like `tf` in order to provide |
28 | | -enough indirection to get around circular dependencies. |
| 17 | +This module provides logic for importing variations on the TensorFlow APIs, as |
| 18 | +lazily loaded imports to help avoid circular dependency issues and defer the |
| 19 | +search and loading of the module until necessary. |
29 | 20 | """ |
30 | 21 |
|
31 | 22 | from __future__ import absolute_import |
32 | 23 | from __future__ import division |
33 | 24 | from __future__ import print_function |
34 | 25 |
|
35 | | -# First, check if using TF is explicitly disabled by request. |
36 | | -USING_TF = True |
37 | | -try: |
38 | | - from tensorboard.compat import notf |
39 | | - USING_TF = False |
40 | | -except ImportError: |
41 | | - pass |
| 26 | +import importlib as _importlib |
| 27 | + |
| 28 | +import tensorboard.lazy as _lazy |
42 | 29 |
|
43 | | -# If TF is not disabled, check if it's available. |
44 | | -if USING_TF: |
45 | | - try: |
46 | | - import tensorflow as tf |
47 | | - except ImportError: |
48 | | - USING_TF = False |
49 | 30 |
|
50 | | -if not USING_TF: |
51 | | - # If we can't use TF, try to provide the stub instead. |
52 | | - # This will only work if the tensorflow_stub dep is included |
53 | | - # in the build, via the `tensorboard/compat:tensorflow` target. |
| 31 | +@_lazy.lazy_load('tensorboard.compat.tf') |
| 32 | +def tf(): |
| 33 | + """Provide the root module of a TF-like API for use within TensorBoard. |
| 34 | +
|
| 35 | + By default this is equivalent to `import tensorflow as tf`, but it can be used |
| 36 | + in combination with //tensorboard/compat:tensorflow (to fall back to a stub TF |
| 37 | + API implementation if the real one is not available) or with |
| 38 | + //tensorboard/compat:no_tensorflow (to force unconditional use of the stub). |
| 39 | +
|
| 40 | + Returns: |
| 41 | + The root module of a TF-like API, if available. |
| 42 | +
|
| 43 | + Raises: |
| 44 | + ImportError: if a TF-like API is not available. |
| 45 | + """ |
54 | 46 | try: |
55 | | - from tensorboard.compat import tensorflow_stub as tf |
| 47 | + _importlib.import_module('tensorboard.compat.notf') |
56 | 48 | except ImportError: |
57 | | - pass |
| 49 | + try: |
| 50 | + return _importlib.import_module('tensorflow') |
| 51 | + except ImportError: |
| 52 | + pass |
| 53 | + return _importlib.import_module('tensorboard.compat.tensorflow_stub') # pylint: disable=line-too-long |
| 54 | + |
| 55 | + |
| 56 | +@_lazy.lazy_load('tensorboard.compat.tf2') |
| 57 | +def tf2(): |
| 58 | + """Provide the root module of a TF-2.0 API for use within TensorBoard. |
58 | 59 |
|
| 60 | + Returns: |
| 61 | + The root module of a TF-2.0 API, if available. |
59 | 62 |
|
60 | | -def import_tf_v2(): |
61 | | - """Import the TF 2.0 API if possible, or raise an ImportError.""" |
62 | | - # We must be able to use TF in order to provide the TF 2.0 API. |
63 | | - if USING_TF: |
64 | | - # Check if this is TF 2.0 by looking for a known 2.0-only tf.summary symbol. |
65 | | - # TODO(nickfelt): determine a cleaner way to do this. |
66 | | - if hasattr(tf, 'summary') and hasattr(tf.summary, 'write'): |
67 | | - return tf |
68 | | - else: |
69 | | - # As a fallback, try `tensorflow.compat.v2` if it's defined. |
70 | | - if hasattr(tf, 'compat') and hasattr(tf.compat, 'v2'): |
71 | | - return tf.compat.v2 |
| 63 | + Raises: |
| 64 | + ImportError: if a TF-2.0 API is not available. |
| 65 | + """ |
| 66 | + # Import the `tf` compat API from this file and check if it's already TF 2.0. |
| 67 | + if tf.__version__.startswith('2.'): |
| 68 | + return tf |
| 69 | + elif hasattr(tf, 'compat') and hasattr(tf.compat, 'v2'): |
| 70 | + # As a fallback, try `tensorflow.compat.v2` if it's defined. |
| 71 | + return tf.compat.v2 |
72 | 72 | raise ImportError('cannot import tensorflow 2.0 API') |
0 commit comments