diff --git a/contrib/deterministic-build/find_restricted_dependencies.py b/contrib/deterministic-build/find_restricted_dependencies.py index d0cf01b2e..476e81018 100755 --- a/contrib/deterministic-build/find_restricted_dependencies.py +++ b/contrib/deterministic-build/find_restricted_dependencies.py @@ -6,40 +6,58 @@ try: except ImportError as e: sys.exit(f"Error: {str(e)}. Try 'sudo python3 -m pip install '") +def is_dependency_edge_blacklisted(*, parent_pkg: str, dep: str) -> bool: + """Sometimes a package declares a hard dependency + for some niche functionality that we really do not care about. + """ + dep = dep.lower() + parent_pkg = parent_pkg.lower() + return (parent_pkg, dep) in { + ("qrcode", "colorama"), # only needed for using qrcode-CLI on Windows. + ("click", "colorama"), # 'click' is a CLI tool, and it only needs colorama on Windows. + # In fact, we should blacklist 'click' itself, but that should be done elsewhere. + } -def check_restriction(p, r): + +def check_restriction(*, dep: str, restricted: str, parent_pkg: str): # See: https://www.python.org/dev/peps/pep-0496/ # Hopefully we don't need to parse the whole microlanguage - if "extra" in r and "[" not in p: + if is_dependency_edge_blacklisted(dep=dep, parent_pkg=parent_pkg): + return False + if "extra" in restricted and "[" not in dep: return False for marker in ["os_name", "platform_release", "sys_platform", "platform_system"]: - if marker in r: + if marker in restricted: return True + return False -for p in sys.stdin.read().split(): - p = p.strip() - if not p: - continue - assert "==" in p, "This script expects a list of packages with pinned version, e.g. package==1.2.3, not {}".format(p) - p, v = p.rsplit("==", 1) - try: - data = requests.get("https://pypi.org/pypi/{}/{}/json".format(p, v)).json()["info"] - except ValueError: - raise Exception("Package could not be found: {}=={}".format(p, v)) - try: - for r in data["requires_dist"]: # type: str - if ";" not in r: - continue - # example value for "r" at this point: "pefile (>=2017.8.1) ; sys_platform == \"win32\"" - dep, restricted = r.split(";", 1) - dep = dep.strip() - restricted = restricted.strip() - dep_basename = dep.split(" ")[0] - if check_restriction(dep, restricted): - print(dep_basename, sep=" ") - print("Installing {} from {} although it is only needed for {}".format(dep, p, restricted), file=sys.stderr) - except TypeError: - # Has no dependencies at all - continue +def main(): + for p in sys.stdin.read().split(): + p = p.strip() + if not p: + continue + assert "==" in p, "This script expects a list of packages with pinned version, e.g. package==1.2.3, not {}".format(p) + p, v = p.rsplit("==", 1) + try: + data = requests.get("https://pypi.org/pypi/{}/{}/json".format(p, v)).json()["info"] + except ValueError: + raise Exception("Package could not be found: {}=={}".format(p, v)) + try: + for r in data["requires_dist"]: # type: str + if ";" not in r: + continue + # example value for "r" at this point: "pefile (>=2017.8.1) ; sys_platform == \"win32\"" + dep, restricted = r.split(";", 1) + dep = dep.strip() + restricted = restricted.strip() + dep_basename = dep.split(" ")[0] + if check_restriction(dep=dep, restricted=restricted, parent_pkg=p): + print(dep_basename, sep=" ") + print("Installing {} from {} although it is only needed for {}".format(dep, p, restricted), file=sys.stderr) + except TypeError: + # Has no dependencies at all + continue +if __name__ == "__main__": + main() diff --git a/contrib/requirements/requirements-hw.txt b/contrib/requirements/requirements-hw.txt index 1b3fa9b4f..d891b7cf3 100644 --- a/contrib/requirements/requirements-hw.txt +++ b/contrib/requirements/requirements-hw.txt @@ -26,8 +26,3 @@ bitbox02>=6.2.0 # device plugin: jade cbor2>=5.4.6,<6.0.0 pyserial>=3.5.0,<4.0.0 - -# prefer older colorama to avoid needing hatchling -# (pulled in via trezor -> click -> colorama) -# (pulled in via safet -> click -> colorama) -colorama<0.4.6