d0c-s4vage / lookatme

An interactive, terminal-based markdown presenter
https://lookatme.readthedocs.io/en/latest/
MIT License
2.11k stars 63 forks source link

lookatme cannot find ueberzug when it's installed using pipx (ubuntu 22.04, python3.8) #135

Open asdf8601 opened 2 years ago

asdf8601 commented 2 years ago

Describe the bug

Apparently when I run lookatme the extension ueberzug cannot be found as it tries to import it from system environment.

To Reproduce

Steps to reproduce the behavior:

  1. pipx install lookatme
  2. pipx runpip lookatme install lookatme.contrib.image_ueberzug
  3. reload terminal
  4. lookatme ./readme.md
  5. see error

readme.md

---
title: hello
author: mgreco
date: 2022-05-24
extensions:
  - image_ueberzug
---

# Hello world

traceback

docker enh/workshop* (10:49|1s) $ lookatme README.md                                  

                   _mBma
                  sQf "QL
                 jW(   -$g.
                jW'     -$m,
              .y@'  _aa.  4m,
             .mD`  ]QQWQ.  4Q,
            _mP`   ]QQQQ    ?Q/
           _QF     )WQQ@     ?Qc
          <QF       QQQF      )Qa
         jW(        QQQf       "QL
        jW'         ]H8'        -Q6.
      .y@'          _as.         -$m.
     .m@`          ]QQWQ.         -4m,
    _mP`           -?$8!            4Q,
    mE                               $m
    ?$gyygggggggggwywgyygggggggygggggD(

New extensions required by 'README.md' are about to be loaded:

  - 'lookatme.contrib.image_ueberzug'

Are you ok with attempting to load them? (Y/N) y
Traceback (most recent call last):
  File "/home/mgreco/.local/pipx/venvs/lookatme/lib/python3.8/site-packages/lookatme/__main__.py", line 139, in main
    pres.run()
  File "/home/mgreco/.local/pipx/venvs/lookatme/lib/python3.8/site-packages/lookatme/pres.py", line 141, in run
    self.tui = lookatme.tui.create_tui(self, start_slide=start_slide)
  File "/home/mgreco/.local/pipx/venvs/lookatme/lib/python3.8/site-packages/lookatme/tui.py", line 364, in create_tui
    tui = MarkdownTui(pres, start_slide)
  File "/home/mgreco/.local/pipx/venvs/lookatme/lib/python3.8/site-packages/lookatme/tui.py", line 211, in __init__
    root_widget = root_urwid_widget(self.root_margins)
  File "/home/mgreco/.local/pipx/venvs/lookatme/lib/python3.8/site-packages/lookatme/contrib/__init__.py", line 101, in inner
    return getattr(mod, fn_name)(*args, **kwargs)
  File "/home/mgreco/.local/pipx/venvs/lookatme/lib/python3.8/site-packages/lookatme/contrib/image_ueberzug.py", line 26, in root_urwid_widget
    CANVAS = ueberzug.Canvas().__enter__()
  File "/home/mgreco/.local/pipx/venvs/lookatme/lib/python3.8/site-packages/ueberzug/lib/v0/__init__.py", line 384, in __enter__
    self.__process.start()
  File "/home/mgreco/.local/pipx/venvs/lookatme/lib/python3.8/site-packages/ueberzug/lib/v0/__init__.py", line 187, in start
    self.__process = subprocess.Popen(
  File "/usr/lib/python3.8/subprocess.py", line 858, in __init__
    self._execute_child(args, executable, preexec_fn, close_fds,
  File "/usr/lib/python3.8/subprocess.py", line 1704, in _execute_child
    raise child_exception_type(errno_num, err_msg, err_filename)
FileNotFoundError: [Errno 2] No such file or directory: 'ueberzug'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/mgreco/.local/bin/lookatme", line 8, in <module>
    sys.exit(main())
  File "/home/mgreco/.local/pipx/venvs/lookatme/lib/python3.8/site-packages/click/core.py", line 829, in __call__
    return self.main(*args, **kwargs)
  File "/home/mgreco/.local/pipx/venvs/lookatme/lib/python3.8/site-packages/click/core.py", line 782, in main
    rv = self.invoke(ctx)
  File "/home/mgreco/.local/pipx/venvs/lookatme/lib/python3.8/site-packages/click/core.py", line 1066, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/home/mgreco/.local/pipx/venvs/lookatme/lib/python3.8/site-packages/click/core.py", line 610, in invoke
    return callback(*args, **kwargs)
  File "/home/mgreco/.local/pipx/venvs/lookatme/lib/python3.8/site-packages/lookatme/__main__.py", line 141, in main
    number = pres.tui.curr_slide.number + 1
AttributeError: 'NoneType' object has no attribute 'curr_slide'

Environment (please complete the following information):

Additional context

Workaround (this is not what I like to do as I prefer to have all my CLI isolated in differents venvs which is what pipx does).

pip install ueberzug --user
d0c-s4vage commented 2 years ago

This is really weird. I was able to duplicate this locally too:

pipx uninstall lookatme
# to double check - make sure that lookatme's venv isn't present anymore: ls ~/.local/pipx/venvs

# now install lookatme again
pipx install lookatme

# see that there isn't an image_ueberzug.py in the contrib folder:
ls ~/.local/pipx/venvs/lookatme/lib/python*/site-packages/lookatme/contrib
# output> file_loader.py  __init__.py  __pycache__  terminal.py

# see the expected error manually activating the lookatme pipx venv
(. ~/.local/pipx/venvs/lookatme/bin/activate && python3 -c "import lookatme.contrib.image_ueberzug")
# output> Traceback (most recent call last):                                                                                     │
# output>   File "<string>", line 1, in <module>                                                                                 │
# output> ModuleNotFoundError: No module named 'lookatme.contrib.image_ueberzug'

pipx runpip lookatme install lookatme.contrib.image_ueberzug
# this doesn't error anymore!
(. ~/.local/pipx/venvs/lookatme/bin/activate && python3 -c "import lookatme.contrib.image_ueberzug")

# So it SHOULD work with pipx run lookatme ....
pipx run lookatme slideshow_with_image_ueberzug.md # errors
# output> ...
# output> No module named 'lookatme.contrib.image_ueberzug'

# But it DOES work manually activating the environment and running lookatme
(. ~/.local/pipx/venvs/lookatme/bin/activate && lookatme slideshow_with_image_ueberzug.md)

As far as I can tell, this isn't something that is lookatme's fault. lookatme is using the normal import system to import the fully-qualified contrib module (code link):

        module_name = f"lookatme.contrib.{contrib_name}"
        try:
            mod = __import__(module_name, fromlist=[contrib_name])
        except Exception as e:
            if ignore_load_failure:
                continue
            errors.append(str(e))