Subject: bug#76528: 30; Advising functions can cause docstring to be lost

From: Jonas Bernoulli <[email-masked]>
Date: Mon, 24 Feb 2025 19:25:36 +0100

Hello,

Depending on where the docstring is stored, advising a function can
cause its original docstring to be lost.  This also affects 29.4 at
least.

(defun embeded-docstr () "embeded docstr" nil)

(defun property-docstr () nil)
(put 'property-docstr 'function-documentation "property docstr")

(defalias 'alias-docstr 'identity "alias docstr")

(defun maybe-loose-docstring (symbol)
  (let ((a (documentation symbol))
        (b nil)
        (advice (lambda (fn &rest args) (apply fn args))))
    (advice-add symbol :around advice)
    (setq b (documentation symbol))
    (advice-remove symbol advice)
    `((,a) (,b) (,(documentation symbol)))))

(maybe-loose-docstring 'embeded-docstr)
=> (("embeded docstr\n\n(fn)")
    ("embeded docstr\n\nThis function has :around advice: No documentation\n\n(fn)")
    ("embeded docstr\n\n(fn)"))

(maybe-loose-docstring 'property-docstr)
=> (("property docstr")
    ("\nThis function has :around advice: No documentation\n\n(fn)")
    ("\n\n(fn)"))

(maybe-loose-docstring 'alias-docstr)
=> (("alias docstr")
    ("Return the ARGUMENT unchanged.\n\nThis function has :around advice: No documentation\n\n(fn ARGUMENT)")
    ("Return the ARGUMENT unchanged.\n\n(fn ARGUMENT)"))

Best regards,
Jonas