mbligh | d90942c | 2008-04-04 15:08:12 +0000 | [diff] [blame] | 1 | __author__ = "jadmanski@google.com (John Admanski)" |
| 2 | |
mbligh | 6d85ad9 | 2009-05-01 23:06:26 +0000 | [diff] [blame] | 3 | import os, sys |
| 4 | |
| 5 | # This must run on Python versions less than 2.4. |
| 6 | dirname = os.path.dirname(sys.modules[__name__].__file__) |
| 7 | common_dir = os.path.abspath(os.path.join(dirname, "common_lib")) |
| 8 | sys.path.insert(0, common_dir) |
| 9 | import check_version |
| 10 | sys.path.pop(0) |
| 11 | check_version.check_python_version() |
| 12 | |
mbligh | 23da87e | 2009-09-03 20:19:38 +0000 | [diff] [blame] | 13 | import new, glob, traceback |
mbligh | d90942c | 2008-04-04 15:08:12 +0000 | [diff] [blame] | 14 | |
| 15 | |
| 16 | def _create_module(name): |
jadmanski | 0afbb63 | 2008-06-06 21:10:57 +0000 | [diff] [blame] | 17 | """Create a single top-level module""" |
| 18 | module = new.module(name) |
| 19 | sys.modules[name] = module |
| 20 | return module |
mbligh | d90942c | 2008-04-04 15:08:12 +0000 | [diff] [blame] | 21 | |
| 22 | |
| 23 | def _create_module_and_parents(name): |
jadmanski | 0afbb63 | 2008-06-06 21:10:57 +0000 | [diff] [blame] | 24 | """Create a module, and all the necessary parents""" |
| 25 | parts = name.split(".") |
| 26 | # first create the top-level module |
| 27 | parent = _create_module(parts[0]) |
| 28 | created_parts = [parts[0]] |
| 29 | parts.pop(0) |
| 30 | # now, create any remaining child modules |
| 31 | while parts: |
| 32 | child_name = parts.pop(0) |
| 33 | module = new.module(child_name) |
| 34 | setattr(parent, child_name, module) |
| 35 | created_parts.append(child_name) |
| 36 | sys.modules[".".join(created_parts)] = module |
| 37 | parent = module |
mbligh | d90942c | 2008-04-04 15:08:12 +0000 | [diff] [blame] | 38 | |
| 39 | |
| 40 | def _import_children_into_module(parent_module_name, path): |
jadmanski | 0afbb63 | 2008-06-06 21:10:57 +0000 | [diff] [blame] | 41 | """Import all the packages on a path into a parent module""" |
| 42 | # find all the packages at 'path' |
| 43 | names = [] |
| 44 | for filename in os.listdir(path): |
| 45 | full_name = os.path.join(path, filename) |
| 46 | if not os.path.isdir(full_name): |
| 47 | continue # skip files |
jadmanski | 8a1ce95 | 2008-07-08 19:12:35 +0000 | [diff] [blame] | 48 | if "." in filename: |
| 49 | continue # if "." is in the name it's not a valid package name |
| 50 | if not os.access(full_name, os.R_OK | os.X_OK): |
| 51 | continue # need read + exec access to make a dir importable |
jadmanski | 0afbb63 | 2008-06-06 21:10:57 +0000 | [diff] [blame] | 52 | if "__init__.py" in os.listdir(full_name): |
| 53 | names.append(filename) |
| 54 | # import all the packages and insert them into 'parent_module' |
| 55 | sys.path.insert(0, path) |
| 56 | for name in names: |
| 57 | module = __import__(name) |
| 58 | # add the package to the parent |
| 59 | parent_module = sys.modules[parent_module_name] |
| 60 | setattr(parent_module, name, module) |
| 61 | full_name = parent_module_name + "." + name |
| 62 | sys.modules[full_name] = module |
| 63 | # restore the system path |
| 64 | sys.path.pop(0) |
mbligh | d90942c | 2008-04-04 15:08:12 +0000 | [diff] [blame] | 65 | |
| 66 | |
mbligh | 4205d89 | 2008-07-14 16:23:20 +0000 | [diff] [blame] | 67 | def import_module(module, from_where): |
| 68 | """Equivalent to 'from from_where import module' |
| 69 | Returns the corresponding module""" |
| 70 | from_module = __import__(from_where, globals(), locals(), [module]) |
| 71 | return getattr(from_module, module) |
| 72 | |
| 73 | |
showard | 756d82e | 2009-04-29 21:35:48 +0000 | [diff] [blame] | 74 | def _autotest_logging_handle_error(self, record): |
| 75 | """Method to monkey patch into logging.Handler to replace handleError.""" |
| 76 | # The same as the default logging.Handler.handleError but also prints |
| 77 | # out the original record causing the error so there is -some- idea |
| 78 | # about which call caused the logging error. |
mbligh | 23da87e | 2009-09-03 20:19:38 +0000 | [diff] [blame] | 79 | import logging |
showard | 756d82e | 2009-04-29 21:35:48 +0000 | [diff] [blame] | 80 | if logging.raiseExceptions: |
mbligh | 33b3ad1 | 2009-08-11 19:14:38 +0000 | [diff] [blame] | 81 | # Avoid recursion as the below output can end up back in here when |
| 82 | # something has *seriously* gone wrong in autotest. |
| 83 | logging.raiseExceptions = 0 |
showard | 756d82e | 2009-04-29 21:35:48 +0000 | [diff] [blame] | 84 | sys.stderr.write('Exception occurred formatting message: ' |
| 85 | '%r using args %r\n' % (record.msg, record.args)) |
| 86 | traceback.print_stack() |
showard | ddda38d | 2009-10-14 16:07:18 +0000 | [diff] [blame] | 87 | sys.stderr.write('-' * 50 + '\n') |
| 88 | traceback.print_exc() |
mbligh | 33b3ad1 | 2009-08-11 19:14:38 +0000 | [diff] [blame] | 89 | sys.stderr.write('Future logging formatting exceptions disabled.\n') |
showard | 756d82e | 2009-04-29 21:35:48 +0000 | [diff] [blame] | 90 | |
| 91 | |
mbligh | 23da87e | 2009-09-03 20:19:38 +0000 | [diff] [blame] | 92 | def _monkeypatch_logging_handle_error(): |
| 93 | # Hack out logging.py* |
| 94 | logging_py = os.path.join(os.path.dirname(__file__), "common_lib", |
| 95 | "logging.py*") |
| 96 | if glob.glob(logging_py): |
| 97 | os.system("rm -f %s" % logging_py) |
| 98 | |
| 99 | # Monkey patch our own handleError into the logging module's StreamHandler. |
| 100 | # A nicer way of doing this -might- be to have our own logging module define |
| 101 | # an autotest Logger instance that added our own Handler subclass with this |
| 102 | # handleError method in it. But that would mean modifying tons of code. |
| 103 | import logging |
| 104 | assert callable(logging.Handler.handleError) |
| 105 | logging.Handler.handleError = _autotest_logging_handle_error |
| 106 | |
| 107 | |
mbligh | d90942c | 2008-04-04 15:08:12 +0000 | [diff] [blame] | 108 | def setup(base_path, root_module_name=""): |
jadmanski | 0afbb63 | 2008-06-06 21:10:57 +0000 | [diff] [blame] | 109 | """ |
| 110 | Perform all the necessary setup so that all the packages at |
| 111 | 'base_path' can be imported via "import root_module_name.package". |
| 112 | If root_module_name is empty, then all the packages at base_path |
| 113 | are inserted as top-level packages. |
mbligh | d90942c | 2008-04-04 15:08:12 +0000 | [diff] [blame] | 114 | |
jadmanski | 0afbb63 | 2008-06-06 21:10:57 +0000 | [diff] [blame] | 115 | Also, setup all the common.* aliases for modules in the common |
| 116 | library. |
mbligh | c61d26d | 2008-07-17 00:22:52 +0000 | [diff] [blame] | 117 | |
| 118 | The setup must be different if you are running on an Autotest server |
mbligh | 23da87e | 2009-09-03 20:19:38 +0000 | [diff] [blame] | 119 | or on a test machine that just has the client directories installed. |
jadmanski | 0afbb63 | 2008-06-06 21:10:57 +0000 | [diff] [blame] | 120 | """ |
mbligh | c61d26d | 2008-07-17 00:22:52 +0000 | [diff] [blame] | 121 | # Hack... Any better ideas? |
| 122 | if (root_module_name == 'autotest_lib.client' and |
| 123 | os.path.exists(os.path.join(os.path.dirname(__file__), |
| 124 | '..', 'server'))): |
| 125 | root_module_name = 'autotest_lib' |
| 126 | base_path = os.path.abspath(os.path.join(base_path, '..')) |
| 127 | |
jadmanski | 0afbb63 | 2008-06-06 21:10:57 +0000 | [diff] [blame] | 128 | _create_module_and_parents(root_module_name) |
| 129 | _import_children_into_module(root_module_name, base_path) |
mbligh | d90942c | 2008-04-04 15:08:12 +0000 | [diff] [blame] | 130 | |
mbligh | 6d85ad9 | 2009-05-01 23:06:26 +0000 | [diff] [blame] | 131 | if root_module_name == 'autotest_lib': |
| 132 | # Allow locally installed third party packages to be found |
| 133 | # before any that are installed on the system itself when not. |
| 134 | # running as a client. |
| 135 | # This is primarily for the benefit of frontend and tko so that they |
| 136 | # may use libraries other than those available as system packages. |
| 137 | sys.path.insert(0, os.path.join(base_path, "site-packages")) |
mbligh | 23da87e | 2009-09-03 20:19:38 +0000 | [diff] [blame] | 138 | |
mbligh | 23da87e | 2009-09-03 20:19:38 +0000 | [diff] [blame] | 139 | _monkeypatch_logging_handle_error() |