From fa3045baa03aa163d31a26273756efc636b91ba6 Mon Sep 17 00:00:00 2001
From: Yong Tang <yong.tang.github@outlook.com>
Date: Fri, 25 Sep 2020 11:17:33 +0000
Subject: [PATCH] Avoid using TF file system before TF is initialized with
 plugins (avoid circular dependency)

While playing with modular file systems I noticed that
if modular file systems is enabled through bazel with linkage inclusion,
tensorflow will not be able to be imported:
```
>>> import tensorflow as tf
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.8/dist-packages/tensorflow/__init__.py", line 434, in <module>
    _ll.load_library(_main_dir)
  File "/usr/local/lib/python3.8/dist-packages/tensorflow/python/framework/load_library.py", line 143, in load_library
    if file_io.file_exists(library_location):
  File "/usr/local/lib/python3.8/dist-packages/tensorflow/python/lib/io/file_io.py", line 250, in file_exists
    return file_exists_v2(filename)
  File "/usr/local/lib/python3.8/dist-packages/tensorflow/python/lib/io/file_io.py", line 268, in file_exists_v2
    _pywrap_file_io.FileExists(compat.path_to_bytes(path))
tensorflow.python.framework.errors_impl.UnimplementedError: File system scheme '[local]' not implemented (file: '/usr/local/lib/python3.8/dist-packages/tensorflow/core/kernels')
```

The reason is that, at the very beginning of tensorflow, tf will try
to load libraries in .so file (see tensorflow/__init__.py).
However, at this time the plugins has not been initialized yet, so
TF's own `file_io.file_exists` is not working yet. But as
`tf.load_library` used `file_io.file_exists`, this causes a circular dependency.

This PR replaces `file_io.file_exists` with `os.path.exists` in or before `tf.load_library`.

This will not impact exisitng behavior: since `tf.load_library` relies on `dlopen`
(and `LoadLibrary` on Windows), a non-native file system (e.g., s3/gcs/etc) will
not work with `tf.load_library` anyway. As such there is no need to use gcs/s3 compatible
`file_io.file_exists`.

This PR is part of the effort to enable modular file system from external repos (e.g., tensorflow-io).

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
---
 tensorflow/api_template.__init__.py         | 4 ++--
 tensorflow/api_template_v1.__init__.py      | 4 ++--
 tensorflow/python/framework/load_library.py | 7 +++----
 3 files changed, 7 insertions(+), 8 deletions(-)

diff --git a/tensorflow/api_template.__init__.py b/tensorflow/api_template.__init__.py
index 5932dda514d..99a278a14a4 100644
--- a/tensorflow/api_template.__init__.py
+++ b/tensorflow/api_template.__init__.py
@@ -138,12 +138,12 @@ if _running_from_pip_package():
   for _s in _site_packages_dirs:
     # Load first party dynamic kernels.
     _main_dir = _os.path.join(_s, 'tensorflow/core/kernels')
-    if _fi.file_exists(_main_dir):
+    if _os.path.exists(_main_dir):
       _ll.load_library(_main_dir)
 
     # Load third party dynamic kernels.
     _plugin_dir = _os.path.join(_s, 'tensorflow-plugins')
-    if _fi.file_exists(_plugin_dir):
+    if _os.path.exists(_plugin_dir):
       _ll.load_library(_plugin_dir)
 
 # Add module aliases
diff --git a/tensorflow/api_template_v1.__init__.py b/tensorflow/api_template_v1.__init__.py
index 0d1d2e56fae..ae82f7b4792 100644
--- a/tensorflow/api_template_v1.__init__.py
+++ b/tensorflow/api_template_v1.__init__.py
@@ -148,12 +148,12 @@ if _running_from_pip_package():
   for _s in _site_packages_dirs:
     # Load first party dynamic kernels.
     _main_dir = _os.path.join(_s, 'tensorflow/core/kernels')
-    if _fi.file_exists(_main_dir):
+    if _os.path.exists(_main_dir):
       _ll.load_library(_main_dir)
 
     # Load third party dynamic kernels.
     _plugin_dir = _os.path.join(_s, 'tensorflow-plugins')
-    if _fi.file_exists(_plugin_dir):
+    if _os.path.exists(_plugin_dir):
       _ll.load_library(_plugin_dir)
 
 # Delete modules that should be hidden from dir().
diff --git a/tensorflow/python/framework/load_library.py b/tensorflow/python/framework/load_library.py
index 2e7bade095b..f37b48e76c2 100644
--- a/tensorflow/python/framework/load_library.py
+++ b/tensorflow/python/framework/load_library.py
@@ -27,7 +27,6 @@ import sys
 
 from tensorflow.python import _pywrap_python_op_gen
 from tensorflow.python.client import pywrap_tf_session as py_tf
-from tensorflow.python.lib.io import file_io
 from tensorflow.python.util import deprecation
 from tensorflow.python.util.tf_export import tf_export
 
@@ -140,9 +139,9 @@ def load_library(library_location):
     OSError: When the file to be loaded is not found.
     RuntimeError: when unable to load the library.
   """
-  if file_io.file_exists(library_location):
-    if file_io.is_directory(library_location):
-      directory_contents = file_io.list_directory(library_location)
+  if os.path.exists(library_location):
+    if os.path.isdir(library_location):
+      directory_contents = os.listdir(library_location)
 
       kernel_libraries = [
           os.path.join(library_location, f) for f in directory_contents