We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
cutils fails when cutils_ext already present elsewhere in sys.path
EDIT: Now it work with the c|py linker, but not with the cvm linker.

Theano's cutils moudle expects to find cutils_ext inside config.compiledir.

In cutils.py, cutils_ext.cutils_ext will be loaded.  On an import error, this extension will be built and eventually cmodule.dlimport will re-import cutils_ext.cutils_ext.  dlimport will inject config.compiledir into the front of sys,path, so the cutils_ext should always be loaded from config.compiledir.

Normally, this will then allow cutils_ext.cutils_ext to be loaded.  The problem is if the cutils_ext package was found elsewhere on sys.path, but not the cutils_ext module (extension) within that package.  cutils.py lacks the sys.path injection of dlimport.  The consequence is that the import of cutils_ext.cutils_ext in dlimport fails because the reference to the outer cutils_ext (the package) will be the incorrect path!

Needless to say, when a user encounters this bug, it is a pain to solve.

The solution is to ensure that the cutils.py try statement starts with:

sys.path.insert(0,theano.config.compiledir)
with the finally doing:
del sys.path[0]


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `theano/gof/cutils.py`
Content:
```
1 import os
2 import sys
3 from compilelock import get_lock, release_lock
4 from theano import config
5 
6 # TODO These two lines may be removed in the future, when we are 100% sure
7 # noone has an old cutils_ext.so lying around anymore.
8 if os.path.exists(os.path.join(config.compiledir, 'cutils_ext.so')):
9     os.remove(os.path.join(config.compiledir, 'cutils_ext.so'))
10 
11 
12 def compile_cutils():
13     """Do just the compilation of cutils_ext"""
14     code = """
15         #include <Python.h>
16         extern "C"{
17         static PyObject *
18         run_cthunk(PyObject *self, PyObject *args)
19         {
20           PyObject *py_cthunk = NULL;
21           if(!PyArg_ParseTuple(args,"O",&py_cthunk))
22             return NULL;
23 
24           if (!PyCObject_Check(py_cthunk)) {
25             PyErr_SetString(PyExc_ValueError,
26                            "Argument to run_cthunk must be a PyCObject.");
27             return NULL;
28           }
29           void * ptr_addr = PyCObject_AsVoidPtr(py_cthunk);
30           int (*fn)(void*) = (int (*)(void*))(ptr_addr);
31           void* it = PyCObject_GetDesc(py_cthunk);
32           int failure = fn(it);
33 
34           return Py_BuildValue("i", failure);
35         }
36 
37         static PyMethodDef CutilsExtMethods[] = {
38             {"run_cthunk",  run_cthunk, METH_VARARGS|METH_KEYWORDS,
39              "Run a theano cthunk."},
40             {NULL, NULL, 0, NULL}        /* Sentinel */
41         };
42 
43         PyMODINIT_FUNC
44         initcutils_ext(void)
45         {
46           (void) Py_InitModule("cutils_ext", CutilsExtMethods);
47         }
48         }
49         """
50 
51     loc = os.path.join(config.compiledir, 'cutils_ext')
52     if not os.path.exists(loc):
53         os.mkdir(loc)
54 
55     args = cmodule.GCC_compiler.compile_args()
56     cmodule.GCC_compiler.compile_str('cutils_ext', code, location=loc,
57                                      preargs=args)
58 
59 try:
60     # See gh issue #728 for why these lines are here. Summary: compiledir
61     # must be at the beginning of the path to avoid conflicts with any other
62     # cutils_ext modules that might exist. An __init__.py file must be created
63     # for the same reason. Note that these 5 lines may seem redundant (they are
64     # repeated in compile_str()) but if another cutils_ext does exist then it
65     # will be imported and compile_str won't get called at all.
66     sys.path.insert(0, config.compiledir)
67     location = os.path.join(config.compiledir, 'cutils_ext')
68     if not os.path.exists(location):
69         os.mkdir(location)
70     file(os.path.join(location, "__init__.py"), 'w').close()
71 
72     try:
73         from cutils_ext.cutils_ext import *
74     except ImportError:
75         import cmodule
76 
77         get_lock()
78     # Ensure no-one else is currently modifying the content of the compilation
79     # directory. This is important to prevent multiple processes from trying to
80     # compile the cutils_ext module simultaneously.
81         try:
82             try:
83                 # We must retry to import it as some other processs could
84                 # have been compiling it between the first failed import
85                 # and when we receive the lock
86                 from cutils_ext.cutils_ext import *
87             except ImportError:
88                 import cmodule
89 
90                 compile_cutils()
91                 from cutils_ext.cutils_ext import *
92 
93         finally:
94             # Release lock on compilation directory.
95             release_lock()
96 finally:
97     if sys.path[0] == config.compiledir:
98         del sys.path[0]
99
```

Path: `theano/gof/lazylinker_c.py`
Content:
```
1 import os, logging, sys
2 
3 import theano
4 from theano import config
5 from theano.gof.compilelock import get_lock, release_lock
6 from theano.gof import cmodule
7 
8 _logger = logging.getLogger('theano.gof.lazylinker_c')
9 
10 force_compile = False
11 version = 0.20  # must match constant returned in function get_version()
12 
13 def try_import():
14     global lazylinker_ext
15     sys.path[0:0] = [config.compiledir]
16     import lazylinker_ext
17     del sys.path[0]
18 
19 def try_reload():
20     sys.path[0:0] = [config.compiledir]
21     reload(lazylinker_ext)
22     del sys.path[0]
23 
24 try:
25     _need_reload = False
26     if force_compile:
27         raise ImportError()
28     else:
29         try_import()
30         _need_reload = True
31         if version != getattr(lazylinker_ext, '_version', None):
32             raise ImportError()
33 except ImportError:
34     get_lock()
35     try:
36         # Maybe someone else already finished compiling it while we were
37         # waiting for the lock?
38         try:
39             if force_compile:
40                 raise ImportError()
41             if _need_reload:
42                 # The module was successfully imported earlier: we need to
43                 # reload it to check if the version was updated.
44                 try_reload()
45             else:
46                 try_import()
47                 _need_reload = True
48             if version != getattr(lazylinker_ext, '_version', None):
49                 raise ImportError()
50         except ImportError:
51             _logger.info("Compiling new CVM")
52             dirname = 'lazylinker_ext'
53             # We use a .txt extensions as otherwise it don't get
54             # included when we create a package to send to pypi
55             # This happen even if we tell to include *.c files
56             cfile = os.path.join(theano.__path__[0], 'gof', 'lazylinker_c.c.txt')
57             code = open(cfile).read()
58             loc = os.path.join(config.compiledir, dirname)
59             if not os.path.exists(loc):
60                 os.mkdir(loc)
61             args = cmodule.GCC_compiler.compile_args()
62             cmodule.GCC_compiler.compile_str(dirname, code, location=loc,
63                                              preargs=args)
64             # Save version into the __init__.py file.
65             init_py = os.path.join(loc, '__init__.py')
66             open(init_py, 'w').write('_version = %s\n' % version)
67             # If we just compiled the module for the first time, then it was
68             # imported at the same time: we need to make sure we do not
69             # reload the now outdated __init__.pyc below.
70             init_pyc = os.path.join(loc, '__init__.pyc')
71             if os.path.isfile(init_pyc):
72                 os.remove(init_pyc)
73             try_import()
74             try_reload()
75             from lazylinker_ext import lazylinker_ext as lazy_c
76             assert (lazylinker_ext._version ==
77                     lazy_c.get_version())
78             _logger.info("New version %s", lazylinker_ext._version)
79     finally:
80         # Release lock on compilation directory.
81         release_lock()
82 
83 from lazylinker_ext.lazylinker_ext import *
84 assert force_compile or (version == get_version())
85
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/theano/gof/cutils.py b/theano/gof/cutils.py
--- a/theano/gof/cutils.py
+++ b/theano/gof/cutils.py
@@ -67,7 +67,8 @@
     location = os.path.join(config.compiledir, 'cutils_ext')
     if not os.path.exists(location):
         os.mkdir(location)
-    file(os.path.join(location, "__init__.py"), 'w').close()
+    if not os.path.exists(os.path.join(location, '__init__.py')):
+        file(os.path.join(location, '__init__.py'), 'w').close()
 
     try:
         from cutils_ext.cutils_ext import *
@@ -80,7 +81,7 @@
     # compile the cutils_ext module simultaneously.
         try:
             try:
-                # We must retry to import it as some other processs could
+                # We must retry to import it as some other process could
                 # have been compiling it between the first failed import
                 # and when we receive the lock
                 from cutils_ext.cutils_ext import *
diff --git a/theano/gof/lazylinker_c.py b/theano/gof/lazylinker_c.py
--- a/theano/gof/lazylinker_c.py
+++ b/theano/gof/lazylinker_c.py
@@ -22,6 +22,19 @@
     del sys.path[0]
 
 try:
+    # See gh issue #728 for why these lines are here. Summary: compiledir must
+    # be at the beginning of the path to avoid conflicts with any other
+    # lazylinker_ext modules that might exist (this step handled in try_import
+    # and try_reload). An __init__.py file must be created for the same reason.
+    # Note that these lines may seem redundant (they are repeated in
+    # compile_str()) but if another lazylinker_ext does exist then it will be
+    # imported and compile_str won't get called at all.
+    location = os.path.join(config.compiledir, 'lazylinker_ext')
+    if not os.path.exists(location):
+        os.mkdir(location)
+    if not os.path.exists(os.path.join(location, '__init__.py')):
+        file(os.path.join(location, '__init__.py'), 'w').close()
+
     _need_reload = False
     if force_compile:
         raise ImportError()

{"golden_diff": "diff --git a/theano/gof/cutils.py b/theano/gof/cutils.py\n--- a/theano/gof/cutils.py\n+++ b/theano/gof/cutils.py\n@@ -67,7 +67,8 @@\n     location = os.path.join(config.compiledir, 'cutils_ext')\n     if not os.path.exists(location):\n         os.mkdir(location)\n-    file(os.path.join(location, \"__init__.py\"), 'w').close()\n+    if not os.path.exists(os.path.join(location, '__init__.py')):\n+        file(os.path.join(location, '__init__.py'), 'w').close()\n \n     try:\n         from cutils_ext.cutils_ext import *\n@@ -80,7 +81,7 @@\n     # compile the cutils_ext module simultaneously.\n         try:\n             try:\n-                # We must retry to import it as some other processs could\n+                # We must retry to import it as some other process could\n                 # have been compiling it between the first failed import\n                 # and when we receive the lock\n                 from cutils_ext.cutils_ext import *\ndiff --git a/theano/gof/lazylinker_c.py b/theano/gof/lazylinker_c.py\n--- a/theano/gof/lazylinker_c.py\n+++ b/theano/gof/lazylinker_c.py\n@@ -22,6 +22,19 @@\n     del sys.path[0]\n \n try:\n+    # See gh issue #728 for why these lines are here. Summary: compiledir must\n+    # be at the beginning of the path to avoid conflicts with any other\n+    # lazylinker_ext modules that might exist (this step handled in try_import\n+    # and try_reload). An __init__.py file must be created for the same reason.\n+    # Note that these lines may seem redundant (they are repeated in\n+    # compile_str()) but if another lazylinker_ext does exist then it will be\n+    # imported and compile_str won't get called at all.\n+    location = os.path.join(config.compiledir, 'lazylinker_ext')\n+    if not os.path.exists(location):\n+        os.mkdir(location)\n+    if not os.path.exists(os.path.join(location, '__init__.py')):\n+        file(os.path.join(location, '__init__.py'), 'w').close()\n+\n     _need_reload = False\n     if force_compile:\n         raise ImportError()\n", "issue": "cutils fails when cutils_ext already present elsewhere in sys.path\nEDIT: Now it work with the c|py linker, but not with the cvm linker.\n\nTheano's cutils moudle expects to find cutils_ext inside config.compiledir.\n\nIn cutils.py, cutils_ext.cutils_ext will be loaded.  On an import error, this extension will be built and eventually cmodule.dlimport will re-import cutils_ext.cutils_ext.  dlimport will inject config.compiledir into the front of sys,path, so the cutils_ext should always be loaded from config.compiledir.\n\nNormally, this will then allow cutils_ext.cutils_ext to be loaded.  The problem is if the cutils_ext package was found elsewhere on sys.path, but not the cutils_ext module (extension) within that package.  cutils.py lacks the sys.path injection of dlimport.  The consequence is that the import of cutils_ext.cutils_ext in dlimport fails because the reference to the outer cutils_ext (the package) will be the incorrect path!\n\nNeedless to say, when a user encounters this bug, it is a pain to solve.\n\nThe solution is to ensure that the cutils.py try statement starts with:\n\nsys.path.insert(0,theano.config.compiledir)\nwith the finally doing:\ndel sys.path[0]\n\n", "before_files": [{"content": "import os\nimport sys\nfrom compilelock import get_lock, release_lock\nfrom theano import config\n\n# TODO These two lines may be removed in the future, when we are 100% sure\n# noone has an old cutils_ext.so lying around anymore.\nif os.path.exists(os.path.join(config.compiledir, 'cutils_ext.so')):\n    os.remove(os.path.join(config.compiledir, 'cutils_ext.so'))\n\n\ndef compile_cutils():\n    \"\"\"Do just the compilation of cutils_ext\"\"\"\n    code = \"\"\"\n        #include <Python.h>\n        extern \"C\"{\n        static PyObject *\n        run_cthunk(PyObject *self, PyObject *args)\n        {\n          PyObject *py_cthunk = NULL;\n          if(!PyArg_ParseTuple(args,\"O\",&py_cthunk))\n            return NULL;\n\n          if (!PyCObject_Check(py_cthunk)) {\n            PyErr_SetString(PyExc_ValueError,\n                           \"Argument to run_cthunk must be a PyCObject.\");\n            return NULL;\n          }\n          void * ptr_addr = PyCObject_AsVoidPtr(py_cthunk);\n          int (*fn)(void*) = (int (*)(void*))(ptr_addr);\n          void* it = PyCObject_GetDesc(py_cthunk);\n          int failure = fn(it);\n\n          return Py_BuildValue(\"i\", failure);\n        }\n\n        static PyMethodDef CutilsExtMethods[] = {\n            {\"run_cthunk\",  run_cthunk, METH_VARARGS|METH_KEYWORDS,\n             \"Run a theano cthunk.\"},\n            {NULL, NULL, 0, NULL}        /* Sentinel */\n        };\n\n        PyMODINIT_FUNC\n        initcutils_ext(void)\n        {\n          (void) Py_InitModule(\"cutils_ext\", CutilsExtMethods);\n        }\n        }\n        \"\"\"\n\n    loc = os.path.join(config.compiledir, 'cutils_ext')\n    if not os.path.exists(loc):\n        os.mkdir(loc)\n\n    args = cmodule.GCC_compiler.compile_args()\n    cmodule.GCC_compiler.compile_str('cutils_ext', code, location=loc,\n                                     preargs=args)\n\ntry:\n    # See gh issue #728 for why these lines are here. Summary: compiledir\n    # must be at the beginning of the path to avoid conflicts with any other\n    # cutils_ext modules that might exist. An __init__.py file must be created\n    # for the same reason. Note that these 5 lines may seem redundant (they are\n    # repeated in compile_str()) but if another cutils_ext does exist then it\n    # will be imported and compile_str won't get called at all.\n    sys.path.insert(0, config.compiledir)\n    location = os.path.join(config.compiledir, 'cutils_ext')\n    if not os.path.exists(location):\n        os.mkdir(location)\n    file(os.path.join(location, \"__init__.py\"), 'w').close()\n\n    try:\n        from cutils_ext.cutils_ext import *\n    except ImportError:\n        import cmodule\n\n        get_lock()\n    # Ensure no-one else is currently modifying the content of the compilation\n    # directory. This is important to prevent multiple processes from trying to\n    # compile the cutils_ext module simultaneously.\n        try:\n            try:\n                # We must retry to import it as some other processs could\n                # have been compiling it between the first failed import\n                # and when we receive the lock\n                from cutils_ext.cutils_ext import *\n            except ImportError:\n                import cmodule\n\n                compile_cutils()\n                from cutils_ext.cutils_ext import *\n\n        finally:\n            # Release lock on compilation directory.\n            release_lock()\nfinally:\n    if sys.path[0] == config.compiledir:\n        del sys.path[0]\n", "path": "theano/gof/cutils.py"}, {"content": "import os, logging, sys\n\nimport theano\nfrom theano import config\nfrom theano.gof.compilelock import get_lock, release_lock\nfrom theano.gof import cmodule\n\n_logger = logging.getLogger('theano.gof.lazylinker_c')\n\nforce_compile = False\nversion = 0.20  # must match constant returned in function get_version()\n\ndef try_import():\n    global lazylinker_ext\n    sys.path[0:0] = [config.compiledir]\n    import lazylinker_ext\n    del sys.path[0]\n\ndef try_reload():\n    sys.path[0:0] = [config.compiledir]\n    reload(lazylinker_ext)\n    del sys.path[0]\n\ntry:\n    _need_reload = False\n    if force_compile:\n        raise ImportError()\n    else:\n        try_import()\n        _need_reload = True\n        if version != getattr(lazylinker_ext, '_version', None):\n            raise ImportError()\nexcept ImportError:\n    get_lock()\n    try:\n        # Maybe someone else already finished compiling it while we were\n        # waiting for the lock?\n        try:\n            if force_compile:\n                raise ImportError()\n            if _need_reload:\n                # The module was successfully imported earlier: we need to\n                # reload it to check if the version was updated.\n                try_reload()\n            else:\n                try_import()\n                _need_reload = True\n            if version != getattr(lazylinker_ext, '_version', None):\n                raise ImportError()\n        except ImportError:\n            _logger.info(\"Compiling new CVM\")\n            dirname = 'lazylinker_ext'\n            # We use a .txt extensions as otherwise it don't get\n            # included when we create a package to send to pypi\n            # This happen even if we tell to include *.c files\n            cfile = os.path.join(theano.__path__[0], 'gof', 'lazylinker_c.c.txt')\n            code = open(cfile).read()\n            loc = os.path.join(config.compiledir, dirname)\n            if not os.path.exists(loc):\n                os.mkdir(loc)\n            args = cmodule.GCC_compiler.compile_args()\n            cmodule.GCC_compiler.compile_str(dirname, code, location=loc,\n                                             preargs=args)\n            # Save version into the __init__.py file.\n            init_py = os.path.join(loc, '__init__.py')\n            open(init_py, 'w').write('_version = %s\\n' % version)\n            # If we just compiled the module for the first time, then it was\n            # imported at the same time: we need to make sure we do not\n            # reload the now outdated __init__.pyc below.\n            init_pyc = os.path.join(loc, '__init__.pyc')\n            if os.path.isfile(init_pyc):\n                os.remove(init_pyc)\n            try_import()\n            try_reload()\n            from lazylinker_ext import lazylinker_ext as lazy_c\n            assert (lazylinker_ext._version ==\n                    lazy_c.get_version())\n            _logger.info(\"New version %s\", lazylinker_ext._version)\n    finally:\n        # Release lock on compilation directory.\n        release_lock()\n\nfrom lazylinker_ext.lazylinker_ext import *\nassert force_compile or (version == get_version())\n", "path": "theano/gof/lazylinker_c.py"}], "after_files": [{"content": "import os\nimport sys\nfrom compilelock import get_lock, release_lock\nfrom theano import config\n\n# TODO These two lines may be removed in the future, when we are 100% sure\n# noone has an old cutils_ext.so lying around anymore.\nif os.path.exists(os.path.join(config.compiledir, 'cutils_ext.so')):\n    os.remove(os.path.join(config.compiledir, 'cutils_ext.so'))\n\n\ndef compile_cutils():\n    \"\"\"Do just the compilation of cutils_ext\"\"\"\n    code = \"\"\"\n        #include <Python.h>\n        extern \"C\"{\n        static PyObject *\n        run_cthunk(PyObject *self, PyObject *args)\n        {\n          PyObject *py_cthunk = NULL;\n          if(!PyArg_ParseTuple(args,\"O\",&py_cthunk))\n            return NULL;\n\n          if (!PyCObject_Check(py_cthunk)) {\n            PyErr_SetString(PyExc_ValueError,\n                           \"Argument to run_cthunk must be a PyCObject.\");\n            return NULL;\n          }\n          void * ptr_addr = PyCObject_AsVoidPtr(py_cthunk);\n          int (*fn)(void*) = (int (*)(void*))(ptr_addr);\n          void* it = PyCObject_GetDesc(py_cthunk);\n          int failure = fn(it);\n\n          return Py_BuildValue(\"i\", failure);\n        }\n\n        static PyMethodDef CutilsExtMethods[] = {\n            {\"run_cthunk\",  run_cthunk, METH_VARARGS|METH_KEYWORDS,\n             \"Run a theano cthunk.\"},\n            {NULL, NULL, 0, NULL}        /* Sentinel */\n        };\n\n        PyMODINIT_FUNC\n        initcutils_ext(void)\n        {\n          (void) Py_InitModule(\"cutils_ext\", CutilsExtMethods);\n        }\n        }\n        \"\"\"\n\n    loc = os.path.join(config.compiledir, 'cutils_ext')\n    if not os.path.exists(loc):\n        os.mkdir(loc)\n\n    args = cmodule.GCC_compiler.compile_args()\n    cmodule.GCC_compiler.compile_str('cutils_ext', code, location=loc,\n                                     preargs=args)\n\ntry:\n    # See gh issue #728 for why these lines are here. Summary: compiledir\n    # must be at the beginning of the path to avoid conflicts with any other\n    # cutils_ext modules that might exist. An __init__.py file must be created\n    # for the same reason. Note that these 5 lines may seem redundant (they are\n    # repeated in compile_str()) but if another cutils_ext does exist then it\n    # will be imported and compile_str won't get called at all.\n    sys.path.insert(0, config.compiledir)\n    location = os.path.join(config.compiledir, 'cutils_ext')\n    if not os.path.exists(location):\n        os.mkdir(location)\n    if not os.path.exists(os.path.join(location, '__init__.py')):\n        file(os.path.join(location, '__init__.py'), 'w').close()\n\n    try:\n        from cutils_ext.cutils_ext import *\n    except ImportError:\n        import cmodule\n\n        get_lock()\n    # Ensure no-one else is currently modifying the content of the compilation\n    # directory. This is important to prevent multiple processes from trying to\n    # compile the cutils_ext module simultaneously.\n        try:\n            try:\n                # We must retry to import it as some other process could\n                # have been compiling it between the first failed import\n                # and when we receive the lock\n                from cutils_ext.cutils_ext import *\n            except ImportError:\n                import cmodule\n\n                compile_cutils()\n                from cutils_ext.cutils_ext import *\n\n        finally:\n            # Release lock on compilation directory.\n            release_lock()\nfinally:\n    if sys.path[0] == config.compiledir:\n        del sys.path[0]\n", "path": "theano/gof/cutils.py"}, {"content": "import os, logging, sys\n\nimport theano\nfrom theano import config\nfrom theano.gof.compilelock import get_lock, release_lock\nfrom theano.gof import cmodule\n\n_logger = logging.getLogger('theano.gof.lazylinker_c')\n\nforce_compile = False\nversion = 0.20  # must match constant returned in function get_version()\n\ndef try_import():\n    global lazylinker_ext\n    sys.path[0:0] = [config.compiledir]\n    import lazylinker_ext\n    del sys.path[0]\n\ndef try_reload():\n    sys.path[0:0] = [config.compiledir]\n    reload(lazylinker_ext)\n    del sys.path[0]\n\ntry:\n    # See gh issue #728 for why these lines are here. Summary: compiledir must\n    # be at the beginning of the path to avoid conflicts with any other\n    # lazylinker_ext modules that might exist (this step handled in try_import\n    # and try_reload). An __init__.py file must be created for the same reason.\n    # Note that these lines may seem redundant (they are repeated in\n    # compile_str()) but if another lazylinker_ext does exist then it will be\n    # imported and compile_str won't get called at all.\n    location = os.path.join(config.compiledir, 'lazylinker_ext')\n    if not os.path.exists(location):\n        os.mkdir(location)\n    if not os.path.exists(os.path.join(location, '__init__.py')):\n        file(os.path.join(location, '__init__.py'), 'w').close()\n\n    _need_reload = False\n    if force_compile:\n        raise ImportError()\n    else:\n        try_import()\n        _need_reload = True\n        if version != getattr(lazylinker_ext, '_version', None):\n            raise ImportError()\nexcept ImportError:\n    get_lock()\n    try:\n        # Maybe someone else already finished compiling it while we were\n        # waiting for the lock?\n        try:\n            if force_compile:\n                raise ImportError()\n            if _need_reload:\n                # The module was successfully imported earlier: we need to\n                # reload it to check if the version was updated.\n                try_reload()\n            else:\n                try_import()\n                _need_reload = True\n            if version != getattr(lazylinker_ext, '_version', None):\n                raise ImportError()\n        except ImportError:\n            _logger.info(\"Compiling new CVM\")\n            dirname = 'lazylinker_ext'\n            # We use a .txt extensions as otherwise it don't get\n            # included when we create a package to send to pypi\n            # This happen even if we tell to include *.c files\n            cfile = os.path.join(theano.__path__[0], 'gof', 'lazylinker_c.c.txt')\n            code = open(cfile).read()\n            loc = os.path.join(config.compiledir, dirname)\n            if not os.path.exists(loc):\n                os.mkdir(loc)\n            args = cmodule.GCC_compiler.compile_args()\n            cmodule.GCC_compiler.compile_str(dirname, code, location=loc,\n                                             preargs=args)\n            # Save version into the __init__.py file.\n            init_py = os.path.join(loc, '__init__.py')\n            open(init_py, 'w').write('_version = %s\\n' % version)\n            # If we just compiled the module for the first time, then it was\n            # imported at the same time: we need to make sure we do not\n            # reload the now outdated __init__.pyc below.\n            init_pyc = os.path.join(loc, '__init__.pyc')\n            if os.path.isfile(init_pyc):\n                os.remove(init_pyc)\n            try_import()\n            try_reload()\n            from lazylinker_ext import lazylinker_ext as lazy_c\n            assert (lazylinker_ext._version ==\n                    lazy_c.get_version())\n            _logger.info(\"New version %s\", lazylinker_ext._version)\n    finally:\n        # Release lock on compilation directory.\n        release_lock()\n\nfrom lazylinker_ext.lazylinker_ext import *\nassert force_compile or (version == get_version())\n", "path": "theano/gof/lazylinker_c.py"}]}