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
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
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)])
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
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
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)
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")
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
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
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')
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();
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)
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
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()
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
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
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
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
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
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
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()
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
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()
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
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
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)
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
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\nAABqAQCHAABmAQBkAQBkAgCGAAB8AABqAgBqAwCDAABEgwEAgwIAUykDTmMBAAAAAAAAAAMAAAAE\nAAAAEwAAAHMjAAAAaQAAfAAAXRkAXAIAfQEAfQIAiAAAfAIAFHwBAJMCAHEGAFNyBgAAAHIGAAAA\nKQPaAi4wcgoAAADaAXgpAdoFYWxwaGFyBgAAAHIHAAAA+go8ZGljdGNvbXA+DAAAAHMCAAAACQB6\nIV9WZWMuX19ybXVsX18uPGxvY2Fscz4uPGRpY3Rjb21wPikEcgIAAAByAwAAAHIEAAAA2gVpdGVt\ncykCcgkAAAByEwAAAHIGAAAAKQFyEwAAAHIHAAAA2ghfX3JtdWxfXwwAAABzAAAAAHoNX1ZlYy5f\nX3JtdWxfX2MCAAAAAAAAAAIAAAAEAAAAAwAAAHNAAAAAdAAAiAAAdAEAgwIAcjgAdAIAhwAAhwEA\nZgIAZAEAZAIAhgAAiAEAagMAagQAgwAARIMBAIMBAFN0BQBTZAAAUykDTmMBAAAAAAAAAAIAAAAF\nAAAAEwAAAHMiAAAAZwAAfAAAXRgAfQEAiAEAfAEAGYgAAHwBABkUkQIAcQYAU3IGAAAAcgYAAAAp\nAnIRAAAAcgoAAAApAtoFb3RoZXJyBQAAAHIGAAAAcgcAAAD6CjxsaXN0Y29tcD4RAAAAcwIAAAAJ\nAHogX1ZlYy5fX211bF9fLjxsb2NhbHM+LjxsaXN0Y29tcD4pBtoKaXNpbnN0YW5jZXICAAAA2gNz\ndW1yBAAAANoEa2V5c9oOTm90SW1wbGVtZW50ZWQpAnIFAAAAchcAAAByBgAAACkCchcAAAByBQAA\nAHIHAAAA2gdfX211bF9fDgAAAHMGAAAAAAIPASkCegxfVmVjLl9fbXVsX19jAgAAAAAAAAACAAAA\nBQAAAAMAAABzRwAAAHQAAIgAAGoBAIcAAIcBAGYCAGQBAGQCAIYAAHQCAIgAAGoDAGoEAIMAAIMB\nAGoFAIgBAGoDAGoEAIMAAIMBAESDAQCDAgBTKQNOYwEAAAAAAAAAAgAAAAUAAAATAAAAcyUAAABp\nAAB8AABdGwB9AQCIAAB8AQAZiAEAfAEAGRd8AQCTAgBxBgBTcgYAAAByBgAAACkCchEAAAByCgAA\nACkC2gF1cgkAAAByBgAAAHIHAAAAchQAAAAVAAAAcwIAAAAJAHogX1ZlYy5fX2FkZF9fLjxsb2Nh\nbHM+LjxkaWN0Y29tcD4pBnICAAAAcgMAAADaA3NldHIEAAAAchsAAADaBXVuaW9uKQJyHgAAAHIJ\nAAAAcgYAAAApAnIeAAAAcgkAAAByBwAAANoHX19hZGRfXxUAAABzAAAAAHoMX1ZlYy5fX2FkZF9f\nYwIAAAAAAAAAAgAAAAIAAABDAAAAcwkAAAB8AAB8AQALF1MpAXo0UmV0dXJucyBhIHZlY3RvciB3\naGljaCBpcyB0aGUgZGlmZmVyZW5jZSBvZiBhIGFuZCBiLnIGAAAAKQLaAWHaAWJyBgAAAHIGAAAA\ncgcAAADaB19fc3ViX18XAAAAcwIAAAAAAnoMX1ZlYy5fX3N1Yl9fTikM2ghfX25hbWVfX9oKX19t\nb2R1bGVfX9oMX19xdWFsbmFtZV9fch8AAAByCAAAAHILAAAAcg0AAAByEAAAAHIWAAAAch0AAABy\nIQAAAHIkAAAAcgYAAAByBgAAAHIGAAAAcgcAAAByAgAAAAQAAABzEAAAAAwBFQQMAQwBDAEMAgwH\nDAJyAgAAAGebK6GGm4QGPWMCAAAAAAAAAAUAAAAGAAAAQwAAAHNsAAAAZwAAfQIAeFkAfAAARF1R\nAH0DAHgoAHwCAERdIAB9BAB8AwB8AwB8BAAUfAQAfAQAFBt8BAAUGH0DAHEaAFd8AwB8AwAUfAEA\nawQAcg0AfAIAagAAfAMAgwEAAXENAHENAFd0AQB8AgCDAQBTKQFOKQLaBmFwcGVuZNoDbGVuKQXa\nAUxaA2Vwc1oJdnN0YXJsaXN0cgkAAABaBXZzdGFycgYAAAByBgAAAHIHAAAA2gdfUl9yYW5rGwAA\nAHMOAAAAAAEGAQ0BDQEeARAAFAFyKwAAAGMBAAAAAAAAAAYAAAAFAAAAAwAAAHO3AAAAdAAAdAEA\ndAIAiAEAgwEAgwEAgwEAfQEAZAEAfQIAeJIAiAEAZAEAGWoDAERdgwCJAACHAACHAQBmAgBkAgBk\nAwCGAAB8AQBEgwEAfQMAfAMAZwAAawMAciwAfAMAZAEAGX0EAHwBAGoEAHwEAIMBAAF8AgBkBAA3\nfQIAeDEAfAMAZAQAZAAAhQIAGURdHAB9BQCIAQB8BQAZiAEAfAQAGReIAQB8BQA8cYwAV3EsAHEs\nAFd8AgBTKQVOcgEAAABjAQAAAAAAAAACAAAABAAAABMAAABzKgAAAGcAAHwAAF0gAH0BAIgBAHwB\nABmIAAAZZAAAawMAcgYAfAEAkQIAcQYAUykBcgEAAAByBgAAACkCchEAAADaAXIpAtoBY9oHcm93\nbGlzdHIGAAAAcgcAAAByGAAAACcAAABzAgAAAAkAeh1fR0YyX3JhbmsuPGxvY2Fscz4uPGxpc3Rj\nb21wPnIOAAAAKQVyHwAAANoFcmFuZ2VyKQAAAHIDAAAA2gZyZW1vdmUpBnIuAAAAWglyb3dzX2xl\nZnRyLAAAAFoRcm93c193aXRoX25vbnplcm9aBXBpdm90Wglyb3dfaW5kZXhyBgAAACkCci0AAABy\nLgAAAHIHAAAA2glfR0YyX3JhbmsjAAAAcxYAAAAAARgBBgEUARwBDAEKAQ0BCgEXASEBcjEAAABj\nAQAAAAAAAAAEAAAABQAAAEMAAABzdAAAAGQBAGQCAIQAAHwAAESDAQB9AQB4WgB8AABEXVIAfQIA\neEkAfAIAagAAagEAgwAARF04AH0DAHwDAGQDAGsDAHIwAHQCAHwDAHQDAGoEAIMCAHJeAHQFAHwB\nAIMBAFN0BgB8AQCDAQBTcTAAV3EaAFdkAwBTKQROYwEAAAAAAAAAAgAAAAUAAABTAAAAcyUAAABn\nAAB8AABdGwB9AQB0AAB8AQBqAQB8AQBqAgCDAgCRAgBxBgBTcgYAAAApA3ICAAAAcgMAAAByBAAA\nACkCchEAAAByHgAAAHIGAAAAcgYAAAByBwAAAHIYAAAAMQAAAHMCAAAACQB6GV9yYW5rLjxsb2Nh\nbHM+LjxsaXN0Y29tcD5yAQAAACkHcgQAAADaBnZhbHVlc3IZAAAA2gNHRjJaA09uZXIxAAAAcisA\nAAApBHIqAAAAWgJMY3IJAAAAchIAAAByBgAAAHIGAAAAcgcAAADaBV9yYW5rMAAAAHMQAAAAAAET\nAQ0BFgEMARIBCgESAXI0AAAAYwEAAAAAAAAAAQAAAAMAAABDAAAAcxkAAAB0AAAEagEAZAEANwJf\nAQB0AgB8AACDAQBTKQJOcg4AAAApA9oEcmFua9oJX19jYWxsc19fcjQAAAApAXIqAAAAcgYAAABy\nBgAAAHIHAAAAcjUAAAA6AAAAcwQAAAAAAQ8BcjUAAABjAQAAAAAAAAABAAAAAwAAAEMAAABzJQAA\nAHQAAARqAQBkAQA3Al8BAHQCAHwAAIMBAHQDAHwAAIMBAGsCAFMpAk5yDgAAACkE2g5pc19pbmRl\ncGVuZGVudHI2AAAAcjQAAAByKQAAACkBcioAAAByBgAAAHIGAAAAcgcAAAByNwAAAD4AAABzBAAA\nAAABDwFyNwAAAFoMaW5zdHJ1bWVudGVkKQlyMwAAAHICAAAAcisAAAByMQAAAHI0AAAAcjUAAABy\nNwAAAHI2AAAA2gtfX3ZlcnNpb25fX3IGAAAAcgYAAAByBgAAAHIHAAAA2gg8bW9kdWxlPgIAAABz\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")
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
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
def _reduce_code(code): """ Reduce a code object to picklable components. """ return marshal.version, imp.get_magic(), marshal.dumps(code)
# # 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")
def test_mtime(self): # Test a change in mtime leads to a new .pyc. self.recreation_check(struct.pack('<4sl', imp.get_magic(), 1))
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.
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
def __current_magic(): """Current Python magic number.""" return imp.get_magic()
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
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')
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
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
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)
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)
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()
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
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
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
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()
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())
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))
# # 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]
# 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.
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
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")
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
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()
"""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'
def __init__(self,parser): self.name=parser.name self.parser = parser self.magic = imp.get_magic()
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()