[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
bug#29220: 26.0.90; eieio-persistent-read fail to restore saved object.
From: |
Noam Postavsky |
Subject: |
bug#29220: 26.0.90; eieio-persistent-read fail to restore saved object. |
Date: |
Mon, 27 May 2019 19:36:04 -0400 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/26.2 (gnu/linux) |
Eric Abrahamsen <eric@ericabrahamsen.net> writes:
>>> Bah, this is annoyingly difficult -- thank you for trying it out. I
>>> suppose one terrible heuristic would be if the errors were different
>>> between emacs-25, emacs-26, and fix/eieio-persistent. Would you mind
>>> sending me the error output, in case anything jumps out at me?
>>>
>> Hope this could help you.
>
> Thanks. They all end in "Corrupt object on disk", which is an
> eieio-persist problem. I'll keep working on this.
So, I think it would be nice to have this fixed for 26.3. It sounds
like the fix you're working on is too risky to have on a release branch
regardless of its current status, so here's a patch which makes eieio
objects use symbols as type tags, when eieio-backward-compatibility is
non-nil. Folks who want the record-with-circular-references as type
tags can still get that by setting eieio-backward-compatibility to nil.
>From f6cc4509073da4ff23a4227d48b33108b1e96828 Mon Sep 17 00:00:00 2001
From: Noam Postavsky <npostavs@gmail.com>
Date: Mon, 27 May 2019 19:05:56 -0400
Subject: [PATCH] Use plain symbols for eieio type descriptors (Bug#29220)
Since Emacs 26, eieio objects use a class record (with circular
references) as the type descriptor of the object record. This causes
problems when reading back an object from a string, because the class
record is not `eq' to the canonical one (which means that read objects
don't satisfy the foo-p predicate).
* lisp/emacs-lisp/eieio.el (make-instance): As a (partial) fix, set
the record's type descriptor to a plain symbol for the type descriptor
when eieio-backward-compatibility is non-nil (the default).
* lisp/emacs-lisp/eieio-core.el (eieio--object-class): Call
eieio--class-object on the type tag when eieio-backward-compatibility
is non-nil.
(eieio-object-p): Use eieio--object-class instead of
eieio--object-class-tag.
* test/lisp/emacs-lisp/eieio-tests/eieio-test-persist.el
(eieio-test-persist-hash-and-vector)
(eieio-test-persist-interior-lists): `persist-test-save-and-compare'
no longer throws an error.
---
lisp/emacs-lisp/eieio-core.el | 11 +++++++----
lisp/emacs-lisp/eieio.el | 3 +++
test/lisp/emacs-lisp/eieio-tests/eieio-test-persist.el | 6 ++----
3 files changed, 12 insertions(+), 8 deletions(-)
diff --git a/lisp/emacs-lisp/eieio-core.el b/lisp/emacs-lisp/eieio-core.el
index f879a3999f..4d55ed6e1d 100644
--- a/lisp/emacs-lisp/eieio-core.el
+++ b/lisp/emacs-lisp/eieio-core.el
@@ -117,9 +117,6 @@ (eval-and-compile
(defsubst eieio--object-class-tag (obj)
(aref obj 0))
-(defsubst eieio--object-class (obj)
- (eieio--object-class-tag obj))
-
;;; Important macros used internally in eieio.
@@ -132,6 +129,12 @@ (defsubst eieio--class-object (class)
(or (cl--find-class class) class)
class))
+(defsubst eieio--object-class (obj)
+ (let ((tag (eieio--object-class-tag obj)))
+ (if eieio-backward-compatibility
+ (eieio--class-object tag)
+ tag)))
+
(defun class-p (x)
"Return non-nil if X is a valid class vector.
X can also be is a symbol."
@@ -163,7 +166,7 @@ (defsubst eieio--class-option (class option)
(defun eieio-object-p (obj)
"Return non-nil if OBJ is an EIEIO object."
(and (recordp obj)
- (eieio--class-p (eieio--object-class-tag obj))))
+ (eieio--class-p (eieio--object-class obj))))
(define-obsolete-function-alias 'object-p 'eieio-object-p "25.1")
diff --git a/lisp/emacs-lisp/eieio.el b/lisp/emacs-lisp/eieio.el
index 38436d1f94..864ac2616b 100644
--- a/lisp/emacs-lisp/eieio.el
+++ b/lisp/emacs-lisp/eieio.el
@@ -710,6 +710,9 @@ (cl-defmethod make-instance
;; Call the initialize method on the new object with the slots
;; that were passed down to us.
(initialize-instance new-object slots)
+ (when eieio-backward-compatibility
+ ;; Use symbol as type descriptor, for backwards compatibility.
+ (aset new-object 0 class))
;; Return the created object.
new-object))
diff --git a/test/lisp/emacs-lisp/eieio-tests/eieio-test-persist.el
b/test/lisp/emacs-lisp/eieio-tests/eieio-test-persist.el
index dfaa031844..f8a0aa30dd 100644
--- a/test/lisp/emacs-lisp/eieio-tests/eieio-test-persist.el
+++ b/test/lisp/emacs-lisp/eieio-tests/eieio-test-persist.el
@@ -297,8 +297,7 @@ (ert-deftest eieio-test-persist-hash-and-vector ()
(aset (car (slot-value class 'janitors)) 1 hans)
(aset (nth 1 (slot-value class 'janitors)) 1 dierdre)
(unwind-protect
- ;; FIXME: This should not error.
- (should-error (persist-test-save-and-compare class))
+ (persist-test-save-and-compare class)
(delete-file (oref class file)))))
;; Extra quotation of lists inside other objects (Gnus registry), also
@@ -335,8 +334,7 @@ (ert-deftest eieio-test-persist-interior-lists ()
(setf (nth 2 (cadar alst)) john
(nth 2 (cadadr alst)) alexie)
(unwind-protect
- ;; FIXME: Should not error.
- (should-error (persist-test-save-and-compare thing))
+ (persist-test-save-and-compare thing)
(delete-file (slot-value thing 'file)))))
;;; eieio-test-persist.el ends here
--
2.11.0
- bug#29220: 26.0.90; eieio-persistent-read fail to restore saved object.,
Noam Postavsky <=