Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 0 additions & 23 deletions mathics/builtin/attributes.py
Original file line number Diff line number Diff line change
Expand Up @@ -203,29 +203,6 @@ class Flat(Predefined):
'Flat' is taken into account in pattern matching:
>> f[a, b, c] /. f[a, b] -> d
= f[d, c]

#> SetAttributes[{u, v}, Flat]
#> u[x_] := {x}
#> u[]
= u[]
#> u[a]
= {a}
#> u[a, b]
: Iteration limit of 1000 exceeded.
= $Aborted
#> u[a, b, c]
: Iteration limit of 1000 exceeded.
= $Aborted
#> v[x_] := x
#> v[]
= v[]
#> v[a]
= a
#> v[a, b] (* in Mathematica: Iteration limit of 4096 exceeded. *)
= v[a, b]
#> v[a, b, c] (* in Mathematica: Iteration limit of 4096 exceeded. *)
: Iteration limit of 1000 exceeded.
= $Aborted
"""

summary_text = "attribute for associative symbols"
Expand Down
20 changes: 0 additions & 20 deletions mathics/builtin/compilation.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,32 +57,12 @@ class Compile(Builtin):
= CompiledFunction[{x}, Sin[x], -CompiledCode-]
>> cf[1.4]
= 0.98545
#> cf[1/2]
= 0.479426
#> cf[4]
= -0.756802
#> cf[x]
: Invalid argument x should be Integer, Real or boolean.
= CompiledFunction[{x}, Sin[x], -CompiledCode-][x]
#> cf = Compile[{{x, _Real}, {x, _Integer}}, Sin[x + y]]
: Duplicate parameter x found in {{x, _Real}, {x, _Integer}}.
= Compile[{{x, _Real}, {x, _Integer}}, Sin[x + y]]
#> cf = Compile[{{x, _Real}, {y, _Integer}}, Sin[x + z]]
= CompiledFunction[{x, y}, Sin[x + z], -PythonizedCode-]
#> cf = Compile[{{x, _Real}, {y, _Integer}}, Sin[x + y]]
= CompiledFunction[{x, y}, Sin[x + y], -CompiledCode-]
#> cf[1, 2]
= 0.14112
#> cf[x + y]
= CompiledFunction[{x, y}, Sin[x + y], -CompiledCode-][x + y]

Compile supports basic flow control:
>> cf = Compile[{{x, _Real}, {y, _Integer}}, If[x == 0.0 && y <= 0, 0.0, Sin[x ^ y] + 1 / Min[x, 0.5]] + 0.5]
= CompiledFunction[{x, y}, ..., -CompiledCode-]
>> cf[3.5, 2]
= 2.18888
#> cf[0, -2]
= 0.5

Loops and variable assignments are supported usinv Python builtin "compile" function:
>> Compile[{{a, _Integer}, {b, _Integer}}, While[b != 0, {a, b} = {b, Mod[a, b]}]; a] (* GCD of a, b *)
Expand Down
24 changes: 0 additions & 24 deletions mathics/builtin/datentime.py
Original file line number Diff line number Diff line change
Expand Up @@ -375,10 +375,6 @@ class AbsoluteTime(_DateFormat):

>> AbsoluteTime[{"6-6-91", {"Day", "Month", "YearShort"}}]
= 2885155200

## Mathematica Bug - Mathics gets it right
#> AbsoluteTime[1000]
= 1000
"""

summary_text = "get absolute time in seconds"
Expand Down Expand Up @@ -834,10 +830,6 @@ class DateList(_DateFormat):
: The interpretation of 1/10/1991 is ambiguous.
= {1991, 1, 10, 0, 0, 0.}

#> DateList["7/8/9"]
: The interpretation of 7/8/9 is ambiguous.
= {2009, 7, 8, 0, 0, 0.}

>> DateList[{"31/10/91", {"Day", "Month", "YearShort"}}]
= {1991, 10, 31, 0, 0, 0.}

Expand Down Expand Up @@ -912,22 +904,6 @@ class DateString(_DateFormat):
Non-integer values are accepted too:
>> DateString[{1991, 6, 6.5}]
= Thu 6 Jun 1991 12:00:00

## Check Leading 0
#> DateString[{1979, 3, 14}, {"DayName", " ", "MonthShort", "-", "YearShort"}]
= Wednesday 3-79

#> DateString[{"DayName", " ", "Month", "/", "YearShort"}]
= ...

## Assumed separators
#> DateString[{"06/06/1991", {"Month", "Day", "Year"}}]
= Thu 6 Jun 1991 00:00:00

## Specified separators
#> DateString[{"06/06/1991", {"Month", "/", "Day", "/", "Year"}}]
= Thu 6 Jun 1991 00:00:00

"""

attributes = A_READ_PROTECTED | A_PROTECTED
Expand Down
3 changes: 0 additions & 3 deletions mathics/builtin/graphics.py
Original file line number Diff line number Diff line change
Expand Up @@ -1450,9 +1450,6 @@ class Text(Inset):

>> Graphics[{Text["First", {0, 0}], Text["Second", {1, 1}]}, Axes->True, PlotRange->{{-2, 2}, {-2, 2}}]
= -Graphics-

#> Graphics[{Text[x, {0,0}]}]
= -Graphics-
"""

summary_text = "arbitrary text or other expressions in 2D or 3D"
Expand Down
82 changes: 0 additions & 82 deletions mathics/builtin/patterns.py
Original file line number Diff line number Diff line change
Expand Up @@ -327,9 +327,6 @@ class ReplaceAll(BinaryOperator):
>> ReplaceAll[{a -> 1}][{a, b}]
= {1, b}

#> a + b /. x_ + y_ -> {x, y}
= {a, b}

ReplaceAll replaces the shallowest levels first:
>> ReplaceAll[x[1], {x[1] -> y, 1 -> 2}]
= y
Expand Down Expand Up @@ -761,9 +758,6 @@ class Alternatives(BinaryOperator, PatternObject):
Alternatives can also be used for string expressions
>> StringReplace["0123 3210", "1" | "2" -> "X"]
= 0XX3 3XX0

#> StringReplace["h1d9a f483", DigitCharacter | WhitespaceCharacter -> ""]
= hdaf
"""

arg_counts = None
Expand Down Expand Up @@ -829,9 +823,6 @@ class Except(PatternObject):
Except can also be used for string expressions:
>> StringReplace["Hello world!", Except[LetterCharacter] -> ""]
= Helloworld

#> StringReplace["abc DEF 123!", Except[LetterCharacter, WordCharacter] -> "0"]
= abc DEF 000!
"""

arg_counts = [1, 2]
Expand Down Expand Up @@ -1091,15 +1082,6 @@ class Optional(BinaryOperator, PatternObject):
>> Default[h, k_] := k
>> h[a] /. h[x_, y_.] -> {x, y}
= {a, 2}

#> a:b:c
= a : b : c
#> FullForm[a:b:c]
= Optional[Pattern[a, b], c]
#> (a:b):c
= a : b : c
#> a:(b:c)
= a : (b : c)
"""

arg_counts = [1, 2]
Expand Down Expand Up @@ -1235,9 +1217,6 @@ class Blank(_Blank):
'Blank' only matches a single expression:
>> MatchQ[f[1, 2], f[_]]
= False

#> StringReplace["hello world!", _ -> "x"]
= xxxxxxxxxxxx
"""

rules = {
Expand Down Expand Up @@ -1293,14 +1272,6 @@ class BlankSequence(_Blank):
'Sequence' object:
>> f[1, 2, 3] /. f[x__] -> x
= Sequence[1, 2, 3]

#> f[a, b, c, d] /. f[x__, c, y__] -> {{x},{y}}
= {{a, b}, {d}}
#> a + b + c + d /. Plus[x__, c] -> {x}
= {a, b, d}

#> StringReplace[{"ab", "abc", "abcd"}, "b" ~~ __ -> "x"]
= {ab, ax, ax}
"""

rules = {
Expand Down Expand Up @@ -1350,21 +1321,6 @@ class BlankNullSequence(_Blank):
empty sequence:
>> MatchQ[f[], f[___]]
= True

## This test hits infinite recursion
##
##The value captured by a named 'BlankNullSequence' pattern is a
##'Sequence' object, which can have no elements:
##>> f[] /. f[x___] -> x
## = Sequence[]

#> ___symbol
= ___symbol
#> ___symbol //FullForm
= BlankNullSequence[symbol]

#> StringReplace[{"ab", "abc", "abcd"}, "b" ~~ ___ -> "x"]
= {ax, ax, ax}
"""

rules = {
Expand Down Expand Up @@ -1414,16 +1370,6 @@ class Repeated(PostfixOperator, PatternObject):
= {{}, a, {a, b}, a, {a, a, a, a}}
>> f[x, 0, 0, 0] /. f[x, s:0..] -> s
= Sequence[0, 0, 0]

#> 1.. // FullForm
= Repeated[1]
#> 8^^1.. // FullForm (* Mathematica gets this wrong *)
= Repeated[1]

#> StringReplace["010110110001010", "01".. -> "a"]
= a1a100a0
#> StringMatchQ[#, "a" ~~ ("b"..) ~~ "a"] &/@ {"aa", "aba", "abba"}
= {False, True, True}
"""

arg_counts = [1, 2]
Expand Down Expand Up @@ -1502,14 +1448,6 @@ class RepeatedNull(Repeated):
= RepeatedNull[Pattern[a, BlankNullSequence[Integer]]]
>> f[x] /. f[x, 0...] -> t
= t

#> 1... // FullForm
= RepeatedNull[1]
#> 8^^1... // FullForm (* Mathematica gets this wrong *)
= RepeatedNull[1]

#> StringMatchQ[#, "a" ~~ ("b"...) ~~ "a"] &/@ {"aa", "aba", "abba"}
= {True, True, True}
"""

operator = "..."
Expand Down Expand Up @@ -1666,26 +1604,6 @@ class OptionsPattern(PatternObject):
Options might be given in nested lists:
>> f[x, {{{n->4}}}]
= x ^ 4

#> {opt -> b} /. OptionsPattern[{}] -> t
= t

#> Clear[f]
#> Options[f] = {Power -> 2};
#> f[x_, OptionsPattern[f]] := x ^ OptionValue[Power]
#> f[10]
= 100
#> f[10, Power -> 3]
= 1000
#> Clear[f]

#> Options[f] = {Power -> 2};
#> f[x_, OptionsPattern[]] := x ^ OptionValue[Power]
#> f[10]
= 100
#> f[10, Power -> 3]
= 1000
#> Clear[f]
"""

arg_counts = [0, 1]
Expand Down
83 changes: 82 additions & 1 deletion test/builtin/test_attributes.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"""

import os
from test.helper import check_evaluation
from test.helper import check_evaluation, session

import pytest

Expand Down Expand Up @@ -226,3 +226,84 @@ def test_Attributes_wrong_args(str_expr, arg_count):
f"SetAttributes called with {arg_count} arguments; 2 arguments are expected.",
),
)


@pytest.mark.parametrize(
("str_expr", "msgs", "str_expected", "fail_msg"),
[
("CleanAll[u];CleanAll[v];", None, None, None),
("SetAttributes[{u, v}, Flat];u[x_] := {x};u[]", None, "u[]", None),
("u[a]", None, "{a}", None),
("v[x_] := x;v[]", None, "v[]", None),
("v[a]", None, "a", None),
(
"v[a, b]",
None,
"v[a, b]",
"in Mathematica: Iteration limit of 4096 exceeded.",
),
("CleanAll[u];CleanAll[v];", None, None, None),
],
)
def test_private_doctests_attributes(str_expr, msgs, str_expected, fail_msg):
""" """
check_evaluation(
str_expr,
str_expected,
to_string_expr=True,
to_string_expected=True,
hold_expected=True,
failure_message=fail_msg,
expected_messages=msgs,
)


@pytest.mark.parametrize(
("str_expr", "msgs", "str_expected", "fail_msg"),
[
("CleanAll[u];CleanAll[v];", None, None, None),
(
"SetAttributes[{u, v}, Flat];u[x_] := {x};u[a, b]",
("Iteration limit of 1000 exceeded.",),
"$Aborted",
None,
),
("u[a, b, c]", ("Iteration limit of 1000 exceeded.",), "$Aborted", None),
(
"v[x_] := x;v[a,b,c]",
("Iteration limit of 1000 exceeded.",),
"$Aborted",
"in Mathematica: Iteration limit of 4096 exceeded.",
),
("CleanAll[u];CleanAll[v];", None, None, None),
],
)
def test_private_doctests_attributes_with_exceptions(
str_expr, msgs, str_expected, fail_msg
):
"""These tests check the behavior of $RecursionLimit and $IterationLimit"""

# Here we do not use the session object to check the messages
# produced by the exceptions. If $RecursionLimit / $IterationLimit
# are reached during the evaluation using a MathicsSession object,
# an exception is raised. On the other hand, using the `Evaluation.evaluate`
# method, the exception is handled.
#
# TODO: Maybe it makes sense to clone this exception handling in
# the check_evaluation function.
#
def eval_expr(expr_str):
query = session.evaluation.parse(expr_str)
res = session.evaluation.evaluate(query)
session.evaluation.stopped = False
return res

res = eval_expr(str_expr)
if msgs is None:
assert len(res.out) == 0
else:
assert len(res.out) == len(msgs)
for li1, li2 in zip(res.out, msgs):
assert li1.text == li2

assert res.result == str_expected
Loading