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

Error: Recursive load #806

Closed
aiguofer opened this issue Nov 21, 2019 · 7 comments
Closed

Error: Recursive load #806

aiguofer opened this issue Nov 21, 2019 · 7 comments

Comments

@aiguofer
Copy link

aiguofer commented Nov 21, 2019

I'm running Emacs 26.3 from Ubuntu repos.

I've recently started getting an issue every time I update packages with straight.el. After I do straight-pull-all followed by straight-rebuild-all, after I restart emacs I get the following error:

Error (use-package): elpy/:init: Recursive load: "/home/aiguofer/.emacs.d/straight/build/elpy/elpy.elc", "/home/aiguofer/.emacs.d/straight/build/elpy/elpy-rpc.elc", "/home/aiguofer/.emacs.d/straight/build/elpy/elpy.elc", "/home/aiguofer/.emacs.d/straight/build/elpy/elpy-rpc.elc", "/home/aiguofer/.emacs.d/straight/build/elpy/elpy.elc", "/home/aiguofer/.emacs.d/straight/build/elpy/elpy-rpc.elc", "/home/aiguofer/.emacs.d/straight/build/elpy/elpy.elc", "/home/aiguofer/.emacs.d/straight/build/elpy/elpy-rpc.elc", "/home/aiguofer/.emacs.d/straight/build/elpy/elpy.elc", "/home/aiguofer/.emacs.d/straight/build/helm-pydoc/helm-pydoc.elc", "/home/aiguofer/.emacs.d/init.el"
Error (use-package): smart-jump/:config: Recursive load: "/home/aiguofer/.emacs.d/straight/build/elpy/elpy.elc", "/home/aiguofer/.emacs.d/straight/build/elpy/elpy-rpc.elc", "/home/aiguofer/.emacs.d/straight/build/elpy/elpy.elc", "/home/aiguofer/.emacs.d/straight/build/elpy/elpy-rpc.elc", "/home/aiguofer/.emacs.d/straight/build/elpy/elpy.elc", "/home/aiguofer/.emacs.d/straight/build/elpy/elpy-rpc.elc", "/home/aiguofer/.emacs.d/straight/build/elpy/elpy.elc", "/home/aiguofer/.emacs.d/straight/build/elpy/elpy-rpc.elc", "/home/aiguofer/.emacs.d/straight/build/elpy/elpy.elc", "/home/aiguofer/.emacs.d/straight/build/smart-jump/smart-jump-python.elc", "/home/aiguofer/.emacs.d/init.el"

If I remove the straight/build/ directory, the next time I start emacs it rebuilds everything and it works as expected. I'm not exactly sure if this is a problem with straight.el or use-package, or maybe the interaction of the 2?

It's reproducible if you do the following (on an empty emacs config):

cd ~/.emacs.d
wget https://raw.githubusercontent.com/aiguofer/dotfiles/master/user/.emacs.d/init.el
wget https://raw.githubusercontent.com/aiguofer/dotfiles/master/user/.emacs.d/custom.el
emacs
# let it load, download straight.el, set up, etc
# exit emacs
emacs
# error should now show in *Warnings*
@jwiegley
Copy link
Owner

Pinging @raxod502, since I know nothing about straight.el.

@raxod502
Copy link
Collaborator

I can't reproduce this following the directions you provided. Could you please demonstrate a minimal example that doesn't involve your full configuration?

@aiguofer
Copy link
Author

Hmm that's weird... I tried this a few times and it happens every time. One thing I did notice is that the error doesn't show up in Messages but in Warnings.

I tried removing everything that seemed unrelated and couldn't get the error to appear, so it was easiest like this. I will try again to reduce it.

@aiguofer
Copy link
Author

Actually, I was able to reproduce it with the following config:

;;; .emacs --- My emacs config -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:

;; Bootstrap `straight.el'
(defvar bootstrap-version)
(let ((bootstrap-file
       (expand-file-name "straight/repos/straight.el/bootstrap.el" user-emacs-directory))
      (bootstrap-version 5))
  (unless (file-exists-p bootstrap-file)
    (with-current-buffer
        (url-retrieve-synchronously
         "https://raw.githubusercontent.com/raxod502/straight.el/develop/install.el"
         'silent 'inhibit-cookies)
      (goto-char (point-max))
      (eval-print-last-sexp)))
  (load bootstrap-file nil 'nomessage))

;; Download and set up use-package
(straight-use-package 'use-package)

(use-package python
  :config
  (use-package elpy
    :straight t
    :bind
    (:map elpy-mode-map
          ("C-M-n" . elpy-nav-forward-block)
          ("C-M-p" . elpy-nav-backward-block))
    :hook ((elpy-mode . flycheck-mode)
           (pyenv-mode . elpy-rpc-restart))
    :init
    (elpy-enable)
    :config
    (setq elpy-modules (delq 'elpy-module-flymake elpy-modules)))

  )

(use-package helm
  :straight t
  :diminish helm-mode
  :bind
  (("M-x" . helm-M-x)
   ("M-y" . helm-show-kill-ring)
   ("C-x b" . helm-mini)
   ("C-c h o" . helm-occur))
  :config
  (helm-mode)
  (helm-adaptive-mode))

(use-package helm-pydoc
  :straight t
  :config
  (with-eval-after-load "python"
    (define-key python-mode-map (kbd "C-c C-d") 'helm-pydoc)))

(use-package smart-jump
  :straight t
  :config
  (smart-jump-setup-default-registers))

;;; init.el ends here

@raxod502
Copy link
Collaborator

@aiguofer in future, it is always helpful to reduce your example as much as possible, otherwise the maintainers (us) have to do it anyway. Here's what I got it down to:

(defvar bootstrap-version)
(let ((bootstrap-file
       (expand-file-name "straight/repos/straight.el/bootstrap.el" user-emacs-directory))
      (bootstrap-version 5))
  (unless (file-exists-p bootstrap-file)
    (with-current-buffer
        (url-retrieve-synchronously
         "https://raw.githubusercontent.com/raxod502/straight.el/develop/install.el"
         'silent 'inhibit-cookies)
      (goto-char (point-max))
      (eval-print-last-sexp)))
  (load bootstrap-file nil 'nomessage))

(straight-use-package 'use-package)

(use-package elpy
  :straight t
  :defer t
  :hook ((pyenv-mode . elpy-rpc-restart))
  :init
  (elpy-enable))

and then based on M-x pp-macroexpand-last-sexp on the use-package form,

(defvar bootstrap-version)
(let ((bootstrap-file
       (expand-file-name "straight/repos/straight.el/bootstrap.el" user-emacs-directory))
      (bootstrap-version 5))
  (unless (file-exists-p bootstrap-file)
    (with-current-buffer
        (url-retrieve-synchronously
         "https://raw.githubusercontent.com/raxod502/straight.el/develop/install.el"
         'silent 'inhibit-cookies)
      (goto-char (point-max))
      (eval-print-last-sexp)))
  (load bootstrap-file nil 'nomessage))

(straight-use-package 'elpy)
(autoload #'elpy-rpc-restart "elpy" nil t)
(require 'elpy)

(I suspect that if you used package.el instead, you would get exactly the same problem, so in future that would be a great thing to check as well before pointing at straight.el.)

In any case, adding some debugging statements in Elpy revealed that the problem is:

  1. use-package creates an autoload for elpy-rpc-restart, seems reasonable
  2. this makes (fboundp #'elpy-rpc-restart) return non-nil, seems reasonable
  3. elpy-rpc.el has a Custom variable with the following code
  :set (lambda (var val)                ;
         (set-default var val)
         (when (fboundp 'elpy-rpc-restart)
           (elpy-rpc-restart)))

which gets evaluated while loading elpy-rpc.el

  1. this code is tricked into thinking that elpy-rpc-restart is already defined, so it calls it, triggering a recursive load because it's actually just a shim that triggers loading Elpy again.

I think Elpy is in the wrong here, and should be patched so that it also verifies (not (autoloadp #'elpy-rpc-restart)) before going ahead and calling it.

The problematic commit is jorgenschaefer/elpy@ff2f8e1 which introduced the code

jorgenschaefer/elpy@ff2f8e1#diff-a01b1e451c8b56727a075f934b1aad0cR239-R243

cc @galaunay

galaunay added a commit to galaunay/elpy that referenced this issue Nov 24, 2019
@galaunay
Copy link

Just fixed it now (commit f64f8e).

I promise to go through the documentation on autoload as a punishment.

@aiguofer
Copy link
Author

Oh wow, you guys are awesome! thanks so much for the thorough debug and quick solution.

I'm curious why there were mentions of /home/aiguofer/.emacs.d/straight/build/smart-jump/smart-jump-python.elc and /home/aiguofer/.emacs.d/straight/build/helm-pydoc/helm-pydoc.elc in the error... I didn't attempt to reduce further since I figured they were involved.

@skangas skangas closed this as completed Nov 13, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants