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

sage.schemes: Reformat doctests, add # optional annotations #35314

Merged
merged 33 commits into from
Apr 6, 2023

Conversation

mkoeppe
Copy link
Contributor

@mkoeppe mkoeppe commented Mar 20, 2023

📚 Description

Adding doctest tags # optional - sage.rings.finite_rings, ...number_field, ...padics.

While going through the doctests line by line, I also made the following changes:

  • some coding style fixes in the doctests (such as adding spaces around some operators and after commas, following PEP 8) - improved the readability of them in the HTML format by breaking long lines to avoid having to scroll horizontally
  • improved indentation of input and output, in particular when morphisms are displayed
  • made better use of the horizontal space in the doctests of some modules in sage.schemes.toric, which were formatted for a very narrow layout
  • improved the sphinx markup of some docstrings.

The doctest tags are preparation for being able to test parts of sage.schemes in a modularized setting, in which not all rings are available. See https://doc.sagemath.org/html/en/developer/packaging_sage_library.html#doctest-only-dependencies

Part of:

📝 Checklist

  • I have made sure that the title is self-explanatory and the description concisely explains the PR.
  • I have linked an issue or discussion.
  • I have created tests covering the changes.
  • I have updated the documentation accordingly.

⌛ Dependencies

The mass edits adding # optional tags were made using the following Emacs macro.

(defun sage-copy-optional-annotation ()
  "In a 'sage: ' line of a docstring, copy '# optional' from a previous line and
advance to the end of the next 'sage: ' line or to the end of the current docstring.
If invoked elsewhere, just advance to the end of the next 'sage: ' line."
  (interactive)
  (if (save-excursion (beginning-of-line)
		      (looking-at " *sage:"))
      (let ((tab-stop-list
	     (list (save-excursion
		     (previous-line)
		     (end-of-line)
		     (re-search-backward "# *optional.*$")
		     (- (match-beginning 0)
			(save-excursion
			  (beginning-of-line) (point)))))))
	(end-of-line)
	(just-one-space)
	(tab-to-tab-stop)
	(insert (match-string-no-properties 0))
	(re-search-forward "sage: \\|\"\"\"")
	(end-of-line))
    (re-search-forward "sage:")
    (end-of-line)))

(with-eval-after-load "python-mode"
  (define-key python-mode-map (kbd "C-M-;") 'sage-copy-optional-annotation))

@codecov-commenter
Copy link

codecov-commenter commented Mar 20, 2023

Codecov Report

Patch coverage: 100.00% and project coverage change: -0.67 ⚠️

Comparison is base (c00e6c2) 88.62% compared to head (ee09844) 87.95%.

Additional details and impacted files
@@             Coverage Diff             @@
##           develop   #35314      +/-   ##
===========================================
- Coverage    88.62%   87.95%   -0.67%     
===========================================
  Files         2148     2148              
  Lines       398855   398860       +5     
===========================================
- Hits        353480   350815    -2665     
- Misses       45375    48045    +2670     
Impacted Files Coverage Δ
src/sage/schemes/affine/affine_homset.py 91.08% <ø> (-1.92%) ⬇️
src/sage/schemes/affine/affine_morphism.py 90.00% <ø> (-0.34%) ⬇️
src/sage/schemes/affine/affine_point.py 81.25% <ø> (-11.46%) ⬇️
src/sage/schemes/affine/affine_rational_point.py 74.69% <ø> (-18.08%) ⬇️
src/sage/schemes/affine/affine_space.py 93.81% <ø> (-2.07%) ⬇️
src/sage/schemes/affine/affine_subscheme.py 91.86% <ø> (-1.63%) ⬇️
src/sage/schemes/berkovich/berkovich_cp_element.py 77.24% <ø> (ø)
src/sage/schemes/curves/affine_curve.py 68.75% <ø> (-14.92%) ⬇️
src/sage/schemes/curves/closed_point.py 53.62% <ø> (-43.48%) ⬇️
src/sage/schemes/curves/constructor.py 81.30% <ø> (-1.63%) ⬇️
... and 99 more

... and 34 files with indirect coverage changes

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

☔ View full report in Codecov by Sentry.
📢 Do you have feedback about the report comment? Let us know in this issue.

@mkoeppe mkoeppe requested a review from yyyyx4 March 22, 2023 17:43
@mkoeppe mkoeppe changed the title sage.schemes: Add # optional annotations to doctests sage.schemes: Reformat doctests, add # optional annotations Mar 25, 2023
@mkoeppe mkoeppe requested a review from mezzarobba March 25, 2023 21:28
@github-actions
Copy link

Documentation preview for this PR is ready! 🎉
Built with commit: ee09844

@@ -355,7 +347,7 @@ def _fastpolys(self):

sage: P.<x,y> = AffineSpace(QQ, 2)
sage: H = Hom(P, P)
sage: f = H([x^2+y^2, y^2/(1+x)])
sage: f = H([x^2 + y^2, y^2/(1+x)])
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

needs spaces around the second +.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not adding spaces within nested sums

@@ -464,58 +456,56 @@ def homogenize(self, n):

sage: A.<x,y> = AffineSpace(CC, 2)
sage: H = Hom(A, A)
sage: f = H([(x^2-2)/(x*y), y^2-x])
sage: f = H([(x^2-2)/(x*y), y^2 - x])
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

needs spaces


::

sage: R.<t> = PolynomialRing(ZZ)
sage: A.<x,y> = AffineSpace(R, 2)
sage: H = Hom(A, A)
sage: f = H([(x^2-2)/y, y^2-x])
sage: f = H([(x^2-2)/y, y^2 - x])
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

needs spaces

@@ -146,7 +146,8 @@ class EllipticCurveFactory(UniqueFactory):

sage: E = EllipticCurve(CC, [0,0,1,-1,0])
sage: E
Elliptic Curve defined by y^2 + 1.00000000000000*y = x^3 + (-1.00000000000000)*x over Complex Field with 53 bits of precision
Elliptic Curve defined by y^2 + 1.00000000000000*y = x^3 + (-1.00000000000000)*x
over Complex Field with 53 bits of precision
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sometimes I see

Elliptic Curve ...
 over ...

Other times

Elliptic Curves ...
over ...

Need to be consistent. Here and elsewhere.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am standardizing on the first format now

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay for this PR.

But for standardizing how to split a long doctest output and formatting nicely multiline output, I don't know what is right. A related idea is to respect the actual output in the sage terminal. I don't know whether we should or not. This issue perhaps belongs to https://doc.sagemath.org/html/en/developer/coding_basics.html#fine-points-on-styles

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think there's a need for setting a policy for developers; to me, anything in the spectrum between the raw actual output (assisted by sage -fixdoctests) and the delicate doctest poetry that I have attempted here is fine. I don't think there is a downside to reformatting the output with the goal of readability / user experience. There is potential for mild disappointment when users try out an example and the output does not look as pretty as it appears in the documentation. But even then the structure-indicating reformatted output guides the user through parsing the complicated raw output. And Sage has various ways to adjust output, using %display latex, %display ascii_art etc.; the difference between documentation and reality may inspire users to explore these facilities (or even improve our _repr_ code).

sage: A.<a> = Qp(3).extension(x^3 - 3)
sage: B(a)
sage: B = Berkovich_Cp_Affine(3) # optional - sage.rings.padics
sage: A.<a> = Qp(3).extension(x^3 - 3) # optional - sage.rings.number_field
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extensions of p-adic fields seems to still belong to sage.rings.padics.

Copy link
Contributor Author

@mkoeppe mkoeppe Mar 30, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, fixed in ed39a64

from Elliptic Curve defined by y^2 = x^3 + (15*z6^5+5*z6^4+8*z6^3+12*z6^2+11*z6+7)*x
over Finite Field in z6 of size 17^6
to Elliptic Curve defined by y^2 = x^3 + z6*x
over Finite Field in z6 of size 17^6
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No optional tags in this file?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 5698dfa

Isogeny of degree 2 from Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 - 5*x + 2 over Rational Field to Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 - 80*x + 242 over Rational Field
Isogeny of degree 2
from Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 - 5*x + 2 over Rational Field
to Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 - 80*x + 242 over Rational Field
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No optional tags in this file?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in d5d51b5

from Elliptic Curve defined by y^2 = x^3 + 10 over Finite Field in a of size 13^2
to Elliptic Curve defined by y^2 = x^3 + (9*a+10)*x + (11*a+12) over Finite Field in a of size 13^2]

sage: K.<a> = NumberField(x**6 - 320*x**3 - 320)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No optional tags in this file?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 289d256

sage: P(S)
sage: S.<t> = R.quo(x^2 + 5) # optional - sage.rings.number_field
sage: P.<X,Y,Z> = ProjectiveSpace(2, S) # optional - sage.rings.number_field
sage: P(S) # optional - sage.rings.number_field
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

S is not really a number field, but a quotient of a polynomial ring.

sage: R.<x> = ZZ[]
sage: S.<t> = R.quo(x^2+5)
sage: type(S)
<class 'sage.rings.polynomial.polynomial_quotient_ring.PolynomialQuotientRing_domain_with_category'>

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed, fixed in 5065211

@kwankyu
Copy link
Collaborator

kwankyu commented Mar 30, 2023

I looked through the changes. They look good to me.

This is a lot of work, and a great improvement of the quality of docstrings in the schemes module.

Copy link
Collaborator

@kwankyu kwankyu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks.

@mkoeppe
Copy link
Contributor Author

mkoeppe commented Mar 31, 2023

Thanks very much for reviewing this mega-patch!

Matthias Koeppe added 18 commits April 1, 2023 10:40
@mkoeppe mkoeppe force-pushed the sage_schemes_doctests_optional branch from c63ad60 to a9588d1 Compare April 1, 2023 17:42
@mkoeppe
Copy link
Contributor Author

mkoeppe commented Apr 1, 2023

Easy rebase.

@vbraun
Copy link
Member

vbraun commented Apr 2, 2023

sage -t --long --warn-long 37.7 --random-seed=123 src/sage/schemes/elliptic_curves/ell_generic.py
**********************************************************************
File "src/sage/schemes/elliptic_curves/ell_generic.py", line 1394, in sage.schemes.elliptic_curves.ell_generic.EllipticCurve_generic.change_ring
Failed example:
    h = F2.hom([a[0]], F4)                                                # optional - sage.rings.finite_rings
Exception raised:
    Traceback (most recent call last):
      File "/home/release/Sage/src/sage/rings/finite_rings/homset.py", line 100, in __call__
        return FiniteFieldHomomorphism_generic(self, im_gens, base_map=base_map, check=check)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "sage/rings/finite_rings/hom_finite_field.pyx", line 239, in sage.rings.finite_rings.hom_finite_field.FiniteFieldHomomorphism_generic.__init__
        RingHomomorphism_im_gens.__init__(self, parent, im_gens, base_map=base_map, check=check)
      File "sage/rings/morphism.pyx", line 1832, in sage.rings.morphism.RingHomomorphism_im_gens.__init__
        raise ValueError("relations do not all (canonically) map to 0 under map determined by images of generators")
    ValueError: relations do not all (canonically) map to 0 under map determined by images of generators

    During handling of the above exception, another exception occurred:

    Traceback (most recent call last):
      File "/home/release/Sage/src/sage/rings/finite_rings/homset.py", line 109, in __call__
        return self._coerce_impl(im_gens)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/home/release/Sage/src/sage/rings/finite_rings/homset.py", line 132, in _coerce_impl
        raise TypeError
    TypeError

    During handling of the above exception, another exception occurred:

    Traceback (most recent call last):
      File "/home/release/Sage/src/sage/doctest/forker.py", line 695, in _run
        self.compile_and_execute(example, compiler, test.globs)
      File "/home/release/Sage/src/sage/doctest/forker.py", line 1093, in compile_and_execute
        exec(compiled, globs)
      File "<doctest sage.schemes.elliptic_curves.ell_generic.EllipticCurve_generic.change_ring[3]>", line 1, in <module>
        h = F2.hom([a[Integer(0)]], F4)                                                # optional - sage.rings.finite_rings
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "sage/structure/parent_gens.pyx", line 300, in sage.structure.parent_gens.ParentWithGens.hom
        return parent.Parent.hom(self, im_gens, codomain, base_map=base_map, category=category, check=check)
      File "sage/structure/parent.pyx", line 1427, in sage.structure.parent.Parent.hom
        return self.Hom(codomain, **Hom_kwds)(im_gens, **kwds)
      File "/home/release/Sage/src/sage/rings/finite_rings/homset.py", line 111, in __call__
        raise TypeError("images do not define a valid homomorphism")
    TypeError: images do not define a valid homomorphism
**********************************************************************
File "src/sage/schemes/elliptic_curves/ell_generic.py", line 1398, in sage.schemes.elliptic_curves.ell_generic.EllipticCurve_generic.change_ring
Failed example:
    E.change_ring(h)                                                      # optional - sage.rings.finite_rings
Exception raised:
    Traceback (most recent call last):
      File "/home/release/Sage/src/sage/doctest/forker.py", line 695, in _run
        self.compile_and_execute(example, compiler, test.globs)
      File "/home/release/Sage/src/sage/doctest/forker.py", line 1093, in compile_and_execute
        exec(compiled, globs)
      File "<doctest sage.schemes.elliptic_curves.ell_generic.EllipticCurve_generic.change_ring[5]>", line 1, in <module>
        E.change_ring(h)                                                      # optional - sage.rings.finite_rings
                      ^
    NameError: name 'h' is not defined
**********************************************************************
1 item had failures:
   2 of   7 in sage.schemes.elliptic_curves.ell_generic.EllipticCurve_generic.change_ring
    [554 tests, 2 failures, 3.71 s]
----------------------------------------------------------------------
sage -t --long --warn-long 37.7 --random-seed=123 src/sage/schemes/elliptic_curves/ell_generic.py  # 2 doctests failed
----------------------------------------------------------------------

@vbraun vbraun mentioned this pull request Apr 4, 2023
4 tasks
@vbraun vbraun merged commit af4ab84 into sagemath:develop Apr 6, 2023
@mkoeppe mkoeppe added this to the sage-10.0 milestone Apr 7, 2023
vbraun pushed a commit that referenced this pull request Apr 23, 2023
    
### 📚 Description

A test is supposed to take < 1s or else be marked # long time.

Here we consider slow tests taking >> 10s. When possible we fix or
change the test to take less time, otherwise we just mark the test as
long time. Occasionally we create a new smaller test and keep the
original one as long.

After this and #35442 the slowest tests are a few taking ~ 10s.
The total time to doctest all goes down from 880 to 806 seconds (using
`-tp 8 --all`).

~~NOTE: there's a minor merge conflict with #35314 which I will resolve
once that PR is merged.~~

### 📝 Checklist

- [x] The title is concise, informative, and self-explanatory.
- [x] The description explains in detail what this PR is about.
    
URL: #35443
Reported by: Gonzalo Tornaría
Reviewer(s): Gonzalo Tornaría, Matthias Köppe
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants