同步操作将从 OpenHarmony-SIG/python 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
import contextlibimport osimport pathlibimport shutilimport statimport sysimport zipfile__all__ = ['ZipAppError', 'create_archive', 'get_interpreter']# The __main__.py used if the users specifies "-m module:fn".# Note that this will always be written as UTF-8 (module and# function names can be non-ASCII in Python 3).# We add a coding cookie even though UTF-8 is the default in Python 3# because the resulting archive may be intended to be run under Python 2.MAIN_TEMPLATE = """\# -*- coding: utf-8 -*-import {module}{module}.{fn}()"""# The Windows launcher defaults to UTF-8 when parsing shebang lines if the# file has no BOM. So use UTF-8 on Windows.# On Unix, use the filesystem encoding.if sys.platform.startswith('win'):shebang_encoding = 'utf-8'else:shebang_encoding = sys.getfilesystemencoding()class ZipAppError(ValueError):pass@contextlib.contextmanagerdef _maybe_open(archive, mode):if isinstance(archive, (str, os.PathLike)):with open(archive, mode) as f:yield felse:yield archivedef _write_file_prefix(f, interpreter):"""Write a shebang line."""if interpreter:shebang = b'#!' + interpreter.encode(shebang_encoding) + b'\n'f.write(shebang)def _copy_archive(archive, new_archive, interpreter=None):"""Copy an application archive, modifying the shebang line."""with _maybe_open(archive, 'rb') as src:# Skip the shebang line from the source.# Read 2 bytes of the source and check if they are #!.first_2 = src.read(2)if first_2 == b'#!':# Discard the initial 2 bytes and the rest of the shebang line.first_2 = b''src.readline()with _maybe_open(new_archive, 'wb') as dst:_write_file_prefix(dst, interpreter)# If there was no shebang, "first_2" contains the first 2 bytes# of the source file, so write them before copying the rest# of the file.dst.write(first_2)shutil.copyfileobj(src, dst)if interpreter and isinstance(new_archive, str):os.chmod(new_archive, os.stat(new_archive).st_mode | stat.S_IEXEC)def create_archive(source, target=None, interpreter=None, main=None,filter=None, compressed=False):"""Create an application archive from SOURCE.The SOURCE can be the name of a directory, or a filename or a file-likeobject referring to an existing archive.The content of SOURCE is packed into an application archive in TARGET,which can be a filename or a file-like object. If SOURCE is a directory,TARGET can be omitted and will default to the name of SOURCE with .pyzappended.The created application archive will have a shebang line specifyingthat it should run with INTERPRETER (there will be no shebang line ifINTERPRETER is None), and a __main__.py which runs MAIN (if MAIN isnot specified, an existing __main__.py will be used). It is an errorto specify MAIN for anything other than a directory source with no__main__.py, and it is an error to omit MAIN if the directory has no__main__.py."""# Are we copying an existing archive?source_is_file = Falseif hasattr(source, 'read') and hasattr(source, 'readline'):source_is_file = Trueelse:source = pathlib.Path(source)if source.is_file():source_is_file = Trueif source_is_file:_copy_archive(source, target, interpreter)return# We are creating a new archive from a directory.if not source.exists():raise ZipAppError("Source does not exist")has_main = (source / '__main__.py').is_file()if main and has_main:raise ZipAppError("Cannot specify entry point if the source has __main__.py")if not (main or has_main):raise ZipAppError("Archive has no entry point")main_py = Noneif main:# Check that main has the right format.mod, sep, fn = main.partition(':')mod_ok = all(part.isidentifier() for part in mod.split('.'))fn_ok = all(part.isidentifier() for part in fn.split('.'))if not (sep == ':' and mod_ok and fn_ok):raise ZipAppError("Invalid entry point: " + main)main_py = MAIN_TEMPLATE.format(module=mod, fn=fn)if target is None:target = source.with_suffix('.pyz')elif not hasattr(target, 'write'):target = pathlib.Path(target)with _maybe_open(target, 'wb') as fd:_write_file_prefix(fd, interpreter)compression = (zipfile.ZIP_DEFLATED if compressed elsezipfile.ZIP_STORED)with zipfile.ZipFile(fd, 'w', compression=compression) as z:for child in source.rglob('*'):arcname = child.relative_to(source)if filter is None or filter(arcname):z.write(child, arcname.as_posix())if main_py:z.writestr('__main__.py', main_py.encode('utf-8'))if interpreter and not hasattr(target, 'write'):target.chmod(target.stat().st_mode | stat.S_IEXEC)def get_interpreter(archive):with _maybe_open(archive, 'rb') as f:if f.read(2) == b'#!':return f.readline().strip().decode(shebang_encoding)def main(args=None):"""Run the zipapp command line interface.The ARGS parameter lets you specify the argument list directly.Omitting ARGS (or setting it to None) works as for argparse, usingsys.argv[1:] as the argument list."""import argparseparser = argparse.ArgumentParser()parser.add_argument('--output', '-o', default=None,help="The name of the output archive. ""Required if SOURCE is an archive.")parser.add_argument('--python', '-p', default=None,help="The name of the Python interpreter to use ""(default: no shebang line).")parser.add_argument('--main', '-m', default=None,help="The main function of the application ""(default: use an existing __main__.py).")parser.add_argument('--compress', '-c', action='store_true',help="Compress files with the deflate method. ""Files are stored uncompressed by default.")parser.add_argument('--info', default=False, action='store_true',help="Display the interpreter from the archive.")parser.add_argument('source',help="Source directory (or existing archive).")args = parser.parse_args(args)# Handle `python -m zipapp archive.pyz --info`.if args.info:if not os.path.isfile(args.source):raise SystemExit("Can only get info for an archive file")interpreter = get_interpreter(args.source)print("Interpreter: {}".format(interpreter or "<none>"))sys.exit(0)if os.path.isfile(args.source):if args.output is None or (os.path.exists(args.output) andos.path.samefile(args.source, args.output)):raise SystemExit("In-place editing of archives is not supported")if args.main:raise SystemExit("Cannot change the main function when copying")create_archive(args.source, args.output,interpreter=args.python, main=args.main,compressed=args.compress)if __name__ == '__main__':main()
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。