From 1457cdc5198fc5154226b5c7c253d2172d2c5f41 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jan=20R=C4=99korajski?= Date: Mon, 4 Nov 2019 23:56:35 +0100 Subject: [PATCH] - test suite fixes --- 0001-Exception-changed-after-numpy-1.17.patch | 71 +++++++ ...-compatibility-issues-with-Python3.8.patch | 193 ++++++++++++++++++ ...parisons-as-per-python3.8-guidelines.patch | 156 ++++++++++++++ python-sympy.spec | 8 + sympy-is.patch | 11 + 5 files changed, 439 insertions(+) create mode 100644 0001-Exception-changed-after-numpy-1.17.patch create mode 100644 0001-Fix-more-compatibility-issues-with-Python3.8.patch create mode 100644 0001-Modify-literal-comparisons-as-per-python3.8-guidelines.patch create mode 100644 sympy-is.patch diff --git a/0001-Exception-changed-after-numpy-1.17.patch b/0001-Exception-changed-after-numpy-1.17.patch new file mode 100644 index 0000000..02df702 --- /dev/null +++ b/0001-Exception-changed-after-numpy-1.17.patch @@ -0,0 +1,71 @@ +From 01af15a136bdfe6bbd0c3c155711632a69e55f98 Mon Sep 17 00:00:00 2001 +From: "S.Y. Lee" +Date: Fri, 2 Aug 2019 07:48:19 +0900 +Subject: [PATCH 1/2] Exception changed after numpy 1.17 + +--- + sympy/utilities/lambdify.py | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/sympy/utilities/lambdify.py b/sympy/utilities/lambdify.py +index 35ae7f83d0f..bb0f51a6bd7 100644 +--- a/sympy/utilities/lambdify.py ++++ b/sympy/utilities/lambdify.py +@@ -484,10 +484,15 @@ def lambdify(args, expr, modules=None, p + + But if we try to pass in a SymPy expression, it fails + +- >>> g(x + 1) ++ >>> try: ++ ... g(x + 1) ++ ... # NumPy release after 1.17 raises TypeError instead of ++ ... # AttributeError ++ ... except (AttributeError, TypeError): ++ ... raise AttributeError() # doctest: +IGNORE_EXCEPTION_DETAIL + Traceback (most recent call last): + ... +- AttributeError: 'Add' object has no attribute 'sin' ++ AttributeError: + + Now, let's look at what happened. The reason this fails is that ``g`` + calls ``numpy.sin`` on the input expression, and ``numpy.sin`` does not + +From 59c2f96043713fa2fdb7cbf4f0335bbb9667fb54 Mon Sep 17 00:00:00 2001 +From: "S.Y. Lee" +Date: Fri, 2 Aug 2019 10:06:44 +0900 +Subject: [PATCH 2/2] Make numpy test version aware + +--- + sympy/external/tests/test_numpy.py | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +diff --git a/sympy/external/tests/test_numpy.py b/sympy/external/tests/test_numpy.py +index 6663d1afd76..1b752bcfc1b 100644 +--- a/sympy/external/tests/test_numpy.py ++++ b/sympy/external/tests/test_numpy.py +@@ -4,6 +4,7 @@ + # Always write regular SymPy tests for anything, that can be tested in pure + # Python (without numpy). Here we test everything, that a user may need when + # using SymPy with NumPy ++from distutils.version import LooseVersion + + from sympy.external import import_module + +@@ -231,8 +232,15 @@ def test_lambdify(): + f = lambdify(x, sin(x), "numpy") + prec = 1e-15 + assert -prec < f(0.2) - sin02 < prec +- with raises(AttributeError): +- f(x) # if this succeeds, it can't be a numpy function ++ ++ # if this succeeds, it can't be a numpy function ++ ++ if LooseVersion(numpy.__version__) >= LooseVersion('1.17'): ++ with raises(TypeError): ++ f(x) ++ else: ++ with raises(AttributeError): ++ f(x) + + + def test_lambdify_matrix(): diff --git a/0001-Fix-more-compatibility-issues-with-Python3.8.patch b/0001-Fix-more-compatibility-issues-with-Python3.8.patch new file mode 100644 index 0000000..e75c0fd --- /dev/null +++ b/0001-Fix-more-compatibility-issues-with-Python3.8.patch @@ -0,0 +1,193 @@ +From 5ea93bc9ab7ae9829ed596e2d53976962164ba78 Mon Sep 17 00:00:00 2001 +From: Vighnesh Shenoy +Date: Sun, 9 Jun 2019 23:34:21 +0530 +Subject: [PATCH] Issue #16977, fix more compatibility issues with Python3.8. + +xml.dom.minidom preserves attribute order in Python3.8 which causes +some test failures. Modified the order of attribute insertion to +ensure that tests run on both 3.8 & earlier versions. Modified the use +of officially removed time.clock with a conditional import in +sympy/core/compatibility.py +--- + examples/advanced/pidigits.py | 2 +- + examples/advanced/pyglet_plotting.py | 4 ++-- + sympy/core/compatibility.py | 5 ++++ + sympy/plotting/pygletplot/plot_window.py | 2 +- + sympy/printing/mathml.py | 30 ++++++++++++------------ + 5 files changed, 24 insertions(+), 19 deletions(-) + +diff --git a/examples/advanced/pidigits.py b/examples/advanced/pidigits.py +index 430ea5aaf83..e444ba2276b 100755 +--- a/examples/advanced/pidigits.py ++++ b/examples/advanced/pidigits.py +@@ -10,7 +10,7 @@ from mpmath import libmp, pi + from mpmath import functions as mpf_funs + + import math +-from time import clock ++from sympy.core.compatibility import clock + import sys + + +diff --git a/examples/advanced/pyglet_plotting.py b/examples/advanced/pyglet_plotting.py +index 16d13ac5137..c12ed54f5b1 100755 +--- a/examples/advanced/pyglet_plotting.py ++++ b/examples/advanced/pyglet_plotting.py +@@ -8,10 +8,10 @@ Suggested Usage: python -i pyglet_plo + + + from sympy import symbols, sin, cos, pi, sqrt +-from sympy.core.compatibility import range ++from sympy.core.compatibility import range, clock + from sympy.plotting.pygletplot import PygletPlot + +-from time import sleep, clock ++from time import sleep + + + def main(): +diff --git a/sympy/core/compatibility.py b/sympy/core/compatibility.py +index 2827b40ca17..9b6a644d847 100644 +--- a/sympy/core/compatibility.py ++++ b/sympy/core/compatibility.py +@@ -945,3 +945,8 @@ try: + except ImportError: # Python 2.7 + def filterfalse(pred, itr): + return filter(lambda x: not pred(x), itr) ++ ++try: ++ from time import clock ++except ImportError: # Python 3.8+ ++ from time import perf_counter as clock +diff --git a/sympy/plotting/pygletplot/plot_window.py b/sympy/plotting/pygletplot/plot_window.py +index 91bf42cc532..193093229b4 100644 +--- a/sympy/plotting/pygletplot/plot_window.py ++++ b/sympy/plotting/pygletplot/plot_window.py +@@ -1,6 +1,6 @@ + from __future__ import print_function, division + +-from time import clock ++from sympy.core.compatibility import clock + + import pyglet.gl as pgl + +diff --git a/sympy/printing/mathml.py b/sympy/printing/mathml.py +index c1eba60b3d4..e5012efe74d 100644 +--- a/sympy/printing/mathml.py ++++ b/sympy/printing/mathml.py +@@ -654,8 +654,8 @@ class MathMLPresentationPrinter(MathMLPr + return table + brac = self.dom.createElement('mfenced') + if self._settings["mat_delim"] == "[": +- brac.setAttribute('open', '[') + brac.setAttribute('close', ']') ++ brac.setAttribute('open', '[') + brac.appendChild(table) + return brac + +@@ -961,8 +961,8 @@ class MathMLPresentationPrinter(MathMLPr + + def _print_AccumulationBounds(self, i): + brac = self.dom.createElement('mfenced') +- brac.setAttribute('open', u'\u27e8') + brac.setAttribute('close', u'\u27e9') ++ brac.setAttribute('open', u'\u27e8') + brac.appendChild(self._print(i.min)) + brac.appendChild(self._print(i.max)) + return brac +@@ -1106,19 +1106,19 @@ class MathMLPresentationPrinter(MathMLPr + brac = self.dom.createElement('mfenced') + if i.start == i.end: + # Most often, this type of Interval is converted to a FiniteSet +- brac.setAttribute('open', '{') + brac.setAttribute('close', '}') ++ brac.setAttribute('open', '{') + brac.appendChild(self._print(i.start)) + else: +- if i.left_open: +- brac.setAttribute('open', '(') +- else: +- brac.setAttribute('open', '[') +- + if i.right_open: + brac.setAttribute('close', ')') + else: + brac.setAttribute('close', ']') ++ ++ if i.left_open: ++ brac.setAttribute('open', '(') ++ else: ++ brac.setAttribute('open', '[') + brac.appendChild(self._print(i.start)) + brac.appendChild(self._print(i.end)) + +@@ -1128,8 +1128,8 @@ class MathMLPresentationPrinter(MathMLPr + def _print_Abs(self, expr, exp=None): + mrow = self.dom.createElement('mrow') + x = self.dom.createElement('mfenced') +- x.setAttribute('open', '|') + x.setAttribute('close', '|') ++ x.setAttribute('open', '|') + x.appendChild(self._print(expr.args[0])) + mrow.appendChild(x) + return mrow +@@ -1191,8 +1191,8 @@ class MathMLPresentationPrinter(MathMLPr + def _print_set(self, s): + items = sorted(s, key=default_sort_key) + brac = self.dom.createElement('mfenced') +- brac.setAttribute('open', '{') + brac.setAttribute('close', '}') ++ brac.setAttribute('open', '{') + for item in items: + brac.appendChild(self._print(item)) + return brac +@@ -1309,8 +1309,8 @@ class MathMLPresentationPrinter(MathMLPr + def _print_Range(self, s): + dots = u"\u2026" + brac = self.dom.createElement('mfenced') +- brac.setAttribute('open', '{') + brac.setAttribute('close', '}') ++ brac.setAttribute('open', '{') + + if s.start.is_infinite: + printset = dots, s[-1] - s.step, s[-1] +@@ -1507,8 +1507,8 @@ class MathMLPresentationPrinter(MathMLPr + power = expr.args[2] + sup = self.dom.createElement('msup') + brac = self.dom.createElement('mfenced') +- brac.setAttribute('open', u'\u27e8') + brac.setAttribute('close', u'\u27e9') ++ brac.setAttribute('open', u'\u27e8') + brac.appendChild(self._print(shift)) + sup.appendChild(brac) + sup.appendChild(self._print(power)) +@@ -1674,8 +1674,8 @@ class MathMLPresentationPrinter(MathMLPr + def _print_floor(self, e): + mrow = self.dom.createElement('mrow') + x = self.dom.createElement('mfenced') +- x.setAttribute('open', u'\u230A') + x.setAttribute('close', u'\u230B') ++ x.setAttribute('open', u'\u230A') + x.appendChild(self._print(e.args[0])) + mrow.appendChild(x) + return mrow +@@ -1683,8 +1683,8 @@ class MathMLPresentationPrinter(MathMLPr + def _print_ceiling(self, e): + mrow = self.dom.createElement('mrow') + x = self.dom.createElement('mfenced') +- x.setAttribute('open', u'\u2308') + x.setAttribute('close', u'\u2309') ++ x.setAttribute('open', u'\u2308') + x.appendChild(self._print(e.args[0])) + mrow.appendChild(x) + return mrow +@@ -1727,8 +1727,8 @@ class MathMLPresentationPrinter(MathMLPr + x = self.dom.createElement('msub') + x.appendChild(self.parenthesize(e.parent, PRECEDENCE["Atom"], strict = True)) + brac = self.dom.createElement('mfenced') +- brac.setAttribute("open", "") + brac.setAttribute("close", "") ++ brac.setAttribute("open", "") + for i in e.indices: + brac.appendChild(self._print(i)) + x.appendChild(brac) diff --git a/0001-Modify-literal-comparisons-as-per-python3.8-guidelines.patch b/0001-Modify-literal-comparisons-as-per-python3.8-guidelines.patch new file mode 100644 index 0000000..5180ea9 --- /dev/null +++ b/0001-Modify-literal-comparisons-as-per-python3.8-guidelines.patch @@ -0,0 +1,156 @@ +From af7fab8860ee152a51b7c29a197b4a37b2f88a87 Mon Sep 17 00:00:00 2001 +From: Vighnesh Shenoy +Date: Fri, 7 Jun 2019 02:31:23 +0530 +Subject: [PATCH] Modify literal comparisons as per python3.8 guidelines + +This is in regards to issue #16973, Python 3.8 beta raises a warning +when comparing with string, int literals using is. The .travis.yml compileall +command has been added another flag to error if the convention is not followed. +A dummy test has been added in utilities/tests, this must cause the travis +build to fail in 3.8. If it does as expected, it can be removed, else the +compileall command will have to be changed. +--- + .travis.yml | 5 ++++- + sympy/core/tests/test_containers.py | 2 +- + sympy/geometry/tests/test_plane.py | 2 +- + sympy/physics/vector/printing.py | 2 +- + sympy/plotting/plot.py | 6 +++--- + sympy/polys/agca/modules.py | 4 ++-- + sympy/solvers/diophantine.py | 2 +- + sympy/utilities/tests/test_travis.py | 6 ++++++ + sympy/vector/coordsysrect.py | 4 ++-- + 9 files changed, 21 insertions(+), 12 deletions(-) + create mode 100644 sympy/utilities/tests/test_travis.py + +diff --git a/sympy/core/tests/test_containers.py b/sympy/core/tests/test_containers.py +index 79e3c9b85ba..af871de597a 100644 +--- a/sympy/core/tests/test_containers.py ++++ b/sympy/core/tests/test_containers.py +@@ -52,7 +52,7 @@ def test_Tuple_concatenation(): + + + def test_Tuple_equality(): +- assert Tuple(1, 2) is not (1, 2) ++ assert not isinstance(Tuple(1, 2), tuple) + assert (Tuple(1, 2) == (1, 2)) is True + assert (Tuple(1, 2) != (1, 2)) is False + assert (Tuple(1, 2) == (1, 3)) is False +diff --git a/sympy/geometry/tests/test_plane.py b/sympy/geometry/tests/test_plane.py +index dec80b4bb99..959b9ff546a 100644 +--- a/sympy/geometry/tests/test_plane.py ++++ b/sympy/geometry/tests/test_plane.py +@@ -187,7 +187,7 @@ def test_plane(): + assert pl8.intersection(Plane(p1, normal_vector=(-1, -1, -11)))[0].equals( + Line3D(p1, direction_ratio=(1, -1, 0))) + assert pl3.random_point() in pl3 +- assert len(pl8.intersection(Ray3D(Point3D(0, 2, 3), Point3D(1, 0, 3)))) is 0 ++ assert len(pl8.intersection(Ray3D(Point3D(0, 2, 3), Point3D(1, 0, 3)))) == 0 + # check if two plane are equals + assert pl6.intersection(pl6)[0].equals(pl6) + assert pl8.equals(Plane(p1, normal_vector=(0, 12, 0))) is False +diff --git a/sympy/physics/vector/printing.py b/sympy/physics/vector/printing.py +index 9d1e769a700..86f4159974a 100644 +--- a/sympy/physics/vector/printing.py ++++ b/sympy/physics/vector/printing.py +@@ -152,7 +152,7 @@ class VectorLatexPrinter(LatexPrinter): + base = r"\ddddot{%s}" % base + else: # Fallback to standard printing + return LatexPrinter().doprint(der_expr) +- if len(base_split) is not 1: ++ if len(base_split) != 1: + base += '_' + base_split[1] + return base + +diff --git a/sympy/plotting/plot.py b/sympy/plotting/plot.py +index 7ad4f550b2f..8d87b93be92 100644 +--- a/sympy/plotting/plot.py ++++ b/sympy/plotting/plot.py +@@ -506,7 +506,7 @@ class LineOver1DRangeSeries(Line2DBaseSe + #at both ends. If there is a real value in between, then + #sample those points further. + elif p[1] is None and q[1] is None: +- if self.xscale is 'log': ++ if self.xscale == 'log': + xarray = np.logspace(p[0],q[0], 10) + else: + xarray = np.linspace(p[0], q[0], 10) +@@ -539,14 +539,14 @@ class LineOver1DRangeSeries(Line2DBaseSe + def get_points(self): + np = import_module('numpy') + if self.only_integers is True: +- if self.xscale is 'log': ++ if self.xscale == 'log': + list_x = np.logspace(int(self.start), int(self.end), + num=int(self.end) - int(self.start) + 1) + else: + list_x = np.linspace(int(self.start), int(self.end), + num=int(self.end) - int(self.start) + 1) + else: +- if self.xscale is 'log': ++ if self.xscale == 'log': + list_x = np.logspace(self.start, self.end, num=self.nb_of_points) + else: + list_x = np.linspace(self.start, self.end, num=self.nb_of_points) +diff --git a/sympy/polys/agca/modules.py b/sympy/polys/agca/modules.py +index aa296c52314..88e1618be11 100644 +--- a/sympy/polys/agca/modules.py ++++ b/sympy/polys/agca/modules.py +@@ -26,7 +26,7 @@ from sympy.polys.agca.ideals import Idea + from sympy.polys.domains.field import Field + from sympy.polys.orderings import ProductOrder, monomial_key + from sympy.polys.polyerrors import CoercionFailed +- ++from sympy.core.basic import _aresame + + # TODO + # - module saturation +@@ -357,7 +357,7 @@ class FreeModule(Module): + if len(tpl) != self.rank: + raise CoercionFailed + return FreeModuleElement(self, tpl) +- elif elem is 0: ++ elif _aresame(elem, 0): + return FreeModuleElement(self, (self.ring.convert(0),)*self.rank) + else: + raise CoercionFailed +diff --git a/sympy/solvers/diophantine.py b/sympy/solvers/diophantine.py +index 1c048d1e57d..2772b08e930 100644 +--- a/sympy/solvers/diophantine.py ++++ b/sympy/solvers/diophantine.py +@@ -3183,7 +3183,7 @@ def power_representation(n, p, k, zeros= + '''Todd G. Will, "When Is n^2 a Sum of k Squares?", [online]. + Available: https://www.maa.org/sites/default/files/Will-MMz-201037918.pdf''' + return +- if feasible is 1: # it's prime and k == 2 ++ if feasible is not True: # it's prime and k == 2 + yield prime_as_sum_of_two_squares(n) + return + +diff --git a/sympy/utilities/tests/test_travis.py b/sympy/utilities/tests/test_travis.py +new file mode 100644 +index 00000000000..f49eaa0cad1 +--- /dev/null ++++ b/sympy/utilities/tests/test_travis.py +@@ -0,0 +1,6 @@ ++def test_travis_issue_16986(): ++ # If this causes the travis build to fail with Python3.8, ++ # then the changes made in PR #16986 are working as ++ # intended, and this file can be deleted. ++ ++ assert int(1) is 1 +diff --git a/sympy/vector/coordsysrect.py b/sympy/vector/coordsysrect.py +index a7b0e91c413..e629824c3cd 100644 +--- a/sympy/vector/coordsysrect.py ++++ b/sympy/vector/coordsysrect.py +@@ -167,9 +167,9 @@ class CoordSys3D(Basic): + if isinstance(transformation, Lambda): + variable_names = ["x1", "x2", "x3"] + elif isinstance(transformation, Symbol): +- if transformation.name is 'spherical': ++ if transformation.name == 'spherical': + variable_names = ["r", "theta", "phi"] +- elif transformation.name is 'cylindrical': ++ elif transformation.name == 'cylindrical': + variable_names = ["r", "theta", "z"] + else: + variable_names = ["x", "y", "z"] diff --git a/python-sympy.spec b/python-sympy.spec index 2e38aea..31d06d4 100644 --- a/python-sympy.spec +++ b/python-sympy.spec @@ -16,6 +16,10 @@ Group: Libraries/Python Source0: https://github.com/sympy/sympy/releases/download/sympy-%{version}/sympy-%{version}.tar.gz # Source0-md5: 478072d75b564c9356990e3027d464e6 Patch0: %{name}-nodisplay.patch +Patch1: 0001-Exception-changed-after-numpy-1.17.patch +Patch2: 0001-Fix-more-compatibility-issues-with-Python3.8.patch +Patch3: 0001-Modify-literal-comparisons-as-per-python3.8-guidelines.patch +Patch4: sympy-is.patch URL: https://www.sympy.org/ BuildRequires: gettext BuildRequires: graphviz @@ -103,6 +107,10 @@ Dokumentacja do SymPy w formacie HTML. %prep %setup -q -n sympy-%{version} %patch0 -p1 +%patch1 -p1 +%patch2 -p1 +%patch3 -p1 +%patch4 -p1 %build %if %{with python2} diff --git a/sympy-is.patch b/sympy-is.patch new file mode 100644 index 0000000..3c2c2f3 --- /dev/null +++ b/sympy-is.patch @@ -0,0 +1,11 @@ +--- sympy-sympy-1.4/sympy/plotting/plot.py.orig 2019-09-13 11:48:00.776818488 -0600 ++++ sympy-sympy-1.4/sympy/plotting/plot.py 2019-09-13 11:49:54.122923162 -0600 +@@ -526,7 +526,7 @@ class LineOver1DRangeSeries(Line2DBaseSe + else: + list_segments.append([p, q]) + +- if self.xscale is 'log': ++ if self.xscale == 'log': + self.start=np.log10(self.start) + self.end=np.log10(self.end) + -- 2.44.0