Exemplo n.º 1
0
    def __setstate__(self, obj):
        if obj[0] == 0:
            magic, functions, nondefault_globals = obj[1:]
            modules = {}
        elif obj[0] == 1:
            magic, functions, modules, nondefault_globals = obj[1:]
        else:
            raise ValueError("unknown version of PicklableModule")

        if magic != imp.get_magic():
            raise ValueError("cannot unpickle function binary: "
                    "incorrect magic value (got: %s, expected: %s)"
                    % (magic, imp.get_magic()))

        mod_globals = _empty_module_dict.copy()
        mod_globals.update(nondefault_globals)

        from pytools.importlib_backport import import_module
        for k, mod_name in six.iteritems(modules):
            mod_globals[k] = import_module(mod_name)

        for k, (name, code_bytes, argdefs) in six.iteritems(functions):
            f = FunctionType(
                    marshal.loads(code_bytes), mod_globals, name=name,
                    argdefs=argdefs)
            mod_globals[k] = f

        self.mod_globals = mod_globals
Exemplo n.º 2
0
 def get_code(self, fullname):
     u"""Get a code object from source or bytecode."""
     warnings.warn(u"importlib_full.abc.PyPycLoader is deprecated and slated for "
                         u"removal in Python 3.4; use SourceLoader instead. "
                         u"If Python 3.1 compatibility is required, see the "
                         u"latest documentation for PyLoader.",
                     PendingDeprecationWarning)
     source_timestamp = self.source_mtime(fullname)
     # Try to use bytecode if it is available.
     bytecode_path = self.bytecode_path(fullname)
     if bytecode_path:
         data = self.get_data(bytecode_path)
         try:
             magic = data[:4]
             if len(magic) < 4:
                 raise ImportError(u"bad magic number in %s" % fullname)
             raw_timestamp = data[4:8]
             if len(raw_timestamp) < 4:
                 raise EOFError(u"bad timestamp in %s" % fullname)
             pyc_timestamp = marshal._r_long(raw_timestamp)
             bytecode = data[8:]
             # Verify that the magic number is valid.
             if imp.get_magic() != magic:
                 raise ImportError(u"bad magic number in %s" % fullname)
             # Verify that the bytecode is not stale (only matters when
             # there is source to fall back on.
             if source_timestamp:
                 if pyc_timestamp < source_timestamp:
                     raise ImportError(u"bytecode is stale")
         except (ImportError, EOFError):
             # If source is available give it a shot.
             if source_timestamp is not None:
                 pass
             else:
                 raise
         else:
             # Bytecode seems fine, so try to use it.
             return marshal.loads(bytecode)
     elif source_timestamp is None:
         raise ImportError(u"no source or bytecode available to create code "
                             u"object for %r" % fullname)
     # Use the source.
     source_path = self.source_path(fullname)
     if source_path is None:
         message = u"a source path must exist to load %s" % fullname
         raise ImportError(message)
     source = self.get_data(source_path)
     code_object = compile(source, source_path, u'exec', dont_inherit=True)
     # Generate bytecode and write it out.
     if not sys.dont_write_bytecode:
         data = bytearray(imp.get_magic())
         data.extend(marshal._w_long(source_timestamp))
         data.extend(marshal.dumps(code_object))
         self.write_bytecode(fullname, data)
     return code_object
Exemplo n.º 3
0
    def read_replace(self):
        if not self.name.endswith(".pyc"):
            return self.read()
        
        data = self.read()
        if data[:4] != imp.get_magic():
            return data
        mtime = data[4:8]

        code = marshal.loads(data[8:])
        from bbfreeze import freezer
        code = freezer.replace_paths_in_code(code, self.name)
        return "".join([imp.get_magic(), mtime, marshal.dumps(code)])
Exemplo n.º 4
0
def compile_to_bytecode(source_code, compile_filename=None):
    """Given source_code, return its compiled bytecode."""
    if sys.version_info[:2] < (3, 1):
        bytecode = imp.get_magic() + struct.pack("<i", 0)
        bytecode += marshal.dumps(compile(source_code, compile_filename, "exec"))
    elif sys.version_info[:2] < (3, 4):
        bytecode = imp.get_magic() + struct.pack("<ii", 0, 0)
        bytecode += marshal.dumps(compile(source_code, compile_filename, "exec"))
    else:
        loader = importlib._bootstrap.SourceLoader()    
        code = loader.source_to_code(source_code, '<string>')
        bytecode = importlib._bootstrap._code_to_bytecode(code, mtime=0, source_size=0)
        
    return bytecode
Exemplo n.º 5
0
 def test_different_magic(self):
     # A different magic number should lead to new bytecode.
     name = 'mod'
     bad_magic = b'\x00\x00\x00\x00'
     assert bad_magic != imp.get_magic()
     mock = PyPycLoaderMock({name: os.path.join('path', 'to', 'mod')},
                             {name: {'path': os.path.join('path', 'to',
                                                 'mod.bytecode'),
                                     'magic': bad_magic}})
     with util.uncache(name):
         mock.load_module(name)
     self.assertTrue(name in mock.module_bytecode)
     magic = mock.module_bytecode[name][:4]
     self.assertEqual(magic, imp.get_magic())
    def _compile(self, filename, source):
        """ Compiles the Python source code to a code object and
        attempts to write it to an appropriate .pyc file.  May raise
        SyntaxError or other errors generated by the compiler. """

        if source and source[-1] != "\n":
            source = source + "\n"
        code = __builtin__.compile(source, filename.toOsSpecific(), "exec")

        # try to cache the compiled code
        pycFilename = Filename(filename)
        pycFilename.setExtension(compiledExtensions[0])
        try:
            f = open(pycFilename.toOsSpecific(), "wb")
        except IOError:
            pass
        else:
            f.write("\0\0\0\0")
            f.write(struct.pack("<I", self.timestamp))
            f.write(marshal.dumps(code))
            f.flush()
            f.seek(0, 0)
            f.write(imp.get_magic())
            f.close()

        return code
Exemplo n.º 7
0
 def __init__(self, srcName):
     self._srcName = srcName
     self.__magic = imp.get_magic()
     self.__sfx = {}
     for sfx, mode, typ in imp.get_suffixes():
         self.__sfx[typ] = (sfx, len(sfx), mode)
     debug.logger & debug.flagBld and debug.logger('trying %s' % self)
Exemplo n.º 8
0
def _get_module():
    del globals()['_get_module']
    import imp
    import base64
    import marshal

    magic = imp.get_magic()
    if magic == b'O\x0c\r\n': # Python 3.1
        pycData = b'TwwNChNz/FRjAAAAAAAAAAAAAAAABAAAAEAAAABzdAAAAGQAAGQBAGwAAFoAAEdkAgCEAABkAwCD\nAgBaAQBkBABkBQCEAQBaAgBkBgCEAABaAwBkBwCEAABaBABkCACEAABaBQBkCQCEAABaBgBkAABl\nBQBfBwBkCgBlBQBfCABkAABlBgBfBwBkCgBlBgBfCABkAQBTKAsAAABpAAAAAE5jAQAAAAAAAAAB\nAAAAAwAAAEIAAABzXwAAAHwAAEVlAABaAQBlAgCDAABpAABkAACEAgBaAwBkAQCEAABaBABkAgCE\nAABaBQBkAwCEAABaBgBkBACEAABaBwBkBQCEAABaCABkBgCEAABaCQBkBwCEAABaCgBkCABTKAkA\nAABjAwAAAAAAAAADAAAAAgAAAEMAAABzFgAAAHwBAHwAAF8AAHwCAHwAAF8BAGQAAFMoAQAAAE4o\nAgAAAHUBAAAARHUBAAAAZigDAAAAdQQAAABzZWxmdQYAAABsYWJlbHN1CAAAAGZ1bmN0aW9uKAAA\nAAAoAAAAAHUkAAAALi4vcmVzb3VyY2VzL3ByaXZhdGUvaW5kZXBlbmRlbmNlLnB5dQgAAABfX2lu\naXRfXwUAAABzBAAAAAABCQFjAgAAAAAAAAACAAAAAgAAAEMAAABzHgAAAHwBAHwAAGoAAGsGAHIa\nAHwAAGoAAHwBABlTZAEAUygCAAAATmkAAAAAKAEAAAB1AQAAAGYoAgAAAHUBAAAAdnUBAAAAaygA\nAAAAKAAAAAB1JAAAAC4uL3Jlc291cmNlcy9wcml2YXRlL2luZGVwZW5kZW5jZS5weXULAAAAX19n\nZXRpdGVtX18JAAAAcwAAAABjAwAAAAAAAAADAAAABAAAAEMAAABzFQAAAHQAAAR8AABqAQB8AQA8\nfQIAZAAAUygBAAAATigCAAAAdQgAAABfc2V0aXRlbXUBAAAAZigDAAAAdQEAAAB2dQEAAABrdQMA\nAAB2YWwoAAAAACgAAAAAdSQAAAAuLi9yZXNvdXJjZXMvcHJpdmF0ZS9pbmRlcGVuZGVuY2UucHl1\nCwAAAF9fc2V0aXRlbV9fCgAAAHMAAAAAYwEAAAAAAAAAAQAAAAIAAABDAAAAcwgAAABkAQB8AAAU\nUygCAAAATmn/////KAAAAAAoAQAAAHUBAAAAdigAAAAAKAAAAAB1JAAAAC4uL3Jlc291cmNlcy9w\ncml2YXRlL2luZGVwZW5kZW5jZS5weXUHAAAAX19uZWdfXwsAAABzAAAAAGMCAAAAAAAAAAIAAAAE\nAAAAAwAAAHMpAAAAdAAAfAAAagEAhwAAZgEAZAEAhgAAfAAAagIAagMAgwAARIMBAIMCAFMoAgAA\nAE5jAQAAAAAAAAADAAAABAAAABMAAABzIwAAAGkAAHwAAF0ZAFwCAH0BAH0CAIgAAHwCABR8AQCT\nAgBxBgBTKAAAAAAoAAAAACgDAAAAdQIAAAAuMHUBAAAAa3UBAAAAeCgBAAAAdQUAAABhbHBoYSgA\nAAAAdSQAAAAuLi9yZXNvdXJjZXMvcHJpdmF0ZS9pbmRlcGVuZGVuY2UucHl1CgAAADxkaWN0Y29t\ncD4MAAAAcwIAAAAJACgEAAAAdQQAAABfVmVjdQEAAABEdQEAAABmdQUAAABpdGVtcygCAAAAdQEA\nAAB2dQUAAABhbHBoYSgAAAAAKAEAAAB1BQAAAGFscGhhdSQAAAAuLi9yZXNvdXJjZXMvcHJpdmF0\nZS9pbmRlcGVuZGVuY2UucHl1CAAAAF9fcm11bF9fDAAAAHMAAAAAYwIAAAAAAAAAAgAAAAMAAAAD\nAAAAcz0AAAB0AACIAQB0AQCDAgByNQB0AgCHAQCHAABmAgBkAQCGAACIAABqAwBqBACDAABEgwEA\ngwEAU3QFAFNkAABTKAIAAABOYwEAAAAAAAAAAgAAAAUAAAATAAAAcyIAAABnAAB8AABdGAB9AQCI\nAQB8AQAZiAAAfAEAGRSRAgBxBgBTKAAAAAAoAAAAACgCAAAAdQIAAAAuMHUBAAAAaygCAAAAdQUA\nAABvdGhlcnUEAAAAc2VsZigAAAAAdSQAAAAuLi9yZXNvdXJjZXMvcHJpdmF0ZS9pbmRlcGVuZGVu\nY2UucHl1CgAAADxsaXN0Y29tcD4RAAAAcwIAAAAJACgGAAAAdQoAAABpc2luc3RhbmNldQQAAABf\nVmVjdQMAAABzdW11AQAAAGZ1BAAAAGtleXN1DgAAAE5vdEltcGxlbWVudGVkKAIAAAB1BAAAAHNl\nbGZ1BQAAAG90aGVyKAAAAAAoAgAAAHUEAAAAc2VsZnUFAAAAb3RoZXJ1JAAAAC4uL3Jlc291cmNl\ncy9wcml2YXRlL2luZGVwZW5kZW5jZS5weXUHAAAAX19tdWxfXw4AAABzBgAAAAACDwEmAmMCAAAA\nAAAAAAIAAAAFAAAAAwAAAHNEAAAAdAAAiAAAagEAhwAAhwEAZgIAZAEAhgAAdAIAiAAAagMAagQA\ngwAAgwEAagUAiAEAagMAagQAgwAAgwEARIMBAIMCAFMoAgAAAE5jAQAAAAAAAAACAAAABQAAABMA\nAABzJQAAAGkAAHwAAF0bAH0BAIgAAHwBABmIAQB8AQAZF3wBAJMCAHEGAFMoAAAAACgAAAAAKAIA\nAAB1AgAAAC4wdQEAAABrKAIAAAB1AQAAAHV1AQAAAHYoAAAAAHUkAAAALi4vcmVzb3VyY2VzL3By\naXZhdGUvaW5kZXBlbmRlbmNlLnB5dQoAAAA8ZGljdGNvbXA+FQAAAHMCAAAACQAoBgAAAHUEAAAA\nX1ZlY3UBAAAARHUDAAAAc2V0dQEAAABmdQQAAABrZXlzdQUAAAB1bmlvbigCAAAAdQEAAAB1dQEA\nAAB2KAAAAAAoAgAAAHUBAAAAdXUBAAAAdnUkAAAALi4vcmVzb3VyY2VzL3ByaXZhdGUvaW5kZXBl\nbmRlbmNlLnB5dQcAAABfX2FkZF9fFQAAAHMAAAAAYwIAAAAAAAAAAgAAAAIAAABDAAAAcwkAAAB8\nAAB8AQALF1MoAQAAAHU0AAAAUmV0dXJucyBhIHZlY3RvciB3aGljaCBpcyB0aGUgZGlmZmVyZW5j\nZSBvZiBhIGFuZCBiLigAAAAAKAIAAAB1AQAAAGF1AQAAAGIoAAAAACgAAAAAdSQAAAAuLi9yZXNv\ndXJjZXMvcHJpdmF0ZS9pbmRlcGVuZGVuY2UucHl1BwAAAF9fc3ViX18XAAAAcwIAAAAAAk4oCwAA\nAHUIAAAAX19uYW1lX191CgAAAF9fbW9kdWxlX191AwAAAHNldHUIAAAAX19pbml0X191CwAAAF9f\nZ2V0aXRlbV9fdQsAAABfX3NldGl0ZW1fX3UHAAAAX19uZWdfX3UIAAAAX19ybXVsX191BwAAAF9f\nbXVsX191BwAAAF9fYWRkX191BwAAAF9fc3ViX18oAQAAAHUKAAAAX19sb2NhbHNfXygAAAAAKAAA\nAAB1JAAAAC4uL3Jlc291cmNlcy9wcml2YXRlL2luZGVwZW5kZW5jZS5weXUEAAAAX1ZlYwQAAABz\nEAAAAAoBEgQJAQkBCQEJAgkHCQJ1BAAAAF9WZWNnmyuhhpuEBj1jAgAAAAAAAAAFAAAABgAAAEMA\nAABzbAAAAGcAAH0CAHhZAHwAAERdUQB9AwB4KAB8AgBEXSAAfQQAfAMAfAMAfAQAFHwEAHwEABQb\nfAQAFBh9AwBxGgBXfAMAfAMAFHwBAGsEAHINAHwCAGoAAHwDAIMBAAFxDQBxDQBXdAEAfAIAgwEA\nUygBAAAATigCAAAAdQYAAABhcHBlbmR1AwAAAGxlbigFAAAAdQEAAABMdQMAAABlcHN1CQAAAHZz\ndGFybGlzdHUBAAAAdnUFAAAAdnN0YXIoAAAAACgAAAAAdSQAAAAuLi9yZXNvdXJjZXMvcHJpdmF0\nZS9pbmRlcGVuZGVuY2UucHl1BwAAAF9SX3JhbmsbAAAAcxIAAAAAAQYBBwAGAQcABgEeARAAFAFj\nAQAAAAAAAAAGAAAABQAAAAMAAABztAAAAHQAAHQBAHQCAIgBAIMBAIMBAIMBAH0BAGQBAH0CAHiP\nAIgBAGQBABlqAwBEXYAAiQAAhwAAhwEAZgIAZAIAhgAAfAEARIMBAH0DAHwDAGcAAGsDAHIsAHwD\nAGQBABl9BAB8AQBqBAB8BACDAQABfAIAZAMAN30CAHgxAHwDAGQDAGQAAIUCABlEXRwAfQUAiAEA\nfAUAGYgBAHwEABkXiAEAfAUAPHGJAFdxLABxLABXfAIAUygEAAAATmkAAAAAYwEAAAAAAAAAAgAA\nAAQAAAATAAAAcyoAAABnAAB8AABdIAB9AQCIAQB8AQAZiAAAGWQAAGsDAHIGAHwBAJECAHEGAFMo\nAQAAAGkAAAAAKAAAAAAoAgAAAHUCAAAALjB1AQAAAHIoAgAAAHUBAAAAY3UHAAAAcm93bGlzdCgA\nAAAAdSQAAAAuLi9yZXNvdXJjZXMvcHJpdmF0ZS9pbmRlcGVuZGVuY2UucHl1CgAAADxsaXN0Y29t\ncD4nAAAAcwIAAAAJAGkBAAAAKAUAAAB1AwAAAHNldHUFAAAAcmFuZ2V1AwAAAGxlbnUBAAAARHUG\nAAAAcmVtb3ZlKAYAAAB1BwAAAHJvd2xpc3R1CQAAAHJvd3NfbGVmdHUBAAAAcnURAAAAcm93c193\naXRoX25vbnplcm91BQAAAHBpdm90dQkAAAByb3dfaW5kZXgoAAAAACgCAAAAdQEAAABjdQcAAABy\nb3dsaXN0dSQAAAAuLi9yZXNvdXJjZXMvcHJpdmF0ZS9pbmRlcGVuZGVuY2UucHl1CQAAAF9HRjJf\ncmFuayMAAABzGgAAAAABGAEGAQ4ABgEZAQwBCgENAQoBEQAGASEBYwEAAAAAAAAABAAAAAUAAABD\nAAAAc3EAAABkAQCEAAB8AABEgwEAfQEAeFoAfAAARF1SAH0CAHhJAHwCAGoAAGoBAIMAAERdOAB9\nAwB8AwBkAgBrAwByLQB0AgB8AwB0AwBqBACDAgByWwB0BQB8AQCDAQBTdAYAfAEAgwEAU3EtAFdx\nFwBXZAIAUygDAAAATmMBAAAAAAAAAAIAAAAFAAAAUwAAAHMlAAAAZwAAfAAAXRsAfQEAdAAAfAEA\nagEAfAEAagIAgwIAkQIAcQYAUygAAAAAKAMAAAB1BAAAAF9WZWN1AQAAAER1AQAAAGYoAgAAAHUC\nAAAALjB1AQAAAHUoAAAAACgAAAAAdSQAAAAuLi9yZXNvdXJjZXMvcHJpdmF0ZS9pbmRlcGVuZGVu\nY2UucHl1CgAAADxsaXN0Y29tcD4xAAAAcwIAAAAJAGkAAAAAKAcAAAB1AQAAAGZ1BgAAAHZhbHVl\nc3UKAAAAaXNpbnN0YW5jZXUDAAAAR0YydQMAAABPbmV1CQAAAF9HRjJfcmFua3UHAAAAX1JfcmFu\naygEAAAAdQEAAABMdQIAAABMY3UBAAAAdnUBAAAAeCgAAAAAKAAAAAB1JAAAAC4uL3Jlc291cmNl\ncy9wcml2YXRlL2luZGVwZW5kZW5jZS5weXUFAAAAX3JhbmswAAAAcxQAAAAAARABBwAGARAABgEM\nARIBCgESAWMBAAAAAAAAAAEAAAAEAAAAQwAAAHM0AAAAdAAAfAAAdAEAdAIAZgIAgwIAcxsAdAMA\nggEAdAQABGoFAGQBADcCXwUAdAYAfAAAgwEAUygCAAAAdXACAABGaW5kcyB0aGUgcmFuayBvZiBh\nIGxpc3Qgb3Igc2V0IG9mIHZlY3RvcnMuCgogICAgQXJnczoKICAgICAgICBMOiBBIGxpc3Qgb3Ig\nc2V0IG9mIHZlY3RvcnMuCgogICAgUmV0dXJuczoKICAgICAgICB4OiBBIG5vbm5lZ2F0aXZlIGlu\ndGVnZXIuICBUaGUgcmFuayBvZiBMLgoKICAgIFJhaXNlczoKICAgICAgICBBc3NlcnRpb25FcnJv\ncjogQW4gZXJyb3Igb2NjdXJzIHdoZW4gTCBpcyBub3QgYSBsaXN0IG9yIHNldC4KCiAgICBFeGFt\ncGxlOgogICAgPj4+IGZyb20gdmVjIGltcG9ydCBWZWMKICAgID4+PiBhMCA9IFZlYyh7J2EnLCAn\nYicsICdjJywgJ2QnfSwgeydhJzogMX0pCiAgICA+Pj4gYTEgPSBWZWMoeydhJywgJ2InLCAnYycs\nICdkJ30sIHsnYic6IDF9KQogICAgPj4+IGEyID0gVmVjKHsnYScsICdiJywgJ2MnLCAnZCd9LCB7\nJ2MnOiAxfSkKICAgID4+PiBhMyA9IFZlYyh7J2EnLCAnYicsICdjJywgJ2QnfSwgeydhJzogMSwg\nJ2MnOiAzfSkKICAgID4+PiByYW5rKFthMCwgYTEsIGEyXSkKICAgIDMKICAgID4+PiByYW5rKHth\nMCwgYTIsIGEzfSkKICAgIDIKICAgID4+PiByYW5rKHthMCwgYTEsIGEzfSkKICAgIDMKICAgID4+\nPiByYW5rKFthMCwgYTEsIGEyLCBhM10pCiAgICAzCiAgICBpAQAAACgHAAAAdQoAAABpc2luc3Rh\nbmNldQQAAABsaXN0dQMAAABzZXR1DgAAAEFzc2VydGlvbkVycm9ydQQAAAByYW5rdQkAAABfX2Nh\nbGxzX191BQAAAF9yYW5rKAEAAAB1AQAAAEwoAAAAACgAAAAAdSQAAAAuLi9yZXNvdXJjZXMvcHJp\ndmF0ZS9pbmRlcGVuZGVuY2UucHl1BAAAAHJhbms6AAAAcwYAAAAAGxsBDwFjAQAAAAAAAAABAAAA\nBAAAAEMAAABzQAAAAHQAAHwAAHQBAHQCAGYCAIMCAHMbAHQDAIIBAHQEAARqBQBkAQA3Al8FAHQG\nAHwAAIMBAHQHAHwAAIMBAGsCAFMoAgAAAHXtAgAARGV0ZXJtaW5lcyBpZiBhIGxpc3Qgb3Igc2V0\nIG9mIHZlY3RvcnMgYXJlIGxpbmVhcmx5IGluZGVwZW5kZW50LgoKICAgIEFyZ3M6CiAgICAgICAg\nTDogQSBsaXN0IG9yIHNldCBvZiB2ZWN0b3JzLgoKICAgIFJldHVybnM6CiAgICAgICAgeDogQSBi\nb29sZWFuLiAgVHJ1ZSBpZiB0aGUgdmVjdG9ycyBpbiBMIGFyZSBsaW5lYXJseSBpbmRlcGVuZGVu\ndC4gIEZhbHNlCiAgICAgICAgb3RoZXJ3aXNlLgoKICAgIFJhaXNlczoKICAgICAgICBBc3NlcnRp\nb25FcnJvcjogQW4gZXJyb3Igb2NjdXJzIHdoZW4gTCBpcyBub3QgYSBsaXN0IG9yIHNldC4KCiAg\nICBFeGFtcGxlOgogICAgPj4+IGZyb20gdmVjIGltcG9ydCBWZWMKICAgID4+PiBhMCA9IFZlYyh7\nJ2EnLCAnYicsICdjJywgJ2QnfSwgeydhJzogMX0pCiAgICA+Pj4gYTEgPSBWZWMoeydhJywgJ2In\nLCAnYycsICdkJ30sIHsnYic6IDF9KQogICAgPj4+IGEyID0gVmVjKHsnYScsICdiJywgJ2MnLCAn\nZCd9LCB7J2MnOiAxfSkKICAgID4+PiBhMyA9IFZlYyh7J2EnLCAnYicsICdjJywgJ2QnfSwgeydh\nJzogMSwgJ2MnOiAzfSkKICAgID4+PiBpc19pbmRlcGVuZGVudChbYTAsIGExLCBhMl0pCiAgICBU\ncnVlCiAgICA+Pj4gaXNfaW5kZXBlbmRlbnQoe2EwLCBhMiwgYTN9KQogICAgRmFsc2UKICAgID4+\nPiBpc19pbmRlcGVuZGVudCh7YTAsIGExLCBhM30pCiAgICBUcnVlCiAgICA+Pj4gaXNfaW5kZXBl\nbmRlbnQoW2EwLCBhMSwgYTIsIGEzXSkKICAgIEZhbHNlCiAgICBpAQAAACgIAAAAdQoAAABpc2lu\nc3RhbmNldQQAAABsaXN0dQMAAABzZXR1DgAAAEFzc2VydGlvbkVycm9ydQ4AAABpc19pbmRlcGVu\nZGVudHUJAAAAX19jYWxsc19fdQUAAABfcmFua3UDAAAAbGVuKAEAAAB1AQAAAEwoAAAAACgAAAAA\ndSQAAAAuLi9yZXNvdXJjZXMvcHJpdmF0ZS9pbmRlcGVuZGVuY2UucHl1DgAAAGlzX2luZGVwZW5k\nZW50WQAAAHMGAAAAABwbAQ8BdQwAAABpbnN0cnVtZW50ZWQoCQAAAHUDAAAAR0YydQQAAABfVmVj\ndQcAAABfUl9yYW5rdQkAAABfR0YyX3Jhbmt1BQAAAF9yYW5rdQQAAAByYW5rdQ4AAABpc19pbmRl\ncGVuZGVudHUJAAAAX19jYWxsc19fdQsAAABfX3ZlcnNpb25fXygAAAAAKAAAAAAoAAAAAHUkAAAA\nLi4vcmVzb3VyY2VzL3ByaXZhdGUvaW5kZXBlbmRlbmNlLnB5dQgAAAA8bW9kdWxlPgIAAABzFAAA\nAAwCEBcMCAkNCQoJHwkgCQEJAQkB\n'
        offset = 8
    elif magic == b'l\x0c\r\n': # Python 3.2
        pycData = b'bAwNChNz/FRjAAAAAAAAAAAAAAAAAwAAAEAAAABzdAAAAGQAAGQBAGwAAFoAAEdkAgCEAABkAwCD\nAgBaAQBkBABkBQCEAQBaAgBkBgCEAABaAwBkBwCEAABaBABkCACEAABaBQBkCQCEAABaBgBkAABl\nBQBfBwBkCgBlBQBfCABkAABlBgBfBwBkCgBlBgBfCABkAQBTKAsAAABpAAAAAE5jAQAAAAAAAAAB\nAAAAAwAAAEIAAABzXwAAAHwAAEVlAABaAQBlAgCDAABpAABkAACEAgBaAwBkAQCEAABaBABkAgCE\nAABaBQBkAwCEAABaBgBkBACEAABaBwBkBQCEAABaCABkBgCEAABaCQBkBwCEAABaCgBkCABTKAkA\nAABjAwAAAAAAAAADAAAAAgAAAEMAAABzFgAAAHwBAHwAAF8AAHwCAHwAAF8BAGQAAFMoAQAAAE4o\nAgAAAHUBAAAARHUBAAAAZigDAAAAdQQAAABzZWxmdQYAAABsYWJlbHN1CAAAAGZ1bmN0aW9uKAAA\nAAAoAAAAAHUkAAAALi4vcmVzb3VyY2VzL3ByaXZhdGUvaW5kZXBlbmRlbmNlLnB5dQgAAABfX2lu\naXRfXwUAAABzBAAAAAABCQFjAgAAAAAAAAACAAAAAgAAAEMAAABzHgAAAHwBAHwAAGoAAGsGAHIa\nAHwAAGoAAHwBABlTZAEAUygCAAAATmkAAAAAKAEAAAB1AQAAAGYoAgAAAHUBAAAAdnUBAAAAaygA\nAAAAKAAAAAB1JAAAAC4uL3Jlc291cmNlcy9wcml2YXRlL2luZGVwZW5kZW5jZS5weXULAAAAX19n\nZXRpdGVtX18JAAAAcwAAAABjAwAAAAAAAAADAAAABAAAAEMAAABzFQAAAHQAAAR8AABqAQB8AQA8\nfQIAZAAAUygBAAAATigCAAAAdQgAAABfc2V0aXRlbXUBAAAAZigDAAAAdQEAAAB2dQEAAABrdQMA\nAAB2YWwoAAAAACgAAAAAdSQAAAAuLi9yZXNvdXJjZXMvcHJpdmF0ZS9pbmRlcGVuZGVuY2UucHl1\nCwAAAF9fc2V0aXRlbV9fCgAAAHMAAAAAYwEAAAAAAAAAAQAAAAIAAABDAAAAcwgAAABkAgB8AAAU\nUygDAAAATmkBAAAAaf////8oAAAAACgBAAAAdQEAAAB2KAAAAAAoAAAAAHUkAAAALi4vcmVzb3Vy\nY2VzL3ByaXZhdGUvaW5kZXBlbmRlbmNlLnB5dQcAAABfX25lZ19fCwAAAHMAAAAAYwIAAAAAAAAA\nAgAAAAQAAAADAAAAcykAAAB0AAB8AABqAQCHAABmAQBkAQCGAAB8AABqAgBqAwCDAABEgwEAgwIA\nUygCAAAATmMBAAAAAAAAAAMAAAAEAAAAEwAAAHMjAAAAaQAAfAAAXRkAXAIAfQEAfQIAiAAAfAIA\nFHwBAJMCAHEGAFMoAAAAACgAAAAAKAMAAAB1AgAAAC4wdQEAAABrdQEAAAB4KAEAAAB1BQAAAGFs\ncGhhKAAAAAB1JAAAAC4uL3Jlc291cmNlcy9wcml2YXRlL2luZGVwZW5kZW5jZS5weXUKAAAAPGRp\nY3Rjb21wPgwAAABzAgAAAAkAKAQAAAB1BAAAAF9WZWN1AQAAAER1AQAAAGZ1BQAAAGl0ZW1zKAIA\nAAB1AQAAAHZ1BQAAAGFscGhhKAAAAAAoAQAAAHUFAAAAYWxwaGF1JAAAAC4uL3Jlc291cmNlcy9w\ncml2YXRlL2luZGVwZW5kZW5jZS5weXUIAAAAX19ybXVsX18MAAAAcwAAAABjAgAAAAAAAAACAAAA\nAwAAAAMAAABzPQAAAHQAAIgAAHQBAIMCAHI1AHQCAIcAAIcBAGYCAGQBAIYAAIgBAGoDAGoEAIMA\nAESDAQCDAQBTdAUAU2QAAFMoAgAAAE5jAQAAAAAAAAACAAAABQAAABMAAABzIgAAAGcAAHwAAF0Y\nAH0BAIgBAHwBABmIAAB8AQAZFJECAHEGAFMoAAAAACgAAAAAKAIAAAB1AgAAAC4wdQEAAABrKAIA\nAAB1BQAAAG90aGVydQQAAABzZWxmKAAAAAB1JAAAAC4uL3Jlc291cmNlcy9wcml2YXRlL2luZGVw\nZW5kZW5jZS5weXUKAAAAPGxpc3Rjb21wPhEAAABzAgAAAAkAKAYAAAB1CgAAAGlzaW5zdGFuY2V1\nBAAAAF9WZWN1AwAAAHN1bXUBAAAAZnUEAAAAa2V5c3UOAAAATm90SW1wbGVtZW50ZWQoAgAAAHUE\nAAAAc2VsZnUFAAAAb3RoZXIoAAAAACgCAAAAdQUAAABvdGhlcnUEAAAAc2VsZnUkAAAALi4vcmVz\nb3VyY2VzL3ByaXZhdGUvaW5kZXBlbmRlbmNlLnB5dQcAAABfX211bF9fDgAAAHMGAAAAAAIPASYC\nYwIAAAAAAAAAAgAAAAUAAAADAAAAc0QAAAB0AACIAABqAQCHAACHAQBmAgBkAQCGAAB0AgCIAABq\nAwBqBACDAACDAQBqBQCIAQBqAwBqBACDAACDAQBEgwEAgwIAUygCAAAATmMBAAAAAAAAAAIAAAAF\nAAAAEwAAAHMlAAAAaQAAfAAAXRsAfQEAiAAAfAEAGYgBAHwBABkXfAEAkwIAcQYAUygAAAAAKAAA\nAAAoAgAAAHUCAAAALjB1AQAAAGsoAgAAAHUBAAAAdXUBAAAAdigAAAAAdSQAAAAuLi9yZXNvdXJj\nZXMvcHJpdmF0ZS9pbmRlcGVuZGVuY2UucHl1CgAAADxkaWN0Y29tcD4VAAAAcwIAAAAJACgGAAAA\ndQQAAABfVmVjdQEAAABEdQMAAABzZXR1AQAAAGZ1BAAAAGtleXN1BQAAAHVuaW9uKAIAAAB1AQAA\nAHV1AQAAAHYoAAAAACgCAAAAdQEAAAB1dQEAAAB2dSQAAAAuLi9yZXNvdXJjZXMvcHJpdmF0ZS9p\nbmRlcGVuZGVuY2UucHl1BwAAAF9fYWRkX18VAAAAcwAAAABjAgAAAAAAAAACAAAAAgAAAEMAAABz\nCQAAAHwAAHwBAAsXUygBAAAAdTQAAABSZXR1cm5zIGEgdmVjdG9yIHdoaWNoIGlzIHRoZSBkaWZm\nZXJlbmNlIG9mIGEgYW5kIGIuKAAAAAAoAgAAAHUBAAAAYXUBAAAAYigAAAAAKAAAAAB1JAAAAC4u\nL3Jlc291cmNlcy9wcml2YXRlL2luZGVwZW5kZW5jZS5weXUHAAAAX19zdWJfXxcAAABzAgAAAAAC\nTigLAAAAdQgAAABfX25hbWVfX3UKAAAAX19tb2R1bGVfX3UDAAAAc2V0dQgAAABfX2luaXRfX3UL\nAAAAX19nZXRpdGVtX191CwAAAF9fc2V0aXRlbV9fdQcAAABfX25lZ19fdQgAAABfX3JtdWxfX3UH\nAAAAX19tdWxfX3UHAAAAX19hZGRfX3UHAAAAX19zdWJfXygBAAAAdQoAAABfX2xvY2Fsc19fKAAA\nAAAoAAAAAHUkAAAALi4vcmVzb3VyY2VzL3ByaXZhdGUvaW5kZXBlbmRlbmNlLnB5dQQAAABfVmVj\nBAAAAHMQAAAACgESBAkBCQEJAQkCCQcJAnUEAAAAX1ZlY2ebK6GGm4QGPWMCAAAAAAAAAAUAAAAG\nAAAAQwAAAHNsAAAAZwAAfQIAeFkAfAAARF1RAH0DAHgoAHwCAERdIAB9BAB8AwB8AwB8BAAUfAQA\nfAQAFBt8BAAUGH0DAHEaAFd8AwB8AwAUfAEAawQAcg0AfAIAagAAfAMAgwEAAXENAHENAFd0AQB8\nAgCDAQBTKAEAAABOKAIAAAB1BgAAAGFwcGVuZHUDAAAAbGVuKAUAAAB1AQAAAEx1AwAAAGVwc3UJ\nAAAAdnN0YXJsaXN0dQEAAAB2dQUAAAB2c3RhcigAAAAAKAAAAAB1JAAAAC4uL3Jlc291cmNlcy9w\ncml2YXRlL2luZGVwZW5kZW5jZS5weXUHAAAAX1JfcmFuaxsAAABzDgAAAAABBgENAQ0BHgEQABQB\nYwEAAAAAAAAABgAAAAUAAAADAAAAc7QAAAB0AAB0AQB0AgCIAQCDAQCDAQCDAQB9AQBkAQB9AgB4\njwCIAQBkAQAZagMARF2AAIkAAIcAAIcBAGYCAGQCAIYAAHwBAESDAQB9AwB8AwBnAABrAwByLAB8\nAwBkAQAZfQQAfAEAagQAfAQAgwEAAXwCAGQDADd9AgB4MQB8AwBkAwBkAACFAgAZRF0cAH0FAIgB\nAHwFABmIAQB8BAAZF4gBAHwFADxxiQBXcSwAcSwAV3wCAFMoBAAAAE5pAAAAAGMBAAAAAAAAAAIA\nAAAEAAAAEwAAAHMqAAAAZwAAfAAAXSAAfQEAiAEAfAEAGYgAABlkAABrAwByBgB8AQCRAgBxBgBT\nKAEAAABpAAAAACgAAAAAKAIAAAB1AgAAAC4wdQEAAAByKAIAAAB1AQAAAGN1BwAAAHJvd2xpc3Qo\nAAAAAHUkAAAALi4vcmVzb3VyY2VzL3ByaXZhdGUvaW5kZXBlbmRlbmNlLnB5dQoAAAA8bGlzdGNv\nbXA+JwAAAHMCAAAACQBpAQAAACgFAAAAdQMAAABzZXR1BQAAAHJhbmdldQMAAABsZW51AQAAAER1\nBgAAAHJlbW92ZSgGAAAAdQcAAAByb3dsaXN0dQkAAAByb3dzX2xlZnR1AQAAAHJ1EQAAAHJvd3Nf\nd2l0aF9ub256ZXJvdQUAAABwaXZvdHUJAAAAcm93X2luZGV4KAAAAAAoAgAAAHUBAAAAY3UHAAAA\ncm93bGlzdHUkAAAALi4vcmVzb3VyY2VzL3ByaXZhdGUvaW5kZXBlbmRlbmNlLnB5dQkAAABfR0Yy\nX3JhbmsjAAAAcxYAAAAAARgBBgEUARkBDAEKAQ0BCgEXASEBYwEAAAAAAAAABAAAAAUAAABDAAAA\nc3EAAABkAQCEAAB8AABEgwEAfQEAeFoAfAAARF1SAH0CAHhJAHwCAGoAAGoBAIMAAERdOAB9AwB8\nAwBkAgBrAwByLQB0AgB8AwB0AwBqBACDAgByWwB0BQB8AQCDAQBTdAYAfAEAgwEAU3EtAFdxFwBX\nZAIAUygDAAAATmMBAAAAAAAAAAIAAAAFAAAAUwAAAHMlAAAAZwAAfAAAXRsAfQEAdAAAfAEAagEA\nfAEAagIAgwIAkQIAcQYAUygAAAAAKAMAAAB1BAAAAF9WZWN1AQAAAER1AQAAAGYoAgAAAHUCAAAA\nLjB1AQAAAHUoAAAAACgAAAAAdSQAAAAuLi9yZXNvdXJjZXMvcHJpdmF0ZS9pbmRlcGVuZGVuY2Uu\ncHl1CgAAADxsaXN0Y29tcD4xAAAAcwIAAAAJAGkAAAAAKAcAAAB1AQAAAGZ1BgAAAHZhbHVlc3UK\nAAAAaXNpbnN0YW5jZXUDAAAAR0YydQMAAABPbmV1CQAAAF9HRjJfcmFua3UHAAAAX1JfcmFuaygE\nAAAAdQEAAABMdQIAAABMY3UBAAAAdnUBAAAAeCgAAAAAKAAAAAB1JAAAAC4uL3Jlc291cmNlcy9w\ncml2YXRlL2luZGVwZW5kZW5jZS5weXUFAAAAX3JhbmswAAAAcxAAAAAAARABDQEWAQwBEgEKARIB\nYwEAAAAAAAAAAQAAAAQAAABDAAAAczQAAAB0AAB8AAB0AQB0AgBmAgCDAgBzGwB0AwCCAQB0BAAE\nagUAZAEANwJfBQB0BgB8AACDAQBTKAIAAAB1cAIAAEZpbmRzIHRoZSByYW5rIG9mIGEgbGlzdCBv\nciBzZXQgb2YgdmVjdG9ycy4KCiAgICBBcmdzOgogICAgICAgIEw6IEEgbGlzdCBvciBzZXQgb2Yg\ndmVjdG9ycy4KCiAgICBSZXR1cm5zOgogICAgICAgIHg6IEEgbm9ubmVnYXRpdmUgaW50ZWdlci4g\nIFRoZSByYW5rIG9mIEwuCgogICAgUmFpc2VzOgogICAgICAgIEFzc2VydGlvbkVycm9yOiBBbiBl\ncnJvciBvY2N1cnMgd2hlbiBMIGlzIG5vdCBhIGxpc3Qgb3Igc2V0LgoKICAgIEV4YW1wbGU6CiAg\nICA+Pj4gZnJvbSB2ZWMgaW1wb3J0IFZlYwogICAgPj4+IGEwID0gVmVjKHsnYScsICdiJywgJ2Mn\nLCAnZCd9LCB7J2EnOiAxfSkKICAgID4+PiBhMSA9IFZlYyh7J2EnLCAnYicsICdjJywgJ2QnfSwg\neydiJzogMX0pCiAgICA+Pj4gYTIgPSBWZWMoeydhJywgJ2InLCAnYycsICdkJ30sIHsnYyc6IDF9\nKQogICAgPj4+IGEzID0gVmVjKHsnYScsICdiJywgJ2MnLCAnZCd9LCB7J2EnOiAxLCAnYyc6IDN9\nKQogICAgPj4+IHJhbmsoW2EwLCBhMSwgYTJdKQogICAgMwogICAgPj4+IHJhbmsoe2EwLCBhMiwg\nYTN9KQogICAgMgogICAgPj4+IHJhbmsoe2EwLCBhMSwgYTN9KQogICAgMwogICAgPj4+IHJhbmso\nW2EwLCBhMSwgYTIsIGEzXSkKICAgIDMKICAgIGkBAAAAKAcAAAB1CgAAAGlzaW5zdGFuY2V1BAAA\nAGxpc3R1AwAAAHNldHUOAAAAQXNzZXJ0aW9uRXJyb3J1BAAAAHJhbmt1CQAAAF9fY2FsbHNfX3UF\nAAAAX3JhbmsoAQAAAHUBAAAATCgAAAAAKAAAAAB1JAAAAC4uL3Jlc291cmNlcy9wcml2YXRlL2lu\nZGVwZW5kZW5jZS5weXUEAAAAcmFuazoAAABzBgAAAAAbGwEPAWMBAAAAAAAAAAEAAAAEAAAAQwAA\nAHNAAAAAdAAAfAAAdAEAdAIAZgIAgwIAcxsAdAMAggEAdAQABGoFAGQBADcCXwUAdAYAfAAAgwEA\ndAcAfAAAgwEAawIAUygCAAAAde0CAABEZXRlcm1pbmVzIGlmIGEgbGlzdCBvciBzZXQgb2YgdmVj\ndG9ycyBhcmUgbGluZWFybHkgaW5kZXBlbmRlbnQuCgogICAgQXJnczoKICAgICAgICBMOiBBIGxp\nc3Qgb3Igc2V0IG9mIHZlY3RvcnMuCgogICAgUmV0dXJuczoKICAgICAgICB4OiBBIGJvb2xlYW4u\nICBUcnVlIGlmIHRoZSB2ZWN0b3JzIGluIEwgYXJlIGxpbmVhcmx5IGluZGVwZW5kZW50LiAgRmFs\nc2UKICAgICAgICBvdGhlcndpc2UuCgogICAgUmFpc2VzOgogICAgICAgIEFzc2VydGlvbkVycm9y\nOiBBbiBlcnJvciBvY2N1cnMgd2hlbiBMIGlzIG5vdCBhIGxpc3Qgb3Igc2V0LgoKICAgIEV4YW1w\nbGU6CiAgICA+Pj4gZnJvbSB2ZWMgaW1wb3J0IFZlYwogICAgPj4+IGEwID0gVmVjKHsnYScsICdi\nJywgJ2MnLCAnZCd9LCB7J2EnOiAxfSkKICAgID4+PiBhMSA9IFZlYyh7J2EnLCAnYicsICdjJywg\nJ2QnfSwgeydiJzogMX0pCiAgICA+Pj4gYTIgPSBWZWMoeydhJywgJ2InLCAnYycsICdkJ30sIHsn\nYyc6IDF9KQogICAgPj4+IGEzID0gVmVjKHsnYScsICdiJywgJ2MnLCAnZCd9LCB7J2EnOiAxLCAn\nYyc6IDN9KQogICAgPj4+IGlzX2luZGVwZW5kZW50KFthMCwgYTEsIGEyXSkKICAgIFRydWUKICAg\nID4+PiBpc19pbmRlcGVuZGVudCh7YTAsIGEyLCBhM30pCiAgICBGYWxzZQogICAgPj4+IGlzX2lu\nZGVwZW5kZW50KHthMCwgYTEsIGEzfSkKICAgIFRydWUKICAgID4+PiBpc19pbmRlcGVuZGVudChb\nYTAsIGExLCBhMiwgYTNdKQogICAgRmFsc2UKICAgIGkBAAAAKAgAAAB1CgAAAGlzaW5zdGFuY2V1\nBAAAAGxpc3R1AwAAAHNldHUOAAAAQXNzZXJ0aW9uRXJyb3J1DgAAAGlzX2luZGVwZW5kZW50dQkA\nAABfX2NhbGxzX191BQAAAF9yYW5rdQMAAABsZW4oAQAAAHUBAAAATCgAAAAAKAAAAAB1JAAAAC4u\nL3Jlc291cmNlcy9wcml2YXRlL2luZGVwZW5kZW5jZS5weXUOAAAAaXNfaW5kZXBlbmRlbnRZAAAA\ncwYAAAAAHBsBDwF1DAAAAGluc3RydW1lbnRlZCgJAAAAdQMAAABHRjJ1BAAAAF9WZWN1BwAAAF9S\nX3Jhbmt1CQAAAF9HRjJfcmFua3UFAAAAX3Jhbmt1BAAAAHJhbmt1DgAAAGlzX2luZGVwZW5kZW50\ndQkAAABfX2NhbGxzX191CwAAAF9fdmVyc2lvbl9fKAAAAAAoAAAAACgAAAAAdSQAAAAuLi9yZXNv\ndXJjZXMvcHJpdmF0ZS9pbmRlcGVuZGVuY2UucHl1CAAAADxtb2R1bGU+AgAAAHMUAAAADAIQFwwI\nCQ0JCgkfCSAJAQkBCQE=\n'
        offset = 8
    elif magic == b'\x9e\x0c\r\n': # Python 3.3
        pycData = b'ngwNChNz/FTtDQAAYwAAAAAAAAAAAAAAAAMAAABAAAAAc4YAAABkAABkAQBsAABaAABHZAIAZAMA\nhAAAZAMAgwIAWgEAZAQAZAUAZAYAhAEAWgIAZAcAZAgAhAAAWgMAZAkAZAoAhAAAWgQAZAsAZAwA\nhAAAWgUAZA0AZA4AhAAAWgYAZAAAZQUAXwcAZA8AZQUAXwgAZAAAZQYAXwcAZA8AZQYAXwgAZAEA\nUygQAAAAaQAAAABOYwEAAAAAAAAAAQAAAAQAAABCAAAAc30AAAB8AABFZQAAWgEAZAAAWgIAZQMA\ngwAAaQAAZAEAZAIAhAIAWgQAZAMAZAQAhAAAWgUAZAUAZAYAhAAAWgYAZAcAZAgAhAAAWgcAZAkA\nZAoAhAAAWggAZAsAZAwAhAAAWgkAZA0AZA4AhAAAWgoAZA8AZBAAhAAAWgsAZBEAUygSAAAAdQQA\nAABfVmVjYwMAAAAAAAAAAwAAAAIAAABDAAAAcxYAAAB8AQB8AABfAAB8AgB8AABfAQBkAABTKAEA\nAABOKAIAAAB1AQAAAER1AQAAAGYoAwAAAHUEAAAAc2VsZnUGAAAAbGFiZWxzdQgAAABmdW5jdGlv\nbigAAAAAKAAAAAB1JAAAAC4uL3Jlc291cmNlcy9wcml2YXRlL2luZGVwZW5kZW5jZS5weXUIAAAA\nX19pbml0X18FAAAAcwQAAAAAAQkBdQ0AAABfVmVjLl9faW5pdF9fYwIAAAAAAAAAAgAAAAIAAABD\nAAAAcx4AAAB8AQB8AABqAABrBgByGgB8AABqAAB8AQAZU2QBAFMoAgAAAE5pAAAAACgBAAAAdQEA\nAABmKAIAAAB1AQAAAHZ1AQAAAGsoAAAAACgAAAAAdSQAAAAuLi9yZXNvdXJjZXMvcHJpdmF0ZS9p\nbmRlcGVuZGVuY2UucHl1CwAAAF9fZ2V0aXRlbV9fCQAAAHMAAAAAdRAAAABfVmVjLl9fZ2V0aXRl\nbV9fYwMAAAAAAAAAAwAAAAQAAABDAAAAcxUAAAB0AAAEfAAAagEAfAEAPH0CAGQAAFMoAQAAAE4o\nAgAAAHUIAAAAX3NldGl0ZW11AQAAAGYoAwAAAHUBAAAAdnUBAAAAa3UDAAAAdmFsKAAAAAAoAAAA\nAHUkAAAALi4vcmVzb3VyY2VzL3ByaXZhdGUvaW5kZXBlbmRlbmNlLnB5dQsAAABfX3NldGl0ZW1f\nXwoAAABzAAAAAHUQAAAAX1ZlYy5fX3NldGl0ZW1fX2MBAAAAAAAAAAEAAAACAAAAQwAAAHMIAAAA\nZAIAfAAAFFMoAwAAAE5pAQAAAGn/////KAAAAAAoAQAAAHUBAAAAdigAAAAAKAAAAAB1JAAAAC4u\nL3Jlc291cmNlcy9wcml2YXRlL2luZGVwZW5kZW5jZS5weXUHAAAAX19uZWdfXwsAAABzAAAAAHUM\nAAAAX1ZlYy5fX25lZ19fYwIAAAAAAAAAAgAAAAUAAAADAAAAcywAAAB0AAB8AABqAQCHAABmAQBk\nAQBkAgCGAAB8AABqAgBqAwCDAABEgwEAgwIAUygDAAAATmMBAAAAAAAAAAMAAAAEAAAAEwAAAHMj\nAAAAaQAAfAAAXRkAXAIAfQEAfQIAiAAAfAIAFHwBAJMCAHEGAFMoAAAAACgAAAAAKAMAAAB1AgAA\nAC4wdQEAAABrdQEAAAB4KAEAAAB1BQAAAGFscGhhKAAAAAB1JAAAAC4uL3Jlc291cmNlcy9wcml2\nYXRlL2luZGVwZW5kZW5jZS5weXUKAAAAPGRpY3Rjb21wPgwAAABzAgAAAAkAdSEAAABfVmVjLl9f\ncm11bF9fLjxsb2NhbHM+LjxkaWN0Y29tcD4oBAAAAHUEAAAAX1ZlY3UBAAAARHUBAAAAZnUFAAAA\naXRlbXMoAgAAAHUBAAAAdnUFAAAAYWxwaGEoAAAAACgBAAAAdQUAAABhbHBoYXUkAAAALi4vcmVz\nb3VyY2VzL3ByaXZhdGUvaW5kZXBlbmRlbmNlLnB5dQgAAABfX3JtdWxfXwwAAABzAAAAAHUNAAAA\nX1ZlYy5fX3JtdWxfX2MCAAAAAAAAAAIAAAAEAAAAAwAAAHNAAAAAdAAAiAAAdAEAgwIAcjgAdAIA\nhwAAhwEAZgIAZAEAZAIAhgAAiAEAagMAagQAgwAARIMBAIMBAFN0BQBTZAAAUygDAAAATmMBAAAA\nAAAAAAIAAAAFAAAAEwAAAHMiAAAAZwAAfAAAXRgAfQEAiAEAfAEAGYgAAHwBABkUkQIAcQYAUygA\nAAAAKAAAAAAoAgAAAHUCAAAALjB1AQAAAGsoAgAAAHUFAAAAb3RoZXJ1BAAAAHNlbGYoAAAAAHUk\nAAAALi4vcmVzb3VyY2VzL3ByaXZhdGUvaW5kZXBlbmRlbmNlLnB5dQoAAAA8bGlzdGNvbXA+EQAA\nAHMCAAAACQB1IAAAAF9WZWMuX19tdWxfXy48bG9jYWxzPi48bGlzdGNvbXA+KAYAAAB1CgAAAGlz\naW5zdGFuY2V1BAAAAF9WZWN1AwAAAHN1bXUBAAAAZnUEAAAAa2V5c3UOAAAATm90SW1wbGVtZW50\nZWQoAgAAAHUEAAAAc2VsZnUFAAAAb3RoZXIoAAAAACgCAAAAdQUAAABvdGhlcnUEAAAAc2VsZnUk\nAAAALi4vcmVzb3VyY2VzL3ByaXZhdGUvaW5kZXBlbmRlbmNlLnB5dQcAAABfX211bF9fDgAAAHMG\nAAAAAAIPASkCdQwAAABfVmVjLl9fbXVsX19jAgAAAAAAAAACAAAABQAAAAMAAABzRwAAAHQAAIgA\nAGoBAIcAAIcBAGYCAGQBAGQCAIYAAHQCAIgAAGoDAGoEAIMAAIMBAGoFAIgBAGoDAGoEAIMAAIMB\nAESDAQCDAgBTKAMAAABOYwEAAAAAAAAAAgAAAAUAAAATAAAAcyUAAABpAAB8AABdGwB9AQCIAAB8\nAQAZiAEAfAEAGRd8AQCTAgBxBgBTKAAAAAAoAAAAACgCAAAAdQIAAAAuMHUBAAAAaygCAAAAdQEA\nAAB1dQEAAAB2KAAAAAB1JAAAAC4uL3Jlc291cmNlcy9wcml2YXRlL2luZGVwZW5kZW5jZS5weXUK\nAAAAPGRpY3Rjb21wPhUAAABzAgAAAAkAdSAAAABfVmVjLl9fYWRkX18uPGxvY2Fscz4uPGRpY3Rj\nb21wPigGAAAAdQQAAABfVmVjdQEAAABEdQMAAABzZXR1AQAAAGZ1BAAAAGtleXN1BQAAAHVuaW9u\nKAIAAAB1AQAAAHV1AQAAAHYoAAAAACgCAAAAdQEAAAB1dQEAAAB2dSQAAAAuLi9yZXNvdXJjZXMv\ncHJpdmF0ZS9pbmRlcGVuZGVuY2UucHl1BwAAAF9fYWRkX18VAAAAcwAAAAB1DAAAAF9WZWMuX19h\nZGRfX2MCAAAAAAAAAAIAAAACAAAAQwAAAHMJAAAAfAAAfAEACxdTKAEAAAB1NAAAAFJldHVybnMg\nYSB2ZWN0b3Igd2hpY2ggaXMgdGhlIGRpZmZlcmVuY2Ugb2YgYSBhbmQgYi4oAAAAACgCAAAAdQEA\nAABhdQEAAABiKAAAAAAoAAAAAHUkAAAALi4vcmVzb3VyY2VzL3ByaXZhdGUvaW5kZXBlbmRlbmNl\nLnB5dQcAAABfX3N1Yl9fFwAAAHMCAAAAAAJ1DAAAAF9WZWMuX19zdWJfX04oDAAAAHUIAAAAX19u\nYW1lX191CgAAAF9fbW9kdWxlX191DAAAAF9fcXVhbG5hbWVfX3UDAAAAc2V0dQgAAABfX2luaXRf\nX3ULAAAAX19nZXRpdGVtX191CwAAAF9fc2V0aXRlbV9fdQcAAABfX25lZ19fdQgAAABfX3JtdWxf\nX3UHAAAAX19tdWxfX3UHAAAAX19hZGRfX3UHAAAAX19zdWJfXygBAAAAdQoAAABfX2xvY2Fsc19f\nKAAAAAAoAAAAAHUkAAAALi4vcmVzb3VyY2VzL3ByaXZhdGUvaW5kZXBlbmRlbmNlLnB5dQQAAABf\nVmVjBAAAAHMQAAAAEAEVBAwBDAEMAQwCDAcMAnUEAAAAX1ZlY2ebK6GGm4QGPWMCAAAAAAAAAAUA\nAAAGAAAAQwAAAHNsAAAAZwAAfQIAeFkAfAAARF1RAH0DAHgoAHwCAERdIAB9BAB8AwB8AwB8BAAU\nfAQAfAQAFBt8BAAUGH0DAHEaAFd8AwB8AwAUfAEAawQAcg0AfAIAagAAfAMAgwEAAXENAHENAFd0\nAQB8AgCDAQBTKAEAAABOKAIAAAB1BgAAAGFwcGVuZHUDAAAAbGVuKAUAAAB1AQAAAEx1AwAAAGVw\nc3UJAAAAdnN0YXJsaXN0dQEAAAB2dQUAAAB2c3RhcigAAAAAKAAAAAB1JAAAAC4uL3Jlc291cmNl\ncy9wcml2YXRlL2luZGVwZW5kZW5jZS5weXUHAAAAX1JfcmFuaxsAAABzDgAAAAABBgENAQ0BHgEQ\nABQBdQcAAABfUl9yYW5rYwEAAAAAAAAABgAAAAUAAAADAAAAc7cAAAB0AAB0AQB0AgCIAQCDAQCD\nAQCDAQB9AQBkAQB9AgB4kgCIAQBkAQAZagMARF2DAIkAAIcAAIcBAGYCAGQCAGQDAIYAAHwBAESD\nAQB9AwB8AwBnAABrAwByLAB8AwBkAQAZfQQAfAEAagQAfAQAgwEAAXwCAGQEADd9AgB4MQB8AwBk\nBABkAACFAgAZRF0cAH0FAIgBAHwFABmIAQB8BAAZF4gBAHwFADxxjABXcSwAcSwAV3wCAFMoBQAA\nAE5pAAAAAGMBAAAAAAAAAAIAAAAEAAAAEwAAAHMqAAAAZwAAfAAAXSAAfQEAiAEAfAEAGYgAABlk\nAABrAwByBgB8AQCRAgBxBgBTKAEAAABpAAAAACgAAAAAKAIAAAB1AgAAAC4wdQEAAAByKAIAAAB1\nAQAAAGN1BwAAAHJvd2xpc3QoAAAAAHUkAAAALi4vcmVzb3VyY2VzL3ByaXZhdGUvaW5kZXBlbmRl\nbmNlLnB5dQoAAAA8bGlzdGNvbXA+JwAAAHMCAAAACQB1HQAAAF9HRjJfcmFuay48bG9jYWxzPi48\nbGlzdGNvbXA+aQEAAAAoBQAAAHUDAAAAc2V0dQUAAAByYW5nZXUDAAAAbGVudQEAAABEdQYAAABy\nZW1vdmUoBgAAAHUHAAAAcm93bGlzdHUJAAAAcm93c19sZWZ0dQEAAABydREAAAByb3dzX3dpdGhf\nbm9uemVyb3UFAAAAcGl2b3R1CQAAAHJvd19pbmRleCgAAAAAKAIAAAB1AQAAAGN1BwAAAHJvd2xp\nc3R1JAAAAC4uL3Jlc291cmNlcy9wcml2YXRlL2luZGVwZW5kZW5jZS5weXUJAAAAX0dGMl9yYW5r\nIwAAAHMWAAAAAAEYAQYBFAEcAQwBCgENAQoBFwEhAXUJAAAAX0dGMl9yYW5rYwEAAAAAAAAABAAA\nAAUAAABDAAAAc3QAAABkAQBkAgCEAAB8AABEgwEAfQEAeFoAfAAARF1SAH0CAHhJAHwCAGoAAGoB\nAIMAAERdOAB9AwB8AwBkAwBrAwByMAB0AgB8AwB0AwBqBACDAgByXgB0BQB8AQCDAQBTdAYAfAEA\ngwEAU3EwAFdxGgBXZAMAUygEAAAATmMBAAAAAAAAAAIAAAAFAAAAUwAAAHMlAAAAZwAAfAAAXRsA\nfQEAdAAAfAEAagEAfAEAagIAgwIAkQIAcQYAUygAAAAAKAMAAAB1BAAAAF9WZWN1AQAAAER1AQAA\nAGYoAgAAAHUCAAAALjB1AQAAAHUoAAAAACgAAAAAdSQAAAAuLi9yZXNvdXJjZXMvcHJpdmF0ZS9p\nbmRlcGVuZGVuY2UucHl1CgAAADxsaXN0Y29tcD4xAAAAcwIAAAAJAHUZAAAAX3JhbmsuPGxvY2Fs\ncz4uPGxpc3Rjb21wPmkAAAAAKAcAAAB1AQAAAGZ1BgAAAHZhbHVlc3UKAAAAaXNpbnN0YW5jZXUD\nAAAAR0YydQMAAABPbmV1CQAAAF9HRjJfcmFua3UHAAAAX1JfcmFuaygEAAAAdQEAAABMdQIAAABM\nY3UBAAAAdnUBAAAAeCgAAAAAKAAAAAB1JAAAAC4uL3Jlc291cmNlcy9wcml2YXRlL2luZGVwZW5k\nZW5jZS5weXUFAAAAX3JhbmswAAAAcxAAAAAAARMBDQEWAQwBEgEKARIBdQUAAABfcmFua2MBAAAA\nAAAAAAEAAAAEAAAAQwAAAHM0AAAAdAAAfAAAdAEAdAIAZgIAgwIAcxsAdAMAggEAdAQABGoFAGQB\nADcCXwUAdAYAfAAAgwEAUygCAAAAdXACAABGaW5kcyB0aGUgcmFuayBvZiBhIGxpc3Qgb3Igc2V0\nIG9mIHZlY3RvcnMuCgogICAgQXJnczoKICAgICAgICBMOiBBIGxpc3Qgb3Igc2V0IG9mIHZlY3Rv\ncnMuCgogICAgUmV0dXJuczoKICAgICAgICB4OiBBIG5vbm5lZ2F0aXZlIGludGVnZXIuICBUaGUg\ncmFuayBvZiBMLgoKICAgIFJhaXNlczoKICAgICAgICBBc3NlcnRpb25FcnJvcjogQW4gZXJyb3Ig\nb2NjdXJzIHdoZW4gTCBpcyBub3QgYSBsaXN0IG9yIHNldC4KCiAgICBFeGFtcGxlOgogICAgPj4+\nIGZyb20gdmVjIGltcG9ydCBWZWMKICAgID4+PiBhMCA9IFZlYyh7J2EnLCAnYicsICdjJywgJ2Qn\nfSwgeydhJzogMX0pCiAgICA+Pj4gYTEgPSBWZWMoeydhJywgJ2InLCAnYycsICdkJ30sIHsnYic6\nIDF9KQogICAgPj4+IGEyID0gVmVjKHsnYScsICdiJywgJ2MnLCAnZCd9LCB7J2MnOiAxfSkKICAg\nID4+PiBhMyA9IFZlYyh7J2EnLCAnYicsICdjJywgJ2QnfSwgeydhJzogMSwgJ2MnOiAzfSkKICAg\nID4+PiByYW5rKFthMCwgYTEsIGEyXSkKICAgIDMKICAgID4+PiByYW5rKHthMCwgYTIsIGEzfSkK\nICAgIDIKICAgID4+PiByYW5rKHthMCwgYTEsIGEzfSkKICAgIDMKICAgID4+PiByYW5rKFthMCwg\nYTEsIGEyLCBhM10pCiAgICAzCiAgICBpAQAAACgHAAAAdQoAAABpc2luc3RhbmNldQQAAABsaXN0\ndQMAAABzZXR1DgAAAEFzc2VydGlvbkVycm9ydQQAAAByYW5rdQkAAABfX2NhbGxzX191BQAAAF9y\nYW5rKAEAAAB1AQAAAEwoAAAAACgAAAAAdSQAAAAuLi9yZXNvdXJjZXMvcHJpdmF0ZS9pbmRlcGVu\nZGVuY2UucHl1BAAAAHJhbms6AAAAcwYAAAAAGxsBDwF1BAAAAHJhbmtjAQAAAAAAAAABAAAABAAA\nAEMAAABzQAAAAHQAAHwAAHQBAHQCAGYCAIMCAHMbAHQDAIIBAHQEAARqBQBkAQA3Al8FAHQGAHwA\nAIMBAHQHAHwAAIMBAGsCAFMoAgAAAHXtAgAARGV0ZXJtaW5lcyBpZiBhIGxpc3Qgb3Igc2V0IG9m\nIHZlY3RvcnMgYXJlIGxpbmVhcmx5IGluZGVwZW5kZW50LgoKICAgIEFyZ3M6CiAgICAgICAgTDog\nQSBsaXN0IG9yIHNldCBvZiB2ZWN0b3JzLgoKICAgIFJldHVybnM6CiAgICAgICAgeDogQSBib29s\nZWFuLiAgVHJ1ZSBpZiB0aGUgdmVjdG9ycyBpbiBMIGFyZSBsaW5lYXJseSBpbmRlcGVuZGVudC4g\nIEZhbHNlCiAgICAgICAgb3RoZXJ3aXNlLgoKICAgIFJhaXNlczoKICAgICAgICBBc3NlcnRpb25F\ncnJvcjogQW4gZXJyb3Igb2NjdXJzIHdoZW4gTCBpcyBub3QgYSBsaXN0IG9yIHNldC4KCiAgICBF\neGFtcGxlOgogICAgPj4+IGZyb20gdmVjIGltcG9ydCBWZWMKICAgID4+PiBhMCA9IFZlYyh7J2En\nLCAnYicsICdjJywgJ2QnfSwgeydhJzogMX0pCiAgICA+Pj4gYTEgPSBWZWMoeydhJywgJ2InLCAn\nYycsICdkJ30sIHsnYic6IDF9KQogICAgPj4+IGEyID0gVmVjKHsnYScsICdiJywgJ2MnLCAnZCd9\nLCB7J2MnOiAxfSkKICAgID4+PiBhMyA9IFZlYyh7J2EnLCAnYicsICdjJywgJ2QnfSwgeydhJzog\nMSwgJ2MnOiAzfSkKICAgID4+PiBpc19pbmRlcGVuZGVudChbYTAsIGExLCBhMl0pCiAgICBUcnVl\nCiAgICA+Pj4gaXNfaW5kZXBlbmRlbnQoe2EwLCBhMiwgYTN9KQogICAgRmFsc2UKICAgID4+PiBp\nc19pbmRlcGVuZGVudCh7YTAsIGExLCBhM30pCiAgICBUcnVlCiAgICA+Pj4gaXNfaW5kZXBlbmRl\nbnQoW2EwLCBhMSwgYTIsIGEzXSkKICAgIEZhbHNlCiAgICBpAQAAACgIAAAAdQoAAABpc2luc3Rh\nbmNldQQAAABsaXN0dQMAAABzZXR1DgAAAEFzc2VydGlvbkVycm9ydQ4AAABpc19pbmRlcGVuZGVu\ndHUJAAAAX19jYWxsc19fdQUAAABfcmFua3UDAAAAbGVuKAEAAAB1AQAAAEwoAAAAACgAAAAAdSQA\nAAAuLi9yZXNvdXJjZXMvcHJpdmF0ZS9pbmRlcGVuZGVuY2UucHl1DgAAAGlzX2luZGVwZW5kZW50\nWQAAAHMGAAAAABwbAQ8BdQ4AAABpc19pbmRlcGVuZGVudHUMAAAAaW5zdHJ1bWVudGVkKAkAAAB1\nAwAAAEdGMnUEAAAAX1ZlY3UHAAAAX1JfcmFua3UJAAAAX0dGMl9yYW5rdQUAAABfcmFua3UEAAAA\ncmFua3UOAAAAaXNfaW5kZXBlbmRlbnR1CQAAAF9fY2FsbHNfX3ULAAAAX192ZXJzaW9uX18oAAAA\nACgAAAAAKAAAAAB1JAAAAC4uL3Jlc291cmNlcy9wcml2YXRlL2luZGVwZW5kZW5jZS5weXUIAAAA\nPG1vZHVsZT4CAAAAcxQAAAAMAhMXDwgMDQwKDB8MIAkBCQEJAQ==\n'
        offset = 12
    elif magic == b'\xee\x0c\r\n': # Python 3.4
        pycData = b'7gwNChNz/FTtDQAA4wAAAAAAAAAAAAAAAAMAAABAAAAAc4YAAABkAABkAQBsAABaAABHZAIAZAMA\nhAAAZAMAgwIAWgEAZAQAZAUAZAYAhAEAWgIAZAcAZAgAhAAAWgMAZAkAZAoAhAAAWgQAZAsAZAwA\nhAAAWgUAZA0AZA4AhAAAWgYAZAAAZQUAXwcAZA8AZQUAXwgAZAAAZQYAXwcAZA8AZQYAXwgAZAEA\nUykQ6QAAAABOYwAAAAAAAAAAAAAAAAQAAABAAAAAc3kAAABlAABaAQBkAABaAgBlAwCDAABpAABk\nAQBkAgCEAgBaBABkAwBkBACEAABaBQBkBQBkBgCEAABaBgBkBwBkCACEAABaBwBkCQBkCgCEAABa\nCABkCwBkDACEAABaCQBkDQBkDgCEAABaCgBkDwBkEACEAABaCwBkEQBTKRLaBF9WZWNjAwAAAAAA\nAAADAAAAAgAAAEMAAABzFgAAAHwBAHwAAF8AAHwCAHwAAF8BAGQAAFMpAU4pAtoBRNoBZikD2gRz\nZWxmWgZsYWJlbHNaCGZ1bmN0aW9uqQByBgAAAPokLi4vcmVzb3VyY2VzL3ByaXZhdGUvaW5kZXBl\nbmRlbmNlLnB52ghfX2luaXRfXwUAAABzBAAAAAABCQF6DV9WZWMuX19pbml0X19jAgAAAAAAAAAC\nAAAAAgAAAEMAAABzHgAAAHwBAHwAAGoAAGsGAHIaAHwAAGoAAHwBABlTZAEAUykCTnIBAAAAKQFy\nBAAAACkC2gF22gFrcgYAAAByBgAAAHIHAAAA2gtfX2dldGl0ZW1fXwkAAABzAAAAAHoQX1ZlYy5f\nX2dldGl0ZW1fX2MDAAAAAAAAAAMAAAAEAAAAQwAAAHMVAAAAdAAABHwAAGoBAHwBADx9AgBkAABT\nKQFOKQJaCF9zZXRpdGVtcgQAAAApA3IJAAAAcgoAAADaA3ZhbHIGAAAAcgYAAAByBwAAANoLX19z\nZXRpdGVtX18KAAAAcwAAAAB6EF9WZWMuX19zZXRpdGVtX19jAQAAAAAAAAABAAAAAgAAAEMAAABz\nCAAAAGQCAHwAABRTKQNO6QEAAADp/////3IGAAAAKQFyCQAAAHIGAAAAcgYAAAByBwAAANoHX19u\nZWdfXwsAAABzAAAAAHoMX1ZlYy5fX25lZ19fYwIAAAAAAAAAAgAAAAUAAAADAAAAcywAAAB0AAB8\n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\nABmIAAAZZAAAawMAcgYAfAEAkQIAcQYAUykBcgEAAAByBgAAACkCchEAAADaAXIpAtoBY9oHcm93\nbGlzdHIGAAAAcgcAAAByGAAAACcAAABzAgAAAAkAeh1fR0YyX3JhbmsuPGxvY2Fscz4uPGxpc3Rj\nb21wPnIOAAAAKQVyHwAAANoFcmFuZ2VyKQAAAHIDAAAA2gZyZW1vdmUpBnIuAAAAWglyb3dzX2xl\nZnRyLAAAAFoRcm93c193aXRoX25vbnplcm9aBXBpdm90Wglyb3dfaW5kZXhyBgAAACkCci0AAABy\nLgAAAHIHAAAA2glfR0YyX3JhbmsjAAAAcxYAAAAAARgBBgEUARwBDAEKAQ0BCgEXASEBcjEAAABj\nAQAAAAAAAAAEAAAABQAAAEMAAABzdAAAAGQBAGQCAIQAAHwAAESDAQB9AQB4WgB8AABEXVIAfQIA\neEkAfAIAagAAagEAgwAARF04AH0DAHwDAGQDAGsDAHIwAHQCAHwDAHQDAGoEAIMCAHJeAHQFAHwB\nAIMBAFN0BgB8AQCDAQBTcTAAV3EaAFdkAwBTKQROYwEAAAAAAAAAAgAAAAUAAABTAAAAcyUAAABn\nAAB8AABdGwB9AQB0AAB8AQBqAQB8AQBqAgCDAgCRAgBxBgBTcgYAAAApA3ICAAAAcgMAAAByBAAA\nACkCchEAAAByHgAAAHIGAAAAcgYAAAByBwAAAHIYAAAAMQAAAHMCAAAACQB6GV9yYW5rLjxsb2Nh\nbHM+LjxsaXN0Y29tcD5yAQAAACkHcgQAAADaBnZhbHVlc3IZAAAA2gNHRjJaA09uZXIxAAAAcisA\nAAApBHIqAAAAWgJMY3IJAAAAchIAAAByBgAAAHIGAAAAcgcAAADaBV9yYW5rMAAAAHMQAAAAAAET\nAQ0BFgEMARIBCgESAXI0AAAAYwEAAAAAAAAAAQAAAAQAAABDAAAAczQAAAB0AAB8AAB0AQB0AgBm\nAgCDAgBzGwB0AwCCAQB0BAAEagUAZAEANwJfBQB0BgB8AACDAQBTKQJhcAIAAEZpbmRzIHRoZSBy\nYW5rIG9mIGEgbGlzdCBvciBzZXQgb2YgdmVjdG9ycy4KCiAgICBBcmdzOgogICAgICAgIEw6IEEg\nbGlzdCBvciBzZXQgb2YgdmVjdG9ycy4KCiAgICBSZXR1cm5zOgogICAgICAgIHg6IEEgbm9ubmVn\nYXRpdmUgaW50ZWdlci4gIFRoZSByYW5rIG9mIEwuCgogICAgUmFpc2VzOgogICAgICAgIEFzc2Vy\ndGlvbkVycm9yOiBBbiBlcnJvciBvY2N1cnMgd2hlbiBMIGlzIG5vdCBhIGxpc3Qgb3Igc2V0LgoK\nICAgIEV4YW1wbGU6CiAgICA+Pj4gZnJvbSB2ZWMgaW1wb3J0IFZlYwogICAgPj4+IGEwID0gVmVj\nKHsnYScsICdiJywgJ2MnLCAnZCd9LCB7J2EnOiAxfSkKICAgID4+PiBhMSA9IFZlYyh7J2EnLCAn\nYicsICdjJywgJ2QnfSwgeydiJzogMX0pCiAgICA+Pj4gYTIgPSBWZWMoeydhJywgJ2InLCAnYycs\nICdkJ30sIHsnYyc6IDF9KQogICAgPj4+IGEzID0gVmVjKHsnYScsICdiJywgJ2MnLCAnZCd9LCB7\nJ2EnOiAxLCAnYyc6IDN9KQogICAgPj4+IHJhbmsoW2EwLCBhMSwgYTJdKQogICAgMwogICAgPj4+\nIHJhbmsoe2EwLCBhMiwgYTN9KQogICAgMgogICAgPj4+IHJhbmsoe2EwLCBhMSwgYTN9KQogICAg\nMwogICAgPj4+IHJhbmsoW2EwLCBhMSwgYTIsIGEzXSkKICAgIDMKICAgIHIOAAAAKQdyGQAAANoE\nbGlzdHIfAAAA2g5Bc3NlcnRpb25FcnJvctoEcmFua9oJX19jYWxsc19fcjQAAAApAXIqAAAAcgYA\nAAByBgAAAHIHAAAAcjcAAAA6AAAAcwYAAAAAGxsBDwFyNwAAAGMBAAAAAAAAAAEAAAAEAAAAQwAA\nAHNAAAAAdAAAfAAAdAEAdAIAZgIAgwIAcxsAdAMAggEAdAQABGoFAGQBADcCXwUAdAYAfAAAgwEA\ndAcAfAAAgwEAawIAUykCYe0CAABEZXRlcm1pbmVzIGlmIGEgbGlzdCBvciBzZXQgb2YgdmVjdG9y\ncyBhcmUgbGluZWFybHkgaW5kZXBlbmRlbnQuCgogICAgQXJnczoKICAgICAgICBMOiBBIGxpc3Qg\nb3Igc2V0IG9mIHZlY3RvcnMuCgogICAgUmV0dXJuczoKICAgICAgICB4OiBBIGJvb2xlYW4uICBU\ncnVlIGlmIHRoZSB2ZWN0b3JzIGluIEwgYXJlIGxpbmVhcmx5IGluZGVwZW5kZW50LiAgRmFsc2UK\nICAgICAgICBvdGhlcndpc2UuCgogICAgUmFpc2VzOgogICAgICAgIEFzc2VydGlvbkVycm9yOiBB\nbiBlcnJvciBvY2N1cnMgd2hlbiBMIGlzIG5vdCBhIGxpc3Qgb3Igc2V0LgoKICAgIEV4YW1wbGU6\nCiAgICA+Pj4gZnJvbSB2ZWMgaW1wb3J0IFZlYwogICAgPj4+IGEwID0gVmVjKHsnYScsICdiJywg\nJ2MnLCAnZCd9LCB7J2EnOiAxfSkKICAgID4+PiBhMSA9IFZlYyh7J2EnLCAnYicsICdjJywgJ2Qn\nfSwgeydiJzogMX0pCiAgICA+Pj4gYTIgPSBWZWMoeydhJywgJ2InLCAnYycsICdkJ30sIHsnYyc6\nIDF9KQogICAgPj4+IGEzID0gVmVjKHsnYScsICdiJywgJ2MnLCAnZCd9LCB7J2EnOiAxLCAnYyc6\nIDN9KQogICAgPj4+IGlzX2luZGVwZW5kZW50KFthMCwgYTEsIGEyXSkKICAgIFRydWUKICAgID4+\nPiBpc19pbmRlcGVuZGVudCh7YTAsIGEyLCBhM30pCiAgICBGYWxzZQogICAgPj4+IGlzX2luZGVw\nZW5kZW50KHthMCwgYTEsIGEzfSkKICAgIFRydWUKICAgID4+PiBpc19pbmRlcGVuZGVudChbYTAs\nIGExLCBhMiwgYTNdKQogICAgRmFsc2UKICAgIHIOAAAAKQhyGQAAAHI1AAAAch8AAAByNgAAANoO\naXNfaW5kZXBlbmRlbnRyOAAAAHI0AAAAcikAAAApAXIqAAAAcgYAAAByBgAAAHIHAAAAcjkAAABZ\nAAAAcwYAAAAAHBsBDwFyOQAAAFoMaW5zdHJ1bWVudGVkKQlyMwAAAHICAAAAcisAAAByMQAAAHI0\nAAAAcjcAAAByOQAAAHI4AAAA2gtfX3ZlcnNpb25fX3IGAAAAcgYAAAByBgAAAHIHAAAA2gg8bW9k\ndWxlPgIAAABzFAAAAAwCExcPCAwNDAoMHwwgCQEJAQkB\n'
        offset = 12
    elif magic == b'\xf8\x0c\r\n': # Python 3.5
        pycData = b'+AwNChNz/FTtDQAA4wAAAAAAAAAAAAAAAAMAAABAAAAAc4YAAABkAABkAQBsAABaAABHZAIAZAMA\nhAAAZAMAgwIAWgEAZAQAZAUAZAYAhAEAWgIAZAcAZAgAhAAAWgMAZAkAZAoAhAAAWgQAZAsAZAwA\nhAAAWgUAZA0AZA4AhAAAWgYAZAAAZQUAXwcAZA8AZQUAXwgAZAAAZQYAXwcAZA8AZQYAXwgAZAEA\nUykQ6QAAAABOYwAAAAAAAAAAAAAAAAQAAABAAAAAc3kAAABlAABaAQBkAABaAgBlAwCDAABpAABk\nAQBkAgCEAgBaBABkAwBkBACEAABaBQBkBQBkBgCEAABaBgBkBwBkCACEAABaBwBkCQBkCgCEAABa\nCABkCwBkDACEAABaCQBkDQBkDgCEAABaCgBkDwBkEACEAABaCwBkEQBTKRLaBF9WZWNjAwAAAAAA\nAAADAAAAAgAAAEMAAABzFgAAAHwBAHwAAF8AAHwCAHwAAF8BAGQAAFMpAU4pAtoBRNoBZikD2gRz\nZWxmWgZsYWJlbHNaCGZ1bmN0aW9uqQByBgAAAPokLi4vcmVzb3VyY2VzL3ByaXZhdGUvaW5kZXBl\nbmRlbmNlLnB52ghfX2luaXRfXwUAAABzBAAAAAABCQF6DV9WZWMuX19pbml0X19jAgAAAAAAAAAC\nAAAAAgAAAEMAAABzHgAAAHwBAHwAAGoAAGsGAHIaAHwAAGoAAHwBABlTZAEAUykCTnIBAAAAKQFy\nBAAAACkC2gF22gFrcgYAAAByBgAAAHIHAAAA2gtfX2dldGl0ZW1fXwkAAABzAAAAAHoQX1ZlYy5f\nX2dldGl0ZW1fX2MDAAAAAAAAAAMAAAAEAAAAQwAAAHMVAAAAdAAABHwAAGoBAHwBADx9AgBkAABT\nKQFOKQJaCF9zZXRpdGVtcgQAAAApA3IJAAAAcgoAAADaA3ZhbHIGAAAAcgYAAAByBwAAANoLX19z\nZXRpdGVtX18KAAAAcwAAAAB6EF9WZWMuX19zZXRpdGVtX19jAQAAAAAAAAABAAAAAgAAAEMAAABz\nCAAAAGQCAHwAABRTKQNO6QEAAADp/////3IGAAAAKQFyCQAAAHIGAAAAcgYAAAByBwAAANoHX19u\nZWdfXwsAAABzAAAAAHoMX1ZlYy5fX25lZ19fYwIAAAAAAAAAAgAAAAUAAAADAAAAcywAAAB0AAB8\n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\nZAAAawMAcgYAfAEAkQIAcQYAUykBcgEAAAByBgAAACkCchEAAADaAXIpAtoBY9oHcm93bGlzdHIG\nAAAAcgcAAAByGAAAACcAAABzAgAAAAkAeh1fR0YyX3JhbmsuPGxvY2Fscz4uPGxpc3Rjb21wPnIO\nAAAAKQVyHwAAANoFcmFuZ2VyKQAAAHIDAAAA2gZyZW1vdmUpBnIuAAAAWglyb3dzX2xlZnRyLAAA\nAFoRcm93c193aXRoX25vbnplcm9aBXBpdm90Wglyb3dfaW5kZXhyBgAAACkCci0AAAByLgAAAHIH\nAAAA2glfR0YyX3JhbmsjAAAAcxYAAAAAARgBBgEUARwBDAEKAQ0BCgEXAR4BcjEAAABjAQAAAAAA\nAAAEAAAABQAAAEMAAABzdAAAAGQBAGQCAIQAAHwAAESDAQB9AQB4WgB8AABEXVIAfQIAeEkAfAIA\nagAAagEAgwAARF04AH0DAHwDAGQDAGsDAHIwAHQCAHwDAHQDAGoEAIMCAHJeAHQFAHwBAIMBAFN0\nBgB8AQCDAQBTcTAAV3EaAFdkAwBTKQROYwEAAAAAAAAAAgAAAAUAAABTAAAAcyUAAABnAAB8AABd\nGwB9AQB0AAB8AQBqAQB8AQBqAgCDAgCRAgBxBgBTcgYAAAApA3ICAAAAcgMAAAByBAAAACkCchEA\nAAByHgAAAHIGAAAAcgYAAAByBwAAAHIYAAAAMQAAAHMCAAAACQB6GV9yYW5rLjxsb2NhbHM+Ljxs\naXN0Y29tcD5yAQAAACkHcgQAAADaBnZhbHVlc3IZAAAA2gNHRjJaA09uZXIxAAAAcisAAAApBHIq\nAAAAWgJMY3IJAAAAchIAAAByBgAAAHIGAAAAcgcAAADaBV9yYW5rMAAAAHMQAAAAAAETAQ0BFgEM\nARIBCgESAXI0AAAAYwEAAAAAAAAAAQAAAAQAAABDAAAAczQAAAB0AAB8AAB0AQB0AgBmAgCDAgBz\nGwB0AwCCAQB0BAAEagUAZAEANwJfBQB0BgB8AACDAQBTKQJhcAIAAEZpbmRzIHRoZSByYW5rIG9m\nIGEgbGlzdCBvciBzZXQgb2YgdmVjdG9ycy4KCiAgICBBcmdzOgogICAgICAgIEw6IEEgbGlzdCBv\nciBzZXQgb2YgdmVjdG9ycy4KCiAgICBSZXR1cm5zOgogICAgICAgIHg6IEEgbm9ubmVnYXRpdmUg\naW50ZWdlci4gIFRoZSByYW5rIG9mIEwuCgogICAgUmFpc2VzOgogICAgICAgIEFzc2VydGlvbkVy\ncm9yOiBBbiBlcnJvciBvY2N1cnMgd2hlbiBMIGlzIG5vdCBhIGxpc3Qgb3Igc2V0LgoKICAgIEV4\nYW1wbGU6CiAgICA+Pj4gZnJvbSB2ZWMgaW1wb3J0IFZlYwogICAgPj4+IGEwID0gVmVjKHsnYScs\nICdiJywgJ2MnLCAnZCd9LCB7J2EnOiAxfSkKICAgID4+PiBhMSA9IFZlYyh7J2EnLCAnYicsICdj\nJywgJ2QnfSwgeydiJzogMX0pCiAgICA+Pj4gYTIgPSBWZWMoeydhJywgJ2InLCAnYycsICdkJ30s\nIHsnYyc6IDF9KQogICAgPj4+IGEzID0gVmVjKHsnYScsICdiJywgJ2MnLCAnZCd9LCB7J2EnOiAx\nLCAnYyc6IDN9KQogICAgPj4+IHJhbmsoW2EwLCBhMSwgYTJdKQogICAgMwogICAgPj4+IHJhbmso\ne2EwLCBhMiwgYTN9KQogICAgMgogICAgPj4+IHJhbmsoe2EwLCBhMSwgYTN9KQogICAgMwogICAg\nPj4+IHJhbmsoW2EwLCBhMSwgYTIsIGEzXSkKICAgIDMKICAgIHIOAAAAKQdyGQAAANoEbGlzdHIf\nAAAA2g5Bc3NlcnRpb25FcnJvctoEcmFua9oJX19jYWxsc19fcjQAAAApAXIqAAAAcgYAAAByBgAA\nAHIHAAAAcjcAAAA6AAAAcwYAAAAAGxsBDwFyNwAAAGMBAAAAAAAAAAEAAAAEAAAAQwAAAHNAAAAA\ndAAAfAAAdAEAdAIAZgIAgwIAcxsAdAMAggEAdAQABGoFAGQBADcCXwUAdAYAfAAAgwEAdAcAfAAA\ngwEAawIAUykCYe0CAABEZXRlcm1pbmVzIGlmIGEgbGlzdCBvciBzZXQgb2YgdmVjdG9ycyBhcmUg\nbGluZWFybHkgaW5kZXBlbmRlbnQuCgogICAgQXJnczoKICAgICAgICBMOiBBIGxpc3Qgb3Igc2V0\nIG9mIHZlY3RvcnMuCgogICAgUmV0dXJuczoKICAgICAgICB4OiBBIGJvb2xlYW4uICBUcnVlIGlm\nIHRoZSB2ZWN0b3JzIGluIEwgYXJlIGxpbmVhcmx5IGluZGVwZW5kZW50LiAgRmFsc2UKICAgICAg\nICBvdGhlcndpc2UuCgogICAgUmFpc2VzOgogICAgICAgIEFzc2VydGlvbkVycm9yOiBBbiBlcnJv\nciBvY2N1cnMgd2hlbiBMIGlzIG5vdCBhIGxpc3Qgb3Igc2V0LgoKICAgIEV4YW1wbGU6CiAgICA+\nPj4gZnJvbSB2ZWMgaW1wb3J0IFZlYwogICAgPj4+IGEwID0gVmVjKHsnYScsICdiJywgJ2MnLCAn\nZCd9LCB7J2EnOiAxfSkKICAgID4+PiBhMSA9IFZlYyh7J2EnLCAnYicsICdjJywgJ2QnfSwgeydi\nJzogMX0pCiAgICA+Pj4gYTIgPSBWZWMoeydhJywgJ2InLCAnYycsICdkJ30sIHsnYyc6IDF9KQog\nICAgPj4+IGEzID0gVmVjKHsnYScsICdiJywgJ2MnLCAnZCd9LCB7J2EnOiAxLCAnYyc6IDN9KQog\nICAgPj4+IGlzX2luZGVwZW5kZW50KFthMCwgYTEsIGEyXSkKICAgIFRydWUKICAgID4+PiBpc19p\nbmRlcGVuZGVudCh7YTAsIGEyLCBhM30pCiAgICBGYWxzZQogICAgPj4+IGlzX2luZGVwZW5kZW50\nKHthMCwgYTEsIGEzfSkKICAgIFRydWUKICAgID4+PiBpc19pbmRlcGVuZGVudChbYTAsIGExLCBh\nMiwgYTNdKQogICAgRmFsc2UKICAgIHIOAAAAKQhyGQAAAHI1AAAAch8AAAByNgAAANoOaXNfaW5k\nZXBlbmRlbnRyOAAAAHI0AAAAcikAAAApAXIqAAAAcgYAAAByBgAAAHIHAAAAcjkAAABZAAAAcwYA\nAAAAHBsBDwFyOQAAAFoMaW5zdHJ1bWVudGVkKQlyMwAAAHICAAAAcisAAAByMQAAAHI0AAAAcjcA\nAAByOQAAAHI4AAAA2gtfX3ZlcnNpb25fX3IGAAAAcgYAAAByBgAAAHIHAAAA2gg8bW9kdWxlPgIA\nAABzFAAAAAwCExcPCAwNDAoMHwwgCQEJAQkB\n'
        offset = 12
    else:
        raise ImportError("Unsupported Python version")

    pycData = base64.decodebytes(pycData)

    assert pycData[:4] == magic, "Bad magic number Independnce"

    try:
        return marshal.loads(pycData[offset:])
    except ValueError:
        raise ImportError("Could not read .pyc data")
Exemplo n.º 9
0
    def _compile(self, filename, source):
        """ Compiles the Python source code to a code object and
        attempts to write it to an appropriate .pyc file.  May raise
        SyntaxError or other errors generated by the compiler. """

        if source and source[-1] != "\n":
            source = source + "\n"
        code = compile(source, filename.toOsSpecific(), "exec")

        # try to cache the compiled code
        pycFilename = Filename(filename)
        pycFilename.setExtension(compiledExtensions[0])
        try:
            f = open(pycFilename.toOsSpecific(), "wb")
        except IOError:
            pass
        else:
            f.write(imp.get_magic())
            if sys.version_info >= (3, 0):
                f.write((self.timestamp & 0xFFFFFFFF).to_bytes(4, "little"))
                f.write(b"\0\0\0\0")
            else:
                f.write(
                    chr(self.timestamp & 0xFF)
                    + chr((self.timestamp >> 8) & 0xFF)
                    + chr((self.timestamp >> 16) & 0xFF)
                    + chr((self.timestamp >> 24) & 0xFF)
                )
            f.write(marshal.dumps(code))
            f.close()

        return code
Exemplo n.º 10
0
	def __import (self, fname, paths):
		rc = None
		for path in paths:
			fpath = os.path.join (path, fname)
			if os.path.isfile (fpath):
				(base, ext) = os.path.splitext (fname)
				try:
					if ext in ('.pyc', '.pyo'):
						fd = open (fpath, 'rb')
						code = fd.read ()
						fd.close ()
						if len (code) < 8:
							raise Exception ('truncated binary')
						magic = imp.get_magic ()
						if code[:len (magic)] != magic:
							raise Exception ('binary version mismatch')
						m = marshal.loads (code[8:])
					else:
						fd = open (fpath, 'r')
						code = fd.read ()
						fd.close ()
						m = compile (code, fpath, 'exec')
					rc = {'_m': self}
					exec m in rc
				except Exception, e:
					self.warning ('Failed to load %s: %s' % (fpath, str (e)))
					if not self.tolerant:
						raise
					rc = None
				break
Exemplo n.º 11
0
Arquivo: core.py Projeto: LLNL/WVL
	def remote_supply_code(self, name, module, sourceaddr):
		if Pyro.config.PYRO_MOBILE_CODE and self.codeValidator(name,module,sourceaddr):
			import imp,marshal,new
			Log.msg('ObjBase','loading supplied code: ',name,'from',str(sourceaddr))
			name=name.split('.')
			# make the module hierarchy and add all names to sys.modules
			path=''
			mod=new.module("pyro-agent-context")

			for m in name:
				path+='.'+m
				# use already loaded modules instead of overwriting them
				real_path = path[1:]
				if sys.modules.has_key(real_path):
					mod = sys.modules[real_path]
				else:
					setattr(mod,m,new.module(path[1:]))
					mod=getattr(mod,m)
					sys.modules[path[1:]]=mod
				
			if module[0:4]!=imp.get_magic():
				# compile source code
				code=compile(module,'<downloaded>','exec')
			else:
				# read bytecode from the client
				code=marshal.loads(module[8:])
			# finally, execute the module code in the right module.	A
			exec code in mod.__dict__
		else:
			Log.warn('ObjBase','attempt to supply code denied: ',name,'from',str(sourceaddr))
			raise PyroError('attempt to supply code denied')
Exemplo n.º 12
0
def Compile(ZipFile):
    """ This function compiles all python files inside a ZIP archive. """
    ZIP = zipfile.PyZipFile(ZipFile, mode="a");
    Files = ZIP.namelist();
    for FileName in Files:
        if not FileName[-3:] == ".py": continue;    # compile onyl python
        if FileName+"c" in Files: continue;         # do not recomplile
        src_data = ZIP.read(FileName);
        src_info = ZIP.getinfo(FileName);
        timestamp = int(time.time());
        if src_data[-1] != "\n": src_data += "/";
        src_data.replace("\r\n","\n");  #windows->unix
        src_data.replace("\r","\n");    #mac->unix
        
        bin_obj  = compile(src_data,"<string>","exec");
        # assamble .pyc file
        bin_str = imp.get_magic();
        bin_str += chr(timestamp      &0xff);
        bin_str += chr((timestamp>>8) &0xff);
        bin_str += chr((timestamp>>16)&0xff);
        bin_str += chr((timestamp>>24)&0xff);
        bin_str += marshal.dumps(bin_obj);
        
        ZIP.writestr(FileName+"c",bin_str);
        print "Compile: %s(%i)\t\t -> (%i)"%(FileName, len(src_data), len(bin_str));
    ZIP.close();
Exemplo n.º 13
0
def test_dev_egg_cache_updated_on_upload_of_dev1rXXXX_egg(pytestconfig,
                                                          pypi_chishop_with_egg_cache):
    cache = pypi_chishop_with_egg_cache.egg_cache
    dev_cache = pypi_chishop_with_egg_cache.dev_egg_cache
    with PkgTemplate(name="acme.pypipkg", dev=False,
                     metadata=dict(name="acme.pypipkg", version="1.2.3.dev1-r184247")) as pkg:
        pkg.install_package('pytest-cov')
        pkg.create_pypirc(pypi_chishop_with_egg_cache.get_rc())

        pkg.run_with_coverage([os.path.join(pkg.trunk_dir, "setup.py"),
                               'bdist_egg', 'register', 'upload',
                               '--show-response'], pytestconfig,
                              env=dict(pkg.env, HOME=pkg.workspace), cd=HERE, capture_stdout=False)
        egg = 'acme.pypipkg-1.2.3.dev1_r184247-py%d.%d.egg' % sys.version_info[:2]

        assert not os.path.exists(os.path.join(cache, 'ap', egg))
        assert os.path.exists(os.path.join(dev_cache, 'ap', egg))
        py, pyc = (os.path.join('acme', 'pypipkg', '__init__.' + ext)
                   for ext in ('py', 'pyc'))
        with closing(ZipFile(os.path.join(dev_cache, 'ap', egg))) as z:
            f = z.open(pyc)
            magic = f.read(4)
            stamp = struct.unpack('<L', f.read(4))[0]
            code = marshal.loads(f.read())  # remainder of the file
            assert magic == imp.get_magic()
            assert (datetime.fromtimestamp(stamp) ==
                    datetime(*z.getinfo(py).date_time))
            assert isinstance(code, types.CodeType)
            assert code.co_filename == os.path.join(dev_cache, 'ap', egg, py)
Exemplo n.º 14
0
def _write_pyc(co, source_path, pyc):
    # Technically, we don't have to have the same pyc format as
    # (C)Python, since these "pycs" should never be seen by builtin
    # import. However, there's little reason deviate, and I hope
    # sometime to be able to use imp.load_compiled to load them. (See
    # the comment in load_module above.)
    mtime = int(source_path.mtime())
    try:
        fp = open(pyc, "wb")
    except IOError:
        err = sys.exc_info()[1].errno
        if err in [errno.ENOENT, errno.ENOTDIR]:
            # This happens when we get a EEXIST in find_module creating the
            # __pycache__ directory and __pycache__ is by some non-dir node.
            return False
        elif err == errno.EACCES:
            # The directory is read-only; this can happen for example when
            # running the tests in a package installed as root
            return False
        raise
    try:
        fp.write(imp.get_magic())
        fp.write(struct.pack("<l", mtime))
        marshal.dump(co, fp)
    finally:
        fp.close()
    return True
Exemplo n.º 15
0
    def __init__(self, path=None, start=0):
        """
        Initialize an Archive. If path is omitted, it will be an empty Archive.
        """
        self.toc = None
        self.path = path
        self.start = start

        # In Python 3 module 'imp' is no longer built-in and we cannot use it.
        # There is for Python 3 another way how to obtain magic value.
        if sys.version_info[0] == 2:
            import imp
            self.pymagic = imp.get_magic()
        else:
            import _frozen_importlib
            if sys.version_info[1] <= 3:
                # We cannot use at this bootstrap stage importlib directly
                # but its frozen variant.
                self.pymagic = _frozen_importlib._MAGIC_BYTES
            else:
                self.pymagic = _frozen_importlib.MAGIC_NUMBER

        if path is not None:
            self.lib = open(self.path, 'rb')
            self.checkmagic()
            self.loadtoc()
Exemplo n.º 16
0
        def get_code(self, fullname=None):
            """Same as `pkgutil.ImpLoader`, with an extra check for Hy
            source"""
            fullname = self._fix_name(fullname)
            ext_type = self.etc[0]
            if ext_type == '.hy':
                # Looks like we have to manually check for--and update--
                # the bytecode.
                t_py = long(os.stat(self.filename).st_mtime)
                pyc_file = cache_from_source(self.filename)
                if os.path.isfile(pyc_file):
                    t_pyc = long(os.stat(pyc_file).st_mtime)

                    if t_pyc is not None and t_pyc >= t_py:
                        with open(pyc_file, 'rb') as f:
                            if f.read(4) == imp.get_magic():
                                t = struct.unpack('<I', f.read(4))[0]
                                if t == t_py:
                                    self.code = marshal.load(f)

                if self.code is None:
                    # There's no existing bytecode, or bytecode timestamp
                    # is older than the source file's.
                    self.code = self.byte_compile_hy(fullname)

            if self.code is None:
                super(HyLoader, self).get_code(fullname=fullname)

            return self.code
Exemplo n.º 17
0
def compile_file(fullname, ddir=None, force=0, rx=None, quiet=0):
    """Byte-compile file.
    file:      the file to byte-compile
    ddir:      if given, purported directory name (this is the
               directory name that will show up in error messages)
    force:     if 1, force compilation, even if timestamps are up-to-date
    quiet:     if 1, be quiet during compilation

    """
    success = 1
    name = os.path.basename(fullname)
    if ddir is not None:
        dfile = os.path.join(ddir, name)
    else:
        dfile = None
    if rx is not None:
        mo = rx.search(fullname)
        if mo:
            return success
    if os.path.isfile(fullname):
        head, tail = name[:-3], name[-3:]
        if tail == '.py':
            if not force:
                try:
                    mtime = int(os.stat(fullname).st_mtime)
                    expect = struct.pack('<4sl', imp.get_magic(), mtime)
                    cfile = fullname + (__debug__ and 'c' or 'o')
                    with open(cfile, 'rb') as chandle:
                        actual = chandle.read(8)
                    if expect == actual:
                        return success
                except IOError:
                    pass
            if not quiet:
                print('Compiling', fullname, '...')
            try:
                ok = py_compile.compile(fullname, None, dfile, True)
            except KeyboardInterrupt:
                raise KeyboardInterrupt
            except py_compile.PyCompileError as err:
                if quiet:
                    print('*** Error compiling', fullname, '...')
                else:
                    print('*** ', end='')
                # escape non-printable characters in msg
                msg = err.msg.encode(sys.stdout.encoding, 'backslashreplace')
                msg = msg.decode(sys.stdout.encoding)
                print(msg)
                success = 0
            except (SyntaxError, UnicodeError, IOError) as e:
                if quiet:
                    print('*** Error compiling', fullname, '...')
                else:
                    print('*** ', end='')
                print(e.__class__.__name__ + ':', e)
                success = 0
            else:
                if ok == 0:
                    success = 0
    return success
Exemplo n.º 18
0
def compileSource(source, filename = '<string>', filetime = time.time()):
	with io.BytesIO() as bytesIO:
		bytesIO.write(imp.get_magic())
		bytesIO.write(struct.pack('<I', int(filetime)))
		bytesIO.write(marshal.dumps(compile(source, filename, 'exec')))
		result = bytesIO.getvalue()
	return result
Exemplo n.º 19
0
def _compile(pathname, timestamp):
    """Compile (and cache) a Python source file.

    The file specified by <pathname> is compiled to a code object and
    returned.

    Presuming the appropriate privileges exist, the bytecodes will be
    saved back to the filesystem for future imports. The source file's
    modification timestamp must be provided as a Long value.
    """
    codestring = open(pathname, 'rU').read()
    if codestring and codestring[-1] != '\n':
        codestring = codestring + '\n'
    code = __builtin__.compile(codestring, pathname, 'exec')

    # try to cache the compiled code
    try:
        f = open(pathname + _suffix_char, 'wb')
    except IOError:
        pass
    else:
        f.write('\0\0\0\0')
        f.write(struct.pack('<I', timestamp))
        marshal.dump(code, f)
        f.flush()
        f.seek(0, 0)
        f.write(imp.get_magic())
        f.close()

    return code
Exemplo n.º 20
0
def _read_pyc(source, pyc, trace=lambda x: None):
    """Possibly read a pytest pyc containing rewritten code.

    Return rewritten code if successful or None if not.
    """
    try:
        fp = open(pyc, "rb")
    except IOError:
        return None
    with fp:
        try:
            mtime = int(source.mtime())
            size = source.size()
            data = fp.read(12)
        except EnvironmentError as e:
            trace('_read_pyc(%s): EnvironmentError %s' % (source, e))
            return None
        # Check for invalid or out of date pyc file.
        if (len(data) != 12 or data[:4] != imp.get_magic() or
                struct.unpack("<ll", data[4:]) != (mtime, size)):
            trace('_read_pyc(%s): invalid or out of date pyc' % source)
            return None
        try:
            co = marshal.load(fp)
        except Exception as e:
            trace('_read_pyc(%s): marshal.load error %s' % (source, e))
            return None
        if not isinstance(co, types.CodeType):
            trace('_read_pyc(%s): not a code object' % source)
            return None
        return co
Exemplo n.º 21
0
def make_code_from_pyc(filename):
    """Get a code object from a .pyc file."""
    try:
        fpyc = open(filename, "rb")
    except IOError:
        raise NoCode("No file to run: %r" % filename)

    try:
        # First four bytes are a version-specific magic number.  It has to
        # match or we won't run the file.
        magic = fpyc.read(4)
        if magic != imp.get_magic():
            raise NoCode("Bad magic number in .pyc file")

        # Skip the junk in the header that we don't need.
        fpyc.read(4)            # Skip the moddate.
        if sys.version_info >= (3, 3):
            # 3.3 added another long to the header (size), skip it.
            fpyc.read(4)

        # The rest of the file is the code object we want.
        code = marshal.load(fpyc)
    finally:
        fpyc.close()

    return code
Exemplo n.º 22
0
def _read_pyc(source, pyc):
    """Possibly read a py.test pyc containing rewritten code.

    Return rewritten code if successful or None if not.
    """
    try:
        fp = open(pyc, "rb")
    except IOError:
        return None
    try:
        try:
            mtime = int(source.mtime())
            data = fp.read(8)
        except EnvironmentError:
            return None
        # Check for invalid or out of date pyc file.
        if (len(data) != 8 or
            data[:4] != imp.get_magic() or
            struct.unpack("<l", data[4:])[0] != mtime):
            return None
        co = marshal.load(fp)
        if not isinstance(co, types.CodeType):
            # That's interesting....
            return None
        return co
    finally:
        fp.close()
Exemplo n.º 23
0
    def _compile(self, filename, source):
        """ Compiles the Python source code to a code object and
        attempts to write it to an appropriate .pyc file. """
        
        if source and source[-1] != '\n':
            source = source + '\n'
        code = __builtin__.compile(source, filename.cStr(), 'exec')

        # try to cache the compiled code
        pycFilename = Filename(filename)
        pycFilename.setExtension(pycExtension)
        try:
            f = open(pycFilename, 'wb')
        except IOError:
            pass
        else:
            f.write('\0\0\0\0')
            f.write(struct.pack('<I', self.timestamp))
            f.write(marshal.dumps(code))
            f.flush()
            f.seek(0, 0)
            f.write(imp.get_magic())
            f.close()

        return code
Exemplo n.º 24
0
def savemodule(code, filename, srcfile):
    # pinched from compiler.pycodegen.Module.getPycHeader
    import struct
    import imp
    import marshal
    
    mtime = os.path.getmtime(srcfile)
    mtime = struct.pack('<i', mtime)
    header = imp.get_magic() + mtime

    f = file(filename, "wb")
    f.write(header)
    try:
        marshal.dump(code, f)
    except ValueError:
        # Something wasn't marshallable - let's try and find what
        import types
        def dump(x):
            if type(x) not in (type(None), type(1), type(""),
                               type(1L), type(1.1), type(True),
                               type([]), type(()), type({}),
                               types.CodeType):
                print "%-30s %r" % (type(x), x)
            if isinstance(x, types.CodeType):
                for c in x.co_consts:
                    dump(c)
            if isinstance(x, (list, tuple)):
                for v in x:
                    dump(v)
        print "---scanning for unmarshallable types---"            
        dump(code)
        print "---done---"
        raise
            
    f.close()
Exemplo n.º 25
0
 def load_module(self, fqname, fp, pathname, file_info):
     suffix, mode, type = file_info
     self.msgin(2, "load_module", fqname, fp and "fp", pathname)
     if type == imp.PKG_DIRECTORY:
         m = self.load_package(fqname, pathname)
         self.msgout(2, "load_module ->", m)
         return m
     if type == imp.PY_SOURCE:
         co = compile(fp.read()+'\n', pathname, 'exec')
     elif type == imp.PY_COMPILED:
         if fp.read(4) != imp.get_magic():
             self.msgout(2, "raise ImportError: Bad magic number", pathname)
             raise ImportError("Bad magic number in %s" % pathname)
         fp.read(4)
         co = marshal.load(fp)
     else:
         co = None
     m = self.add_module(fqname)
     m.__file__ = pathname
     if co:
         if self.replace_paths:
             co = self.replace_paths_in_code(co)
         m.__code__ = co
         self.scan_code(co, m)
     self.msgout(2, "load_module ->", m)
     return m
Exemplo n.º 26
0
def _LoadModuleCode(filename):
  """Loads the code of a module, using compiled bytecode if available.

  Args:
    filename: The Python script filename.

  Returns:
    A 2-tuple (code, filename) where:
      code: A code object contained in the file or None if it does not exist.
      filename: The name of the file loaded, either the same as the arg
          filename, or the corresponding .pyc file.
  """
  compiled_filename = filename + 'c'
  if os.path.exists(compiled_filename):
    with open(compiled_filename, 'r') as f:
      magic_numbers = f.read(8)
      if len(magic_numbers) == 8 and magic_numbers[:4] == imp.get_magic():
        try:
          return _FixCodeFilename(marshal.load(f), filename), compiled_filename
        except (EOFError, ValueError):
          pass

  if os.path.exists(filename):
    with open(filename, 'r') as f:
      code = compile(f.read(), filename, 'exec', 0, True)
    return code, filename
  else:
    return None, filename
Exemplo n.º 27
0
    def _handle_file(self):
        """Load and compile the config source code from the given filename
        """

        source_timestamp = None
        # use bytecode if available
        if self._bytecode_is_available():
            magic, timestamp, bytecode = self._get_bytecode()
            try:
                if imp.get_magic() != magic:
                    raise DeployerError('bad magic number for obj config file')

                source_timestamp = self._get_timestamp()
                if timestamp < source_timestamp:
                    return self._compile_source_file(source_timestamp)

                try:
                    # use marshal to read the binary data
                    return marshal.loads(bytecode)
                except ValueError:
                    # bytecode is not good, just fallback to source code
                    pass
            except DeployerError:
                raise  # propagate

        # use the source
        return self._compile_source_file(source_timestamp)
Exemplo n.º 28
0
def compile_source(sourcePath, sourceFile):
    """Given python code source path and file obj, Create a compiled version.

    Return path of compiled version, or None if file creation is not
    successful.  (Compilation errors themselves are passed without restraint.)

    This is an import-private interface, and not well-behaved for general use.
    
    In particular, we presume the validity of the sourcePath, and that it
    includes a '.py' extension."""

    compiledPath = sourcePath[:-3] + '.pyc'
    try:
	compiledFile = open(compiledPath, 'wb')
    except IOError:
	note("write permission denied to " + compiledPath)
	return None
    mtime = os.stat(sourcePath)[8]
    sourceFile.seek(0)			# rewind
    try:
	compiledFile.write(imp.get_magic())		# compiled magic number
	compiledFile.seek(8, 0)				# mtime space holder
	# We let compilation errors go their own way...
	compiled = compile(sourceFile.read(), sourcePath, 'exec')
	marshal.dump(compiled, compiledFile)		# write the code obj
	compiledFile.seek(4, 0)				# position for mtime
	compiledFile.write(marshal.dumps(mtime)[1:])	# register mtime
	compiledFile.flush()
	compiledFile.close()
	return compiledPath
    except IOError:
	return None
Exemplo n.º 29
0
def _get_module():
    del globals()['_get_module']
    import imp
    import base64
    import marshal

    magic = imp.get_magic()
    if magic == b'O\x0c\r\n': # Python 3.1
        pycData = b'TwwNCrTAR1RjAAAAAAAAAAAAAAAABAAAAEAAAABzdAAAAGQAAGQBAGwAAFoAAEdkAgCEAABkAwCD\nAgBaAQBkBABkBQCEAQBaAgBkBgCEAABaAwBkBwCEAABaBABkCACEAABaBQBkCQCEAABaBgBkAABl\nBQBfBwBkCgBlBQBfCABkAABlBgBfBwBkCgBlBgBfCABkAQBTKAsAAABpAAAAAE5jAQAAAAAAAAAB\nAAAAAwAAAEIAAABzXwAAAHwAAEVlAABaAQBlAgCDAABpAABkAACEAgBaAwBkAQCEAABaBABkAgCE\nAABaBQBkAwCEAABaBgBkBACEAABaBwBkBQCEAABaCABkBgCEAABaCQBkBwCEAABaCgBkCABTKAkA\nAABjAwAAAAAAAAADAAAAAgAAAEMAAABzFgAAAHwBAHwAAF8AAHwCAHwAAF8BAGQAAFMoAQAAAE4o\nAgAAAHUBAAAARHUBAAAAZigDAAAAdQQAAABzZWxmdQYAAABsYWJlbHN1CAAAAGZ1bmN0aW9uKAAA\nAAAoAAAAAHUkAAAALi4vcmVzb3VyY2VzL3ByaXZhdGUvaW5kZXBlbmRlbmNlLnB5dQgAAABfX2lu\naXRfXwUAAABzBAAAAAABCQFjAgAAAAAAAAACAAAAAgAAAEMAAABzHgAAAHwBAHwAAGoAAGsGAHIa\nAHwAAGoAAHwBABlTZAEAUygCAAAATmkAAAAAKAEAAAB1AQAAAGYoAgAAAHUBAAAAdnUBAAAAaygA\nAAAAKAAAAAB1JAAAAC4uL3Jlc291cmNlcy9wcml2YXRlL2luZGVwZW5kZW5jZS5weXULAAAAX19n\nZXRpdGVtX18JAAAAcwAAAABjAwAAAAAAAAADAAAABAAAAEMAAABzFQAAAHQAAAR8AABqAQB8AQA8\nfQIAZAAAUygBAAAATigCAAAAdQgAAABfc2V0aXRlbXUBAAAAZigDAAAAdQEAAAB2dQEAAABrdQMA\nAAB2YWwoAAAAACgAAAAAdSQAAAAuLi9yZXNvdXJjZXMvcHJpdmF0ZS9pbmRlcGVuZGVuY2UucHl1\nCwAAAF9fc2V0aXRlbV9fCgAAAHMAAAAAYwEAAAAAAAAAAQAAAAIAAABDAAAAcwgAAABkAQB8AAAU\nUygCAAAATmn/////KAAAAAAoAQAAAHUBAAAAdigAAAAAKAAAAAB1JAAAAC4uL3Jlc291cmNlcy9w\ncml2YXRlL2luZGVwZW5kZW5jZS5weXUHAAAAX19uZWdfXwsAAABzAAAAAGMCAAAAAAAAAAIAAAAE\nAAAAAwAAAHMpAAAAdAAAfAAAagEAhwAAZgEAZAEAhgAAfAAAagIAagMAgwAARIMBAIMCAFMoAgAA\nAE5jAQAAAAAAAAADAAAABAAAABMAAABzIwAAAGkAAHwAAF0ZAFwCAH0BAH0CAIgAAHwCABR8AQCT\nAgBxBgBTKAAAAAAoAAAAACgDAAAAdQIAAAAuMHUBAAAAa3UBAAAAeCgBAAAAdQUAAABhbHBoYSgA\nAAAAdSQAAAAuLi9yZXNvdXJjZXMvcHJpdmF0ZS9pbmRlcGVuZGVuY2UucHl1CgAAADxkaWN0Y29t\ncD4MAAAAcwIAAAAJACgEAAAAdQQAAABfVmVjdQEAAABEdQEAAABmdQUAAABpdGVtcygCAAAAdQEA\nAAB2dQUAAABhbHBoYSgAAAAAKAEAAAB1BQAAAGFscGhhdSQAAAAuLi9yZXNvdXJjZXMvcHJpdmF0\nZS9pbmRlcGVuZGVuY2UucHl1CAAAAF9fcm11bF9fDAAAAHMAAAAAYwIAAAAAAAAAAgAAAAMAAAAD\nAAAAcz0AAAB0AACIAQB0AQCDAgByNQB0AgCHAQCHAABmAgBkAQCGAACIAABqAwBqBACDAABEgwEA\ngwEAU3QFAFNkAABTKAIAAABOYwEAAAAAAAAAAgAAAAUAAAATAAAAcyIAAABnAAB8AABdGAB9AQCI\nAQB8AQAZiAAAfAEAGRSRAgBxBgBTKAAAAAAoAAAAACgCAAAAdQIAAAAuMHUBAAAAaygCAAAAdQUA\nAABvdGhlcnUEAAAAc2VsZigAAAAAdSQAAAAuLi9yZXNvdXJjZXMvcHJpdmF0ZS9pbmRlcGVuZGVu\nY2UucHl1CgAAADxsaXN0Y29tcD4RAAAAcwIAAAAJACgGAAAAdQoAAABpc2luc3RhbmNldQQAAABf\nVmVjdQMAAABzdW11AQAAAGZ1BAAAAGtleXN1DgAAAE5vdEltcGxlbWVudGVkKAIAAAB1BAAAAHNl\nbGZ1BQAAAG90aGVyKAAAAAAoAgAAAHUEAAAAc2VsZnUFAAAAb3RoZXJ1JAAAAC4uL3Jlc291cmNl\ncy9wcml2YXRlL2luZGVwZW5kZW5jZS5weXUHAAAAX19tdWxfXw4AAABzBgAAAAACDwEmAmMCAAAA\nAAAAAAIAAAAFAAAAAwAAAHNEAAAAdAAAiAAAagEAhwAAhwEAZgIAZAEAhgAAdAIAiAAAagMAagQA\ngwAAgwEAagUAiAEAagMAagQAgwAAgwEARIMBAIMCAFMoAgAAAE5jAQAAAAAAAAACAAAABQAAABMA\nAABzJQAAAGkAAHwAAF0bAH0BAIgAAHwBABmIAQB8AQAZF3wBAJMCAHEGAFMoAAAAACgAAAAAKAIA\nAAB1AgAAAC4wdQEAAABrKAIAAAB1AQAAAHV1AQAAAHYoAAAAAHUkAAAALi4vcmVzb3VyY2VzL3By\naXZhdGUvaW5kZXBlbmRlbmNlLnB5dQoAAAA8ZGljdGNvbXA+FQAAAHMCAAAACQAoBgAAAHUEAAAA\nX1ZlY3UBAAAARHUDAAAAc2V0dQEAAABmdQQAAABrZXlzdQUAAAB1bmlvbigCAAAAdQEAAAB1dQEA\nAAB2KAAAAAAoAgAAAHUBAAAAdXUBAAAAdnUkAAAALi4vcmVzb3VyY2VzL3ByaXZhdGUvaW5kZXBl\nbmRlbmNlLnB5dQcAAABfX2FkZF9fFQAAAHMAAAAAYwIAAAAAAAAAAgAAAAIAAABDAAAAcwkAAAB8\nAAB8AQALF1MoAQAAAHU0AAAAUmV0dXJucyBhIHZlY3RvciB3aGljaCBpcyB0aGUgZGlmZmVyZW5j\nZSBvZiBhIGFuZCBiLigAAAAAKAIAAAB1AQAAAGF1AQAAAGIoAAAAACgAAAAAdSQAAAAuLi9yZXNv\ndXJjZXMvcHJpdmF0ZS9pbmRlcGVuZGVuY2UucHl1BwAAAF9fc3ViX18XAAAAcwIAAAAAAk4oCwAA\nAHUIAAAAX19uYW1lX191CgAAAF9fbW9kdWxlX191AwAAAHNldHUIAAAAX19pbml0X191CwAAAF9f\nZ2V0aXRlbV9fdQsAAABfX3NldGl0ZW1fX3UHAAAAX19uZWdfX3UIAAAAX19ybXVsX191BwAAAF9f\nbXVsX191BwAAAF9fYWRkX191BwAAAF9fc3ViX18oAQAAAHUKAAAAX19sb2NhbHNfXygAAAAAKAAA\nAAB1JAAAAC4uL3Jlc291cmNlcy9wcml2YXRlL2luZGVwZW5kZW5jZS5weXUEAAAAX1ZlYwQAAABz\nEAAAAAoBEgQJAQkBCQEJAgkHCQJ1BAAAAF9WZWNnmyuhhpuEBj1jAgAAAAAAAAAFAAAABgAAAEMA\nAABzbAAAAGcAAH0CAHhZAHwAAERdUQB9AwB4KAB8AgBEXSAAfQQAfAMAfAMAfAQAFHwEAHwEABQb\nfAQAFBh9AwBxGgBXfAMAfAMAFHwBAGsEAHINAHwCAGoAAHwDAIMBAAFxDQBxDQBXdAEAfAIAgwEA\nUygBAAAATigCAAAAdQYAAABhcHBlbmR1AwAAAGxlbigFAAAAdQEAAABMdQMAAABlcHN1CQAAAHZz\ndGFybGlzdHUBAAAAdnUFAAAAdnN0YXIoAAAAACgAAAAAdSQAAAAuLi9yZXNvdXJjZXMvcHJpdmF0\nZS9pbmRlcGVuZGVuY2UucHl1BwAAAF9SX3JhbmsbAAAAcxIAAAAAAQYBBwAGAQcABgEeARAAFAFj\nAQAAAAAAAAAGAAAABQAAAAMAAABztAAAAHQAAHQBAHQCAIgBAIMBAIMBAIMBAH0BAGQBAH0CAHiP\nAIgBAGQBABlqAwBEXYAAiQAAhwAAhwEAZgIAZAIAhgAAfAEARIMBAH0DAHwDAGcAAGsDAHIsAHwD\nAGQBABl9BAB8AQBqBAB8BACDAQABfAIAZAMAN30CAHgxAHwDAGQDAGQAAIUCABlEXRwAfQUAiAEA\nfAUAGYgBAHwEABkXiAEAfAUAPHGJAFdxLABxLABXfAIAUygEAAAATmkAAAAAYwEAAAAAAAAAAgAA\nAAQAAAATAAAAcyoAAABnAAB8AABdIAB9AQCIAQB8AQAZiAAAGWQAAGsDAHIGAHwBAJECAHEGAFMo\nAQAAAGkAAAAAKAAAAAAoAgAAAHUCAAAALjB1AQAAAHIoAgAAAHUBAAAAY3UHAAAAcm93bGlzdCgA\nAAAAdSQAAAAuLi9yZXNvdXJjZXMvcHJpdmF0ZS9pbmRlcGVuZGVuY2UucHl1CgAAADxsaXN0Y29t\ncD4nAAAAcwIAAAAJAGkBAAAAKAUAAAB1AwAAAHNldHUFAAAAcmFuZ2V1AwAAAGxlbnUBAAAARHUG\nAAAAcmVtb3ZlKAYAAAB1BwAAAHJvd2xpc3R1CQAAAHJvd3NfbGVmdHUBAAAAcnURAAAAcm93c193\naXRoX25vbnplcm91BQAAAHBpdm90dQkAAAByb3dfaW5kZXgoAAAAACgCAAAAdQEAAABjdQcAAABy\nb3dsaXN0dSQAAAAuLi9yZXNvdXJjZXMvcHJpdmF0ZS9pbmRlcGVuZGVuY2UucHl1CQAAAF9HRjJf\ncmFuayMAAABzGgAAAAABGAEGAQ4ABgEZAQwBCgENAQoBEQAGASEBYwEAAAAAAAAABAAAAAUAAABD\nAAAAc3EAAABkAQCEAAB8AABEgwEAfQEAeFoAfAAARF1SAH0CAHhJAHwCAGoAAGoBAIMAAERdOAB9\nAwB8AwBkAgBrAwByLQB0AgB8AwB0AwBqBACDAgByWwB0BQB8AQCDAQBTdAYAfAEAgwEAU3EtAFdx\nFwBXZAIAUygDAAAATmMBAAAAAAAAAAIAAAAFAAAAUwAAAHMlAAAAZwAAfAAAXRsAfQEAdAAAfAEA\nagEAfAEAagIAgwIAkQIAcQYAUygAAAAAKAMAAAB1BAAAAF9WZWN1AQAAAER1AQAAAGYoAgAAAHUC\nAAAALjB1AQAAAHUoAAAAACgAAAAAdSQAAAAuLi9yZXNvdXJjZXMvcHJpdmF0ZS9pbmRlcGVuZGVu\nY2UucHl1CgAAADxsaXN0Y29tcD4xAAAAcwIAAAAJAGkAAAAAKAcAAAB1AQAAAGZ1BgAAAHZhbHVl\nc3UKAAAAaXNpbnN0YW5jZXUDAAAAR0YydQMAAABPbmV1CQAAAF9HRjJfcmFua3UHAAAAX1JfcmFu\naygEAAAAdQEAAABMdQIAAABMY3UBAAAAdnUBAAAAeCgAAAAAKAAAAAB1JAAAAC4uL3Jlc291cmNl\ncy9wcml2YXRlL2luZGVwZW5kZW5jZS5weXUFAAAAX3JhbmswAAAAcxQAAAAAARABBwAGARAABgEM\nARIBCgESAWMBAAAAAAAAAAEAAAADAAAAQwAAAHMZAAAAdAAABGoBAGQBADcCXwEAdAIAfAAAgwEA\nUygCAAAATmkBAAAAKAMAAAB1BAAAAHJhbmt1CQAAAF9fY2FsbHNfX3UFAAAAX3JhbmsoAQAAAHUB\nAAAATCgAAAAAKAAAAAB1JAAAAC4uL3Jlc291cmNlcy9wcml2YXRlL2luZGVwZW5kZW5jZS5weXUE\nAAAAcmFuazoAAABzBAAAAAABDwFjAQAAAAAAAAABAAAAAwAAAEMAAABzJQAAAHQAAARqAQBkAQA3\nAl8BAHQCAHwAAIMBAHQDAHwAAIMBAGsCAFMoAgAAAE5pAQAAACgEAAAAdQ4AAABpc19pbmRlcGVu\nZGVudHUJAAAAX19jYWxsc19fdQUAAABfcmFua3UDAAAAbGVuKAEAAAB1AQAAAEwoAAAAACgAAAAA\ndSQAAAAuLi9yZXNvdXJjZXMvcHJpdmF0ZS9pbmRlcGVuZGVuY2UucHl1DgAAAGlzX2luZGVwZW5k\nZW50PgAAAHMEAAAAAAEPAXUMAAAAaW5zdHJ1bWVudGVkKAkAAAB1AwAAAEdGMnUEAAAAX1ZlY3UH\nAAAAX1JfcmFua3UJAAAAX0dGMl9yYW5rdQUAAABfcmFua3UEAAAAcmFua3UOAAAAaXNfaW5kZXBl\nbmRlbnR1CQAAAF9fY2FsbHNfX3ULAAAAX192ZXJzaW9uX18oAAAAACgAAAAAKAAAAAB1JAAAAC4u\nL3Jlc291cmNlcy9wcml2YXRlL2luZGVwZW5kZW5jZS5weXUIAAAAPG1vZHVsZT4CAAAAcxQAAAAM\nAhAXDAgJDQkKCQQJBAkBCQEJAQ==\n'
        offset = 8
    elif magic == b'l\x0c\r\n': # Python 3.2
        pycData = b'bAwNCrTAR1RjAAAAAAAAAAAAAAAAAwAAAEAAAABzdAAAAGQAAGQBAGwAAFoAAEdkAgCEAABkAwCD\nAgBaAQBkBABkBQCEAQBaAgBkBgCEAABaAwBkBwCEAABaBABkCACEAABaBQBkCQCEAABaBgBkAABl\nBQBfBwBkCgBlBQBfCABkAABlBgBfBwBkCgBlBgBfCABkAQBTKAsAAABpAAAAAE5jAQAAAAAAAAAB\nAAAAAwAAAEIAAABzXwAAAHwAAEVlAABaAQBlAgCDAABpAABkAACEAgBaAwBkAQCEAABaBABkAgCE\nAABaBQBkAwCEAABaBgBkBACEAABaBwBkBQCEAABaCABkBgCEAABaCQBkBwCEAABaCgBkCABTKAkA\nAABjAwAAAAAAAAADAAAAAgAAAEMAAABzFgAAAHwBAHwAAF8AAHwCAHwAAF8BAGQAAFMoAQAAAE4o\nAgAAAHUBAAAARHUBAAAAZigDAAAAdQQAAABzZWxmdQYAAABsYWJlbHN1CAAAAGZ1bmN0aW9uKAAA\nAAAoAAAAAHUkAAAALi4vcmVzb3VyY2VzL3ByaXZhdGUvaW5kZXBlbmRlbmNlLnB5dQgAAABfX2lu\naXRfXwUAAABzBAAAAAABCQFjAgAAAAAAAAACAAAAAgAAAEMAAABzHgAAAHwBAHwAAGoAAGsGAHIa\nAHwAAGoAAHwBABlTZAEAUygCAAAATmkAAAAAKAEAAAB1AQAAAGYoAgAAAHUBAAAAdnUBAAAAaygA\nAAAAKAAAAAB1JAAAAC4uL3Jlc291cmNlcy9wcml2YXRlL2luZGVwZW5kZW5jZS5weXULAAAAX19n\nZXRpdGVtX18JAAAAcwAAAABjAwAAAAAAAAADAAAABAAAAEMAAABzFQAAAHQAAAR8AABqAQB8AQA8\nfQIAZAAAUygBAAAATigCAAAAdQgAAABfc2V0aXRlbXUBAAAAZigDAAAAdQEAAAB2dQEAAABrdQMA\nAAB2YWwoAAAAACgAAAAAdSQAAAAuLi9yZXNvdXJjZXMvcHJpdmF0ZS9pbmRlcGVuZGVuY2UucHl1\nCwAAAF9fc2V0aXRlbV9fCgAAAHMAAAAAYwEAAAAAAAAAAQAAAAIAAABDAAAAcwgAAABkAgB8AAAU\nUygDAAAATmkBAAAAaf////8oAAAAACgBAAAAdQEAAAB2KAAAAAAoAAAAAHUkAAAALi4vcmVzb3Vy\nY2VzL3ByaXZhdGUvaW5kZXBlbmRlbmNlLnB5dQcAAABfX25lZ19fCwAAAHMAAAAAYwIAAAAAAAAA\nAgAAAAQAAAADAAAAcykAAAB0AAB8AABqAQCHAABmAQBkAQCGAAB8AABqAgBqAwCDAABEgwEAgwIA\nUygCAAAATmMBAAAAAAAAAAMAAAAEAAAAEwAAAHMjAAAAaQAAfAAAXRkAXAIAfQEAfQIAiAAAfAIA\nFHwBAJMCAHEGAFMoAAAAACgAAAAAKAMAAAB1AgAAAC4wdQEAAABrdQEAAAB4KAEAAAB1BQAAAGFs\ncGhhKAAAAAB1JAAAAC4uL3Jlc291cmNlcy9wcml2YXRlL2luZGVwZW5kZW5jZS5weXUKAAAAPGRp\nY3Rjb21wPgwAAABzAgAAAAkAKAQAAAB1BAAAAF9WZWN1AQAAAER1AQAAAGZ1BQAAAGl0ZW1zKAIA\nAAB1AQAAAHZ1BQAAAGFscGhhKAAAAAAoAQAAAHUFAAAAYWxwaGF1JAAAAC4uL3Jlc291cmNlcy9w\ncml2YXRlL2luZGVwZW5kZW5jZS5weXUIAAAAX19ybXVsX18MAAAAcwAAAABjAgAAAAAAAAACAAAA\nAwAAAAMAAABzPQAAAHQAAIgAAHQBAIMCAHI1AHQCAIcAAIcBAGYCAGQBAIYAAIgBAGoDAGoEAIMA\nAESDAQCDAQBTdAUAU2QAAFMoAgAAAE5jAQAAAAAAAAACAAAABQAAABMAAABzIgAAAGcAAHwAAF0Y\nAH0BAIgBAHwBABmIAAB8AQAZFJECAHEGAFMoAAAAACgAAAAAKAIAAAB1AgAAAC4wdQEAAABrKAIA\nAAB1BQAAAG90aGVydQQAAABzZWxmKAAAAAB1JAAAAC4uL3Jlc291cmNlcy9wcml2YXRlL2luZGVw\nZW5kZW5jZS5weXUKAAAAPGxpc3Rjb21wPhEAAABzAgAAAAkAKAYAAAB1CgAAAGlzaW5zdGFuY2V1\nBAAAAF9WZWN1AwAAAHN1bXUBAAAAZnUEAAAAa2V5c3UOAAAATm90SW1wbGVtZW50ZWQoAgAAAHUE\nAAAAc2VsZnUFAAAAb3RoZXIoAAAAACgCAAAAdQUAAABvdGhlcnUEAAAAc2VsZnUkAAAALi4vcmVz\nb3VyY2VzL3ByaXZhdGUvaW5kZXBlbmRlbmNlLnB5dQcAAABfX211bF9fDgAAAHMGAAAAAAIPASYC\nYwIAAAAAAAAAAgAAAAUAAAADAAAAc0QAAAB0AACIAABqAQCHAACHAQBmAgBkAQCGAAB0AgCIAABq\nAwBqBACDAACDAQBqBQCIAQBqAwBqBACDAACDAQBEgwEAgwIAUygCAAAATmMBAAAAAAAAAAIAAAAF\nAAAAEwAAAHMlAAAAaQAAfAAAXRsAfQEAiAAAfAEAGYgBAHwBABkXfAEAkwIAcQYAUygAAAAAKAAA\nAAAoAgAAAHUCAAAALjB1AQAAAGsoAgAAAHUBAAAAdXUBAAAAdigAAAAAdSQAAAAuLi9yZXNvdXJj\nZXMvcHJpdmF0ZS9pbmRlcGVuZGVuY2UucHl1CgAAADxkaWN0Y29tcD4VAAAAcwIAAAAJACgGAAAA\ndQQAAABfVmVjdQEAAABEdQMAAABzZXR1AQAAAGZ1BAAAAGtleXN1BQAAAHVuaW9uKAIAAAB1AQAA\nAHV1AQAAAHYoAAAAACgCAAAAdQEAAAB1dQEAAAB2dSQAAAAuLi9yZXNvdXJjZXMvcHJpdmF0ZS9p\nbmRlcGVuZGVuY2UucHl1BwAAAF9fYWRkX18VAAAAcwAAAABjAgAAAAAAAAACAAAAAgAAAEMAAABz\nCQAAAHwAAHwBAAsXUygBAAAAdTQAAABSZXR1cm5zIGEgdmVjdG9yIHdoaWNoIGlzIHRoZSBkaWZm\nZXJlbmNlIG9mIGEgYW5kIGIuKAAAAAAoAgAAAHUBAAAAYXUBAAAAYigAAAAAKAAAAAB1JAAAAC4u\nL3Jlc291cmNlcy9wcml2YXRlL2luZGVwZW5kZW5jZS5weXUHAAAAX19zdWJfXxcAAABzAgAAAAAC\nTigLAAAAdQgAAABfX25hbWVfX3UKAAAAX19tb2R1bGVfX3UDAAAAc2V0dQgAAABfX2luaXRfX3UL\nAAAAX19nZXRpdGVtX191CwAAAF9fc2V0aXRlbV9fdQcAAABfX25lZ19fdQgAAABfX3JtdWxfX3UH\nAAAAX19tdWxfX3UHAAAAX19hZGRfX3UHAAAAX19zdWJfXygBAAAAdQoAAABfX2xvY2Fsc19fKAAA\nAAAoAAAAAHUkAAAALi4vcmVzb3VyY2VzL3ByaXZhdGUvaW5kZXBlbmRlbmNlLnB5dQQAAABfVmVj\nBAAAAHMQAAAACgESBAkBCQEJAQkCCQcJAnUEAAAAX1ZlY2ebK6GGm4QGPWMCAAAAAAAAAAUAAAAG\nAAAAQwAAAHNsAAAAZwAAfQIAeFkAfAAARF1RAH0DAHgoAHwCAERdIAB9BAB8AwB8AwB8BAAUfAQA\nfAQAFBt8BAAUGH0DAHEaAFd8AwB8AwAUfAEAawQAcg0AfAIAagAAfAMAgwEAAXENAHENAFd0AQB8\nAgCDAQBTKAEAAABOKAIAAAB1BgAAAGFwcGVuZHUDAAAAbGVuKAUAAAB1AQAAAEx1AwAAAGVwc3UJ\nAAAAdnN0YXJsaXN0dQEAAAB2dQUAAAB2c3RhcigAAAAAKAAAAAB1JAAAAC4uL3Jlc291cmNlcy9w\ncml2YXRlL2luZGVwZW5kZW5jZS5weXUHAAAAX1JfcmFuaxsAAABzDgAAAAABBgENAQ0BHgEQABQB\nYwEAAAAAAAAABgAAAAUAAAADAAAAc7QAAAB0AAB0AQB0AgCIAQCDAQCDAQCDAQB9AQBkAQB9AgB4\njwCIAQBkAQAZagMARF2AAIkAAIcAAIcBAGYCAGQCAIYAAHwBAESDAQB9AwB8AwBnAABrAwByLAB8\nAwBkAQAZfQQAfAEAagQAfAQAgwEAAXwCAGQDADd9AgB4MQB8AwBkAwBkAACFAgAZRF0cAH0FAIgB\nAHwFABmIAQB8BAAZF4gBAHwFADxxiQBXcSwAcSwAV3wCAFMoBAAAAE5pAAAAAGMBAAAAAAAAAAIA\nAAAEAAAAEwAAAHMqAAAAZwAAfAAAXSAAfQEAiAEAfAEAGYgAABlkAABrAwByBgB8AQCRAgBxBgBT\nKAEAAABpAAAAACgAAAAAKAIAAAB1AgAAAC4wdQEAAAByKAIAAAB1AQAAAGN1BwAAAHJvd2xpc3Qo\nAAAAAHUkAAAALi4vcmVzb3VyY2VzL3ByaXZhdGUvaW5kZXBlbmRlbmNlLnB5dQoAAAA8bGlzdGNv\nbXA+JwAAAHMCAAAACQBpAQAAACgFAAAAdQMAAABzZXR1BQAAAHJhbmdldQMAAABsZW51AQAAAER1\nBgAAAHJlbW92ZSgGAAAAdQcAAAByb3dsaXN0dQkAAAByb3dzX2xlZnR1AQAAAHJ1EQAAAHJvd3Nf\nd2l0aF9ub256ZXJvdQUAAABwaXZvdHUJAAAAcm93X2luZGV4KAAAAAAoAgAAAHUBAAAAY3UHAAAA\ncm93bGlzdHUkAAAALi4vcmVzb3VyY2VzL3ByaXZhdGUvaW5kZXBlbmRlbmNlLnB5dQkAAABfR0Yy\nX3JhbmsjAAAAcxYAAAAAARgBBgEUARkBDAEKAQ0BCgEXASEBYwEAAAAAAAAABAAAAAUAAABDAAAA\nc3EAAABkAQCEAAB8AABEgwEAfQEAeFoAfAAARF1SAH0CAHhJAHwCAGoAAGoBAIMAAERdOAB9AwB8\nAwBkAgBrAwByLQB0AgB8AwB0AwBqBACDAgByWwB0BQB8AQCDAQBTdAYAfAEAgwEAU3EtAFdxFwBX\nZAIAUygDAAAATmMBAAAAAAAAAAIAAAAFAAAAUwAAAHMlAAAAZwAAfAAAXRsAfQEAdAAAfAEAagEA\nfAEAagIAgwIAkQIAcQYAUygAAAAAKAMAAAB1BAAAAF9WZWN1AQAAAER1AQAAAGYoAgAAAHUCAAAA\nLjB1AQAAAHUoAAAAACgAAAAAdSQAAAAuLi9yZXNvdXJjZXMvcHJpdmF0ZS9pbmRlcGVuZGVuY2Uu\ncHl1CgAAADxsaXN0Y29tcD4xAAAAcwIAAAAJAGkAAAAAKAcAAAB1AQAAAGZ1BgAAAHZhbHVlc3UK\nAAAAaXNpbnN0YW5jZXUDAAAAR0YydQMAAABPbmV1CQAAAF9HRjJfcmFua3UHAAAAX1JfcmFuaygE\nAAAAdQEAAABMdQIAAABMY3UBAAAAdnUBAAAAeCgAAAAAKAAAAAB1JAAAAC4uL3Jlc291cmNlcy9w\ncml2YXRlL2luZGVwZW5kZW5jZS5weXUFAAAAX3JhbmswAAAAcxAAAAAAARABDQEWAQwBEgEKARIB\nYwEAAAAAAAAAAQAAAAMAAABDAAAAcxkAAAB0AAAEagEAZAEANwJfAQB0AgB8AACDAQBTKAIAAABO\naQEAAAAoAwAAAHUEAAAAcmFua3UJAAAAX19jYWxsc19fdQUAAABfcmFuaygBAAAAdQEAAABMKAAA\nAAAoAAAAAHUkAAAALi4vcmVzb3VyY2VzL3ByaXZhdGUvaW5kZXBlbmRlbmNlLnB5dQQAAAByYW5r\nOgAAAHMEAAAAAAEPAWMBAAAAAAAAAAEAAAADAAAAQwAAAHMlAAAAdAAABGoBAGQBADcCXwEAdAIA\nfAAAgwEAdAMAfAAAgwEAawIAUygCAAAATmkBAAAAKAQAAAB1DgAAAGlzX2luZGVwZW5kZW50dQkA\nAABfX2NhbGxzX191BQAAAF9yYW5rdQMAAABsZW4oAQAAAHUBAAAATCgAAAAAKAAAAAB1JAAAAC4u\nL3Jlc291cmNlcy9wcml2YXRlL2luZGVwZW5kZW5jZS5weXUOAAAAaXNfaW5kZXBlbmRlbnQ+AAAA\ncwQAAAAAAQ8BdQwAAABpbnN0cnVtZW50ZWQoCQAAAHUDAAAAR0YydQQAAABfVmVjdQcAAABfUl9y\nYW5rdQkAAABfR0YyX3Jhbmt1BQAAAF9yYW5rdQQAAAByYW5rdQ4AAABpc19pbmRlcGVuZGVudHUJ\nAAAAX19jYWxsc19fdQsAAABfX3ZlcnNpb25fXygAAAAAKAAAAAAoAAAAAHUkAAAALi4vcmVzb3Vy\nY2VzL3ByaXZhdGUvaW5kZXBlbmRlbmNlLnB5dQgAAAA8bW9kdWxlPgIAAABzFAAAAAwCEBcMCAkN\nCQoJBAkECQEJAQkB\n'
        offset = 8
    elif magic == b'\x9e\x0c\r\n': # Python 3.3
        pycData = b'ngwNCrTAR1QuCAAAYwAAAAAAAAAAAAAAAAMAAABAAAAAc4YAAABkAABkAQBsAABaAABHZAIAZAMA\nhAAAZAMAgwIAWgEAZAQAZAUAZAYAhAEAWgIAZAcAZAgAhAAAWgMAZAkAZAoAhAAAWgQAZAsAZAwA\nhAAAWgUAZA0AZA4AhAAAWgYAZAAAZQUAXwcAZA8AZQUAXwgAZAAAZQYAXwcAZA8AZQYAXwgAZAEA\nUygQAAAAaQAAAABOYwEAAAAAAAAAAQAAAAQAAABCAAAAc30AAAB8AABFZQAAWgEAZAAAWgIAZQMA\ngwAAaQAAZAEAZAIAhAIAWgQAZAMAZAQAhAAAWgUAZAUAZAYAhAAAWgYAZAcAZAgAhAAAWgcAZAkA\nZAoAhAAAWggAZAsAZAwAhAAAWgkAZA0AZA4AhAAAWgoAZA8AZBAAhAAAWgsAZBEAUygSAAAAdQQA\nAABfVmVjYwMAAAAAAAAAAwAAAAIAAABDAAAAcxYAAAB8AQB8AABfAAB8AgB8AABfAQBkAABTKAEA\nAABOKAIAAAB1AQAAAER1AQAAAGYoAwAAAHUEAAAAc2VsZnUGAAAAbGFiZWxzdQgAAABmdW5jdGlv\nbigAAAAAKAAAAAB1JAAAAC4uL3Jlc291cmNlcy9wcml2YXRlL2luZGVwZW5kZW5jZS5weXUIAAAA\nX19pbml0X18FAAAAcwQAAAAAAQkBdQ0AAABfVmVjLl9faW5pdF9fYwIAAAAAAAAAAgAAAAIAAABD\nAAAAcx4AAAB8AQB8AABqAABrBgByGgB8AABqAAB8AQAZU2QBAFMoAgAAAE5pAAAAACgBAAAAdQEA\nAABmKAIAAAB1AQAAAHZ1AQAAAGsoAAAAACgAAAAAdSQAAAAuLi9yZXNvdXJjZXMvcHJpdmF0ZS9p\nbmRlcGVuZGVuY2UucHl1CwAAAF9fZ2V0aXRlbV9fCQAAAHMAAAAAdRAAAABfVmVjLl9fZ2V0aXRl\nbV9fYwMAAAAAAAAAAwAAAAQAAABDAAAAcxUAAAB0AAAEfAAAagEAfAEAPH0CAGQAAFMoAQAAAE4o\nAgAAAHUIAAAAX3NldGl0ZW11AQAAAGYoAwAAAHUBAAAAdnUBAAAAa3UDAAAAdmFsKAAAAAAoAAAA\nAHUkAAAALi4vcmVzb3VyY2VzL3ByaXZhdGUvaW5kZXBlbmRlbmNlLnB5dQsAAABfX3NldGl0ZW1f\nXwoAAABzAAAAAHUQAAAAX1ZlYy5fX3NldGl0ZW1fX2MBAAAAAAAAAAEAAAACAAAAQwAAAHMIAAAA\nZAIAfAAAFFMoAwAAAE5pAQAAAGn/////KAAAAAAoAQAAAHUBAAAAdigAAAAAKAAAAAB1JAAAAC4u\nL3Jlc291cmNlcy9wcml2YXRlL2luZGVwZW5kZW5jZS5weXUHAAAAX19uZWdfXwsAAABzAAAAAHUM\nAAAAX1ZlYy5fX25lZ19fYwIAAAAAAAAAAgAAAAUAAAADAAAAcywAAAB0AAB8AABqAQCHAABmAQBk\nAQBkAgCGAAB8AABqAgBqAwCDAABEgwEAgwIAUygDAAAATmMBAAAAAAAAAAMAAAAEAAAAEwAAAHMj\nAAAAaQAAfAAAXRkAXAIAfQEAfQIAiAAAfAIAFHwBAJMCAHEGAFMoAAAAACgAAAAAKAMAAAB1AgAA\nAC4wdQEAAABrdQEAAAB4KAEAAAB1BQAAAGFscGhhKAAAAAB1JAAAAC4uL3Jlc291cmNlcy9wcml2\nYXRlL2luZGVwZW5kZW5jZS5weXUKAAAAPGRpY3Rjb21wPgwAAABzAgAAAAkAdSEAAABfVmVjLl9f\ncm11bF9fLjxsb2NhbHM+LjxkaWN0Y29tcD4oBAAAAHUEAAAAX1ZlY3UBAAAARHUBAAAAZnUFAAAA\naXRlbXMoAgAAAHUBAAAAdnUFAAAAYWxwaGEoAAAAACgBAAAAdQUAAABhbHBoYXUkAAAALi4vcmVz\nb3VyY2VzL3ByaXZhdGUvaW5kZXBlbmRlbmNlLnB5dQgAAABfX3JtdWxfXwwAAABzAAAAAHUNAAAA\nX1ZlYy5fX3JtdWxfX2MCAAAAAAAAAAIAAAAEAAAAAwAAAHNAAAAAdAAAiAAAdAEAgwIAcjgAdAIA\nhwAAhwEAZgIAZAEAZAIAhgAAiAEAagMAagQAgwAARIMBAIMBAFN0BQBTZAAAUygDAAAATmMBAAAA\nAAAAAAIAAAAFAAAAEwAAAHMiAAAAZwAAfAAAXRgAfQEAiAEAfAEAGYgAAHwBABkUkQIAcQYAUygA\nAAAAKAAAAAAoAgAAAHUCAAAALjB1AQAAAGsoAgAAAHUFAAAAb3RoZXJ1BAAAAHNlbGYoAAAAAHUk\nAAAALi4vcmVzb3VyY2VzL3ByaXZhdGUvaW5kZXBlbmRlbmNlLnB5dQoAAAA8bGlzdGNvbXA+EQAA\nAHMCAAAACQB1IAAAAF9WZWMuX19tdWxfXy48bG9jYWxzPi48bGlzdGNvbXA+KAYAAAB1CgAAAGlz\naW5zdGFuY2V1BAAAAF9WZWN1AwAAAHN1bXUBAAAAZnUEAAAAa2V5c3UOAAAATm90SW1wbGVtZW50\nZWQoAgAAAHUEAAAAc2VsZnUFAAAAb3RoZXIoAAAAACgCAAAAdQUAAABvdGhlcnUEAAAAc2VsZnUk\nAAAALi4vcmVzb3VyY2VzL3ByaXZhdGUvaW5kZXBlbmRlbmNlLnB5dQcAAABfX211bF9fDgAAAHMG\nAAAAAAIPASkCdQwAAABfVmVjLl9fbXVsX19jAgAAAAAAAAACAAAABQAAAAMAAABzRwAAAHQAAIgA\nAGoBAIcAAIcBAGYCAGQBAGQCAIYAAHQCAIgAAGoDAGoEAIMAAIMBAGoFAIgBAGoDAGoEAIMAAIMB\nAESDAQCDAgBTKAMAAABOYwEAAAAAAAAAAgAAAAUAAAATAAAAcyUAAABpAAB8AABdGwB9AQCIAAB8\nAQAZiAEAfAEAGRd8AQCTAgBxBgBTKAAAAAAoAAAAACgCAAAAdQIAAAAuMHUBAAAAaygCAAAAdQEA\nAAB1dQEAAAB2KAAAAAB1JAAAAC4uL3Jlc291cmNlcy9wcml2YXRlL2luZGVwZW5kZW5jZS5weXUK\nAAAAPGRpY3Rjb21wPhUAAABzAgAAAAkAdSAAAABfVmVjLl9fYWRkX18uPGxvY2Fscz4uPGRpY3Rj\nb21wPigGAAAAdQQAAABfVmVjdQEAAABEdQMAAABzZXR1AQAAAGZ1BAAAAGtleXN1BQAAAHVuaW9u\nKAIAAAB1AQAAAHV1AQAAAHYoAAAAACgCAAAAdQEAAAB1dQEAAAB2dSQAAAAuLi9yZXNvdXJjZXMv\ncHJpdmF0ZS9pbmRlcGVuZGVuY2UucHl1BwAAAF9fYWRkX18VAAAAcwAAAAB1DAAAAF9WZWMuX19h\nZGRfX2MCAAAAAAAAAAIAAAACAAAAQwAAAHMJAAAAfAAAfAEACxdTKAEAAAB1NAAAAFJldHVybnMg\nYSB2ZWN0b3Igd2hpY2ggaXMgdGhlIGRpZmZlcmVuY2Ugb2YgYSBhbmQgYi4oAAAAACgCAAAAdQEA\nAABhdQEAAABiKAAAAAAoAAAAAHUkAAAALi4vcmVzb3VyY2VzL3ByaXZhdGUvaW5kZXBlbmRlbmNl\nLnB5dQcAAABfX3N1Yl9fFwAAAHMCAAAAAAJ1DAAAAF9WZWMuX19zdWJfX04oDAAAAHUIAAAAX19u\nYW1lX191CgAAAF9fbW9kdWxlX191DAAAAF9fcXVhbG5hbWVfX3UDAAAAc2V0dQgAAABfX2luaXRf\nX3ULAAAAX19nZXRpdGVtX191CwAAAF9fc2V0aXRlbV9fdQcAAABfX25lZ19fdQgAAABfX3JtdWxf\nX3UHAAAAX19tdWxfX3UHAAAAX19hZGRfX3UHAAAAX19zdWJfXygBAAAAdQoAAABfX2xvY2Fsc19f\nKAAAAAAoAAAAAHUkAAAALi4vcmVzb3VyY2VzL3ByaXZhdGUvaW5kZXBlbmRlbmNlLnB5dQQAAABf\nVmVjBAAAAHMQAAAAEAEVBAwBDAEMAQwCDAcMAnUEAAAAX1ZlY2ebK6GGm4QGPWMCAAAAAAAAAAUA\nAAAGAAAAQwAAAHNsAAAAZwAAfQIAeFkAfAAARF1RAH0DAHgoAHwCAERdIAB9BAB8AwB8AwB8BAAU\nfAQAfAQAFBt8BAAUGH0DAHEaAFd8AwB8AwAUfAEAawQAcg0AfAIAagAAfAMAgwEAAXENAHENAFd0\nAQB8AgCDAQBTKAEAAABOKAIAAAB1BgAAAGFwcGVuZHUDAAAAbGVuKAUAAAB1AQAAAEx1AwAAAGVw\nc3UJAAAAdnN0YXJsaXN0dQEAAAB2dQUAAAB2c3RhcigAAAAAKAAAAAB1JAAAAC4uL3Jlc291cmNl\ncy9wcml2YXRlL2luZGVwZW5kZW5jZS5weXUHAAAAX1JfcmFuaxsAAABzDgAAAAABBgENAQ0BHgEQ\nABQBdQcAAABfUl9yYW5rYwEAAAAAAAAABgAAAAUAAAADAAAAc7cAAAB0AAB0AQB0AgCIAQCDAQCD\nAQCDAQB9AQBkAQB9AgB4kgCIAQBkAQAZagMARF2DAIkAAIcAAIcBAGYCAGQCAGQDAIYAAHwBAESD\nAQB9AwB8AwBnAABrAwByLAB8AwBkAQAZfQQAfAEAagQAfAQAgwEAAXwCAGQEADd9AgB4MQB8AwBk\nBABkAACFAgAZRF0cAH0FAIgBAHwFABmIAQB8BAAZF4gBAHwFADxxjABXcSwAcSwAV3wCAFMoBQAA\nAE5pAAAAAGMBAAAAAAAAAAIAAAAEAAAAEwAAAHMqAAAAZwAAfAAAXSAAfQEAiAEAfAEAGYgAABlk\nAABrAwByBgB8AQCRAgBxBgBTKAEAAABpAAAAACgAAAAAKAIAAAB1AgAAAC4wdQEAAAByKAIAAAB1\nAQAAAGN1BwAAAHJvd2xpc3QoAAAAAHUkAAAALi4vcmVzb3VyY2VzL3ByaXZhdGUvaW5kZXBlbmRl\nbmNlLnB5dQoAAAA8bGlzdGNvbXA+JwAAAHMCAAAACQB1HQAAAF9HRjJfcmFuay48bG9jYWxzPi48\nbGlzdGNvbXA+aQEAAAAoBQAAAHUDAAAAc2V0dQUAAAByYW5nZXUDAAAAbGVudQEAAABEdQYAAABy\nZW1vdmUoBgAAAHUHAAAAcm93bGlzdHUJAAAAcm93c19sZWZ0dQEAAABydREAAAByb3dzX3dpdGhf\nbm9uemVyb3UFAAAAcGl2b3R1CQAAAHJvd19pbmRleCgAAAAAKAIAAAB1AQAAAGN1BwAAAHJvd2xp\nc3R1JAAAAC4uL3Jlc291cmNlcy9wcml2YXRlL2luZGVwZW5kZW5jZS5weXUJAAAAX0dGMl9yYW5r\nIwAAAHMWAAAAAAEYAQYBFAEcAQwBCgENAQoBFwEhAXUJAAAAX0dGMl9yYW5rYwEAAAAAAAAABAAA\nAAUAAABDAAAAc3QAAABkAQBkAgCEAAB8AABEgwEAfQEAeFoAfAAARF1SAH0CAHhJAHwCAGoAAGoB\nAIMAAERdOAB9AwB8AwBkAwBrAwByMAB0AgB8AwB0AwBqBACDAgByXgB0BQB8AQCDAQBTdAYAfAEA\ngwEAU3EwAFdxGgBXZAMAUygEAAAATmMBAAAAAAAAAAIAAAAFAAAAUwAAAHMlAAAAZwAAfAAAXRsA\nfQEAdAAAfAEAagEAfAEAagIAgwIAkQIAcQYAUygAAAAAKAMAAAB1BAAAAF9WZWN1AQAAAER1AQAA\nAGYoAgAAAHUCAAAALjB1AQAAAHUoAAAAACgAAAAAdSQAAAAuLi9yZXNvdXJjZXMvcHJpdmF0ZS9p\nbmRlcGVuZGVuY2UucHl1CgAAADxsaXN0Y29tcD4xAAAAcwIAAAAJAHUZAAAAX3JhbmsuPGxvY2Fs\ncz4uPGxpc3Rjb21wPmkAAAAAKAcAAAB1AQAAAGZ1BgAAAHZhbHVlc3UKAAAAaXNpbnN0YW5jZXUD\nAAAAR0YydQMAAABPbmV1CQAAAF9HRjJfcmFua3UHAAAAX1JfcmFuaygEAAAAdQEAAABMdQIAAABM\nY3UBAAAAdnUBAAAAeCgAAAAAKAAAAAB1JAAAAC4uL3Jlc291cmNlcy9wcml2YXRlL2luZGVwZW5k\nZW5jZS5weXUFAAAAX3JhbmswAAAAcxAAAAAAARMBDQEWAQwBEgEKARIBdQUAAABfcmFua2MBAAAA\nAAAAAAEAAAADAAAAQwAAAHMZAAAAdAAABGoBAGQBADcCXwEAdAIAfAAAgwEAUygCAAAATmkBAAAA\nKAMAAAB1BAAAAHJhbmt1CQAAAF9fY2FsbHNfX3UFAAAAX3JhbmsoAQAAAHUBAAAATCgAAAAAKAAA\nAAB1JAAAAC4uL3Jlc291cmNlcy9wcml2YXRlL2luZGVwZW5kZW5jZS5weXUEAAAAcmFuazoAAABz\nBAAAAAABDwF1BAAAAHJhbmtjAQAAAAAAAAABAAAAAwAAAEMAAABzJQAAAHQAAARqAQBkAQA3Al8B\nAHQCAHwAAIMBAHQDAHwAAIMBAGsCAFMoAgAAAE5pAQAAACgEAAAAdQ4AAABpc19pbmRlcGVuZGVu\ndHUJAAAAX19jYWxsc19fdQUAAABfcmFua3UDAAAAbGVuKAEAAAB1AQAAAEwoAAAAACgAAAAAdSQA\nAAAuLi9yZXNvdXJjZXMvcHJpdmF0ZS9pbmRlcGVuZGVuY2UucHl1DgAAAGlzX2luZGVwZW5kZW50\nPgAAAHMEAAAAAAEPAXUOAAAAaXNfaW5kZXBlbmRlbnR1DAAAAGluc3RydW1lbnRlZCgJAAAAdQMA\nAABHRjJ1BAAAAF9WZWN1BwAAAF9SX3Jhbmt1CQAAAF9HRjJfcmFua3UFAAAAX3Jhbmt1BAAAAHJh\nbmt1DgAAAGlzX2luZGVwZW5kZW50dQkAAABfX2NhbGxzX191CwAAAF9fdmVyc2lvbl9fKAAAAAAo\nAAAAACgAAAAAdSQAAAAuLi9yZXNvdXJjZXMvcHJpdmF0ZS9pbmRlcGVuZGVuY2UucHl1CAAAADxt\nb2R1bGU+AgAAAHMUAAAADAITFw8IDA0MCgwEDAQJAQkBCQE=\n'
        offset = 12
    elif magic == b'\xee\x0c\r\n': # Python 3.4
        pycData = b'7gwNCrTAR1QuCAAA4wAAAAAAAAAAAAAAAAMAAABAAAAAc4YAAABkAABkAQBsAABaAABHZAIAZAMA\nhAAAZAMAgwIAWgEAZAQAZAUAZAYAhAEAWgIAZAcAZAgAhAAAWgMAZAkAZAoAhAAAWgQAZAsAZAwA\nhAAAWgUAZA0AZA4AhAAAWgYAZAAAZQUAXwcAZA8AZQUAXwgAZAAAZQYAXwcAZA8AZQYAXwgAZAEA\nUykQ6QAAAABOYwAAAAAAAAAAAAAAAAQAAABAAAAAc3kAAABlAABaAQBkAABaAgBlAwCDAABpAABk\nAQBkAgCEAgBaBABkAwBkBACEAABaBQBkBQBkBgCEAABaBgBkBwBkCACEAABaBwBkCQBkCgCEAABa\nCABkCwBkDACEAABaCQBkDQBkDgCEAABaCgBkDwBkEACEAABaCwBkEQBTKRLaBF9WZWNjAwAAAAAA\nAAADAAAAAgAAAEMAAABzFgAAAHwBAHwAAF8AAHwCAHwAAF8BAGQAAFMpAU4pAtoBRNoBZikD2gRz\nZWxmWgZsYWJlbHNaCGZ1bmN0aW9uqQByBgAAAPokLi4vcmVzb3VyY2VzL3ByaXZhdGUvaW5kZXBl\nbmRlbmNlLnB52ghfX2luaXRfXwUAAABzBAAAAAABCQF6DV9WZWMuX19pbml0X19jAgAAAAAAAAAC\nAAAAAgAAAEMAAABzHgAAAHwBAHwAAGoAAGsGAHIaAHwAAGoAAHwBABlTZAEAUykCTnIBAAAAKQFy\nBAAAACkC2gF22gFrcgYAAAByBgAAAHIHAAAA2gtfX2dldGl0ZW1fXwkAAABzAAAAAHoQX1ZlYy5f\nX2dldGl0ZW1fX2MDAAAAAAAAAAMAAAAEAAAAQwAAAHMVAAAAdAAABHwAAGoBAHwBADx9AgBkAABT\nKQFOKQJaCF9zZXRpdGVtcgQAAAApA3IJAAAAcgoAAADaA3ZhbHIGAAAAcgYAAAByBwAAANoLX19z\nZXRpdGVtX18KAAAAcwAAAAB6EF9WZWMuX19zZXRpdGVtX19jAQAAAAAAAAABAAAAAgAAAEMAAABz\nCAAAAGQCAHwAABRTKQNO6QEAAADp/////3IGAAAAKQFyCQAAAHIGAAAAcgYAAAByBwAAANoHX19u\nZWdfXwsAAABzAAAAAHoMX1ZlYy5fX25lZ19fYwIAAAAAAAAAAgAAAAUAAAADAAAAcywAAAB0AAB8\n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\nFAAAAAwCExcPCAwNDAoMBAwECQEJAQkB\n'
        offset = 12
    else:
        raise ImportError("Unsupported Python version")

    pycData = base64.decodebytes(pycData)

    assert pycData[:4] == magic, "Bad magic number"

    try:
        return marshal.loads(pycData[offset:])
    except ValueError:
        raise ImportError("Could not read .pyc data")
Exemplo n.º 30
0
    def _compile(self, filename, source):
        """ Compiles the Python source code to a code object and
        attempts to write it to an appropriate .pyc file.  May raise
        SyntaxError or other errors generated by the compiler. """
        
        if source and source[-1] != '\n':
            source = source + '\n'
        code = __builtin__.compile(source, filename.toOsSpecific(), 'exec')

        # try to cache the compiled code
        pycFilename = Filename(filename)
        pycFilename.setExtension(compiledExtensions[0])
        try:
            f = open(pycFilename.toOsSpecific(), 'wb')
        except IOError:
            pass
        else:
            f.write('\0\0\0\0')
            f.write(chr(self.timestamp & 0xff) +
                    chr((self.timestamp >> 8) & 0xff) +
                    chr((self.timestamp >> 16) & 0xff) +
                    chr((self.timestamp >> 24) & 0xff))
            f.write(marshal.dumps(code))
            f.flush()
            f.seek(0, 0)
            f.write(imp.get_magic())
            f.close()

        return code
Exemplo n.º 31
0
    def _WriteModules(self, fileName, finder):
        for module in self.constantsModules:
            module.Create(finder)
        modules = [m for m in finder.modules \
                if m.name not in self.excludeModules]
        modules.sort(key=lambda m: m.name)

        if not self.silent:
            self._PrintReport(fileName, modules)
        finder.ReportMissingModules()

        targetDir = os.path.dirname(fileName)
        self._CreateDirectory(targetDir)

        # Prepare zip file
        outFile = zipfile.PyZipFile(fileName, "w", zipfile.ZIP_DEFLATED)

        filesToCopy = []
        magic = imp.get_magic()
        ignorePatterns = shutil.ignore_patterns("*.py", "*.pyc", "*.pyo",
                                                "__pycache__")
        for module in modules:

            # determine if the module should be written to the file system;
            # a number of packages make the assumption that files that they
            # require will be found in a location relative to where
            # they are located on disk; these packages will fail with strange
            # errors when they are written to a zip file instead
            includeInFileSystem = self._ShouldIncludeInFileSystem(module)

            # if the module refers to a package, check to see if this package
            # should be included in the zip file or should be written to the
            # file system; if the package should be written to the file system,
            # any non-Python files are copied at this point if the target
            # directory does not already exist
            if module.path is not None and includeInFileSystem:
                parts = module.name.split(".")
                targetPackageDir = os.path.join(targetDir, *parts)
                sourcePackageDir = os.path.dirname(module.file)
                if not os.path.exists(targetPackageDir):
                    print("Copying data from package", module.name + "...")
                    shutil.copytree(sourcePackageDir,
                                    targetPackageDir,
                                    ignore=ignorePatterns)

            # if an extension module is found in a package that is to be
            # included in a zip file, save a Python loader in the zip file and
            # copy the actual file to the build directory because shared
            # libraries cannot be loaded from a zip file
            if module.code is None and module.file is not None \
                    and not includeInFileSystem:
                fileName = os.path.basename(module.file)
                if "." in module.name:
                    baseFileName, ext = os.path.splitext(fileName)
                    fileName = module.name + ext
                    generatedFileName = "ExtensionLoader_%s.py" % \
                            module.name.replace(".", "_")
                    module.code = compile(EXTENSION_LOADER_SOURCE % fileName,
                                          generatedFileName, "exec")
                target = os.path.join(targetDir, fileName)
                filesToCopy.append((module, target))

            # starting with Python 3.3 the pyc file format contains the source
            # size; it is not actually used for anything except determining if
            # the file is up to date so we can safely set this value to zero
            if module.code is not None:
                if module.file is not None and os.path.exists(module.file):
                    mtime = os.stat(module.file).st_mtime
                else:
                    mtime = time.time()
                if sys.version_info[:2] < (3, 3):
                    header = magic + struct.pack("<i", int(mtime))
                else:
                    header = magic + struct.pack("<ii", int(mtime), 0)
                data = header + marshal.dumps(module.code)

            # if the module should be written to the file system, do so
            if includeInFileSystem:
                parts = module.name.split(".")
                if module.code is None:
                    parts.pop()
                    parts.append(os.path.basename(module.file))
                    targetName = os.path.join(targetDir, *parts)
                    self._CopyFile(module.file,
                                   targetName,
                                   copyDependentFiles=True)
                else:
                    if module.path is not None:
                        parts.append("__init__")
                    targetName = os.path.join(targetDir, *parts) + ".pyc"
                    open(targetName, "wb").write(data)

            # otherwise, write to the zip file
            elif module.code is not None:
                zipTime = time.localtime(mtime)[:6]
                fileName = "/".join(module.name.split("."))
                if module.path:
                    fileName += "/__init__"
                zinfo = zipfile.ZipInfo(fileName + ".pyc", zipTime)
                if self.compress:
                    zinfo.compress_type = zipfile.ZIP_DEFLATED
                outFile.writestr(zinfo, data)

        # write any files to the zip file that were requested specially
        for sourceFileName, targetFileName in self.zipIncludes:
            outFile.write(sourceFileName, targetFileName)

        outFile.close()

        # Copy Python extension modules from the list built above.
        origPath = os.environ["PATH"]
        for module, target in filesToCopy:
            try:
                if module.parent is not None:
                    path = os.pathsep.join([origPath] + module.parent.path)
                    os.environ["PATH"] = path
                self._CopyFile(module.file, target, copyDependentFiles=True)
            finally:
                os.environ["PATH"] = origPath
Exemplo n.º 32
0
def _reduce_code(code):
    """
    Reduce a code object to picklable components.
    """
    return marshal.version, imp.get_magic(), marshal.dumps(code)
Exemplo n.º 33
0
#
# get loader

loader = getloader(data, zlib, package)

if zlib:
    zbegin, zend = "zlib.decompress(", ")"
    zimport = 'try:import zlib\n'\
        'except:raise RuntimeError,"requires zlib"\n'
    loader = zlib.compress(loader, 9)
else:
    zbegin = zend = zimport = ""

loaderlen = len(loader)

magic = repr(imp.get_magic())
version = string.split(sys.version)[0]

magictest = 'import imp\n'\
    's="requires python %s or bytecode compatible"\n'\
    'if imp.get_magic()!=%s:raise RuntimeError,s' % (version, magic)

#
# generate script and package files

if embed:

    # embedded archive
    data = base64.encodestring(loader + package)

    fp = open(bootstrap, "w")
Exemplo n.º 34
0
 def test_mtime(self):
     # Test a change in mtime leads to a new .pyc.
     self.recreation_check(struct.pack('<4sl', imp.get_magic(), 1))
Exemplo n.º 35
0
    def __init__(self, f):
        self.filename = "unknown"
        self.last_error = None
        self.key_to_events = {}
        if hasattr(f, "readline"):
            fp = f
            self.filename = "<config string>"
            compiled_name = None
        else:
            try:
                f = find_config_file(f)
                src_stat = os.stat(f)
            except os.error:
                self.report_error("Config file '%s' not found" % f)
                return
            self.filename = f
            self.basename = os.path.basename(f)
            trace("Loading configuration", self.basename)
            compiled_name = os.path.splitext(f)[0] + ".cfc"
            try:
                cf = open(compiled_name, "rb")
                try:
                    ver = marshal.load(cf)
                    ok = compiled_config_version == ver
                    if ok:
                        magic = marshal.load(cf)
                        size = marshal.load(cf)
                        mtime = marshal.load(cf)
                        if magic == imp.get_magic() and \
                           src_stat[stat.ST_MTIME] == mtime and \
                           src_stat[stat.ST_SIZE] == size:
                            self.cache = marshal.load(cf)
                            trace("Configuration loaded cached", compiled_name)
                            return  # We are ready to roll!
                finally:
                    cf.close()
            except (os.error, IOError, EOFError):
                pass
            fp = open(f)
        self.cache = {}
        lineno = 1
        line = fp.readline()
        while line:
            # Skip to the next section (maybe already there!)
            section, subsection = get_section_header(line)
            while line and section is None:
                line = fp.readline()
                if not line: break
                lineno = lineno + 1
                section, subsection = get_section_header(line)
            if not line: break

            if section == "keys":
                line, lineno = self._load_keys(subsection, fp, lineno)
            elif section == "extensions":
                line, lineno = self._load_extensions(subsection, fp, lineno)
            elif section == "idle extensions":
                line, lineno = self._load_idle_extensions(
                    subsection, fp, lineno)
            elif section == "general":
                line, lineno = self._load_general(subsection, fp, lineno)
            else:
                self.report_error("Unrecognised section header '%s:%s'" %
                                  (section, subsection))
                line = fp.readline()
                lineno = lineno + 1
        # Check critical data.
        if not self.cache.get("keys"):
            self.report_error("No keyboard definitions were loaded")
        if not self.last_error and compiled_name:
            try:
                cf = open(compiled_name, "wb")
                marshal.dump(compiled_config_version, cf)
                marshal.dump(imp.get_magic(), cf)
                marshal.dump(src_stat[stat.ST_SIZE], cf)
                marshal.dump(src_stat[stat.ST_MTIME], cf)
                marshal.dump(self.cache, cf)
                cf.close()
            except (IOError, EOFError):
                pass  # Ignore errors - may be read only.
Exemplo n.º 36
0
def __by_version(magics):
    for m, v in list(magics.items()):
        if m not in by_magic:
            by_magic[m] = set([v])
        else:
            by_magic[m].add(v)
        by_version[v] = m
    return by_version

# Documentation for the below variables is above.
by_magic = {}
by_version = {}
magicint2version = {}
versions = {}
PYTHON_MAGIC_INT = magic2int(imp.get_magic())

# The magic word is used to reject .pyc files generated by other
# Python versions.  It should change for each incompatible change to
# the bytecode.
#
# The value of CR and LF is incorporated so if you ever read or write
# a .pyc file in text mode the magic number will be wrong; also, the
# Apple MPW compiler swaps their values, botching string constants.
#
# The magic numbers must be spaced apart at least 2 values, as the
# -U interpeter flag will cause MAGIC+1 being used. They have been
# odd numbers for some time now.
#
# There were a variety of old schemes for setting the magic number.
# The current working scheme is to increment the previous value by
Exemplo n.º 37
0
def __current_magic():
    """Current Python magic number."""
    return imp.get_magic()
Exemplo n.º 38
0
    def _LoadModule(self,
                    name,
                    fp,
                    path,
                    info,
                    deferredImports,
                    parent=None,
                    namespace=False):
        """Load the module, given the information acquired by the finder."""
        suffix, mode, type = info
        if type == imp.PKG_DIRECTORY:
            return self._LoadPackage(name, path, parent, deferredImports,
                                     namespace)
        module = self._AddModule(name)
        module.file = path
        module.parent = parent

        if type == imp.PY_SOURCE:
            logging.debug("Adding module [%s] [PY_SOURCE]", name)
            # Load & compile Python source code
            if sys.version_info[0] >= 3:
                # For Python 3, read the file with the correct encoding
                import tokenize
                fp = open(path, "rb")
                encoding, lines = tokenize.detect_encoding(fp.readline)
                fp = open(path, "U", encoding=encoding)
            codeString = fp.read()
            if codeString and codeString[-1] != "\n":
                codeString = codeString + "\n"
            try:
                module.code = compile(codeString, path, "exec")
            except SyntaxError:
                raise ImportError("Invalid syntax in %s" % path)

        elif type == imp.PY_COMPILED:
            logging.debug("Adding module [%s] [PY_COMPILED]", name)
            # Load Python bytecode
            if isinstance(fp, bytes):
                magic = fp[:4]
            else:
                magic = fp.read(4)
            if magic != imp.get_magic():
                raise ImportError("Bad magic number in %s" % path)
            skip_bytes = 8 if (sys.version_info[:2] >= (3, 3)) else 4
            if isinstance(fp, bytes):
                module.code = marshal.loads(fp[skip_bytes + 4:])
                module.inZipFile = True
            else:
                fp.read(skip_bytes)
                module.code = marshal.load(fp)

        elif type == imp.C_EXTENSION:
            logging.debug("Adding module [%s] [C_EXTENSION]", name)
            if parent is None:
                # Our extension loader (see the freezer module) uses imp to
                # load compiled extensions.
                self.IncludeModule("imp")

        # If there's a custom hook for this module, run it.
        self._RunHook("load", module.name, module)

        if module.code is not None:
            if self.replacePaths:
                topLevelModule = module
                while topLevelModule.parent is not None:
                    topLevelModule = topLevelModule.parent
                module.code = self._ReplacePathsInCode(topLevelModule,
                                                       module.code)

            # Scan the module code for import statements
            self._ScanCode(module.code, module, deferredImports)

        module.inImport = False
        return module
Exemplo n.º 39
0
    def compile_templates(self,
                          target,
                          extensions=None,
                          filter_func=None,
                          zip='deflated',
                          log_function=None,
                          ignore_errors=True,
                          py_compile=False):
        """Finds all the templates the loader can find, compiles them
        and stores them in `target`.  If `zip` is `None`, instead of in a
        zipfile, the templates will be stored in a directory.
        By default a deflate zip algorithm is used. To switch to
        the stored algorithm, `zip` can be set to ``'stored'``.

        `extensions` and `filter_func` are passed to :meth:`list_templates`.
        Each template returned will be compiled to the target folder or
        zipfile.

        By default template compilation errors are ignored.  In case a
        log function is provided, errors are logged.  If you want template
        syntax errors to abort the compilation you can set `ignore_errors`
        to `False` and you will get an exception on syntax errors.

        If `py_compile` is set to `True` .pyc files will be written to the
        target instead of standard .py files.  This flag does not do anything
        on pypy and Python 3 where pyc files are not picked up by itself and
        don't give much benefit.

        .. versionadded:: 2.4
        """
        from jinja2.loaders import ModuleLoader

        if log_function is None:
            log_function = lambda x: None

        if py_compile:
            if not PY2 or PYPY:
                from warnings import warn
                warn(Warning('py_compile has no effect on pypy or Python 3'))
                py_compile = False
            else:
                import imp
                import marshal
                py_header = imp.get_magic() + \
                    u'\xff\xff\xff\xff'.encode('iso-8859-15')

                # Python 3.3 added a source filesize to the header
                if sys.version_info >= (3, 3):
                    py_header += u'\x00\x00\x00\x00'.encode('iso-8859-15')

        def write_file(filename, data, mode):
            if zip:
                info = ZipInfo(filename)
                info.external_attr = 0o755 << 16
                zip_file.writestr(info, data)
            else:
                f = open(os.path.join(target, filename), mode)
                try:
                    f.write(data)
                finally:
                    f.close()

        if zip is not None:
            from zipfile import ZipFile, ZipInfo, ZIP_DEFLATED, ZIP_STORED
            zip_file = ZipFile(
                target, 'w',
                dict(deflated=ZIP_DEFLATED, stored=ZIP_STORED)[zip])
            log_function('Compiling into Zip archive "%s"' % target)
        else:
            if not os.path.isdir(target):
                os.makedirs(target)
            log_function('Compiling into folder "%s"' % target)

        try:
            for name in self.list_templates(extensions, filter_func):
                source, filename, _ = self.loader.get_source(self, name)
                try:
                    code = self.compile(source, name, filename, True, True)
                except TemplateSyntaxError as e:
                    if not ignore_errors:
                        raise
                    log_function('Could not compile "%s": %s' % (name, e))
                    continue

                filename = ModuleLoader.get_module_filename(name)

                if py_compile:
                    c = self._compile(code, encode_filename(filename))
                    write_file(filename + 'c', py_header + marshal.dumps(c),
                               'wb')
                    log_function('Byte-compiled "%s" as %s' %
                                 (name, filename + 'c'))
                else:
                    write_file(filename, code, 'w')
                    log_function('Compiled "%s" as %s' % (name, filename))
        finally:
            if zip:
                zip_file.close()

        log_function('Finished compiling templates')
Exemplo n.º 40
0
def compile_file(fullname,
                 ddir=None,
                 force=False,
                 rx=None,
                 quiet=False,
                 legacy=False,
                 optimize=-1):
    """Byte-compile one file.

    Arguments (only fullname is required):

    fullname:  the file to byte-compile
    ddir:      if given, the directory name compiled in to the
               byte-code file.
    force:     if True, force compilation, even if timestamps are up-to-date
    quiet:     if True, be quiet during compilation
    legacy:    if True, produce legacy pyc paths instead of PEP 3147 paths
    optimize:  optimization level or -1 for level of the interpreter
    """
    success = 1
    name = os.path.basename(fullname)
    if ddir is not None:
        dfile = os.path.join(ddir, name)
    else:
        dfile = None
    if rx is not None:
        mo = rx.search(fullname)
        if mo:
            return success
    if os.path.isfile(fullname):
        if legacy:
            cfile = fullname + ('c' if __debug__ else 'o')
        else:
            if optimize >= 0:
                cfile = imp.cache_from_source(fullname,
                                              debug_override=not optimize)
            else:
                cfile = imp.cache_from_source(fullname)
            cache_dir = os.path.dirname(cfile)
        head, tail = name[:-3], name[-3:]
        if tail == '.py':
            if not force:
                try:
                    mtime = int(os.stat(fullname).st_mtime)
                    expect = struct.pack('<4sl', imp.get_magic(), mtime)
                    with open(cfile, 'rb') as chandle:
                        actual = chandle.read(8)
                    if expect == actual:
                        return success
                except IOError:
                    pass
            if not quiet:
                print('Compiling {!r}...'.format(fullname))
            try:
                ok = py_compile.compile(fullname,
                                        cfile,
                                        dfile,
                                        True,
                                        optimize=optimize)
            except py_compile.PyCompileError as err:
                if quiet:
                    print('*** Error compiling {!r}...'.format(fullname))
                else:
                    print('*** ', end='')
                # escape non-printable characters in msg
                msg = err.msg.encode(sys.stdout.encoding,
                                     errors='backslashreplace')
                msg = msg.decode(sys.stdout.encoding)
                print(msg)
                success = 0
            except (SyntaxError, UnicodeError, IOError) as e:
                if quiet:
                    print('*** Error compiling {!r}...'.format(fullname))
                else:
                    print('*** ', end='')
                print(e.__class__.__name__ + ':', e)
                success = 0
            else:
                if ok == 0:
                    success = 0
    return success
Exemplo n.º 41
0
def load_module_from_file_object(fp,
                                 filename='<unknown>',
                                 code_objects=None,
                                 fast_load=False,
                                 get_code=True):
    """load a module from a file object without importing it.

    See :func:load_module for a list of return values.
    """

    if code_objects is None:
        code_objects = {}

    timestamp = 0
    try:
        magic = fp.read(4)
        magic_int = magics.magic2int(magic)

        # For reasons I don't understand, PyPy 3.2 stores a magic
        # of '0'...  The two values below are for Python 2.x and 3.x respectively
        if magic[0:1] in ['0', b'0']:
            magic = magics.int2magic(3180 + 7)

        try:
            # FIXME: use the internal routine below
            float_version = float(magics.versions[magic][:3])
            # float_version = magics.magic_int2float(magic_int)
        except KeyError:
            if magic_int in (2657, 22138):
                raise ImportError(
                    "This smells like Pyston which is not supported.")

            if len(magic) >= 2:
                raise ImportError(
                    "Unknown magic number %s in %s" %
                    (ord(magic[0:1]) + 256 * ord(magic[1:2]), filename))
            else:
                raise ImportError("Bad magic number: '%s'" % magic)

        if magic_int in (3010, 3020, 3030, 3040, 3050, 3060, 3061, 3361, 3371):
            raise ImportError(
                "%s is interim Python %s (%d) bytecode which is "
                "not supported.\nFinal released versions are "
                "supported." %
                (filename, magics.versions[magic], magics.magic2int(magic)))
        elif magic_int == 62135:
            fp.seek(0)
            return fix_dropbox_pyc(fp)
        elif magic_int == 62215:
            raise ImportError(
                "%s is a dropbox-hacked Python %s (bytecode %d).\n"
                "See https://github.com/kholia/dedrop for how to "
                "decrypt." %
                (filename, magics.versions[magic], magics.magic2int(magic)))

        try:
            # print version
            ts = fp.read(4)
            my_magic_int = magics.magic2int(imp.get_magic())
            magic_int = magics.magic2int(magic)

            if magic_int == 3393:
                timestamp = 0
                _ = unpack("<I", ts)[0]  # hash word 1
                _ = unpack("<I", fp.read(4))[0]  # hash word 2
            elif magic_int in (3394, 3401):
                timestamp = 0
                _ = unpack("<I", fp.read(4))[0]  # pep552_bits
            else:
                timestamp = unpack("<I", ts)[0]

            # Note: a higher magic number doesn't necessarily mean a later
            # release.  At Python 3.0 the magic number decreased
            # significantly. Hence the range below. Also note inclusion of
            # the size info, occurred within a Python major/minor
            # release. Hence the test on the magic value rather than
            # PYTHON_VERSION, although PYTHON_VERSION would probably work.
            if (((3200 <= magic_int < 20121) and
                 (magic_int not in (5892, 11913, 39170, 39171)))
                    or (magic_int in magics.IS_PYPY3)):

                source_size = unpack("<I", fp.read(4))[0]  # size mod 2**32
            else:
                source_size = None

            if get_code:
                if my_magic_int == magic_int:
                    bytecode = fp.read()
                    co = marshal.loads(bytecode)
                elif fast_load:
                    co = xdis.marsh.load(fp,
                                         magics.magicint2version[magic_int])
                else:
                    co = xdis.unmarshal.load_code(fp, magic_int, code_objects)
                pass
            else:
                co = None
        except:
            kind, msg = sys.exc_info()[0:2]
            import traceback
            traceback.print_exc()
            raise ImportError("Ill-formed bytecode file %s\n%s; %s" %
                              (filename, kind, msg))

    finally:
        fp.close()

    return float_version, timestamp, magic_int, co, is_pypy(
        magic_int), source_size
Exemplo n.º 42
0
    def _extractPyz(self, name):
        dirName =  name + '_extracted'
        # Create a directory for the contents of the pyz
        if not os.path.exists(dirName):
            os.mkdir(dirName)

        with open(name, 'rb') as f:
            pyzMagic = f.read(4)
            assert pyzMagic == b'PYZ\0' # Sanity Check

            pycHeader = f.read(4) # Python magic value

            if imp.get_magic() != pycHeader:
                print('[!] Warning: The script is running in a different python version than the one used to build the executable')
                print('    Run this script in Python{0} to prevent extraction errors(if any) during unmarshalling'.format(self.pyver))

            (tocPosition, ) = struct.unpack('!i', f.read(4))
            f.seek(tocPosition, os.SEEK_SET)

            try:
                toc = marshal.load(f)
            except:
                print('[!] Unmarshalling FAILED. Cannot extract {0}. Extracting remaining files.'.format(name))
                return

            print('[*] Found {0} files in PYZ archive'.format(len(toc)))

            # From pyinstaller 3.1+ toc is a list of tuples
            if type(toc) == list:
                toc = dict(toc)

            for key in toc.keys():
                (ispkg, pos, length) = toc[key]
                f.seek(pos, os.SEEK_SET)

                fileName = key
                try:
                    # for Python > 3.3 some keys are bytes object some are str object
                    fileName = key.decode('utf-8')
                except:
                    pass

                # Make sure destination directory exists, ensuring we keep inside dirName
                destName = os.path.join(dirName, fileName.replace("..", "__"))
                destDirName = os.path.dirname(destName)
                if not os.path.exists(destDirName):
                    os.makedirs(destDirName)

                try:
                    data = f.read(length)
                    data = zlib.decompress(data)
                except:
                    print('[!] Error: Failed to decompress {0}, probably encrypted. Extracting as is.'.format(fileName))
                    open(destName + '.pyc.encrypted', 'wb').write(data)
                    continue

                with open(destName + '.pyc', 'wb') as pycFile:
                    pycFile.write(pycHeader)      # Write pyc magic
                    pycFile.write(b'\0' * 4)      # Write timestamp
                    if self.pyver >= 33:
                        pycFile.write(b'\0' * 4)  # Size parameter added in Python 3.3
                    pycFile.write(data)
Exemplo n.º 43
0
def freeze(dist):
    """Freeze the given distribution data using py2app."""
    includes = dist.includes
    excludes = dist.excludes
    options = dist.freezer_options
    #  Merge in any includes/excludes given in freezer_options
    includes.append("esky")
    for inc in options.pop("includes", ()):
        includes.append(inc)
    for exc in options.pop("excludes", ()):
        excludes.append(exc)
    if "pypy" not in includes and "pypy" not in excludes:
        excludes.append("pypy")
    options["includes"] = includes
    options["excludes"] = excludes
    # The control info (name, icon, etc) for the app will be taken from
    # the first script in the list.  Subsequent scripts will be passed
    # as the extra_scripts argument.
    exes = list(dist.get_executables())
    if not exes:
        raise RuntimeError("no scripts specified")
    cmd = _make_py2app_cmd(dist.freeze_dir, dist.distribution, options, exes)
    cmd.run()
    #  Remove any .pyc files with a corresponding .py file.
    #  This helps avoid timestamp changes that might interfere with
    #  the generation of useful patches between versions.
    appnm = dist.distribution.get_name() + ".app"
    app_dir = os.path.join(dist.freeze_dir, appnm)
    resdir = os.path.join(app_dir, "Contents/Resources")
    for (dirnm, _, filenms) in os.walk(resdir):
        for nm in filenms:
            if nm.endswith(".pyc"):
                pyfile = os.path.join(dirnm, nm[:-1])
                if os.path.exists(pyfile):
                    os.unlink(pyfile + "c")
            if nm.endswith(".pyo"):
                pyfile = os.path.join(dirnm, nm[:-1])
                if os.path.exists(pyfile):
                    os.unlink(pyfile + "o")
    #  Copy data files into the freeze dir
    for (src, dst) in dist.get_data_files():
        dst = os.path.join(app_dir, "Contents", "Resources", dst)
        dstdir = os.path.dirname(dst)
        if not os.path.isdir(dstdir):
            dist.mkpath(dstdir)
        dist.copy_file(src, dst)
    #  Copy package data into site-packages.zip
    zfpath = os.path.join(cmd.lib_dir, get_zipfile(dist.distribution))
    lib = zipfile.ZipFile(zfpath, "a")
    for (src, arcnm) in dist.get_package_data():
        lib.write(src, arcnm)
    lib.close()
    #  Create the bootstraping code, using custom code if specified.
    esky_name = dist.distribution.get_name()
    code_source = ["__esky_name__ = %r" % (esky_name, )]
    code_source.append(inspect.getsource(esky.bootstrap))
    if not dist.compile_bootstrap_exes:
        code_source.append(_FAKE_ESKY_BOOTSTRAP_MODULE)
        code_source.append(_EXTRA_BOOTSTRAP_CODE)
    code_source.append(dist.get_bootstrap_code())
    code_source.append("if not __rpython__:")
    code_source.append("    bootstrap()")
    code_source = "\n".join(code_source)

    def copy_to_bootstrap_env(src, dst=None):
        if dst is None:
            dst = src
        src = os.path.join(appnm, src)
        dist.copy_to_bootstrap_env(src, dst)

    if dist.compile_bootstrap_exes:
        for exe in dist.get_executables(normalise=False):
            if not exe.include_in_bootstrap_env:
                continue
            relpath = os.path.join("Contents", "MacOS", exe.name)
            dist.compile_to_bootstrap_exe(exe, code_source, relpath)
    else:
        #  Copy the core dependencies into the bootstrap env.
        pydir = "python%d.%d" % sys.version_info[:2]
        for nm in (
                "Python.framework",
                "lib" + pydir + ".dylib",
        ):
            try:
                copy_to_bootstrap_env("Contents/Frameworks/" + nm)
            except Exception, e:
                #  Distutils does its own crazy exception-raising which I
                #  have no interest in examining right now.  Eventually this
                #  guard will be more conservative.
                pass
        copy_to_bootstrap_env("Contents/Resources/include")
        copy_to_bootstrap_env("Contents/Resources/lib/" + pydir + "/config")
        if "fcntl" not in sys.builtin_module_names:
            dynload = "Contents/Resources/lib/" + pydir + "/lib-dynload"
            for nm in os.listdir(os.path.join(app_dir, dynload)):
                if nm.startswith("fcntl"):
                    copy_to_bootstrap_env(os.path.join(dynload, nm))
        copy_to_bootstrap_env("Contents/Resources/__error__.sh")
        # Copy site.py/site.pyc into the boostrap env, then zero them out.
        bsdir = dist.bootstrap_dir
        if os.path.exists(os.path.join(app_dir, "Contents/Resources/site.py")):
            copy_to_bootstrap_env("Contents/Resources/site.py")
            with open(bsdir + "/Contents/Resources/site.py", "wt") as f:
                pass
        if os.path.exists(os.path.join(app_dir,
                                       "Contents/Resources/site.pyc")):
            copy_to_bootstrap_env("Contents/Resources/site.pyc")
            with open(bsdir + "/Contents/Resources/site.pyc", "wb") as f:
                f.write(imp.get_magic() + struct.pack("<i", 0))
                f.write(marshal.dumps(compile("", "site.py", "exec")))
        if os.path.exists(os.path.join(app_dir,
                                       "Contents/Resources/site.pyo")):
            copy_to_bootstrap_env("Contents/Resources/site.pyo")
            with open(bsdir + "/Contents/Resources/site.pyo", "wb") as f:
                f.write(imp.get_magic() + struct.pack("<i", 0))
        #  Copy the bootstrapping code into the __boot__.py file.
        copy_to_bootstrap_env("Contents/Resources/__boot__.py")
        with open(bsdir + "/Contents/Resources/__boot__.py", "wt") as f:
            f.write(code_source)
        #  Copy the loader program for each script into the bootstrap env.
        copy_to_bootstrap_env("Contents/MacOS/python")
        for exe in dist.get_executables(normalise=False):
            if not exe.include_in_bootstrap_env:
                continue
            exepath = copy_to_bootstrap_env("Contents/MacOS/" + exe.name)
Exemplo n.º 44
0
def recompile(filename):
    """Create a .pyc by disassembling the file and assembling it again, printing
    a message that the reassembled file was loaded."""
    # Most of the code here based on the compile.py module.
    import os
    import imp
    import marshal
    import struct
    try:
        from importlib.util import cache_from_source
    except ImportError:
        if python_version < '3':

            def cache_from_source(filename):
                return filename + 'c'
        else:

            def cache_from_source(filename):
                dir, base = os.path.split(filename)
                base, ext = os.path.splitext(base)
                x, y = sys.version_info[:2]
                p = os.path.join(dir, '__pycache__',
                                 base + '.cpython-{0}{1}.pyc'.format(x, y))
                return p

    f = open(filename, 'U')
    try:
        st = os.fstat(f.fileno())
    except AttributeError:
        timestamp = os.stat(filename)
    timestamp = int(st.st_mtime)
    sourcesize = st.st_size
    codestring = f.read()
    f.close()
    if codestring and codestring[-1] != '\n':
        codestring = codestring + '\n'
    try:
        codeobject = compile(codestring, filename, 'exec', 0, 1)
    except SyntaxError as e:
        print("Skipping %s - syntax error: %s." % (filename, e),
              file=sys.stderr)
        return
    cod = Code.from_code(codeobject)
    message = "reassembled %r imported.\n" % filename
    cod.code[:0] = [  # __import__('sys').stderr.write(message)
        (LOAD_GLOBAL, '__import__'),
        (LOAD_CONST, 'sys'),
        (CALL_FUNCTION, 1),
        (LOAD_ATTR, 'stderr'),
        (LOAD_ATTR, 'write'),
        (LOAD_CONST, message),
        (CALL_FUNCTION, 1),
        (POP_TOP, None),
    ]
    try:
        codeobject2 = cod.to_code()
    except:
        print(cod.code)
        print('Failed to compile')
        raise
    fc = open(cache_from_source(filename), 'wb')
    fc.write(b'\0\0\0\0')
    fc.write(struct.pack('<l', timestamp))
    if python_version >= '3':
        fc.write(struct.pack('<l', sourcesize))
    try:
        marshal.dump(codeobject2, fc)
    except:
        print(cod.code)
        print('Failed on {0}'.format(type(codeobject2)))
        raise
    fc.flush()
    fc.seek(0, 0)
    fc.write(imp.get_magic())
    fc.close()
Exemplo n.º 45
0
class ModuleFinder:
    def __init__(self, path=None, debug=0, excludes=[], replace_paths=[]):
        if path is None:
            path = sys.path
        self.path = path
        self.modules = {}
        self.badmodules = {}
        self.debug = debug
        self.indent = 0
        self.excludes = excludes
        self.replace_paths = replace_paths
        self.processed_paths = []  # Used in debugging only

    def msg(self, level, str, *args):
        if level <= self.debug:
            for i in range(self.indent):
                print "   ",
            print str,
            for arg in args:
                print repr(arg),
            print

    def msgin(self, *args):
        level = args[0]
        if level <= self.debug:
            self.indent = self.indent + 1
            self.msg(*args)

    def msgout(self, *args):
        level = args[0]
        if level <= self.debug:
            self.indent = self.indent - 1
            self.msg(*args)

    def run_script(self, pathname):
        self.msg(2, "run_script", pathname)
        fp = open(pathname, READ_MODE)
        stuff = ("", "r", imp.PY_SOURCE)
        self.load_module('__main__', fp, pathname, stuff)

    def load_file(self, pathname):
        dir, name = os.path.split(pathname)
        name, ext = os.path.splitext(name)
        fp = open(pathname, READ_MODE)
        stuff = (ext, "r", imp.PY_SOURCE)
        self.load_module(name, fp, pathname, stuff)

    def import_hook(self, name, caller=None, fromlist=None):
        self.msg(3, "import_hook", name, caller, fromlist)
        parent = self.determine_parent(caller)
        q, tail = self.find_head_package(parent, name)
        m = self.load_tail(q, tail)
        if not fromlist:
            return q
        if m.__path__:
            self.ensure_fromlist(m, fromlist)
        return None

    def determine_parent(self, caller):
        self.msgin(4, "determine_parent", caller)
        if not caller:
            self.msgout(4, "determine_parent -> None")
            return None
        pname = caller.__name__
        if caller.__path__:
            parent = self.modules[pname]
            assert caller is parent
            self.msgout(4, "determine_parent ->", parent)
            return parent
        if '.' in pname:
            i = pname.rfind('.')
            pname = pname[:i]
            parent = self.modules[pname]
            assert parent.__name__ == pname
            self.msgout(4, "determine_parent ->", parent)
            return parent
        self.msgout(4, "determine_parent -> None")
        return None

    def find_head_package(self, parent, name):
        self.msgin(4, "find_head_package", parent, name)
        if '.' in name:
            i = name.find('.')
            head = name[:i]
            tail = name[i + 1:]
        else:
            head = name
            tail = ""
        if parent:
            qname = "%s.%s" % (parent.__name__, head)
        else:
            qname = head
        q = self.import_module(head, qname, parent)
        if q:
            self.msgout(4, "find_head_package ->", (q, tail))
            return q, tail
        if parent:
            qname = head
            parent = None
            q = self.import_module(head, qname, parent)
            if q:
                self.msgout(4, "find_head_package ->", (q, tail))
                return q, tail
        self.msgout(4, "raise ImportError: No module named", qname)
        raise ImportError, "No module named " + qname

    def load_tail(self, q, tail):
        self.msgin(4, "load_tail", q, tail)
        m = q
        while tail:
            i = tail.find('.')
            if i < 0: i = len(tail)
            head, tail = tail[:i], tail[i + 1:]
            mname = "%s.%s" % (m.__name__, head)
            m = self.import_module(head, mname, m)
            if not m:
                self.msgout(4, "raise ImportError: No module named", mname)
                raise ImportError, "No module named " + mname
        self.msgout(4, "load_tail ->", m)
        return m

    def ensure_fromlist(self, m, fromlist, recursive=0):
        self.msg(4, "ensure_fromlist", m, fromlist, recursive)
        for sub in fromlist:
            if sub == "*":
                if not recursive:
                    all = self.find_all_submodules(m)
                    if all:
                        self.ensure_fromlist(m, all, 1)
            elif not hasattr(m, sub):
                subname = "%s.%s" % (m.__name__, sub)
                submod = self.import_module(sub, subname, m)
                if not submod:
                    raise ImportError, "No module named " + subname

    def find_all_submodules(self, m):
        if not m.__path__:
            return
        modules = {}
        # 'suffixes' used to be a list hardcoded to [".py", ".pyc", ".pyo"].
        # But we must also collect Python extension modules - although
        # we cannot separate normal dlls from Python extensions.
        suffixes = []
        for triple in imp.get_suffixes():
            suffixes.append(triple[0])
        for dir in m.__path__:
            try:
                names = os.listdir(dir)
            except os.error:
                self.msg(2, "can't list directory", dir)
                continue
            for name in names:
                mod = None
                for suff in suffixes:
                    n = len(suff)
                    if name[-n:] == suff:
                        mod = name[:-n]
                        break
                if mod and mod != "__init__":
                    modules[mod] = mod
        return modules.keys()

    def import_module(self, partname, fqname, parent):
        self.msgin(3, "import_module", partname, fqname, parent)
        try:
            m = self.modules[fqname]
        except KeyError:
            pass
        else:
            self.msgout(3, "import_module ->", m)
            return m
        if self.badmodules.has_key(fqname):
            self.msgout(3, "import_module -> None")
            return None
        if parent and parent.__path__ is None:
            self.msgout(3, "import_module -> None")
            return None
        try:
            fp, pathname, stuff = self.find_module(partname, parent
                                                   and parent.__path__, parent)
        except ImportError:
            self.msgout(3, "import_module ->", None)
            return None
        try:
            m = self.load_module(fqname, fp, pathname, stuff)
        finally:
            if fp: fp.close()
        if parent:
            setattr(parent, partname, m)
        self.msgout(3, "import_module ->", m)
        return m

    def load_module(self, fqname, fp, pathname, (suffix, mode, type)):
        self.msgin(2, "load_module", fqname, fp and "fp", pathname)
        if type == imp.PKG_DIRECTORY:
            m = self.load_package(fqname, pathname)
            self.msgout(2, "load_module ->", m)
            return m
        if type == imp.PY_SOURCE:
            co = compile(fp.read() + '\n', pathname, 'exec')
        elif type == imp.PY_COMPILED:
            if fp.read(4) != imp.get_magic():
                self.msgout(2, "raise ImportError: Bad magic number", pathname)
                raise ImportError, "Bad magic number in %s" % pathname
            fp.read(4)
            co = marshal.load(fp)
        else:
            co = None
        m = self.add_module(fqname)
        m.__file__ = pathname
        if co:
            if self.replace_paths:
                co = self.replace_paths_in_code(co)
            m.__code__ = co
            self.scan_code(co, m)
        self.msgout(2, "load_module ->", m)
        return m
Exemplo n.º 46
0
 def data(self):
     with open(self.bc_path, 'rb') as file:
         data = file.read(8)
     mtime = int(os.stat(self.source_path).st_mtime)
     compare = struct.pack('<4sl', imp.get_magic(), mtime)
     return data, compare
Exemplo n.º 47
0
	def _retrieveCode(self, mname, level):
		Log.msg("PYROAdapter","client cannot find module: "+mname)
		# XXX this is nasty code, and also duplicated in core.py remote_supply_code()
		if mname in sys.modules:
			# module is already loaded, do nothing
			# XXX how can we be sure if the module is "complete"?
			# XXX because things might go wrong during the loading code below?
			return
		try:
			# Called by the client-side to obtain code from the server-side.
			# Call the special method on the server to retrieve the code.
			# No need for complex exception stuff like when the server needs
			# code from the client (see handleInvocation): because the server
			# is a Pyro object we can actually *call* it :-)
			module = self._remoteInvocationMobileCode("remote_retrieve_code",0,mname)
			imp.acquire_lock()  # obtain the global import lock
			mname = mname.split('.')
			path = ''
			mod = new.module("pyro-server-context")
			for m in mname:
				path += '.' + m
				# use already loaded modules instead of overwriting them
				real_path = path[1:]
				if sys.modules.has_key(real_path):
					mod = sys.modules[real_path]
				else:
					setattr(mod, m, new.module(real_path))
					mod = getattr(mod, m)
					sys.modules[real_path] = mod

			Log.msg('PYROAdapter','loading supplied code: ',mname)
			if module[0:4] != imp.get_magic():
				code = compile(module, "<downloaded>", "exec")
			else:
				code = marshal.loads(module[8:])
	 
			importer=None
			try:
				loaded = 0
				# XXX probably want maxtries here...
				while not loaded:
					# install a custom importer to intercept any extra needed modules
					# when executing the module code just obtained from the server
					imp.acquire_lock()
					importer = agent_import(__builtin__.__import__)
					__builtin__.__import__ = importer
					imp.release_lock()
	 
					try:
						exec code in mod.__dict__
						loaded = 1
					except ImportError:
						mname = importer.name
						if importer is not None:
							__builtin__.__import__ = importer.orig_import
							importer = None
	 
						# XXX probably want maxrecursion here...
						self._retrieveCode(mname, level+1)
	 
			finally:
				if importer is not None:
					__builtin__.__import__ = importer.orig_import
		finally:
			imp.release_lock() # release the global import lock
Exemplo n.º 48
0
def make_python_freeze(platform, modules, frozen_file):
    """Get a list of python native modules, return them frozen"""
    target = get_target(platform)
    frozen_h = '//Ignifuga auto generated file, contains the following modules: %s\n#include "Python.h"\n\n' % (
        ','.join(modules))
    mod_sizes = {}
    # Locate the Python library
    locations = os.listdir(join(HOST_DIST_DIR, 'lib'))
    python_version = None
    for l in locations:
        if l.startswith('python') and isdir(join(HOST_DIST_DIR, 'lib', l)):
            python_version = l

    if python_version == None:
        error('Could not find Python library')
        exit()

    # Copy module source to a temp location
    modtemp = join(target.tmp, 'freezer')
    if isdir(modtemp):
        shutil.rmtree(modtemp)

    os.makedirs(modtemp)
    for mod in modules:
        f = join(HOST_DIST_DIR, 'lib', python_version,
                 mod.replace('.', os.sep))
        if isdir(f):
            # It's a package!
            f = join(HOST_DIST_DIR, 'lib', python_version,
                     mod.replace('.', os.sep), '__init__') + '.py'
            newf = join(modtemp, mod.replace('.', os.sep), '__init__') + '.py'
        else:
            f = f + '.py'
            newf = join(modtemp, mod.replace('.', os.sep)) + '.py'

        if isfile(f):
            if not isdir(dirname(newf)):
                os.makedirs(dirname(newf))
            shutil.copy(f, newf)

            # Patch some modules
            if mod == 'site':
                # Patch USER_BASE, etc
                cmd = 'patch -p0 -i %s %s' % (join(
                    PATCHES_DIR, 'site.py.diff'), basename(newf))
                Popen(shlex.split(cmd), cwd=dirname(newf)).communicate()
            elif mod == 'platform':
                # Add Android platform detection
                cmd = 'patch -p0 -i %s %s' % (join(
                    PATCHES_DIR, 'platform.py.diff'), basename(newf))
                Popen(shlex.split(cmd), cwd=dirname(newf)).communicate()

    f = open(join(modtemp, 'ignifuga_compile.py'), 'w')
    f.write("""
import compileall
compileall.compile_dir("%s")
""" % (modtemp, ))
    f.close()

    cmd = '%s %s' % (join(HOST_DIST_DIR, 'bin',
                          'python'), join(modtemp, 'ignifuga_compile.py'))
    Popen(shlex.split(cmd), cwd=modtemp).communicate()

    for mod in modules:
        is_package = False
        f = join(modtemp, mod.replace('.', os.sep))
        if isdir(f):
            # It's a package!
            f = join(modtemp, mod.replace('.', os.sep), '__init__') + '.pyc'
            is_package = True
        else:
            f = f + '.pyc'

        if isfile(f):
            log("Freezing...%s" % f)
            fp = open(f, 'rb')
            if fp.read(4) == imp.get_magic():
                fp.read(4)
                code = marshal.dumps(marshal.load(fp))
                mod_sizes[mod] = len(code) if not is_package else -len(
                    code)  # A package is signaled by a negative size

                frozen_h += 'unsigned char M_ignifuga_frozen_%s[] = {' % mod.replace(
                    '.', '_')
                for i in range(0, len(code), 16):
                    frozen_h += '\n\t'
                    for c in code[i:i + 16]:
                        frozen_h += '%d,' % ord(c)
                frozen_h += '\n};\n'
            fp.close()

        else:
            error("Could not Freeze...%s" % f)
            exit()

    frozen_h += 'static struct _frozen _PyImport_FrozenModules[] = {\n'
    for mod in modules:
        if mod in mod_sizes:
            frozen_h += '\t{"%s",M_ignifuga_frozen_%s, %d},\n' % (
                mod, mod.replace('.', '_'), mod_sizes[mod])
    frozen_h += '\t{0, 0, 0} /* sentinel */\n};\n'

    frozen_h += '\nstruct _frozen *PyImport_FrozenModules = _PyImport_FrozenModules;\n'

    f = open(frozen_file, 'w')
    f.write(frozen_h)
    f.close()
Exemplo n.º 49
0
 def _getpyc(self, src):
     """Get the .pyc contents to match th given .py source code."""
     code = imp.get_magic() + struct.pack("<i", 0)
     code += marshal.dumps(compile(src, __file__, "exec"))
     return code
 def test(name, mapping, bytecode_path):
     self.import_(mapping[name], name)
     with open(bytecode_path, 'rb') as bytecode_file:
         self.assertEqual(bytecode_file.read(4), imp.get_magic())
Exemplo n.º 51
0
    imp = None
except ImportError:
    importlib = None

# We only want to use importlib if it has everything we need.
try:
    importlib_util_find_spec = importlib.util.find_spec
except Exception:
    import imp
    importlib_util_find_spec = None

# What is the .pyc magic number for this version of Python?
try:
    PYC_MAGIC_NUMBER = importlib.util.MAGIC_NUMBER
except AttributeError:
    PYC_MAGIC_NUMBER = imp.get_magic()

try:
    from types import SimpleNamespace
except ImportError:
    # The code from https://docs.python.org/3/library/types.html#types.SimpleNamespace
    class SimpleNamespace:
        """Python implementation of SimpleNamespace, for Python 2."""
        def __init__(self, **kwargs):
            self.__dict__.update(kwargs)

        def __repr__(self):
            keys = sorted(self.__dict__)
            items = ("{}={!r}".format(k, self.__dict__[k]) for k in keys)
            return "{}({})".format(type(self).__name__, ", ".join(items))
Exemplo n.º 52
0
#
# In Python 3, importlib does caching internally, and deteministic pycs may be had with PEP
# 552. Therefore, none of this file should be used on Python 3.

from __future__ import print_function

import ast
import errno
import hashlib
import imp
import marshal
import os
import pkgutil
import sys

DBX_MAGIC = b"dbx" + imp.get_magic()


# Unfortunately, it is critical that DBXImporter subclasses pkgutil.ImpImporter. pkg_resources
# inspects of the MRO of path importer while building its global distribution working
# set. Technically, we could register our importer with pkg_resources.register_finder(), but I don't
# want to pull in pkg_resources if we don't have to—building the aforementioned global working set
# is not cheap.
class DBXImporter(pkgutil.ImpImporter):
    def __init__(self, d, cache=False):
        # type: (str, bool) -> None
        pkgutil.ImpImporter.__init__(self, d)
        self._dir_ents = os.listdir(d) if cache else None

    def find_module(self, fullname, path=None):
        name = fullname.rpartition(".")[2]
Exemplo n.º 53
0
# Conda environments sometimes have different paths or apply patches to
# packages that can affect how a hook or package should access resources.
# Method for determining conda taken from:
# https://stackoverflow.com/questions/47610844#47610844
is_conda = os.path.isdir(os.path.join(base_prefix, 'conda-meta'))

# In Python 3.4 module 'imp' is deprecated and there is another way how
# to obtain magic value.
if is_py3:
    import importlib.util
    BYTECODE_MAGIC = importlib.util.MAGIC_NUMBER
else:
    # This fallback should work with Python 2.7.
    import imp
    BYTECODE_MAGIC = imp.get_magic()

# List of suffixes for Python C extension modules.
try:
    # In Python 3.3+ there is a list
    from importlib.machinery import EXTENSION_SUFFIXES, all_suffixes
    ALL_SUFFIXES = all_suffixes()
except ImportError:
    import imp
    ALL_SUFFIXES = [f[0] for f in imp.get_suffixes()]
    EXTENSION_SUFFIXES = [
        f[0] for f in imp.get_suffixes() if f[2] == imp.C_EXTENSION
    ]

# In Python 3 'Tkinter' has been made lowercase - 'tkinter'. Keep Python 2
# compatibility.
Exemplo n.º 54
0
    def _WriteModules(self,
                      fileName,
                      initScript,
                      finder,
                      compress,
                      copyDependentFiles,
                      scriptModule=None):
        initModule = finder.IncludeFile(initScript, "cx_Freeze__init__")
        if scriptModule is None:
            for module in self.constantsModules:
                module.Create(finder)
            modules = [m for m in finder.modules \
                    if m.name not in self.excludeModules]
        else:
            modules = [initModule, scriptModule]
            self.excludeModules[initModule.name] = None
            self.excludeModules[scriptModule.name] = None
        modules.sort(key=lambda m: m.name)
        if not self.silent:
            self._PrintReport(fileName, modules)
        if scriptModule is None:
            finder.ReportMissingModules()

        targetDir = os.path.dirname(fileName)
        self._CreateDirectory(targetDir)

        # Prepare zip file. This can be library.zip, or named after the
        # executable, or even appended to the executable.
        if os.path.exists(fileName):
            mode = "a"
        else:
            mode = "w"
        outFile = zipfile.PyZipFile(fileName, mode, zipfile.ZIP_DEFLATED)

        filesToCopy = []
        for module in modules:
            if module.code is None and module.file is not None:
                # Extension module: save a Python loader in the zip file, and
                # copy the actual file to the build directory, because pyd/so
                # libraries can't be loaded from a zip file.
                fileName = os.path.basename(module.file)
                baseFileName, ext = os.path.splitext(fileName)
                if baseFileName != module.name and module.name != "zlib":
                    if "." in module.name:
                        fileName = module.name + ext
                    generatedFileName = "ExtensionLoader_%s.py" % \
                            module.name.replace(".", "_")
                    module.code = compile(EXTENSION_LOADER_SOURCE % fileName,
                                          generatedFileName, "exec")
                target = os.path.join(targetDir, fileName)
                filesToCopy.append((module, target))

            if module.code is None:
                continue

            fileName = "/".join(module.name.split("."))
            if module.path:
                fileName += "/__init__"
            if module.file is not None and os.path.exists(module.file):
                mtime = os.stat(module.file).st_mtime
            else:
                mtime = time.time()
            zipTime = time.localtime(mtime)[:6]
            # starting with Python 3.3 the pyc file format contains the source
            # size; it is not actually used for anything except determining if
            # the file is up to date so we can safely set this value to zero
            if sys.version_info[:2] < (3, 3):
                header = imp.get_magic() + struct.pack("<i", int(mtime))
            else:
                header = imp.get_magic() + struct.pack("<ii", int(mtime), 0)
            data = header + marshal.dumps(module.code)
            zinfo = zipfile.ZipInfo(fileName + ".pyc", zipTime)
            if compress:
                zinfo.compress_type = zipfile.ZIP_DEFLATED
            outFile.writestr(zinfo, data)

        for sourceFileName, targetFileName in self.zipIncludes:
            outFile.write(sourceFileName, targetFileName)

        outFile.close()

        # Copy Python extension modules from the list built above.
        origPath = os.environ["PATH"]
        for module, target in filesToCopy:
            try:
                if module.parent is not None:
                    path = os.pathsep.join([origPath] + module.parent.path)
                    os.environ["PATH"] = path
                self._CopyFile(module.file, target, copyDependentFiles)
            finally:
                os.environ["PATH"] = origPath
Exemplo n.º 55
0
    async def compile_templates(
        self,
        target: str,
        extensions: Iterable[str] = None,
        filter_func: Callable = None,
        zip: Optional[str] = "deflated",
        log_function: Callable = None,
        ignore_errors: bool = True,
        py_compile: bool = False,
    ):
        """Finds all the templates the loader can find, compiles them
        and stores them in `target`.  If `zip` is `None`, instead of in a
        zipfile, the templates will be stored in a directory.
        By default a deflate zip algorithm is used. To switch to
        the stored algorithm, `zip` can be set to ``'stored'``.

        `extensions` and `filter_func` are passed to :meth:`list_templates`.
        Each template returned will be compiled to the target folder or
        zipfile.

        By default template compilation errors are ignored.  In case a
        log function is provided, errors are logged.  If you want template
        syntax errors to abort the compilation you can set `ignore_errors`
        to `False` and you will get an exception on syntax errors.

        If `py_compile` is set to `True` .pyc files will be written to the
        target instead of standard .py files.  This flag does not do anything
        on pypy and Python 3 where pyc files are not picked up by itself and
        don't give much benefit.

        .. versionadded:: 2.4
        """
        from .loaders import ModuleLoader

        if log_function is None:

            def log_function(x):
                pass

        if py_compile:
            if not PY2 or PYPY:
                import warnings

                warnings.warn(
                    "'py_compile=True' has no effect on PyPy or Python"
                    " 3 and will be removed in version 3.0",
                    DeprecationWarning,
                    stacklevel=2,
                )
                py_compile = False
            else:
                import imp
                import marshal

                py_header = imp.get_magic() + u"\xff\xff\xff\xff".encode(
                    "iso-8859-15")

                # Python 3.3 added a source filesize to the header
                if sys.version_info >= (3, 3):
                    py_header += u"\x00\x00\x00\x00".encode("iso-8859-15")

        async def write_file(filename, data):
            if zip:
                info = ZipInfo(filename)
                info.external_attr = 0o755 << 16
                zip_file.writestr(info, data)
            else:
                if isinstance(data, text_type):
                    data = data.encode("utf8")

                async with aiofiles.open(os.path.join(target, filename),
                                         "wb") as f:
                    await f.write(data)

        if zip is not None:
            from zipfile import ZIP_DEFLATED, ZIP_STORED, ZipFile, ZipInfo

            zip_file = ZipFile(
                target, "w",
                dict(deflated=ZIP_DEFLATED, stored=ZIP_STORED)[zip])
            log_function('Compiling into Zip archive "%s"' % target)
        else:
            if not os.path.isdir(target):
                os.makedirs(target)
            log_function('Compiling into folder "%s"' % target)

        try:
            names = await self.list_templates(extensions, filter_func)
            for name in names:
                source, filename, _ = await self.loader.get_source(self, name)
                try:
                    code = self.compile(source, name, filename, True, True)
                except TemplateSyntaxError as e:
                    if not ignore_errors:
                        raise
                    log_function('Could not compile "%s": %s' % (name, e))
                    continue

                filename = ModuleLoader.get_module_filename(name)

                if py_compile:
                    c = self._compile(code, encode_filename(filename))
                    await write_file(filename + "c",
                                     py_header + marshal.dumps(c))
                    log_function('Byte-compiled "%s" as %s' %
                                 (name, filename + "c"))
                else:
                    await write_file(filename, code)
                    log_function('Compiled "%s" as %s' % (name, filename))
        finally:
            if zip is not None:
                zip_file.close()

        log_function("Finished compiling templates")
Exemplo n.º 56
0
from __future__ import print_function
import os
import struct
import marshal
import zlib
import sys
from uuid import uuid4 as uniquename

# imp is deprecated in Python3 in favour of importlib
if sys.version_info.major == 3:
    from importlib.util import MAGIC_NUMBER
    pyc_magic = MAGIC_NUMBER
else:
    import imp
    pyc_magic = imp.get_magic()


class CTOCEntry:
    def __init__(self, position, cmprsdDataSize, uncmprsdDataSize, cmprsFlag,
                 typeCmprsData, name):
        self.position = position
        self.cmprsdDataSize = cmprsdDataSize
        self.uncmprsdDataSize = uncmprsdDataSize
        self.cmprsFlag = cmprsFlag
        self.typeCmprsData = typeCmprsData
        self.name = name


class PyInstArchive:
    PYINST20_COOKIE_SIZE = 24  # For pyinstaller 2.0
Exemplo n.º 57
0
    def build_archive(self, libpath, delete_existing_resources=False):
        """Build the archive containing the Python library.
        """
        if self.options.bundle_files <= 1:
            # Add pythonXY.dll as resource into the library file
            #
            # XXX We should add a flag to the exe so that it does not try to load pythonXY.dll
            # from the file system.
            # XXX XXX XXX
            with UpdateResources(
                    libpath,
                    delete_existing=delete_existing_resources) as resource:
                with open(pydll, "rb") as ifi:
                    pydll_bytes = ifi.read()
                # We do not need to replace the winver string resource
                # in the python dll since it will be loaded via
                # MemoryLoadLibrary, and so python cannot find the
                # string resources anyway.
                if self.options.verbose > 1:
                    print("Add resource %s/%s(%d bytes) to %s" %
                          (os.path.basename(pydll), 1, len(pydll_bytes),
                           libpath))
                resource.add(type=os.path.basename(pydll),
                             name=1,
                             value=pydll_bytes)

        if self.options.optimize:
            bytecode_suffix = OPTIMIZED_BYTECODE_SUFFIXES[0]
        else:
            bytecode_suffix = DEBUG_BYTECODE_SUFFIXES[0]

        if self.options.compress:
            compression = zipfile.ZIP_DEFLATED
        else:
            compression = zipfile.ZIP_STORED

        # Create a zipfile and append it to the library file
        arc = zipfile.ZipFile(libpath, "a", compression=compression)

        # The same modules may be in self.ms.modules under different
        # keys; we only need one of them in the archive.
        for mod in set(self.mf.modules.values()):
            if mod.__code__:
                path = mod.__dest_file__
                stream = io.BytesIO()
                stream.write(imp.get_magic())
                if sys.version_info >= (3, 7, 0):
                    stream.write(b"\0\0\0\0")  # null flags
                stream.write(b"\0\0\0\0")  # null timestamp
                stream.write(b"\0\0\0\0")  # null size
                marshal.dump(mod.__code__, stream)
                arc.writestr(path, stream.getvalue())

            elif hasattr(mod, "__file__"):
                assert mod.__file__.endswith(EXTENSION_TARGET_SUFFIX)
                if self.options.bundle_files <= 2:
                    # put .pyds into the archive
                    arcfnm = mod.__name__.replace(
                        ".", "\\") + EXTENSION_TARGET_SUFFIX
                    if self.options.verbose > 1:
                        print("Add %s to %s" %
                              (os.path.basename(mod.__file__), libpath))
                    arc.write(mod.__file__, arcfnm)
                else:
                    # The extension modules will be copied into
                    # dlldir.  To be able to import it without dlldir
                    # being on sys.path, create a loader module and
                    # put that into the archive.
                    pydfile = mod.__name__ + EXTENSION_TARGET_SUFFIX
                    if self.options.verbose > 1:
                        print("Add Loader for %s to %s" %
                              (os.path.basename(mod.__file__), libpath))
                    loader = LOAD_FROM_DIR.format(pydfile)

                    code = compile(loader,
                                   "<loader>",
                                   "exec",
                                   optimize=self.options.optimize)
                    if hasattr(mod, "__path__"):
                        path = mod.__name__.replace(
                            ".", "\\") + "\\__init__" + bytecode_suffix
                    else:
                        path = mod.__name__.replace(".",
                                                    "\\") + bytecode_suffix
                    stream = io.BytesIO()
                    stream.write(imp.get_magic())
                    if sys.version_info >= (3, 7, 0):
                        stream.write(b"\0\0\0\0")  # null flags
                    stream.write(b"\0\0\0\0")  # null timestamp
                    stream.write(b"\0\0\0\0")  # null size
                    marshal.dump(code, stream)
                    arc.writestr(path, stream.getvalue())

        if self.options.bundle_files == 0:
            # put everything into the arc
            files = self.mf.all_dlls()
        elif self.options.bundle_files in (1, 2):
            # put only extension dlls into the arc
            files = self.mf.extension_dlls()
        else:
            arc.close()
            return

        for src in files:
            if self.options.verbose > 1:
                print("Add DLL %s to %s" % (os.path.basename(src), libpath))
            arc.write(src, os.path.basename(src))

        arc.close()
Exemplo n.º 58
0
"""Routine to "compile" a .py file to a .pyc (or .pyo) file.

This module has intimate knowledge of the format of .pyc files.
"""

import __builtin__
import imp
import marshal
import os
import sys
import traceback

MAGIC = imp.get_magic()

__all__ = ["compile", "main", "PyCompileError"]


class PyCompileError(Exception):
    """Exception raised when an error occurs while attempting to
    compile the file.

    To raise this exception, use

        raise PyCompileError(exc_type,exc_value,file[,msg])

    where

        exc_type:   exception type to be used in error message
                    type name can be accesses as class variable
                    'exc_type_name'
Exemplo n.º 59
0
 def __init__(self,parser):
     self.name=parser.name
     self.parser = parser
     self.magic = imp.get_magic()
Exemplo n.º 60
0
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
"""

import marshal
from types import FunctionType, ModuleType

import six

try:
    from importlib.util import MAGIC_NUMBER as BYTECODE_VERSION
except ImportError:
    # Pre-3.4
    import imp
    BYTECODE_VERSION = imp.get_magic()

# loosely based on
# http://effbot.org/zone/python-code-generator.htm


class Indentation(object):
    def __init__(self, generator):
        self.generator = generator

    def __enter__(self):
        self.generator.indent()

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.generator.dedent()