Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Poetry install: broken dependencies #3687

Closed
martin-tomes opened this issue Apr 7, 2024 · 7 comments · Fixed by #3730
Closed

Poetry install: broken dependencies #3687

martin-tomes opened this issue Apr 7, 2024 · 7 comments · Fixed by #3730
Labels
bug Something isn't working as expected

Comments

@martin-tomes
Copy link

Describe the bug
After cloning the main branch poetry won't install pyyaml depenency with python version 3.12.2 and older (see bellow).

Firmware version and revision
main branch. Just cloned git clone --recurse-submodules https://github.com/trezor/trezor-firmware.git
poetry install

Desktop setup:

  • OS: macOS Sonoma 14.4.1 (23E224)
  • python: 3.12.2 also occurs on 3.11.9, 3.8.1 and 3.8.2

To Reproduce
Steps to reproduce the behavior just follow the build instructions from docs:

  1. git clone --recurse-submodules https://github.com/trezor/trezor-firmware.git
  2. cd trezor-firmware
  3. poetry install

Expected behavior
No error. I can proceed to
4. cd core

Screenshots

 Installing pyyaml (6.0): Failed

  ChefBuildError

  Backend subprocess exited when trying to invoke get_requires_for_build_wheel

  running egg_info
  writing lib/PyYAML.egg-info/PKG-INFO
  writing dependency_links to lib/PyYAML.egg-info/dependency_links.txt
  writing top-level names to lib/PyYAML.egg-info/top_level.txt
  Traceback (most recent call last):
    File "/Users/martin/Library/Application Support/pipx/venvs/poetry/lib/python3.12/site-packages/pyproject_hooks/_in_process/_in_process.py", line 353, in <module>
      main()
    File "/Users/martin/Library/Application Support/pipx/venvs/poetry/lib/python3.12/site-packages/pyproject_hooks/_in_process/_in_process.py", line 335, in main
      json_out['return_val'] = hook(**hook_input['kwargs'])
                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    File "/Users/martin/Library/Application Support/pipx/venvs/poetry/lib/python3.12/site-packages/pyproject_hooks/_in_process/_in_process.py", line 118, in get_requires_for_build_wheel
      return hook(config_settings)
             ^^^^^^^^^^^^^^^^^^^^^
    File "/private/var/folders/zh/s5jmjfgn78vcz6ryn05ghls00000gn/T/tmpwonam_m1/.venv/lib/python3.12/site-packages/setuptools/build_meta.py", line 325, in get_requires_for_build_wheel
      return self._get_build_requires(config_settings, requirements=['wheel'])
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    File "/private/var/folders/zh/s5jmjfgn78vcz6ryn05ghls00000gn/T/tmpwonam_m1/.venv/lib/python3.12/site-packages/setuptools/build_meta.py", line 295, in _get_build_requires
      self.run_setup()
    File "/private/var/folders/zh/s5jmjfgn78vcz6ryn05ghls00000gn/T/tmpwonam_m1/.venv/lib/python3.12/site-packages/setuptools/build_meta.py", line 311, in run_setup
      exec(code, locals())
    File "<string>", line 288, in <module>
    File "/private/var/folders/zh/s5jmjfgn78vcz6ryn05ghls00000gn/T/tmpwonam_m1/.venv/lib/python3.12/site-packages/setuptools/__init__.py", line 104, in setup
      return distutils.core.setup(**attrs)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    File "/private/var/folders/zh/s5jmjfgn78vcz6ryn05ghls00000gn/T/tmpwonam_m1/.venv/lib/python3.12/site-packages/setuptools/_distutils/core.py", line 185, in setup
      return run_commands(dist)
             ^^^^^^^^^^^^^^^^^^
    File "/private/var/folders/zh/s5jmjfgn78vcz6ryn05ghls00000gn/T/tmpwonam_m1/.venv/lib/python3.12/site-packages/setuptools/_distutils/core.py", line 201, in run_commands
      dist.run_commands()
    File "/private/var/folders/zh/s5jmjfgn78vcz6ryn05ghls00000gn/T/tmpwonam_m1/.venv/lib/python3.12/site-packages/setuptools/_distutils/dist.py", line 969, in run_commands
      self.run_command(cmd)
    File "/private/var/folders/zh/s5jmjfgn78vcz6ryn05ghls00000gn/T/tmpwonam_m1/.venv/lib/python3.12/site-packages/setuptools/dist.py", line 967, in run_command
      super().run_command(command)
    File "/private/var/folders/zh/s5jmjfgn78vcz6ryn05ghls00000gn/T/tmpwonam_m1/.venv/lib/python3.12/site-packages/setuptools/_distutils/dist.py", line 988, in run_command
      cmd_obj.run()
    File "/private/var/folders/zh/s5jmjfgn78vcz6ryn05ghls00000gn/T/tmpwonam_m1/.venv/lib/python3.12/site-packages/setuptools/command/egg_info.py", line 321, in run
      self.find_sources()
    File "/private/var/folders/zh/s5jmjfgn78vcz6ryn05ghls00000gn/T/tmpwonam_m1/.venv/lib/python3.12/site-packages/setuptools/command/egg_info.py", line 329, in find_sources
      mm.run()
    File "/private/var/folders/zh/s5jmjfgn78vcz6ryn05ghls00000gn/T/tmpwonam_m1/.venv/lib/python3.12/site-packages/setuptools/command/egg_info.py", line 550, in run
      self.add_defaults()
    File "/private/var/folders/zh/s5jmjfgn78vcz6ryn05ghls00000gn/T/tmpwonam_m1/.venv/lib/python3.12/site-packages/setuptools/command/egg_info.py", line 588, in add_defaults
      sdist.add_defaults(self)
    File "/private/var/folders/zh/s5jmjfgn78vcz6ryn05ghls00000gn/T/tmpwonam_m1/.venv/lib/python3.12/site-packages/setuptools/command/sdist.py", line 102, in add_defaults
      super().add_defaults()
    File "/private/var/folders/zh/s5jmjfgn78vcz6ryn05ghls00000gn/T/tmpwonam_m1/.venv/lib/python3.12/site-packages/setuptools/_distutils/command/sdist.py", line 251, in add_defaults
      self._add_defaults_ext()
    File "/private/var/folders/zh/s5jmjfgn78vcz6ryn05ghls00000gn/T/tmpwonam_m1/.venv/lib/python3.12/site-packages/setuptools/_distutils/command/sdist.py", line 336, in _add_defaults_ext
      self.filelist.extend(build_ext.get_source_files())
                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    File "<string>", line 204, in get_source_files
    File "/private/var/folders/zh/s5jmjfgn78vcz6ryn05ghls00000gn/T/tmpwonam_m1/.venv/lib/python3.12/site-packages/setuptools/_distutils/cmd.py", line 107, in __getattr__
      raise AttributeError(attr)
  AttributeError: cython_sources


  at ~/Library/Application Support/pipx/venvs/poetry/lib/python3.12/site-packages/poetry/installation/chef.py:164 in _prepare

 160│
      161│                 error = ChefBuildError("\n\n".join(message_parts))
      162│
      163│             if error is not None:
    → 164│                 raise error from None
      165│
      166│             return path
      167│
      168│     def _prepare_sdist(self, archive: Path, destination: Path | None = None) -> Path:

Note: This error originates from the build backend, and is likely not a problem with poetry but with pyyaml (6.0) not supporting PEP 517 builds. You can verify this by running 'pip wheel --no-cache-dir --use-pep517 "pyyaml (==6.0)"'.

Additional context

The problem is caused by pyyaml version 6.0 as described here. The problem is fixed in pyyaml version 6.0.1 which, for some reason, is not installed during the poetry installation process.

I suspect some dependency requires exactly 6.0.0 version. I have tried to install the pyyaml in an empty dummy project with the exact dependency from trezor-firmware/poetry.lock :

 891 testing = ["astroid (>=1.5.3,<1.6.0)", "astroid (>=2.0)", "coverage", "pylint (>=1.7.2,<1.8.0)", "pylint (>=2.3.1,<2.4.0)", "pytest"]
 892 yaml = ["PyYAML (>=5.1.0)"]

and the latest version 6.0.1 was installed without problems.

As a workaround I have tried to remove the poetry.lock file and add pyyaml version 6.0.1 as the project dependency in pyproject.toml:

[tool.poetry.dependencies]
# all
python = "^3.8.1"
trezor = {path = "./python", develop = true}
scons = "*"
protobuf = "*"
nanopb = "^0.4.3"
pyyaml = "=>6.0.1"

Which installs the pyyaml correctly but throws another error. The ed25519 installation now failing:

Installing ed25519 (1.5): Failed

  ChefBuildError

  Backend subprocess exited when trying to invoke get_requires_for_build_wheel

  /private/var/folders/zh/s5jmjfgn78vcz6ryn05ghls00000gn/T/tmp3vvasons/ed25519-1.5/versioneer.py:467: SyntaxWarning: invalid escape sequence '\s'
    LONG_VERSION_PY['git'] = '''
  Traceback (most recent call last):
    File "/Users/martin/Library/Application Support/pipx/venvs/poetry/lib/python3.12/site-packages/pyproject_hooks/_in_process/_in_process.py", line 353, in <module>
      main()
    File "/Users/martin/Library/Application Support/pipx/venvs/poetry/lib/python3.12/site-packages/pyproject_hooks/_in_process/_in_process.py", line 335, in main
      json_out['return_val'] = hook(**hook_input['kwargs'])
                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    File "/Users/martin/Library/Application Support/pipx/venvs/poetry/lib/python3.12/site-packages/pyproject_hooks/_in_process/_in_process.py", line 118, in get_requires_for_build_wheel
      return hook(config_settings)
             ^^^^^^^^^^^^^^^^^^^^^
    File "/private/var/folders/zh/s5jmjfgn78vcz6ryn05ghls00000gn/T/tmpic8gg11o/.venv/lib/python3.12/site-packages/setuptools/build_meta.py", line 325, in get_requires_for_build_wheel
      return self._get_build_requires(config_settings, requirements=['wheel'])
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    File "/private/var/folders/zh/s5jmjfgn78vcz6ryn05ghls00000gn/T/tmpic8gg11o/.venv/lib/python3.12/site-packages/setuptools/build_meta.py", line 295, in _get_build_requires
      self.run_setup()
    File "/private/var/folders/zh/s5jmjfgn78vcz6ryn05ghls00000gn/T/tmpic8gg11o/.venv/lib/python3.12/site-packages/setuptools/build_meta.py", line 487, in run_setup
      super().run_setup(setup_script=setup_script)
    File "/private/var/folders/zh/s5jmjfgn78vcz6ryn05ghls00000gn/T/tmpic8gg11o/.venv/lib/python3.12/site-packages/setuptools/build_meta.py", line 311, in run_setup
      exec(code, locals())
    File "<string>", line 115, in <module>
    File "/private/var/folders/zh/s5jmjfgn78vcz6ryn05ghls00000gn/T/tmp3vvasons/ed25519-1.5/versioneer.py", line 1405, in get_version
      return get_versions()["version"]
             ^^^^^^^^^^^^^^
    File "/private/var/folders/zh/s5jmjfgn78vcz6ryn05ghls00000gn/T/tmp3vvasons/ed25519-1.5/versioneer.py", line 1339, in get_versions
      cfg = get_config_from_root(root)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^
    File "/private/var/folders/zh/s5jmjfgn78vcz6ryn05ghls00000gn/T/tmp3vvasons/ed25519-1.5/versioneer.py", line 399, in get_config_from_root
      parser = configparser.SafeConfigParser()
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  AttributeError: module 'configparser' has no attribute 'SafeConfigParser'. Did you mean: 'RawConfigParser'?

The problem with ed25519 could be caused by changing the configparser API in python 3.12 as described here. The problem seems to be with package versioneer in particular which does not seem to be supporting the latest python as described here

So, I tried several python environments older than 3.12 (3.11.9, 3.8.1 and 3.8.2).

With these older version I got error when installing curve25519-donna package:

 Installing curve25519-donna (1.3): Failed

  ChefBuildError

  Backend subprocess exited when trying to invoke build_wheel

  python-src/curve25519/curve25519module.c:90:9: error: incompatible pointer to integer conversion initializing 'Py_ssize_t' (aka 'long') with an expression of type 'void *' [-Wint-conversion]
          NULL,
          ^~~~
  /Library/Developer/CommandLineTools/SDKs/MacOSX14.sdk/usr/include/sys/_types/_null.h:30:15: note: expanded from macro 'NULL'
  #define NULL  __DARWIN_NULL
                ^~~~~~~~~~~~~
  /Library/Developer/CommandLineTools/SDKs/MacOSX14.sdk/usr/include/sys/_types.h:52:23: note: expanded from macro '__DARWIN_NULL'
  #define __DARWIN_NULL ((void *)0)
                        ^~~~~~~~~~~
  1 error generated.
  error: command '/usr/bin/clang' failed with exit code 1

In sum, it is very nice dependency hell and I wonder if there is anyone who could confirm this bug and/or tell me what is the working python version setup on mac OS for the current master branch.

@martin-tomes martin-tomes added the bug Something isn't working as expected label Apr 7, 2024
@matejcik
Copy link
Contributor

well me what is the working python version setup on mac OS for the current master branch.

Going with nixos is the safe bet. You can install nix on your Mac and then enter nix-shell in the trezor-firmware checkout, which should give you working versions of everything.

@prusnak
Copy link
Member

prusnak commented Apr 16, 2024

PyYAML issue fixed here: #3720
ed25519 issue has no easy fix I am afraid ... maybe we should us another library that was not abandoned in 2019

@matejcik
Copy link
Contributor

iiiiii don't think we even need the ed25519 package.......... trezorlib has its own internal pure-Python implementation, and i don't see any imports mentioning it.
i'll make a PR that tries to drop it

@matejcik
Copy link
Contributor

curve25519-donna is used in crypto tests -- and in some strange manner too, i'm having trouble replacing it with any other library. but I don't think breaking the whole env just for two test cases is the right thing to do

@onvej-sl you're probably the person who can best look at test_curves.py:test_curve25519 and figure out how to drop the curve25519-donna dependency?
i'm thinking, we should be able to use _ed25519.py from trezorlib, but any way I call things i'm getting bad results

@onvej-sl
Copy link
Contributor

i'm thinking, we should be able to use _ed25519.py from trezorlib, but any way I call things i'm getting bad results

This doesn't work because _ed225519.py implements ed25519 instead of curve25519. Nevertheless, both the curves are birationally equivalent. This means the underlying groups are isomorphic and the isomorphism is easily computable.

@onvej-sl you're probably the person who can best look at test_curves.py:test_curve25519 and figure out how to drop the curve25519-donna dependency?

I think we can use the package cryptography which is already used in device tests.

@onvej-sl
Copy link
Contributor

onvej-sl commented Apr 16, 2024

See the diff:
--- a/crypto/tests/test_curves.py
+++ b/crypto/tests/test_curves.py
@@ -5,9 +5,9 @@ import hashlib
 import os
 import random
 
-import curve25519
 import ecdsa
 import pytest
+from cryptography.hazmat.primitives.asymmetric.x25519 import X25519PrivateKey
 
 
 def bytes2num(s):
@@ -344,17 +344,17 @@ def test_validate_pubkey_direct(point):
 def test_curve25519(r):
     sec1 = bytes(bytearray(r.randbytes(32)))
     sec2 = bytes(bytearray(r.randbytes(32)))
-    pub1 = curve25519.Private(sec1).get_public()
-    pub2 = curve25519.Private(sec2).get_public()
+    pub1 = X25519PrivateKey.from_private_bytes(sec1).public_key()
+    pub2 = X25519PrivateKey.from_private_bytes(sec2).public_key()
 
     session1 = r.randbytes(32)
-    lib.curve25519_scalarmult(session1, sec2, pub1.public)
+    lib.curve25519_scalarmult(session1, sec2, pub1.public_bytes_raw())
     session2 = r.randbytes(32)
-    lib.curve25519_scalarmult(session2, sec1, pub2.public)
+    lib.curve25519_scalarmult(session2, sec1, pub2.public_bytes_raw())
     assert bytearray(session1) == bytearray(session2)
 
-    shared1 = curve25519.Private(sec2).get_shared_key(pub1, hashfunc=lambda x: x)
-    shared2 = curve25519.Private(sec1).get_shared_key(pub2, hashfunc=lambda x: x)
+    shared1 = X25519PrivateKey.from_private_bytes(sec2).exchange(pub1)
+    shared2 = X25519PrivateKey.from_private_bytes(sec1).exchange(pub2)
     assert shared1 == shared2
     assert bytearray(session1) == shared1
     assert bytearray(session2) == shared2
@@ -362,10 +362,10 @@ def test_curve25519(r):
 
 def test_curve25519_pubkey(r):
     sec = bytes(bytearray(r.randbytes(32)))
-    pub = curve25519.Private(sec).get_public()
+    pub = X25519PrivateKey.from_private_bytes(sec).public_key()
     res = r.randbytes(32)
     lib.curve25519_scalarmult_basepoint(res, sec)
-    assert bytearray(res) == pub.public
+    assert bytearray(res) == pub.public_bytes_raw()
 
 
 def test_curve25519_scalarmult_from_gpg(r):

@prusnak
Copy link
Member

prusnak commented Apr 17, 2024

See the diff:

Perfect. Let's do this and drop both curve-donna and ed25519 from pyproject.toml -> #3730

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working as expected
Projects
Archived in project
Development

Successfully merging a pull request may close this issue.

4 participants