importer.py revision 5522
15522Snate@binkert.org# Copyright (c) 2008 The Hewlett-Packard Development Company
25522Snate@binkert.org# All rights reserved.
35522Snate@binkert.org#
45522Snate@binkert.org# Redistribution and use in source and binary forms, with or without
55522Snate@binkert.org# modification, are permitted provided that the following conditions are
65522Snate@binkert.org# met: redistributions of source code must retain the above copyright
75522Snate@binkert.org# notice, this list of conditions and the following disclaimer;
85522Snate@binkert.org# redistributions in binary form must reproduce the above copyright
95522Snate@binkert.org# notice, this list of conditions and the following disclaimer in the
105522Snate@binkert.org# documentation and/or other materials provided with the distribution;
115522Snate@binkert.org# neither the name of the copyright holders nor the names of its
125522Snate@binkert.org# contributors may be used to endorse or promote products derived from
135522Snate@binkert.org# this software without specific prior written permission.
145522Snate@binkert.org#
155522Snate@binkert.org# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
165522Snate@binkert.org# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
175522Snate@binkert.org# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
185522Snate@binkert.org# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
195522Snate@binkert.org# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
205522Snate@binkert.org# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
215522Snate@binkert.org# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
225522Snate@binkert.org# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
235522Snate@binkert.org# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
245522Snate@binkert.org# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
255522Snate@binkert.org# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
265522Snate@binkert.org#
275522Snate@binkert.org# Authors: Nathan Binkert
285522Snate@binkert.org
295522Snate@binkert.org# Simple importer that allows python to import data from a dict of
305522Snate@binkert.org# code objects.  The keys are the module path, and the items are the
315522Snate@binkert.org# filename and bytecode of the file.
325522Snate@binkert.orgclass CodeImporter(object):
335522Snate@binkert.org    def __init__(self):
345522Snate@binkert.org        self.modules = {}
355522Snate@binkert.org
365522Snate@binkert.org    def add_module(self, filename, modpath, code):
375522Snate@binkert.org        if modpath in self.modules:
385522Snate@binkert.org            raise AttributeError, "%s already found in importer"
395522Snate@binkert.org
405522Snate@binkert.org        self.modules[modpath] = (filename, code)
415522Snate@binkert.org
425522Snate@binkert.org    def find_module(self, fullname, path):
435522Snate@binkert.org        if fullname in self.modules:
445522Snate@binkert.org            return self
455522Snate@binkert.org
465522Snate@binkert.org        return None
475522Snate@binkert.org
485522Snate@binkert.org    def load_module(self, fullname):
495522Snate@binkert.org        # Because the importer is created and initialized in its own
505522Snate@binkert.org        # little sandbox (in init.cc), the globals that were available
515522Snate@binkert.org        # when the importer module was loaded and CodeImporter was
525522Snate@binkert.org        # defined are not available when load_module is actually
535522Snate@binkert.org        # called. Soooo, the imports must live here.
545522Snate@binkert.org        import imp
555522Snate@binkert.org        import os
565522Snate@binkert.org        import sys
575522Snate@binkert.org        mod = imp.new_module(fullname)
585522Snate@binkert.org        sys.modules[fullname] = mod
595522Snate@binkert.org
605522Snate@binkert.org        try:
615522Snate@binkert.org            mod.__loader__ = self
625522Snate@binkert.org            srcfile,code = self.modules[fullname]
635522Snate@binkert.org            if os.path.basename(srcfile) == '__init__.py':
645522Snate@binkert.org                mod.__path__ = fullname.split('.')
655522Snate@binkert.org            mod.__file__ = srcfile
665522Snate@binkert.org
675522Snate@binkert.org            exec code in mod.__dict__
685522Snate@binkert.org        except Exception:
695522Snate@binkert.org            del sys.modules[fullname]
705522Snate@binkert.org            raise
715522Snate@binkert.org
725522Snate@binkert.org        return mod
735522Snate@binkert.org
745522Snate@binkert.org# Create an importer and add it to the meta_path so future imports can
755522Snate@binkert.org# use it.  There's currently nothing in the importer, but calls to
765522Snate@binkert.org# add_module can be used to add code.
775522Snate@binkert.orgimport sys
785522Snate@binkert.orgimporter = CodeImporter()
795522Snate@binkert.orgadd_module = importer.add_module
805522Snate@binkert.orgsys.meta_path.append(importer)
81