Skip to content

Commit

Permalink
Merge pull request #26451 from oscarbenjamin/pr_doctest_plus
Browse files Browse the repository at this point in the history
docs: adjust doctests for pytest-doctestplus
  • Loading branch information
oscarbenjamin committed Apr 16, 2024
2 parents d11d0b2 + 1e51ac6 commit 87bf9d4
Show file tree
Hide file tree
Showing 28 changed files with 160 additions and 31 deletions.
4 changes: 3 additions & 1 deletion conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ def _mk_group(group_dict):
return list(chain(*[[k+'::'+v for v in files] for k, files in group_dict.items()]))

if os.path.exists(durations_path):
veryslow_group, slow_group = [_mk_group(group_dict) for group_dict in json.loads(open(durations_path, 'rt').read())]
with open(durations_path, 'rt') as fin:
text = fin.read()
veryslow_group, slow_group = [_mk_group(group_dict) for group_dict in json.loads(text)]
else:
# warnings in conftest has issues: https://github.com/pytest-dev/pytest/issues/2891
warnings.warn("conftest.py:22: Could not find %s, --quickcheck and --veryquickcheck will have no effect.\n" % durations_path)
Expand Down
9 changes: 4 additions & 5 deletions doc/src/modules/evalf.rst
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,10 @@ expression is a polynomial in expanded form, the coefficients are evaluated:
You can also use the standard Python functions ``float()``, ``complex()`` to
convert SymPy expressions to regular Python numbers:

>>> float(pi)
3.1415926535...
>>> complex(pi+E*I)
(3.1415926535...+2.7182818284...j)

>>> float(pi) # doctest: +SKIP
3.141592653589793
>>> complex(pi+E*I) # doctest: +SKIP
(3.141592653589793+2.718281828459045j)

If these functions are used, failure to evaluate the expression to an explicit
number (for example if the expression contains symbols) will raise an exception.
Expand Down
6 changes: 5 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
[tool.pytest.ini_options]
# Don't run the tests marked as slow by default.
addopts = "-m 'not slow and not tooslow'"
filterwarnings = [
'ignore:More than 20 figures have been opened.*:RuntimeWarning',
'ignore:FigureCanvasAgg is non-interactive, and thus cannot be shown:UserWarning',
]

# Only run tests under the sympy/ directory. Otherwise pytest will attempt to
# collect tests from e.g. the bin/ directory as well.
Expand Down Expand Up @@ -148,4 +152,4 @@ exclude-modules = '''
|sympy.galgebra
|sympy.plotting.pygletplot
)
'''
'''
5 changes: 5 additions & 0 deletions sympy/crypto/crypto.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

from itertools import cycle

from sympy.external.gmpy import GROUND_TYPES
from sympy.core import Symbol
from sympy.core.numbers import Rational
from sympy.core.random import _randrange, _randint
Expand All @@ -35,6 +36,10 @@
from sympy.utilities.decorator import doctest_depends_on


if GROUND_TYPES == 'flint':
__doctest_skip__ = ['lfsr_sequence']


class NonInvertibleCipherWarning(RuntimeWarning):
"""A warning raised if the cipher is not invertible."""
def __init__(self, msg):
Expand Down
11 changes: 6 additions & 5 deletions sympy/integrals/integrals.py
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,8 @@ def transform(self, x, u):
transform can perform u-substitution as long as a unique
integrand is obtained:
>>> i.transform(x**2 - 1, u)
>>> ui = i.transform(x**2 - 1, u)
>>> ui
Integral(cos(u)/2, (u, -1, 0))
This attempt fails because x = +/-sqrt(u + 1) and the
Expand All @@ -233,8 +234,7 @@ def transform(self, x, u):
result is transformed back into the original expression
using "u-substitution":
>>> ui = _
>>> _.transform(sqrt(u + 1), x) == i
>>> ui.transform(sqrt(u + 1), x) == i
True
We can accomplish the same with a regular substitution:
Expand Down Expand Up @@ -1251,9 +1251,10 @@ def as_sum(self, n=None, method="midpoint", evaluate=True):
intervals. This is equivalent to taking the average of the left and
right hand rule results:
>>> e.as_sum(2, 'trapezoid')
>>> s = e.as_sum(2, 'trapezoid')
>>> s
2*sin(5) + sin(3) + sin(7)
>>> (e.as_sum(2, 'left') + e.as_sum(2, 'right'))/2 == _
>>> (e.as_sum(2, 'left') + e.as_sum(2, 'right'))/2 == s
True
Here, the discontinuity at x = 0 can be avoided by using the
Expand Down
17 changes: 6 additions & 11 deletions sympy/logic/boolalg.py
Original file line number Diff line number Diff line change
Expand Up @@ -323,15 +323,7 @@ class when they evaluate to true.
Python operators give a boolean result for true but a
bitwise result for True
>>> ~true, ~True
(False, -2)
>>> true >> true, True >> True
(True, 0)
Python operators give a boolean result for true but a
bitwise result for True
>>> ~true, ~True
>>> ~true, ~True # doctest: +SKIP
(False, -2)
>>> true >> true, True >> True
(True, 0)
Expand Down Expand Up @@ -406,7 +398,7 @@ class BooleanFalse(BooleanAtom, metaclass=Singleton):
Python operators give a boolean result for false but a
bitwise result for False
>>> ~false, ~False
>>> ~false, ~False # doctest: +SKIP
(True, -1)
>>> false >> false, False >> False
(True, 0)
Expand Down Expand Up @@ -854,8 +846,11 @@ class Not(BooleanFunction):
value of True. To avoid this issue, use the SymPy boolean types
``true`` and ``false``.
- As of Python 3.12, the bitwise not operator ``~`` used on a
Python ``bool`` is deprecated and will emit a warning.
>>> from sympy import true
>>> ~True
>>> ~True # doctest: +SKIP
-2
>>> ~true
False
Expand Down
3 changes: 3 additions & 0 deletions sympy/matrices/dense.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
from .solvers import _lower_triangular_solve, _upper_triangular_solve


__doctest_requires__ = {('symarray',): ['numpy']}


def _iszero(x):
"""Returns True if x is zero."""
return x.is_zero
Expand Down
9 changes: 9 additions & 0 deletions sympy/matrices/eigen.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,15 @@
from .utilities import _iszero, _simplify


__doctest_requires__ = {
('_is_indefinite',
'_is_negative_definite',
'_is_negative_semidefinite',
'_is_positive_definite',
'_is_positive_semidefinite'): ['matplotlib'],
}


def _eigenvals_eigenvects_mpmath(M):
norm2 = lambda v: mp.sqrt(sum(i**2 for i in v))

Expand Down
9 changes: 9 additions & 0 deletions sympy/matrices/matrices.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,15 @@
from .matrixbase import MatrixBase


__doctest_requires__ = {
('MatrixEigen.is_indefinite',
'MatrixEigen.is_negative_definite',
'MatrixEigen.is_negative_semidefinite',
'MatrixEigen.is_positive_definite',
'MatrixEigen.is_positive_semidefinite'): ['matplotlib'],
}


class MatrixDeterminant(MatrixCommon):
"""Provides basic matrix determinant operations. Should not be instantiated
directly. See ``determinant.py`` for their implementations."""
Expand Down
9 changes: 9 additions & 0 deletions sympy/matrices/matrixbase.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,15 @@
_strongly_connected_components, _strongly_connected_components_decomposition)


__doctest_requires__ = {
('MatrixBase.is_indefinite',
'MatrixBase.is_positive_definite',
'MatrixBase.is_positive_semidefinite',
'MatrixBase.is_negative_definite',
'MatrixBase.is_negative_semidefinite'): ['matplotlib'],
}


class MatrixBase(Printable):
"""All common matrix operations including basic arithmetic, shaping,
and special matrices like `zeros`, and `eye`."""
Expand Down
4 changes: 4 additions & 0 deletions sympy/parsing/latex/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@

from .errors import LaTeXParsingError # noqa


__doctest_requires__ = {('parse_latex',): ['antlr4', 'lark']}


@doctest_depends_on(modules=('antlr4', 'lark'))
def parse_latex(s, strict=False, backend="antlr"):
r"""Converts the input LaTeX string ``s`` to a SymPy ``Expr``.
Expand Down
16 changes: 14 additions & 2 deletions sympy/physics/continuum_mechanics/beam.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,20 @@
from sympy.utilities.iterables import iterable
import warnings

numpy = import_module('numpy', import_kwargs={'fromlist':['arange']})

__doctest_requires__ = {
('Beam.draw',
'Beam.plot_bending_moment',
'Beam.plot_deflection',
'Beam.plot_ild_moment',
'Beam.plot_ild_shear',
'Beam.plot_shear_force',
'Beam.plot_shear_stress',
'Beam.plot_slope'): ['matplotlib'],
}


numpy = import_module('numpy', import_kwargs={'fromlist':['arange']})


class Beam:
Expand Down Expand Up @@ -2168,7 +2180,7 @@ def draw(self, pictorial=True):
>>> b.apply_support(50, "pin")
>>> b.apply_support(0, "fixed")
>>> b.apply_support(20, "roller")
>>> p = b.draw()
>>> p = b.draw() # doctest: +SKIP
>>> p # doctest: +ELLIPSIS
Plot object containing:
[0]: cartesian line: 25*SingularityFunction(x, 5, 0) - 25*SingularityFunction(x, 23, 0)
Expand Down
5 changes: 5 additions & 0 deletions sympy/physics/continuum_mechanics/truss.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,13 @@
from sympy.utilities.decorator import doctest_depends_on
from sympy import sin, cos


__doctest_requires__ = {('Truss.draw'): ['matplotlib']}


numpy = import_module('numpy', import_kwargs={'fromlist':['arange']})


class Truss:
"""
A Truss is an assembly of members such as beams,
Expand Down
12 changes: 6 additions & 6 deletions sympy/physics/wigner.py
Original file line number Diff line number Diff line change
Expand Up @@ -584,11 +584,11 @@ def wigner_9j(j_1, j_2, j_3, j_4, j_5, j_6, j_7, j_8, j_9, prec=None):
========
>>> from sympy.physics.wigner import wigner_9j
>>> wigner_9j(1,1,1, 1,1,1, 1,1,0, prec=64) # ==1/18
0.05555555...
>>> wigner_9j(1,1,1, 1,1,1, 1,1,0, prec=64)
0.05555555555555555555555555555555555555555555555555555555555555555
>>> wigner_9j(1/2,1/2,0, 1/2,3/2,1, 0,1,1, prec=64) # ==1/6
0.1666666...
>>> wigner_9j(1/2,1/2,0, 1/2,3/2,1, 0,1,1, prec=64)
0.1666666666666666666666666666666666666666666666666666666666666667
It is an error to have arguments that are not integer or half
integer values or do not fulfill the triangle relation::
Expand Down Expand Up @@ -665,7 +665,7 @@ def gaunt(l_1, l_2, l_3, m_1, m_2, m_3, prec=None):
>>> gaunt(1,0,1,1,0,-1)
-1/(2*sqrt(pi))
>>> gaunt(1000,1000,1200,9,3,-12).n(64)
0.00689500421922113448...
0.006895004219221134484332976156744208248842039317638217822322799675
It is an error to use non-integer values for `l` and `m`::
Expand Down Expand Up @@ -843,7 +843,7 @@ def real_gaunt(l_1, l_2, l_3, m_1, m_2, m_3, prec=None):
>>> real_gaunt(2,2,4,-1,-1,0)
-2/(7*sqrt(pi))
>>> real_gaunt(10,10,20,-9,-9,0).n(64)
-0.00002480019791932209313156167...
-0.00002480019791932209313156167176797577821140084216297395518482071448
It is an error to use non-integer values for `l` and `m`::
real_gaunt(2.8,0.5,1.3,0,0,0)
Expand Down
5 changes: 5 additions & 0 deletions sympy/plotting/backends/base_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@
from sympy.utilities.iterables import is_sequence


__doctest_requires__ = {
('Plot.append', 'Plot.extend'): ['matplotlib'],
}


# Global variable
# Set to False when running tests / doctests so that the plots don't show.
_show = True
Expand Down
11 changes: 11 additions & 0 deletions sympy/plotting/plot.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,17 @@
from sympy.plotting.textplot import textplot # noqa: F401


__doctest_requires__ = {
('plot3d',
'plot3d_parametric_line',
'plot3d_parametric_surface',
'plot_parametric'): ['matplotlib'],
# XXX: The plot doctest possibly should not require matplotlib. It fails at
# plot(x**2, (x, -5, 5)) which should be fine for text backend.
('plot',): ['matplotlib'],
}


def _process_summations(sum_bound, *args):
"""Substitute oo (infinity) in the lower/upper bounds of a summation with
some integer number.
Expand Down
3 changes: 3 additions & 0 deletions sympy/plotting/plot_implicit.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@
from sympy.utilities.iterables import flatten


__doctest_requires__ = {'plot_implicit': ['matplotlib']}


@doctest_depends_on(modules=('matplotlib',))
def plot_implicit(expr, x_var=None, y_var=None, adaptive=True, depth=0,
n=300, line_color="blue", show=True, **kwargs):
Expand Down
5 changes: 5 additions & 0 deletions sympy/plotting/plotgrid.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@
# the same in the `SymPyDocTestFinder`` in `sympy/testing/runtests.py`


__doctest_requires__ = {
("PlotGrid",): ["matplotlib"],
}


class PlotGrid:
"""This class helps to plot subplots from already created SymPy plots
in a single figure.
Expand Down
4 changes: 4 additions & 0 deletions sympy/polys/domains/finitefield.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@
from sympy.polys.domains.groundtypes import SymPyInteger


if GROUND_TYPES == 'flint':
__doctest_skip__ = ['FiniteField']


if GROUND_TYPES == 'flint':
import flint
# Don't use python-flint < 0.5.0 because nmod was missing some features in
Expand Down
6 changes: 6 additions & 0 deletions sympy/polys/matrices/_dfm.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
# and also to make some of the above methods simpler or more efficient e.g.
# slicing, fancy indexing etc.

from sympy.external.gmpy import GROUND_TYPES
from sympy.external.importtools import import_module
from sympy.utilities.decorator import doctest_depends_on

Expand All @@ -54,6 +55,11 @@
DMValueError,
)


if GROUND_TYPES != 'flint':
__doctest_skip__ = ['*']


flint = import_module('flint')


Expand Down
5 changes: 5 additions & 0 deletions sympy/polys/matrices/ddm.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ class takes care of copying etc and also stores a Domain object associated
"""
from itertools import chain

from sympy.external.gmpy import GROUND_TYPES
from sympy.utilities.decorator import doctest_depends_on

from .exceptions import (
Expand Down Expand Up @@ -94,6 +95,10 @@ class takes care of copying etc and also stores a Domain object associated
from .lll import ddm_lll, ddm_lll_transform


if GROUND_TYPES != 'flint':
__doctest_skip__ = ['DDM.to_dfm', 'DDM.to_dfm_or_ddm']


class DDM(list):
"""Dense matrix based on polys domain elements
Expand Down

0 comments on commit 87bf9d4

Please sign in to comment.