From b2c30d5f6939f9ffbf4631a511d7b3b6ae81777d Mon Sep 17 00:00:00 2001 From: Jerry James Date: Sun, 22 Nov 2015 20:00:15 -0700 Subject: [PATCH] Use upstream's adaptation for python 3.5. --- sympy-python35.patch | 353 +++++++++++++++++++++++++++++++++++++++++++ sympy.spec | 17 +-- 2 files changed, 358 insertions(+), 12 deletions(-) create mode 100644 sympy-python35.patch diff --git a/sympy-python35.patch b/sympy-python35.patch new file mode 100644 index 0000000..5d4c33e --- /dev/null +++ b/sympy-python35.patch @@ -0,0 +1,353 @@ +--- doc/src/gotchas.rst.orig 2015-09-03 14:34:00.000000000 -0600 ++++ doc/src/gotchas.rst 2015-11-21 15:24:18.475852154 -0700 +@@ -148,7 +148,7 @@ See the Python docs for more information + + + If you define a circular relationship, you will get a +-:exc:`RuntimeError`. ++:exc:`RecursionError`. + + >>> def a(): + ... return b() +@@ -169,7 +169,7 @@ If you define a circular relationship, y + File "<...>", line 2, in a + return b() + ... +- RuntimeError: maximum recursion depth exceeded ++ RecursionError: maximum recursion depth exceeded + + + .. note:: +--- sympy/concrete/expr_with_limits.py.orig 2015-09-03 14:34:00.000000000 -0600 ++++ sympy/concrete/expr_with_limits.py 2015-11-21 15:26:31.337139532 -0700 +@@ -25,12 +25,12 @@ def _process_limits(*symbols): + limits = [] + orientation = 1 + for V in symbols: +- if isinstance(V, Symbol): ++ if isinstance(V, Symbol) or getattr(V, '_diff_wrt', False): + limits.append(Tuple(V)) + continue + elif is_sequence(V, Tuple): + V = sympify(flatten(V)) +- if V[0].is_Symbol: ++ if V[0].is_Symbol or getattr(V[0], '_diff_wrt', False): + newsymbol = V[0] + if len(V) == 2 and isinstance(V[1], Interval): + V[1:] = [V[1].start, V[1].end] +--- sympy/parsing/sympy_parser.py.orig 2015-09-03 14:34:00.000000000 -0600 ++++ sympy/parsing/sympy_parser.py 2015-11-21 15:28:46.742218940 -0700 +@@ -568,6 +568,8 @@ def lambda_notation(tokens, local_dict, + if tokNum == OP and tokVal == ':': + tokVal = ',' + flag = True ++ if not flag and tokNum == OP and tokVal in ['*', '**']: ++ raise TokenError("Starred arguments in lambda not supported") + if flag: + result.insert(-1, (tokNum, tokVal)) + else: +--- sympy/physics/vector/frame.py.orig 2015-09-03 14:34:00.000000000 -0600 ++++ sympy/physics/vector/frame.py 2015-11-21 15:30:46.308575762 -0700 +@@ -45,7 +45,11 @@ class CoordinateSym(Symbol): + """ + + def __new__(cls, name, frame, index): +- obj = super(CoordinateSym, cls).__new__(cls, name) ++ # We can't use the cached Symbol.__new__ because this class depends on ++ # frame and index, which are not passed to Symbol.__xnew__. ++ assumptions = {} ++ super(CoordinateSym, cls)._sanitize(assumptions, cls) ++ obj = super(CoordinateSym, cls).__xnew__(cls, name, **assumptions) + _check_frame(frame) + if index not in range(0, 3): + raise ValueError("Invalid index specified") +--- sympy/printing/pretty/pretty.py.orig 2015-09-03 14:34:00.000000000 -0600 ++++ sympy/printing/pretty/pretty.py 2015-11-21 15:35:28.750796441 -0700 +@@ -761,82 +761,77 @@ class PrettyPrinter(Printer): + + if not self._use_unicode: + raise NotImplementedError("ASCII pretty printing of BasisDependent is not implemented") +- class Fake(object): +- baseline = 0 + +- # slf to distinguish from self from _print_BasisDependent +- def render(slf, *args, **kwargs): +- if expr == expr.zero: +- return expr.zero._pretty_form +- o1 = [] +- vectstrs = [] +- if isinstance(expr, Vector): +- items = expr.separate().items() ++ if expr == expr.zero: ++ return prettyForm(expr.zero._pretty_form) ++ o1 = [] ++ vectstrs = [] ++ if isinstance(expr, Vector): ++ items = expr.separate().items() ++ else: ++ items = [(0, expr)] ++ for system, vect in items: ++ inneritems = list(vect.components.items()) ++ inneritems.sort(key = lambda x: x[0].__str__()) ++ for k, v in inneritems: ++ #if the coef of the basis vector is 1 ++ #we skip the 1 ++ if v == 1: ++ o1.append(u("") + ++ k._pretty_form) ++ #Same for -1 ++ elif v == -1: ++ o1.append(u("(-1) ") + ++ k._pretty_form) ++ #For a general expr + else: +- items = [(0, expr)] +- for system, vect in items: +- inneritems = list(vect.components.items()) +- inneritems.sort(key = lambda x: x[0].__str__()) +- for k, v in inneritems: +- #if the coef of the basis vector is 1 +- #we skip the 1 +- if v == 1: +- o1.append(u("") + +- k._pretty_form) +- #Same for -1 +- elif v == -1: +- o1.append(u("(-1) ") + +- k._pretty_form) +- #For a general expr +- else: +- #We always wrap the measure numbers in +- #parentheses +- arg_str = self._print( +- v).parens()[0] ++ #We always wrap the measure numbers in ++ #parentheses ++ arg_str = self._print( ++ v).parens()[0] + +- o1.append(arg_str + ' ' + k._pretty_form) +- vectstrs.append(k._pretty_form) ++ o1.append(arg_str + ' ' + k._pretty_form) ++ vectstrs.append(k._pretty_form) + +- #outstr = u("").join(o1) +- if o1[0].startswith(u(" + ")): +- o1[0] = o1[0][3:] +- elif o1[0].startswith(" "): +- o1[0] = o1[0][1:] +- #Fixing the newlines +- lengths = [] +- strs = [''] +- for i, partstr in enumerate(o1): +- # XXX: What is this hack? +- if '\n' in partstr: +- tempstr = partstr +- tempstr = tempstr.replace(vectstrs[i], '') +- tempstr = tempstr.replace(u('\u239e'), +- u('\u239e') +- + ' ' + vectstrs[i]) +- o1[i] = tempstr +- o1 = [x.split('\n') for x in o1] +- n_newlines = max([len(x) for x in o1]) +- for parts in o1: +- lengths.append(len(parts[0])) +- for j in range(n_newlines): +- if j+1 <= len(parts): +- if j >= len(strs): +- strs.append(' ' * (sum(lengths[:-1]) + +- 3*(len(lengths)-1))) +- if j == 0: +- strs[0] += parts[0] + ' + ' +- else: +- strs[j] += parts[j] + ' '*(lengths[-1] - +- len(parts[j])+ +- 3) +- else: +- if j >= len(strs): +- strs.append(' ' * (sum(lengths[:-1]) + +- 3*(len(lengths)-1))) +- strs[j] += ' '*(lengths[-1]+3) ++ #outstr = u("").join(o1) ++ if o1[0].startswith(u(" + ")): ++ o1[0] = o1[0][3:] ++ elif o1[0].startswith(" "): ++ o1[0] = o1[0][1:] ++ #Fixing the newlines ++ lengths = [] ++ strs = [''] ++ for i, partstr in enumerate(o1): ++ # XXX: What is this hack? ++ if '\n' in partstr: ++ tempstr = partstr ++ tempstr = tempstr.replace(vectstrs[i], '') ++ tempstr = tempstr.replace(u('\N{RIGHT PARENTHESIS UPPER HOOK}'), ++ u('\N{RIGHT PARENTHESIS UPPER HOOK}') ++ + ' ' + vectstrs[i]) ++ o1[i] = tempstr ++ o1 = [x.split('\n') for x in o1] ++ n_newlines = max([len(x) for x in o1]) ++ for parts in o1: ++ lengths.append(len(parts[0])) ++ for j in range(n_newlines): ++ if j+1 <= len(parts): ++ if j >= len(strs): ++ strs.append(' ' * (sum(lengths[:-1]) + ++ 3*(len(lengths)-1))) ++ if j == 0: ++ strs[0] += parts[0] + ' + ' ++ else: ++ strs[j] += parts[j] + ' '*(lengths[-1] - ++ len(parts[j])+ ++ 3) ++ else: ++ if j >= len(strs): ++ strs.append(' ' * (sum(lengths[:-1]) + ++ 3*(len(lengths)-1))) ++ strs[j] += ' '*(lengths[-1]+3) + +- return u('\n').join([s[:-3] for s in strs]) +- return Fake() ++ return prettyForm(u('\n').join([s[:-3] for s in strs])) + + def _print_Piecewise(self, pexpr): + +--- sympy/printing/pretty/stringpict.py.orig 2015-09-03 14:34:00.000000000 -0600 ++++ sympy/printing/pretty/stringpict.py 2015-11-21 15:36:01.748135163 -0700 +@@ -29,6 +29,7 @@ class stringPict(object): + """Initialize from string. + Multiline strings are centered. + """ ++ self.s = s + #picture is a string that just can be printed + self.picture = stringPict.equalLengths(s.splitlines()) + #baseline is the line number of the "base line" +--- sympy/printing/pretty/tests/test_pretty.py.orig 2015-09-03 14:34:00.000000000 -0600 ++++ sympy/printing/pretty/tests/test_pretty.py 2015-11-21 15:37:58.227740936 -0700 +@@ -14,6 +14,8 @@ from sympy.functions import (Abs, Chi, C + lowergamma, meijerg, sin, sqrt, subfactorial, tan, uppergamma, + elliptic_k, elliptic_f, elliptic_e, elliptic_pi) + ++from sympy.matrices import Adjoint, Inverse, MatrixSymbol, Transpose ++ + from sympy.printing.pretty import pretty as xpretty + from sympy.printing.pretty import pprint + +@@ -2478,7 +2480,6 @@ u("""\ + + + def test_Adjoint(): +- from sympy.matrices import Adjoint, Inverse, MatrixSymbol, Transpose + X = MatrixSymbol('X', 2, 2) + Y = MatrixSymbol('Y', 2, 2) + assert pretty(Adjoint(X)) == " +\nX " +@@ -2511,6 +2512,26 @@ def test_Adjoint(): + u(" T\n⎛ †⎞ \n⎝X ⎠ ") + + ++def test_MatrixExpressions(): ++ n = Symbol('n', integer=True) ++ X = MatrixSymbol('X', n, n) ++ ++ assert pretty(X) == upretty(X) == "X" ++ ++ Y = X[1:2:3, 4:5:6] ++ ++ ascii_str = ucode_str = "X[1:3, 4:6]" ++ ++ assert pretty(Y) == ascii_str ++ assert upretty(Y) == ucode_str ++ ++ Z = X[1:10:2] ++ ++ ascii_str = ucode_str = "X[1:10:2, :n]" ++ ++ assert pretty(Z) == ascii_str ++ assert upretty(Z) == ucode_str ++ + def test_pretty_piecewise(): + expr = Piecewise((x, x < 1), (x**2, True)) + ascii_str = \ +--- sympy/vector/coordsysrect.py.orig 2015-09-03 14:34:00.000000000 -0600 ++++ sympy/vector/coordsysrect.py 2015-11-21 15:44:01.012479961 -0700 +@@ -436,6 +436,12 @@ class CoordSysCartesian(Basic): + final_matrix = orienters.rotation_matrix(self) + else: + final_matrix = orienters.rotation_matrix() ++ # TODO: trigsimp is needed here so that the matrix becomes ++ # canonical (scalar_map also calls trigsimp; without this, you can ++ # end up with the same CoordinateSystem that compares differently ++ # due to a differently formatted matrix). However, this is ++ # probably not so good for performance. ++ final_matrix = trigsimp(final_matrix) + else: + final_matrix = Matrix(eye(3)) + for orienter in orienters: +--- sympy/vector/deloperator.py.orig 2015-09-03 14:34:00.000000000 -0600 ++++ sympy/vector/deloperator.py 2015-11-21 15:44:44.065004287 -0700 +@@ -3,6 +3,7 @@ from sympy.core.function import Derivati + from sympy.vector.vector import Vector + from sympy.vector.functions import express + from sympy.vector.coordsysrect import CoordSysCartesian ++from sympy.vector.scalar import BaseScalar + from sympy.core import S + + +@@ -171,6 +172,6 @@ def _diff_conditional(expr, base_scalar) + """ + + new_expr = express(expr, base_scalar.system, variables = True) +- if base_scalar in new_expr.atoms(): ++ if base_scalar in new_expr.atoms(BaseScalar): + return Derivative(new_expr, base_scalar) + return S(0) +--- sympy/vector/functions.py.orig 2015-09-03 14:34:00.000000000 -0600 ++++ sympy/vector/functions.py 2015-11-21 15:46:08.050224073 -0700 +@@ -69,9 +69,8 @@ def express(expr, system, system2=None, + #If variables attribute is True, substitute + #the coordinate variables in the Vector + system_list = [] +- for x in expr.atoms(): +- if (isinstance(x, (BaseScalar, BaseVector)) +- and x.system != system): ++ for x in expr.atoms(BaseScalar, BaseVector): ++ if x.system != system: + system_list.append(x.system) + system_list = set(system_list) + subs_dict = {} +@@ -113,8 +112,8 @@ def express(expr, system, system2=None, + system_set = set([]) + expr = sympify(expr) + #Subsitute all the coordinate variables +- for x in expr.atoms(): +- if isinstance(x, BaseScalar)and x.system != system: ++ for x in expr.atoms(BaseScalar): ++ if x.system != system: + system_set.add(x.system) + subs_dict = {} + for f in system_set: +--- sympy/vector/point.py.orig 2015-09-03 14:34:00.000000000 -0600 ++++ sympy/vector/point.py 2015-11-21 15:47:51.025910739 -0700 +@@ -15,11 +15,11 @@ class Point(Basic): + def __new__(cls, name, position=Vector.zero, parent_point=None): + #Check the args first + if not isinstance(position, Vector): +- raise TypeError("position should be a Vector instance") ++ raise TypeError("position should be an instance of Vector, not %s" % type(position)) + if (not isinstance(parent_point, Point) + and parent_point is not None): +- raise TypeError("parent_point should be a Point instance") +- #Create an object ++ raise TypeError("parent_point should be an instance of Point, not %s" % type(parent_point)) ++ # Super class construction + if parent_point is None: + arg_parent = Symbol('default') + arg_self = Symbol(name) +--- sympy/vector/tests/test_field_functions.py.orig 2015-09-03 14:34:00.000000000 -0600 ++++ sympy/vector/tests/test_field_functions.py 2015-11-21 15:55:13.935154218 -0700 +@@ -219,4 +219,4 @@ def test_scalar_potential_difference(): + (P.x*cos(q) - P.y*sin(q))**2) + assert (scalar_potential_difference(grad_field, P, P.origin, + genericpointP).simplify() == +- potential_diff_P) ++ potential_diff_P.simplify()) diff --git a/sympy.spec b/sympy.spec index 20b0073..9537ab4 100644 --- a/sympy.spec +++ b/sympy.spec @@ -9,6 +9,8 @@ Source0: https://github.com/%{name}/%{name}/releases/download/%{name}-%{v # it out (rhbz# 551576): Patch0: %{name}-0.7.6-strip-internal-mpmath.patch Patch1: https://github.com/AadityaNair/sympy/commit/1be64700c1063eff2b2747ce63ca03eac797b4a4.patch +# This is https://github.com/sympy/sympy/pull/10084/ adapted to 0.7.6.1 +Patch2: %{name}-python35.patch BuildArch: noarch BuildRequires: gcc-gfortran @@ -105,18 +107,9 @@ fixtimestamp sympy/plotting/tests/test_plot_implicit.py # Make a copy for building the python3 version rm -rf %{py3dir} cp -a . %{py3dir} - -# Handle a new way eval() can fail in python 3.5 -sed -e 's/SyntaxError/&, TypeError/' \ - -e 's/unbound method/contains() missing 1 required positional argument...\n /' \ - -i.orig %{py3dir}/sympy/core/sympify.py -fixtimestamp %{py3dir}/sympy/core/sympify.py - -# Handle two changes in an error message in python 3.5 -sed -e 's/ in test\.globs/, test.globs)/' \ - -e 's/RuntimeError/RecursionError/' \ - -i.orig %{py3dir}/doc/src/gotchas.rst -fixtimestamp %{py3dir}/doc/src/gotchas.rst +pushd %{py3dir} +%patch2 +popd %build # Build the python2 version