We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Cannot create action with a name that collides with a Python library
We created an action called "elasticsearch.py" (with the appropriate yaml). When we try to run it we get an ST2 exception. We are able to reproduce with another action called "test.py". Our hypothesis is that if the action name is the same as a Python library, it fails to run it. This happens after migrating to 1.4.0 from 0.13.2 (it works fine in 0.13.2).

Here's the stacktrace:

```
$ st2 run netflix_samples.elasticsearch app_region=us-east-1
.
id: 57211d9b7279e6326f6b025f
status: failed
parameters: 
 app_region: us-east-1
result: 
 exit_code: 1
 result: null
 stderr: "Traceback (most recent call last):
 File "/opt/stackstorm/st2/local/lib/python2.7/site-packages/st2actions/runners/python_action_wrapper.py", line 164, in <module>
   obj.run()
 File "/opt/stackstorm/st2/local/lib/python2.7/site-packages/st2actions/runners/python_action_wrapper.py", line 102, in run
   action = self._get_action_instance()
 File "/opt/stackstorm/st2/local/lib/python2.7/site-packages/st2actions/runners/python_action_wrapper.py", line 116, in _get_action_instance
   actions_cls = action_loader.register_plugin(Action, self._file_path)
 File "/opt/stackstorm/st2/lib/python2.7/site-packages/st2common/util/loader.py", line 163, in register_plugin
   (plugin_abs_file_path))
Exception: Found no classes in plugin file "/opt/stackstorm/packs/netflix_samples/actions/elasticsearch.py" matching requirements.
"
 stdout: ''
```


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `st2common/st2common/util/loader.py`
Content:
```
1 # Licensed to the StackStorm, Inc ('StackStorm') under one or more
2 # contributor license agreements.  See the NOTICE file distributed with
3 # this work for additional information regarding copyright ownership.
4 # The ASF licenses this file to You under the Apache License, Version 2.0
5 # (the "License"); you may not use this file except in compliance with
6 # the License.  You may obtain a copy of the License at
7 #
8 #     http://www.apache.org/licenses/LICENSE-2.0
9 #
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15 
16 import importlib
17 import inspect
18 import json
19 import os
20 import sys
21 import yaml
22 
23 from st2common.exceptions.plugins import IncompatiblePluginException
24 from st2common import log as logging
25 
26 __all__ = [
27     'register_plugin',
28     'register_plugin_class'
29 ]
30 
31 
32 LOG = logging.getLogger(__name__)
33 PYTHON_EXTENSIONS = ('.py')
34 
35 
36 def _register_plugin_path(plugin_dir_abs_path):
37     if not os.path.isdir(plugin_dir_abs_path):
38         raise Exception('Directory "%s" with plugins doesn\'t exist' % (plugin_dir_abs_path))
39 
40     for x in sys.path:
41         if plugin_dir_abs_path in (x, x + os.sep):
42             return
43     sys.path.append(plugin_dir_abs_path)
44 
45 
46 def _get_plugin_module(plugin_file_path):
47     plugin_module = os.path.basename(plugin_file_path)
48     if plugin_module.endswith(PYTHON_EXTENSIONS):
49         plugin_module = plugin_module[:plugin_module.rfind('.py')]
50     else:
51         plugin_module = None
52     return plugin_module
53 
54 
55 def _get_classes_in_module(module):
56     return [kls for name, kls in inspect.getmembers(module,
57             lambda member: inspect.isclass(member) and member.__module__ == module.__name__)]
58 
59 
60 def _get_plugin_classes(module_name):
61     return _get_classes_in_module(module_name)
62 
63 
64 def _get_plugin_methods(plugin_klass):
65     """
66     Return a list of names of all the methods in the provided class.
67 
68     Note: Abstract methods which are not implemented are excluded from the
69     list.
70 
71     :rtype: ``list`` of ``str``
72     """
73     methods = inspect.getmembers(plugin_klass, inspect.ismethod)
74 
75     # Exclude inherited abstract methods from the parent class
76     method_names = []
77     for name, method in methods:
78         method_properties = method.__dict__
79         is_abstract = method_properties.get('__isabstractmethod__', False)
80 
81         if is_abstract:
82             continue
83 
84         method_names.append(name)
85     return method_names
86 
87 
88 def _validate_methods(plugin_base_class, plugin_klass):
89     '''
90     XXX: This is hacky but we'd like to validate the methods
91     in plugin_impl at least has all the *abstract* methods in
92     plugin_base_class.
93     '''
94     expected_methods = plugin_base_class.__abstractmethods__
95     plugin_methods = _get_plugin_methods(plugin_klass)
96     for method in expected_methods:
97         if method not in plugin_methods:
98             message = 'Class "%s" doesn\'t implement required "%s" method from the base class'
99             raise IncompatiblePluginException(message % (plugin_klass.__name__, method))
100 
101 
102 def _register_plugin(plugin_base_class, plugin_impl):
103     _validate_methods(plugin_base_class, plugin_impl)
104     plugin_base_class.register(plugin_impl)
105 
106 
107 def register_plugin_class(base_class, file_path, class_name):
108     """
109     Retrieve a register plugin class from the provided file.
110 
111     This method also validate that the class implements all the abstract methods
112     from the base plugin class.
113 
114     :param base_class: Base plugin class.
115     :param base_class: ``class``
116 
117     :param file_path: File absolute path to the plugin module file.
118     :type file_path: ``str``
119 
120     :param class_name: Class name of a plugin.
121     :type class_name: ``str``
122     """
123     plugin_dir = os.path.dirname(os.path.realpath(file_path))
124     _register_plugin_path(plugin_dir)
125     module_name = _get_plugin_module(file_path)
126 
127     if module_name is None:
128         return None
129 
130     module = importlib.import_module(module_name)
131     klass = getattr(module, class_name, None)
132 
133     if not klass:
134         raise Exception('Plugin file "%s" doesn\'t expose class named "%s"' %
135                         (file_path, class_name))
136 
137     _register_plugin(base_class, klass)
138     return klass
139 
140 
141 def register_plugin(plugin_base_class, plugin_abs_file_path):
142     registered_plugins = []
143     plugin_dir = os.path.dirname(os.path.realpath(plugin_abs_file_path))
144     _register_plugin_path(plugin_dir)
145     module_name = _get_plugin_module(plugin_abs_file_path)
146     if module_name is None:
147         return None
148     module = importlib.import_module(module_name)
149     klasses = _get_plugin_classes(module)
150 
151     # Try registering classes in plugin file. Some may fail.
152     for klass in klasses:
153         try:
154             _register_plugin(plugin_base_class, klass)
155             registered_plugins.append(klass)
156         except Exception as e:
157             LOG.exception(e)
158             LOG.debug('Skipping class %s as it doesn\'t match specs.', klass)
159             continue
160 
161     if len(registered_plugins) == 0:
162         raise Exception('Found no classes in plugin file "%s" matching requirements.' %
163                         (plugin_abs_file_path))
164 
165     return registered_plugins
166 
167 
168 ALLOWED_EXTS = ['.json', '.yaml', '.yml']
169 PARSER_FUNCS = {'.json': json.load, '.yml': yaml.safe_load, '.yaml': yaml.safe_load}
170 
171 
172 def load_meta_file(file_path):
173     if not os.path.isfile(file_path):
174         raise Exception('File "%s" does not exist.' % file_path)
175 
176     file_name, file_ext = os.path.splitext(file_path)
177     if file_ext not in ALLOWED_EXTS:
178         raise Exception('Unsupported meta type %s, file %s. Allowed: %s' %
179                         (file_ext, file_path, ALLOWED_EXTS))
180 
181     with open(file_path, 'r') as f:
182         return PARSER_FUNCS[file_ext](f)
183
```
--- 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/st2common/st2common/util/loader.py b/st2common/st2common/util/loader.py
--- a/st2common/st2common/util/loader.py
+++ b/st2common/st2common/util/loader.py
@@ -13,7 +13,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-import importlib
+import imp
 import inspect
 import json
 import os
@@ -127,7 +127,7 @@
     if module_name is None:
         return None
 
-    module = importlib.import_module(module_name)
+    module = imp.load_source(module_name, file_path)
     klass = getattr(module, class_name, None)
 
     if not klass:
@@ -142,10 +142,12 @@
     registered_plugins = []
     plugin_dir = os.path.dirname(os.path.realpath(plugin_abs_file_path))
     _register_plugin_path(plugin_dir)
+
     module_name = _get_plugin_module(plugin_abs_file_path)
     if module_name is None:
         return None
-    module = importlib.import_module(module_name)
+
+    module = imp.load_source(module_name, plugin_abs_file_path)
     klasses = _get_plugin_classes(module)
 
     # Try registering classes in plugin file. Some may fail.

{"golden_diff": "diff --git a/st2common/st2common/util/loader.py b/st2common/st2common/util/loader.py\n--- a/st2common/st2common/util/loader.py\n+++ b/st2common/st2common/util/loader.py\n@@ -13,7 +13,7 @@\n # See the License for the specific language governing permissions and\n # limitations under the License.\n \n-import importlib\n+import imp\n import inspect\n import json\n import os\n@@ -127,7 +127,7 @@\n     if module_name is None:\n         return None\n \n-    module = importlib.import_module(module_name)\n+    module = imp.load_source(module_name, file_path)\n     klass = getattr(module, class_name, None)\n \n     if not klass:\n@@ -142,10 +142,12 @@\n     registered_plugins = []\n     plugin_dir = os.path.dirname(os.path.realpath(plugin_abs_file_path))\n     _register_plugin_path(plugin_dir)\n+\n     module_name = _get_plugin_module(plugin_abs_file_path)\n     if module_name is None:\n         return None\n-    module = importlib.import_module(module_name)\n+\n+    module = imp.load_source(module_name, plugin_abs_file_path)\n     klasses = _get_plugin_classes(module)\n \n     # Try registering classes in plugin file. Some may fail.\n", "issue": "Cannot create action with a name that collides with a Python library\nWe created an action called \"elasticsearch.py\" (with the appropriate yaml). When we try to run it we get an ST2 exception. We are able to reproduce with another action called \"test.py\". Our hypothesis is that if the action name is the same as a Python library, it fails to run it. This happens after migrating to 1.4.0 from 0.13.2 (it works fine in 0.13.2).\n\nHere's the stacktrace:\n\n```\n$ st2 run netflix_samples.elasticsearch app_region=us-east-1\n.\nid: 57211d9b7279e6326f6b025f\nstatus: failed\nparameters: \n app_region: us-east-1\nresult: \n exit_code: 1\n result: null\n stderr: \"Traceback (most recent call last):\n File \"/opt/stackstorm/st2/local/lib/python2.7/site-packages/st2actions/runners/python_action_wrapper.py\", line 164, in <module>\n   obj.run()\n File \"/opt/stackstorm/st2/local/lib/python2.7/site-packages/st2actions/runners/python_action_wrapper.py\", line 102, in run\n   action = self._get_action_instance()\n File \"/opt/stackstorm/st2/local/lib/python2.7/site-packages/st2actions/runners/python_action_wrapper.py\", line 116, in _get_action_instance\n   actions_cls = action_loader.register_plugin(Action, self._file_path)\n File \"/opt/stackstorm/st2/lib/python2.7/site-packages/st2common/util/loader.py\", line 163, in register_plugin\n   (plugin_abs_file_path))\nException: Found no classes in plugin file \"/opt/stackstorm/packs/netflix_samples/actions/elasticsearch.py\" matching requirements.\n\"\n stdout: ''\n```\n\n", "before_files": [{"content": "# Licensed to the StackStorm, Inc ('StackStorm') under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nimport importlib\nimport inspect\nimport json\nimport os\nimport sys\nimport yaml\n\nfrom st2common.exceptions.plugins import IncompatiblePluginException\nfrom st2common import log as logging\n\n__all__ = [\n    'register_plugin',\n    'register_plugin_class'\n]\n\n\nLOG = logging.getLogger(__name__)\nPYTHON_EXTENSIONS = ('.py')\n\n\ndef _register_plugin_path(plugin_dir_abs_path):\n    if not os.path.isdir(plugin_dir_abs_path):\n        raise Exception('Directory \"%s\" with plugins doesn\\'t exist' % (plugin_dir_abs_path))\n\n    for x in sys.path:\n        if plugin_dir_abs_path in (x, x + os.sep):\n            return\n    sys.path.append(plugin_dir_abs_path)\n\n\ndef _get_plugin_module(plugin_file_path):\n    plugin_module = os.path.basename(plugin_file_path)\n    if plugin_module.endswith(PYTHON_EXTENSIONS):\n        plugin_module = plugin_module[:plugin_module.rfind('.py')]\n    else:\n        plugin_module = None\n    return plugin_module\n\n\ndef _get_classes_in_module(module):\n    return [kls for name, kls in inspect.getmembers(module,\n            lambda member: inspect.isclass(member) and member.__module__ == module.__name__)]\n\n\ndef _get_plugin_classes(module_name):\n    return _get_classes_in_module(module_name)\n\n\ndef _get_plugin_methods(plugin_klass):\n    \"\"\"\n    Return a list of names of all the methods in the provided class.\n\n    Note: Abstract methods which are not implemented are excluded from the\n    list.\n\n    :rtype: ``list`` of ``str``\n    \"\"\"\n    methods = inspect.getmembers(plugin_klass, inspect.ismethod)\n\n    # Exclude inherited abstract methods from the parent class\n    method_names = []\n    for name, method in methods:\n        method_properties = method.__dict__\n        is_abstract = method_properties.get('__isabstractmethod__', False)\n\n        if is_abstract:\n            continue\n\n        method_names.append(name)\n    return method_names\n\n\ndef _validate_methods(plugin_base_class, plugin_klass):\n    '''\n    XXX: This is hacky but we'd like to validate the methods\n    in plugin_impl at least has all the *abstract* methods in\n    plugin_base_class.\n    '''\n    expected_methods = plugin_base_class.__abstractmethods__\n    plugin_methods = _get_plugin_methods(plugin_klass)\n    for method in expected_methods:\n        if method not in plugin_methods:\n            message = 'Class \"%s\" doesn\\'t implement required \"%s\" method from the base class'\n            raise IncompatiblePluginException(message % (plugin_klass.__name__, method))\n\n\ndef _register_plugin(plugin_base_class, plugin_impl):\n    _validate_methods(plugin_base_class, plugin_impl)\n    plugin_base_class.register(plugin_impl)\n\n\ndef register_plugin_class(base_class, file_path, class_name):\n    \"\"\"\n    Retrieve a register plugin class from the provided file.\n\n    This method also validate that the class implements all the abstract methods\n    from the base plugin class.\n\n    :param base_class: Base plugin class.\n    :param base_class: ``class``\n\n    :param file_path: File absolute path to the plugin module file.\n    :type file_path: ``str``\n\n    :param class_name: Class name of a plugin.\n    :type class_name: ``str``\n    \"\"\"\n    plugin_dir = os.path.dirname(os.path.realpath(file_path))\n    _register_plugin_path(plugin_dir)\n    module_name = _get_plugin_module(file_path)\n\n    if module_name is None:\n        return None\n\n    module = importlib.import_module(module_name)\n    klass = getattr(module, class_name, None)\n\n    if not klass:\n        raise Exception('Plugin file \"%s\" doesn\\'t expose class named \"%s\"' %\n                        (file_path, class_name))\n\n    _register_plugin(base_class, klass)\n    return klass\n\n\ndef register_plugin(plugin_base_class, plugin_abs_file_path):\n    registered_plugins = []\n    plugin_dir = os.path.dirname(os.path.realpath(plugin_abs_file_path))\n    _register_plugin_path(plugin_dir)\n    module_name = _get_plugin_module(plugin_abs_file_path)\n    if module_name is None:\n        return None\n    module = importlib.import_module(module_name)\n    klasses = _get_plugin_classes(module)\n\n    # Try registering classes in plugin file. Some may fail.\n    for klass in klasses:\n        try:\n            _register_plugin(plugin_base_class, klass)\n            registered_plugins.append(klass)\n        except Exception as e:\n            LOG.exception(e)\n            LOG.debug('Skipping class %s as it doesn\\'t match specs.', klass)\n            continue\n\n    if len(registered_plugins) == 0:\n        raise Exception('Found no classes in plugin file \"%s\" matching requirements.' %\n                        (plugin_abs_file_path))\n\n    return registered_plugins\n\n\nALLOWED_EXTS = ['.json', '.yaml', '.yml']\nPARSER_FUNCS = {'.json': json.load, '.yml': yaml.safe_load, '.yaml': yaml.safe_load}\n\n\ndef load_meta_file(file_path):\n    if not os.path.isfile(file_path):\n        raise Exception('File \"%s\" does not exist.' % file_path)\n\n    file_name, file_ext = os.path.splitext(file_path)\n    if file_ext not in ALLOWED_EXTS:\n        raise Exception('Unsupported meta type %s, file %s. Allowed: %s' %\n                        (file_ext, file_path, ALLOWED_EXTS))\n\n    with open(file_path, 'r') as f:\n        return PARSER_FUNCS[file_ext](f)\n", "path": "st2common/st2common/util/loader.py"}], "after_files": [{"content": "# Licensed to the StackStorm, Inc ('StackStorm') under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nimport imp\nimport inspect\nimport json\nimport os\nimport sys\nimport yaml\n\nfrom st2common.exceptions.plugins import IncompatiblePluginException\nfrom st2common import log as logging\n\n__all__ = [\n    'register_plugin',\n    'register_plugin_class'\n]\n\n\nLOG = logging.getLogger(__name__)\nPYTHON_EXTENSIONS = ('.py')\n\n\ndef _register_plugin_path(plugin_dir_abs_path):\n    if not os.path.isdir(plugin_dir_abs_path):\n        raise Exception('Directory \"%s\" with plugins doesn\\'t exist' % (plugin_dir_abs_path))\n\n    for x in sys.path:\n        if plugin_dir_abs_path in (x, x + os.sep):\n            return\n    sys.path.append(plugin_dir_abs_path)\n\n\ndef _get_plugin_module(plugin_file_path):\n    plugin_module = os.path.basename(plugin_file_path)\n    if plugin_module.endswith(PYTHON_EXTENSIONS):\n        plugin_module = plugin_module[:plugin_module.rfind('.py')]\n    else:\n        plugin_module = None\n    return plugin_module\n\n\ndef _get_classes_in_module(module):\n    return [kls for name, kls in inspect.getmembers(module,\n            lambda member: inspect.isclass(member) and member.__module__ == module.__name__)]\n\n\ndef _get_plugin_classes(module_name):\n    return _get_classes_in_module(module_name)\n\n\ndef _get_plugin_methods(plugin_klass):\n    \"\"\"\n    Return a list of names of all the methods in the provided class.\n\n    Note: Abstract methods which are not implemented are excluded from the\n    list.\n\n    :rtype: ``list`` of ``str``\n    \"\"\"\n    methods = inspect.getmembers(plugin_klass, inspect.ismethod)\n\n    # Exclude inherited abstract methods from the parent class\n    method_names = []\n    for name, method in methods:\n        method_properties = method.__dict__\n        is_abstract = method_properties.get('__isabstractmethod__', False)\n\n        if is_abstract:\n            continue\n\n        method_names.append(name)\n    return method_names\n\n\ndef _validate_methods(plugin_base_class, plugin_klass):\n    '''\n    XXX: This is hacky but we'd like to validate the methods\n    in plugin_impl at least has all the *abstract* methods in\n    plugin_base_class.\n    '''\n    expected_methods = plugin_base_class.__abstractmethods__\n    plugin_methods = _get_plugin_methods(plugin_klass)\n    for method in expected_methods:\n        if method not in plugin_methods:\n            message = 'Class \"%s\" doesn\\'t implement required \"%s\" method from the base class'\n            raise IncompatiblePluginException(message % (plugin_klass.__name__, method))\n\n\ndef _register_plugin(plugin_base_class, plugin_impl):\n    _validate_methods(plugin_base_class, plugin_impl)\n    plugin_base_class.register(plugin_impl)\n\n\ndef register_plugin_class(base_class, file_path, class_name):\n    \"\"\"\n    Retrieve a register plugin class from the provided file.\n\n    This method also validate that the class implements all the abstract methods\n    from the base plugin class.\n\n    :param base_class: Base plugin class.\n    :param base_class: ``class``\n\n    :param file_path: File absolute path to the plugin module file.\n    :type file_path: ``str``\n\n    :param class_name: Class name of a plugin.\n    :type class_name: ``str``\n    \"\"\"\n    plugin_dir = os.path.dirname(os.path.realpath(file_path))\n    _register_plugin_path(plugin_dir)\n    module_name = _get_plugin_module(file_path)\n\n    if module_name is None:\n        return None\n\n    module = imp.load_source(module_name, file_path)\n    klass = getattr(module, class_name, None)\n\n    if not klass:\n        raise Exception('Plugin file \"%s\" doesn\\'t expose class named \"%s\"' %\n                        (file_path, class_name))\n\n    _register_plugin(base_class, klass)\n    return klass\n\n\ndef register_plugin(plugin_base_class, plugin_abs_file_path):\n    registered_plugins = []\n    plugin_dir = os.path.dirname(os.path.realpath(plugin_abs_file_path))\n    _register_plugin_path(plugin_dir)\n\n    module_name = _get_plugin_module(plugin_abs_file_path)\n    if module_name is None:\n        return None\n\n    module = imp.load_source(module_name, plugin_abs_file_path)\n    klasses = _get_plugin_classes(module)\n\n    # Try registering classes in plugin file. Some may fail.\n    for klass in klasses:\n        try:\n            _register_plugin(plugin_base_class, klass)\n            registered_plugins.append(klass)\n        except Exception as e:\n            LOG.exception(e)\n            LOG.debug('Skipping class %s as it doesn\\'t match specs.', klass)\n            continue\n\n    if len(registered_plugins) == 0:\n        raise Exception('Found no classes in plugin file \"%s\" matching requirements.' %\n                        (plugin_abs_file_path))\n\n    return registered_plugins\n\n\nALLOWED_EXTS = ['.json', '.yaml', '.yml']\nPARSER_FUNCS = {'.json': json.load, '.yml': yaml.safe_load, '.yaml': yaml.safe_load}\n\n\ndef load_meta_file(file_path):\n    if not os.path.isfile(file_path):\n        raise Exception('File \"%s\" does not exist.' % file_path)\n\n    file_name, file_ext = os.path.splitext(file_path)\n    if file_ext not in ALLOWED_EXTS:\n        raise Exception('Unsupported meta type %s, file %s. Allowed: %s' %\n                        (file_ext, file_path, ALLOWED_EXTS))\n\n    with open(file_path, 'r') as f:\n        return PARSER_FUNCS[file_ext](f)\n", "path": "st2common/st2common/util/loader.py"}]}