mikedh / trimesh

Python library for loading and using triangular meshes.
https://trimesh.org
MIT License
2.95k stars 574 forks source link

pyembree isn't optional #728

Open df7cb opened 4 years ago

df7cb commented 4 years ago

Hi, I'm working on getting trimesh packaged for Debian because Cura needs it. The trimesh README says that the pyemtree (which isn't packaged for Debian yet) dependency is optional, but that doesn't seem to be the case:

   dh_auto_test -O--buildsystem=pybuild
I: pybuild base:217: cd /srv/debian/3d/trimesh/trimesh/.pybuild/cpython3_3.8/build; python3.8 -m unittest discover -v 
Traceback (most recent call last):
  File "/usr/lib/python3.8/runpy.py", line 193, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "/usr/lib/python3.8/runpy.py", line 86, in _run_code
    exec(code, run_globals)
  File "/usr/lib/python3.8/unittest/__main__.py", line 18, in <module>
    main(module=None)
  File "/usr/lib/python3.8/unittest/main.py", line 100, in __init__
    self.parseArgs(argv)
  File "/usr/lib/python3.8/unittest/main.py", line 124, in parseArgs
    self._do_discovery(argv[2:])
  File "/usr/lib/python3.8/unittest/main.py", line 244, in _do_discovery
    self.createTests(from_discovery=True, Loader=Loader)
  File "/usr/lib/python3.8/unittest/main.py", line 154, in createTests
    self.test = loader.discover(self.start, self.pattern, self.top)
  File "/usr/lib/python3.8/unittest/loader.py", line 349, in discover
    tests = list(self._find_tests(start_dir, pattern))
  File "/usr/lib/python3.8/unittest/loader.py", line 414, in _find_tests
    yield from self._find_tests(full_path, pattern, namespace)
  File "/usr/lib/python3.8/unittest/loader.py", line 405, in _find_tests
    tests, should_recurse = self._find_test_path(
  File "/usr/lib/python3.8/unittest/loader.py", line 483, in _find_test_path
    tests = self.loadTestsFromModule(package, pattern=pattern)
  File "/usr/lib/python3.8/unittest/loader.py", line 123, in loadTestsFromModule
    if isinstance(obj, type) and issubclass(obj, case.TestCase):
  File "/srv/debian/3d/trimesh/trimesh/.pybuild/cpython3_3.8/build/trimesh/exceptions.py", line 23, in __getattribute__
    raise super(ExceptionModule, self).__getattribute__('exc')
  File "/srv/debian/3d/trimesh/trimesh/.pybuild/cpython3_3.8/build/trimesh/ray/__init__.py", line 5, in <module>
    from . import ray_pyembree
  File "/srv/debian/3d/trimesh/trimesh/.pybuild/cpython3_3.8/build/trimesh/ray/ray_pyembree.py", line 9, in <module>
    from pyembree import __version__ as _ver
ModuleNotFoundError: No module named 'pyembree'
E: pybuild pybuild:341: test: plugin distutils failed with: exit code=1: cd /srv/debian/3d/trimesh/trimesh/.pybuild/cpython3_3.8/build; python3.8 -m unittest discover -v 
dh_auto_test: error: pybuild --test -i python{version} -p "3.8 3.7" returned exit code 13

For reference, the packaging repo is https://salsa.debian.org/3dprinting-team/trimesh.

df7cb commented 4 years ago

Full build log: https://salsa.debian.org/3dprinting-team/trimesh/-/jobs/589222

onitake commented 4 years ago

It does look like it's only a "hard" dependency because dpkg is running all unit tests by default.

What would be the best way to solve this problem? Make pyembree an actual soft dependency by import-guarding it? What should the expected behaviour be if it's not found?

try:
    from pyembree import __version__ as _ver
except ImportError:
    # skip rest of file? provide stubs?
mikedh commented 4 years ago

Thanks for the report, and also thanks for the great packaging work! Happy to help and I'd love to get trimesh in to dpkg.

Yeah pyembree is "soft" in the sense that you can run trimesh without it. I guess the real question is "should all unit tests pass with only a minimal install" which I think the answer is probably "yes." I'll poke around and try to make that a true statement, though also happy to accept PR's! I'm working on a branch which would unify all of trimesh's CI to Github Actions (from a mix of travis/circle/appveyor), and I can definitely add a step which runs pytest on a minimal install.

It seems like the "soft" dependencies would align pretty well with the concept of Debian package recommends? Though interested in your take on that!

mikedh commented 4 years ago

To narrow down on the issue from the build logs slightly: "With a minimal install of trimesh, python -m unittest discover -v should execute correctly"

onitake commented 4 years ago

This may help: http://doc.pytest.org/en/latest/skipping.html#skipping-on-a-missing-import-dependency

df7cb commented 4 years ago

Indeed the soft dependencies align pretty well with "Recommends". Thanks for looking into this!

mikedh commented 4 years ago

Unfortunately I think pyembree is the tip of the iceberg here. I was able to fix that failure, but then there are 179 more (out of 349 total tests).

Is there any way to change the test command the Debian build runs? I was testing minimal installs locally with:

FROM python:3.7-slim-buster

# copy and install trimesh
COPY . /tmp/trimesh
RUN cd /tmp/trimesh && pip install . pytest

# run tests in the same way as debian packaging
# RUN cd /tmp/trimesh && python -m unittest discover -v
# run tests with pytest
RUN cd /tmp/trimesh && pytest