## upip - Package manager for MicroPython## Copyright (c) 2015-2018 Paul Sokolovsky## Licensed under the MIT license.#import sysimport gcimport uos as osimport uerrno as errnoimport ujson as jsonimport uzlibimport upip_utarfile as tarfilegc.collect()debug = Falseindex_urls = ["https://micropython.org/pi", "https://pypi.org/pypi"]install_path = Nonecleanup_files = []gzdict_sz = 16 + 15file_buf = bytearray(512)class NotFoundError(Exception):passdef op_split(path):if path == "":return ("", "")r = path.rsplit("/", 1)if len(r) == 1:return ("", path)head = r[0]if not head:head = "/"return (head, r[1])def op_basename(path):return op_split(path)[1]# Expects *file* namedef _makedirs(name, mode=0o777):ret = Falses = ""comps = name.rstrip("/").split("/")[:-1]if comps[0] == "":s = "/"for c in comps:if s and s[-1] != "/":s += "/"s += ctry:os.mkdir(s)ret = Trueexcept OSError as e:if e.args[0] != errno.EEXIST and e.args[0] != errno.EISDIR:raise eret = Falsereturn retdef save_file(fname, subf):global file_bufwith open(fname, "wb") as outf:while True:sz = subf.readinto(file_buf)if not sz:breakoutf.write(file_buf, sz)def install_tar(f, prefix):meta = {}for info in f:# print(info)fname = info.nametry:fname = fname[fname.index("/") + 1 :]except ValueError:fname = ""save = Truefor p in ("setup.", "PKG-INFO", "README"):# print(fname, p)if fname.startswith(p) or ".egg-info" in fname:if fname.endswith("/requires.txt"):meta["deps"] = f.extractfile(info).read()save = Falseif debug:print("Skipping", fname)breakif save:outfname = prefix + fnameif info.type != tarfile.DIRTYPE:if debug:print("Extracting " + outfname)_makedirs(outfname)subf = f.extractfile(info)save_file(outfname, subf)return metadef expandhome(s):if "~/" in s:h = os.getenv("HOME")s = s.replace("~/", h + "/")return simport usslimport usocketwarn_ussl = Truedef url_open(url):global warn_usslif debug:print(url)proto, _, host, urlpath = url.split("/", 3)try:port = 443if ":" in host:host, port = host.split(":")port = int(port)ai = usocket.getaddrinfo(host, port, 0, usocket.SOCK_STREAM)except OSError as e:fatal("Unable to resolve %s (no Internet?)" % host, e)# print("Address infos:", ai)ai = ai[0]s = usocket.socket(ai[0], ai[1], ai[2])try:# print("Connect address:", addr)s.connect(ai[-1])if proto == "https:":s = ussl.wrap_socket(s, server_hostname=host)if warn_ussl:print("Warning: %s SSL certificate is not validated" % host)warn_ussl = False# MicroPython rawsocket module supports file interface directlys.write("GET /%s HTTP/1.0\r\nHost: %s:%s\r\n\r\n" % (urlpath, host, port))l = s.readline()protover, status, msg = l.split(None, 2)if status != b"200":if status == b"404" or status == b"301":raise NotFoundError("Package not found")raise ValueError(status)while 1:l = s.readline()if not l:raise ValueError("Unexpected EOF in HTTP headers")if l == b"\r\n":breakexcept Exception as e:s.close()raise ereturn sdef get_pkg_metadata(name):for url in index_urls:try:f = url_open("%s/%s/json" % (url, name))except NotFoundError:continuetry:return json.load(f)finally:f.close()raise NotFoundError("Package not found")def fatal(msg, exc=None):print("Error:", msg)if exc and debug:raise excsys.exit(1)def install_pkg(pkg_spec, install_path):data = get_pkg_metadata(pkg_spec)latest_ver = data["info"]["version"]packages = data["releases"][latest_ver]del datagc.collect()assert len(packages) == 1package_url = packages[0]["url"]print("Installing %s %s from %s" % (pkg_spec, latest_ver, package_url))package_fname = op_basename(package_url)f1 = url_open(package_url)try:f2 = uzlib.DecompIO(f1, gzdict_sz)f3 = tarfile.TarFile(fileobj=f2)meta = install_tar(f3, install_path)finally:f1.close()del f3del f2gc.collect()return metadef install(to_install, install_path=None):# Calculate gzip dictionary size to useglobal gzdict_szsz = gc.mem_free() + gc.mem_alloc()if sz <= 65536:gzdict_sz = 16 + 12if install_path is None:install_path = get_install_path()if install_path[-1] != "/":install_path += "/"if not isinstance(to_install, list):to_install = [to_install]print("Installing to: " + install_path)# sets would be perfect here, but don't depend on theminstalled = []try:while to_install:if debug:print("Queue:", to_install)pkg_spec = to_install.pop(0)if pkg_spec in installed:continuemeta = install_pkg(pkg_spec, install_path)installed.append(pkg_spec)if debug:print(meta)deps = meta.get("deps", "").rstrip()if deps:deps = deps.decode("utf-8").split("\n")to_install.extend(deps)except Exception as e:print("Error installing '{}': {}, packages may be partially installed".format(pkg_spec, e),file=sys.stderr,)def get_install_path():global install_pathif install_path is None:# sys.path[0] is current module's pathinstall_path = sys.path[1]install_path = expandhome(install_path)return install_pathdef cleanup():for fname in cleanup_files:try:os.unlink(fname)except OSError:print("Warning: Cannot delete " + fname)def help():print("""\upip - Simple PyPI package manager for MicroPythonUsage: micropython -m upip install [-p <path>] <package>... | -r <requirements.txt>import upip; upip.install(package_or_list, [<path>])If <path> is not given, packages will be installed into sys.path[1](can be set from MICROPYPATH environment variable, if current systemsupports that).""")print("Current value of sys.path[1]:", sys.path[1])print("""\Note: only MicroPython packages (usually, named micropython-*) are supportedfor installation, upip does not support arbitrary code in setup.py.""")def main():global debugglobal index_urlsglobal install_pathinstall_path = Noneif len(sys.argv) < 2 or sys.argv[1] == "-h" or sys.argv[1] == "--help":help()returnif sys.argv[1] != "install":fatal("Only 'install' command supported")to_install = []i = 2while i < len(sys.argv) and sys.argv[i][0] == "-":opt = sys.argv[i]i += 1if opt == "-h" or opt == "--help":help()returnelif opt == "-p":install_path = sys.argv[i]i += 1elif opt == "-r":list_file = sys.argv[i]i += 1with open(list_file) as f:while True:l = f.readline()if not l:breakif l[0] == "#":continueto_install.append(l.rstrip())elif opt == "-i":index_urls = [sys.argv[i]]i += 1elif opt == "--debug":debug = Trueelse:fatal("Unknown/unsupported option: " + opt)to_install.extend(sys.argv[i:])if not to_install:help()returninstall(to_install)if not debug:cleanup()if __name__ == "__main__":main()
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。