srcanamdw/codescanner/pyinstaller/archive.py
author noe\swadi
Thu, 18 Feb 2010 12:29:02 +0530
changeset 1 22878952f6e2
permissions -rw-r--r--
Committing the CodeScanner Core tool This component has been moved from the StaticAnaApps package. BUG : 5889 (http://developer.symbian.org/webbugs/show_bug.cgi?id=5889).
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
     1
# Copyright (C) 2005, Giovanni Bajo
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
     2
# Based on previous work under copyright (c) 2002 McMillan Enterprises, Inc.
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
     3
#
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
     4
# This program is free software; you can redistribute it and/or
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
     5
# modify it under the terms of the GNU General Public License
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
     6
# as published by the Free Software Foundation; either version 2
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
     7
# of the License, or (at your option) any later version.
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
     8
#
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
     9
# In addition to the permissions in the GNU General Public License, the
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    10
# authors give you unlimited permission to link or embed the compiled
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    11
# version of this file into combinations with other programs, and to
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    12
# distribute those combinations without any restriction coming from the
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    13
# use of this file. (The General Public License restrictions do apply in
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    14
# other respects; for example, they cover modification of the file, and
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    15
# distribution when not linked into a combine executable.)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    16
#
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    17
# This program is distributed in the hope that it will be useful,
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    18
# but WITHOUT ANY WARRANTY; without even the implied warranty of
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    19
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    20
# GNU General Public License for more details.
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    21
#
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    22
# You should have received a copy of the GNU General Public License
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    23
# along with this program; if not, write to the Free Software
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    24
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    25
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    26
# subclasses may not need marshal or struct, but since they're
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    27
# builtin, importing is safe.
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    28
#
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    29
# While an Archive is really an abstraction for any "filesystem
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    30
# within a file", it is tuned for use with imputil.FuncImporter.
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    31
# This assumes it contains python code objects, indexed by the
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    32
# the internal name (ie, no '.py').
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    33
# See carchive.py for a more general archive (contains anything)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    34
# that can be understood by a C program.
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    35
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    36
_verbose = 0
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    37
_listdir = None
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    38
_environ = None
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    39
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    40
# **NOTE** This module is used during bootstrap. Import *ONLY* builtin modules.
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    41
import marshal
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    42
import struct
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    43
import imp
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    44
import sys
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    45
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    46
_c_suffixes = filter(lambda x: x[2] == imp.C_EXTENSION, imp.get_suffixes())
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    47
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    48
for nm in ('nt', 'posix', 'dos', 'os2', 'mac'):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    49
    if nm in sys.builtin_module_names:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    50
        mod = __import__(nm)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    51
        _listdir = mod.listdir
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    52
        _environ = mod.environ
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    53
        break
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    54
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    55
if hasattr(sys, 'version_info'):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    56
    versuffix = '%d%d'%(sys.version_info[0],sys.version_info[1])
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    57
else:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    58
    vers = sys.version
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    59
    dot1 = dot2 = 0
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    60
    for i in range(len(vers)):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    61
        if vers[i] == '.':
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    62
            if dot1:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    63
                dot2 = i
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    64
                break
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    65
            else:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    66
                dot1 = i
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    67
    else:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    68
        dot2 = len(vers)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    69
    versuffix = '%s%s' % (vers[:dot1], vers[dot1+1:dot2])
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    70
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    71
if "-vi" in sys.argv[1:]:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    72
    _verbose = 1
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    73
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    74
class Archive:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    75
    """ A base class for a repository of python code objects.
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    76
        The extract method is used by imputil.ArchiveImporter
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    77
        to get code objects by name (fully qualified name), so
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    78
        an enduser "import a.b" would become
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    79
          extract('a.__init__')
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    80
          extract('a.b')
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    81
    """
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    82
    MAGIC = 'PYL\0'
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    83
    HDRLEN = 12        # default is MAGIC followed by python's magic, int pos of toc
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    84
    TOCPOS = 8
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    85
    TRLLEN = 0        # default - no trailer
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    86
    TOCTMPLT = {}     #
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    87
    os = None
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    88
    _bincache = None
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    89
    def __init__(self, path=None, start=0):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    90
        "Initialize an Archive. If path is omitted, it will be an empty Archive."
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    91
        self.toc = None
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    92
        self.path = path
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    93
        self.start = start
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    94
        import imp
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    95
        self.pymagic = imp.get_magic()
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    96
        if path is not None:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    97
            self.lib = open(self.path, 'rb')
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    98
            self.checkmagic()
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    99
            self.loadtoc()
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   100
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   101
            ####### Sub-methods of __init__ - override as needed #############
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   102
    def checkmagic(self):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   103
        """ Overridable.
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   104
            Check to see if the file object self.lib actually has a file
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   105
            we understand.
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   106
        """
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   107
        self.lib.seek(self.start)	#default - magic is at start of file
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   108
        if self.lib.read(len(self.MAGIC)) != self.MAGIC:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   109
            raise RuntimeError, "%s is not a valid %s archive file" \
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   110
              % (self.path, self.__class__.__name__)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   111
        if self.lib.read(len(self.pymagic)) != self.pymagic:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   112
            raise RuntimeError, "%s has version mismatch to dll" % (self.path)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   113
        self.lib.read(4)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   114
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   115
    def loadtoc(self):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   116
        """ Overridable.
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   117
            Default: After magic comes an int (4 byte native) giving the
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   118
            position of the TOC within self.lib.
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   119
            Default: The TOC is a marshal-able string.
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   120
        """
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   121
        self.lib.seek(self.start + self.TOCPOS)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   122
        (offset,) = struct.unpack('=i', self.lib.read(4))
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   123
        self.lib.seek(self.start + offset)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   124
        self.toc = marshal.load(self.lib)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   125
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   126
        ######## This is what is called by FuncImporter #######
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   127
        ## Since an Archive is flat, we ignore parent and modname.
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   128
        #XXX obsolete - imputil only code
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   129
        ##  def get_code(self, parent, modname, fqname):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   130
        ####    if _verbose:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   131
        ####      print "I: get_code(%s, %s, %s, %s)" % (self, parent, modname, fqname)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   132
        ##    iname = fqname
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   133
        ##    if parent:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   134
        ##        iname = '%s.%s' % (parent.__dict__.get('__iname__', parent.__name__), modname)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   135
        ####        if _verbose:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   136
        ####            print "I: get_code: iname is %s" % iname
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   137
        ##    rslt = self.extract(iname) # None if not found, (ispkg, code) otherwise
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   138
        ####    if _verbose:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   139
        ####        print 'I: get_code: rslt', rslt
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   140
        ##    if rslt is None:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   141
        ####      if _verbose:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   142
        ####          print 'I: get_code: importer', getattr(parent, "__importer__", None),'self',self
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   143
        ##      # check the cache if there is no parent or self is the parents importer
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   144
        ##      if parent is None or getattr(parent, "__importer__", None) is self:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   145
        ####            if _verbose:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   146
        ####                print 'I: get_code: cached 1',iname
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   147
        ##            file, desc = Archive._bincache.get(iname, (None, None))
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   148
        ####            if _verbose:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   149
        ####                print 'I: get_code: file',file,'desc',desc
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   150
        ##            if file:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   151
        ##              try:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   152
        ##                fp = open(file, desc[1])
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   153
        ##              except IOError:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   154
        ##                pass
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   155
        ##              else:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   156
        ##                module = imp.load_module(fqname, fp, file, desc)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   157
        ##                if _verbose:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   158
        ##                    print "I: import %s found %s" % (fqname, file)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   159
        ##                return 0, module, {'__file__':file}
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   160
        ##      if _verbose:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   161
        ##          print "I: import %s failed" % fqname
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   162
        ##
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   163
        ##      return None
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   164
        ##
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   165
        ##    ispkg, code = rslt
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   166
        ##    values = {'__file__' : code.co_filename, '__iname__' : iname}
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   167
        ##    if ispkg:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   168
        ##      values['__path__'] = [fqname]
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   169
        ##    if _verbose:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   170
        ##        print "I: import %s found %s" % (fqname, iname)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   171
        ##    return ispkg, code, values
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   172
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   173
        ####### Core method - Override as needed  #########
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   174
    def extract(self, name):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   175
        """ Get the object corresponding to name, or None.
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   176
            For use with imputil ArchiveImporter, object is a python code object.
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   177
            'name' is the name as specified in an 'import name'.
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   178
            'import a.b' will become:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   179
            extract('a') (return None because 'a' is not a code object)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   180
            extract('a.__init__') (return a code object)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   181
            extract('a.b') (return a code object)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   182
            Default implementation:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   183
              self.toc is a dict
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   184
              self.toc[name] is pos
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   185
              self.lib has the code object marshal-ed at pos
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   186
        """
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   187
        ispkg, pos = self.toc.get(name, (0,None))
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   188
        if pos is None:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   189
            return None
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   190
        self.lib.seek(self.start + pos)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   191
        return ispkg, marshal.load(self.lib)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   192
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   193
        ########################################################################
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   194
        # Informational methods
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   195
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   196
    def contents(self):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   197
        """Return a list of the contents
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   198
           Default implementation assumes self.toc is a dict like object.
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   199
           Not required by ArchiveImporter.
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   200
        """
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   201
        return self.toc.keys()
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   202
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   203
        ########################################################################
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   204
        # Building
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   205
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   206
        ####### Top level method - shouldn't need overriding #######
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   207
    def build(self, path, lTOC):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   208
        """Create an archive file of name 'path'.
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   209
           lTOC is a 'logical TOC' - a list of (name, path, ...)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   210
           where name is the internal name, eg 'a'
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   211
           and path is a file to get the object from, eg './a.pyc'.
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   212
        """
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   213
        self.path = path
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   214
        self.lib = open(path, 'wb')
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   215
        #reserve space for the header
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   216
        if self.HDRLEN:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   217
            self.lib.write('\0'*self.HDRLEN)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   218
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   219
            #create an empty toc
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   220
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   221
        if type(self.TOCTMPLT) == type({}):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   222
            self.toc = {}
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   223
        else:       # assume callable
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   224
            self.toc = self.TOCTMPLT()
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   225
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   226
        for tocentry in lTOC:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   227
            self.add(tocentry)   # the guts of the archive
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   228
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   229
        tocpos = self.lib.tell()
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   230
        self.save_toc(tocpos)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   231
        if self.TRLLEN:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   232
            self.save_trailer(tocpos)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   233
        if self.HDRLEN:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   234
            self.update_headers(tocpos)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   235
        self.lib.close()
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   236
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   237
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   238
        ####### manages keeping the internal TOC and the guts in sync #######
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   239
    def add(self, entry):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   240
        """Override this to influence the mechanics of the Archive.
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   241
           Assumes entry is a seq beginning with (nm, pth, ...) where
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   242
           nm is the key by which we'll be asked for the object.
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   243
           pth is the name of where we find the object. Overrides of
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   244
           get_obj_from can make use of further elements in entry.
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   245
        """
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   246
        if self.os is None:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   247
            import os
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   248
            self.os = os
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   249
        nm = entry[0]
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   250
        pth = entry[1]
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   251
        pynm, ext = self.os.path.splitext(self.os.path.basename(pth))
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   252
        ispkg = pynm == '__init__'
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   253
        assert ext in ('.pyc', '.pyo')
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   254
        self.toc[nm] = (ispkg, self.lib.tell())
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   255
        f = open(entry[1], 'rb')
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   256
        f.seek(8)	#skip magic and timestamp
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   257
        self.lib.write(f.read())
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   258
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   259
    def save_toc(self, tocpos):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   260
        """Default - toc is a dict
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   261
           Gets marshaled to self.lib
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   262
        """
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   263
        marshal.dump(self.toc, self.lib)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   264
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   265
    def save_trailer(self, tocpos):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   266
        """Default - not used"""
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   267
        pass
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   268
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   269
    def update_headers(self, tocpos):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   270
        """Default - MAGIC + Python's magic + tocpos"""
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   271
        self.lib.seek(self.start)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   272
        self.lib.write(self.MAGIC)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   273
        self.lib.write(self.pymagic)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   274
        self.lib.write(struct.pack('=i', tocpos))
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   275
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   276
class DummyZlib:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   277
    def decompress(self, data):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   278
        return data
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   279
    def compress(self, data, lvl):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   280
        return data
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   281
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   282
import iu
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   283
##############################################################
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   284
#
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   285
# ZlibArchive - an archive with compressed entries
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   286
#
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   287
class ZlibArchive(Archive):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   288
    MAGIC = 'PYZ\0'
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   289
    TOCPOS = 8
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   290
    HDRLEN = 16
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   291
    TRLLEN = 0
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   292
    TOCTMPLT = {}
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   293
    LEVEL = 9
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   294
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   295
    def __init__(self, path=None, offset=None, level=9):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   296
        if path is None:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   297
            offset = 0
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   298
        elif offset is None:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   299
            for i in range(len(path)-1, -1, -1):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   300
                if path[i] == '?':
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   301
                    offset = int(path[i+1:])
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   302
                    path = path[:i]
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   303
                    break
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   304
            else:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   305
                offset = 0
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   306
        self.LEVEL = level
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   307
        Archive.__init__(self, path, offset)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   308
        # dynamic import so not imported if not needed
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   309
        global zlib
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   310
        if self.LEVEL:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   311
            try:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   312
                import zlib
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   313
            except ImportError:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   314
                zlib = DummyZlib()
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   315
        else:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   316
            zlib = DummyZlib()
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   317
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   318
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   319
    def extract(self, name):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   320
        (ispkg, pos, lngth) = self.toc.get(name, (0, None, 0))
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   321
        if pos is None:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   322
            return None
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   323
        self.lib.seek(self.start + pos)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   324
        try:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   325
            co = marshal.loads(zlib.decompress(self.lib.read(lngth)))
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   326
        except EOFError:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   327
            raise ImportError, "PYZ entry '%s' failed to unmarshal" % name
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   328
        return ispkg, co
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   329
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   330
    def add(self, entry):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   331
        if self.os is None:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   332
            import os
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   333
            self.os = os
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   334
        nm = entry[0]
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   335
        pth = entry[1]
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   336
        base, ext = self.os.path.splitext(self.os.path.basename(pth))
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   337
        ispkg = base == '__init__'
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   338
        try:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   339
            txt = open(pth[:-1], 'r').read()+'\n'
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   340
        except (IOError, OSError):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   341
            try:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   342
                f = open(pth, 'rb')
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   343
                f.seek(8)	#skip magic and timestamp
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   344
                bytecode = f.read()
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   345
                marshal.loads(bytecode).co_filename # to make sure it's valid
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   346
                obj = zlib.compress(bytecode, self.LEVEL)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   347
            except (IOError, ValueError, EOFError, AttributeError):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   348
                raise ValueError("bad bytecode in %s and no source" % pth)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   349
        else:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   350
            txt = iu._string_replace(txt, '\r\n', '\n')
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   351
            try:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   352
                co = compile(txt, "%s/%s" % (self.path, nm), 'exec')
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   353
            except SyntaxError, e:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   354
                print "Syntax error in", pth[:-1]
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   355
                print e.args
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   356
                raise
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   357
            obj = zlib.compress(marshal.dumps(co), self.LEVEL)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   358
        self.toc[nm] = (ispkg, self.lib.tell(), len(obj))
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   359
        self.lib.write(obj)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   360
    def update_headers(self, tocpos):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   361
        """add level"""
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   362
        Archive.update_headers(self, tocpos)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   363
        self.lib.write(struct.pack('!i', self.LEVEL))
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   364
    def checkmagic(self):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   365
        Archive.checkmagic(self)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   366
        self.LEVEL = struct.unpack('!i', self.lib.read(4))[0]
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   367
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   368
class PYZOwner(iu.Owner):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   369
    def __init__(self, path):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   370
        self.pyz = ZlibArchive(path)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   371
        iu.Owner.__init__(self, path)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   372
    def getmod(self, nm, newmod=imp.new_module):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   373
        rslt = self.pyz.extract(nm)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   374
        if rslt is None:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   375
            return None
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   376
        ispkg, co = rslt
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   377
        mod = newmod(nm)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   378
        try:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   379
            mod.__file__ = co.co_filename
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   380
        except AttributeError:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   381
            raise ImportError, "PYZ entry '%s' (%s) is not a valid code object" % (nm, repr(co))
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   382
        if ispkg:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   383
            if _environ.has_key('_MEIPASS2'):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   384
                localpath = _environ['_MEIPASS2'][:-1]
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   385
            else:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   386
                localpath = iu._os_path_dirname(self.path)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   387
            mod.__path__ = [self.path, localpath, iu._os_path_dirname(mod.__file__)]
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   388
            #print "PYZOwner setting %s's __path__: %s" % (nm, mod.__path__)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   389
            importer = iu.PathImportDirector(mod.__path__,
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   390
                                              {self.path:PkgInPYZImporter(nm, self),
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   391
                                               localpath:ExtInPkgImporter(localpath, nm)},
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   392
                                              [iu.DirOwner])
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   393
            mod.__importsub__ = importer.getmod
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   394
        mod.__co__ = co
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   395
        return mod
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   396
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   397
class PkgInPYZImporter:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   398
    def __init__(self, name, owner):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   399
        self.name = name
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   400
        self.owner = owner
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   401
    def getmod(self, nm):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   402
        #print "PkgInPYZImporter.getmod %s -> %s" % (nm, self.name+'.'+nm)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   403
        return self.owner.getmod(self.name+'.'+nm)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   404
class ExtInPkgImporter(iu.DirOwner):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   405
    def __init__(self, path, prefix):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   406
        iu.DirOwner.__init__(self, path)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   407
        self.prefix = prefix
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   408
    def getmod(self, nm):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   409
        return iu.DirOwner.getmod(self, self.prefix+'.'+nm)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   410
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   411
        #XXX this should also get moved out
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   412
        ##iu._globalownertypes.insert(0, PYZOwner)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   413
        ##iu.ImportManager().install()