importer.py revision 13670
12SN/A# Copyright (c) 2008 The Hewlett-Packard Development Company
213590Srekai.gonzalezalberquilla@arm.com# All rights reserved.
313429Srekai.gonzalezalberquilla@arm.com#
413429Srekai.gonzalezalberquilla@arm.com# Redistribution and use in source and binary forms, with or without
513429Srekai.gonzalezalberquilla@arm.com# modification, are permitted provided that the following conditions are
613429Srekai.gonzalezalberquilla@arm.com# met: redistributions of source code must retain the above copyright
713429Srekai.gonzalezalberquilla@arm.com# notice, this list of conditions and the following disclaimer;
813429Srekai.gonzalezalberquilla@arm.com# redistributions in binary form must reproduce the above copyright
913429Srekai.gonzalezalberquilla@arm.com# notice, this list of conditions and the following disclaimer in the
1013429Srekai.gonzalezalberquilla@arm.com# documentation and/or other materials provided with the distribution;
1113429Srekai.gonzalezalberquilla@arm.com# neither the name of the copyright holders nor the names of its
1213429Srekai.gonzalezalberquilla@arm.com# contributors may be used to endorse or promote products derived from
1313429Srekai.gonzalezalberquilla@arm.com# this software without specific prior written permission.
141762SN/A#
152SN/A# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
162SN/A# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
172SN/A# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
182SN/A# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
192SN/A# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
202SN/A# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
212SN/A# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
222SN/A# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
232SN/A# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
242SN/A# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
252SN/A# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
262SN/A#
272SN/A# Authors: Nathan Binkert
282SN/A
292SN/A# Simple importer that allows python to import data from a dict of
302SN/A# code objects.  The keys are the module path, and the items are the
312SN/A# filename and bytecode of the file.
322SN/Aclass CodeImporter(object):
332SN/A    def __init__(self):
342SN/A        self.modules = {}
352SN/A
362SN/A    def add_module(self, filename, abspath, modpath, code):
372SN/A        if modpath in self.modules:
382SN/A            raise AttributeError("%s already found in importer" % modpath)
392665Ssaidi@eecs.umich.edu
402665Ssaidi@eecs.umich.edu        self.modules[modpath] = (filename, abspath, code)
412SN/A
422SN/A    def find_module(self, fullname, path):
433877Sbinkertn@umich.edu        if fullname in self.modules:
443877Sbinkertn@umich.edu            return self
452147SN/A
4613429Srekai.gonzalezalberquilla@arm.com        return None
4713429Srekai.gonzalezalberquilla@arm.com
488221Snate@binkert.org    def load_module(self, fullname):
498221Snate@binkert.org        # Because the importer is created and initialized in its own
508221Snate@binkert.org        # little sandbox (in init.cc), the globals that were available
518221Snate@binkert.org        # when the importer module was loaded and CodeImporter was
528221Snate@binkert.org        # defined are not available when load_module is actually
538221Snate@binkert.org        # called. Soooo, the imports must live here.
548221Snate@binkert.org        import imp
558221Snate@binkert.org        import os
568221Snate@binkert.org        import sys
578221Snate@binkert.org
588221Snate@binkert.org        try:
592SN/A            mod = sys.modules[fullname]
602SN/A        except KeyError:
612SN/A            mod = imp.new_module(fullname)
628221Snate@binkert.org            sys.modules[fullname] = mod
638221Snate@binkert.org
648221Snate@binkert.org        try:
658221Snate@binkert.org            mod.__loader__ = self
667866Snate@binkert.org            srcfile,abspath,code = self.modules[fullname]
672SN/A
682SN/A            override = os.environ.get('M5_OVERRIDE_PY_SOURCE', 'false').lower()
697057Snate@binkert.org            if override in ('true', 'yes') and  os.path.exists(abspath):
707057Snate@binkert.org                src = open(abspath, 'r').read()
717057Snate@binkert.org                code = compile(src, abspath, 'exec')
722SN/A
737057Snate@binkert.org            if os.path.basename(srcfile) == '__init__.py':
742SN/A                mod.__path__ = fullname.split('.')
752SN/A                mod.__package__ = fullname
768221Snate@binkert.org            else:
778221Snate@binkert.org                mod.__package__ = fullname.rpartition('.')[0]
788221Snate@binkert.org            mod.__file__ = srcfile
798221Snate@binkert.org
808221Snate@binkert.org            exec code in mod.__dict__
818221Snate@binkert.org        except Exception:
828221Snate@binkert.org            del sys.modules[fullname]
832SN/A            raise
848221Snate@binkert.org
858221Snate@binkert.org        return mod
868221Snate@binkert.org
878221Snate@binkert.org# Create an importer and add it to the meta_path so future imports can
888221Snate@binkert.org# use it.  There's currently nothing in the importer, but calls to
898221Snate@binkert.org# add_module can be used to add code.
908221Snate@binkert.orgimport sys
918221Snate@binkert.orgimporter = CodeImporter()
928221Snate@binkert.orgadd_module = importer.add_module
938221Snate@binkert.orgsys.meta_path.append(importer)
942SN/A