Skip to content

Fix fricas doctest pickling #40570

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

Closed
wants to merge 8 commits into from

Conversation

cxzhong
Copy link
Contributor

@cxzhong cxzhong commented Aug 11, 2025

Fix FriCAS doctest pickling failures

Problem: Doctests in sage.interfaces.fricas were failing with TypeError: cannot pickle 'sage.misc.lazy_import.LazyImport' object when testing fricas == loads(dumps(fricas)).

sage: fricas == loads(dumps(fricas))
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
File ~/sage/src/sage/misc/persist.pyx:338, in sage.misc.persist.dumps()
    337         type_obj = type((<LazyImport>obj).get_object())
--> 338     ans = type_obj.dumps(obj, compress)
    339 except (AttributeError, RuntimeError, TypeError):

File ~/sage/src/sage/structure/sage_object.pyx:508, in sage.structure.sage_object.SageObject.dumps()
    507
--> 508         return _base_dumps(self, compress=compress)
    509

File ~/sage/src/sage/misc/persist.pyx:306, in sage.misc.persist._base_dumps()
    305 global already_pickled
--> 306 gherkin = SagePickler.dumps(obj)
    307 already_pickled = {}

File ~/sage/src/sage/misc/persist.pyx:830, in sage.misc.persist.SagePickler.dumps()
    829 pickler = cls(buf, **kwargs)
--> 830 pickler.dump(obj)
    831 already_pickled = {}

TypeError: cannot pickle 'sage.misc.lazy_import.LazyImport' object

During handling of the above exception, another exception occurred:

TypeError                                 Traceback (most recent call last)
Cell In[1], line 1
----> 1 fricas == loads(dumps(fricas))

File ~/sage/src/sage/misc/persist.pyx:340, in sage.misc.persist.dumps()
    338     ans = type_obj.dumps(obj, compress)
    339 except (AttributeError, RuntimeError, TypeError):
--> 340     ans = _base_dumps(obj, compress=compress)
    341 already_pickled = {}
    342 return ans

File ~/sage/src/sage/misc/persist.pyx:306, in sage.misc.persist._base_dumps()
    304
    305     global already_pickled
--> 306     gherkin = SagePickler.dumps(obj)
    307     already_pickled = {}
    308

File ~/sage/src/sage/misc/persist.pyx:830, in sage.misc.persist.SagePickler.dumps()
    828 buf = io.BytesIO()
    829 pickler = cls(buf, **kwargs)
--> 830 pickler.dump(obj)
    831 already_pickled = {}
    832 return buf.getvalue()

TypeError: cannot pickle 'sage.misc.lazy_import.LazyImport' object

Solution: Replace the problematic equality test with isinstance(loads(dumps(a)), FriCAS) using a fresh FriCAS instance instead of the global fricas object, which contains unpicklable lazy imports.

Changes:

Modified doctests in FriCAS.__init__ and FriCAS._quit_string methods
Preserves serialization testing while avoiding LazyImport pickling issues

📝 Checklist

  • The title is concise and informative.
  • The description explains in detail what this PR is about.
  • I have linked a relevant issue or discussion.
  • I have created tests covering the changes.
  • I have updated the documentation and checked the documentation preview.

⌛ Dependencies

Replace problematic doctest 'fricas == loads(dumps(fricas))' with
'isinstance(loads(dumps(a)), FriCAS)' where a is a fresh FriCAS instance.

The original test was failing because the global 'fricas' object contains
module-level lazy imports that cannot be pickled. Using a fresh instance
and checking type instead of equality avoids the LazyImport pickling issue
while still validating serialization round-trip functionality.

Fixes doctest failures in sage.interfaces.fricas.FriCAS.__init__ and
sage.interfaces.fricas.FriCAS._quit_string methods.
Fix ruff linting error W293 by removing trailing whitespace from blank line in doctest.
Remove malformed literal block structure in TESTS section that was
causing RST218 error. Properly format the doctest examples.
Remove TESTS:: header that was causing RST218 literal block formatting error
while preserving the meaningful doctest that verifies new process starts
after quit(). This addresses linting compliance while maintaining
documentation quality.
Copy link

github-actions bot commented Aug 11, 2025

Documentation preview for this PR (built with commit b38bf8d; changes) is ready! 🎉
This preview will update shortly after each push to this PR.

@cxzhong cxzhong marked this pull request as ready for review August 11, 2025 12:36
@tscrim
Copy link
Collaborator

tscrim commented Aug 13, 2025

This test works for me (both from the command line and running sage -t on the interface file). The test should resolve the lazy import, which would make it pass. You have fricas installed, correct?

@cxzhong
Copy link
Contributor Author

cxzhong commented Aug 13, 2025

This test works for me (both from the command line and running sage -t on the interface file). The test should resolve the lazy import, which would make it pass. You have fricas installed, correct?

@tscrim do you use system's fricas or sage's fricas?Thank you for your reply.

@tscrim
Copy link
Collaborator

tscrim commented Aug 13, 2025

This test works for me (both from the command line and running sage -t on the interface file). The test should resolve the lazy import, which would make it pass. You have fricas installed, correct?

@tscrim do you use system's fricas or sage's fricas?Thank you for your reply.

@cxzhong Sage's fricas.

@cxzhong
Copy link
Contributor Author

cxzhong commented Aug 13, 2025

This test works for me (both from the command line and running sage -t on the interface file). The test should resolve the lazy import, which would make it pass. You have fricas installed, correct?

@tscrim do you use system's fricas or sage's fricas?Thank you for your reply.

@cxzhong Sage's fracas.

@tscrim Thank you. I rebuild sage and fricas. But I found that

sage: fricas == loads(dumps(fricas))
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
File sage/misc/persist.pyx:338, in sage.misc.persist.dumps()

File sage/structure/sage_object.pyx:508, in sage.structure.sage_object.SageObject.dumps()

File sage/misc/persist.pyx:306, in sage.misc.persist._base_dumps()

File sage/misc/persist.pyx:830, in sage.misc.persist.SagePickler.dumps()

TypeError: cannot pickle 'sage.misc.lazy_import.LazyImport' object

During handling of the above exception, another exception occurred:

TypeError                                 Traceback (most recent call last)
Cell In[1], line 1
----> 1 fricas == loads(dumps(fricas))

File sage/misc/persist.pyx:340, in sage.misc.persist.dumps()

File sage/misc/persist.pyx:306, in sage.misc.persist._base_dumps()

File sage/misc/persist.pyx:830, in sage.misc.persist.SagePickler.dumps()

TypeError: cannot pickle 'sage.misc.lazy_import.LazyImport' object
sage: fricas(3)
3
sage: fricas == loads(dumps(fricas))
True

I run fricas(3) then run fricas == loads(dumps(fricas)), it will return the right result. But directly run fricas == loads(dumps(fricas)) then it leads to error. and I do not know how to deal with it.
OS: Ubuntu 25.04 WSL
Python: 3.13.5
Sage: Sage 10.7 with the sage's fricas

@cxzhong cxzhong closed this Aug 14, 2025
@cxzhong cxzhong deleted the fix-fricas-doctest-pickling branch August 14, 2025 07:11
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

Successfully merging this pull request may close these issues.

2 participants