Skip to content

Commit 6481223

Browse files
committed
fixing connection between definitions and symbols
1 parent 79ba0e2 commit 6481223

File tree

5 files changed

+73
-48
lines changed

5 files changed

+73
-48
lines changed

mathics/builtin/assignment.py

Lines changed: 62 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import mathics.builtin
66
from mathics.builtin.base import (
77
Builtin, BinaryOperator, PostfixOperator, PrefixOperator)
8-
from mathics.core.expression import (Expression, Symbol, SymbolFailed, valid_context_name,
8+
from mathics.core.expression import (Expression, Symbol, SymbolFailed, SymbolNull, valid_context_name,
99
system_symbols, String)
1010
from mathics.core.rules import Rule, BuiltinRule
1111
from mathics.builtin.patterns import RuleDelayed
@@ -833,23 +833,34 @@ def _get_usage_string(symbol, evaluation, htmlout=False):
833833
definition = evaluation.definitions.get_definition(symbol.name)
834834
ruleusage = definition.get_values_list('messages')
835835
usagetext = None
836-
from mathics.builtin import builtins
837836
import re
838-
bio = builtins.get(definition.name)
839-
837+
# First look at user definitions:
838+
for rulemsg in ruleusage:
839+
if rulemsg.pattern.expr.leaves[1].__str__() == "\"usage\"":
840+
usagetext = rulemsg.replace.value
841+
if usagetext is not None:
842+
# Maybe, if htmltout is True, we should convert
843+
# the value to a HTML form...
844+
return usagetext
845+
# Otherwise, look at the pymathics, and builtin docstrings:
846+
builtins = evaluation.definitions.builtin
847+
pymathics = evaluation.definitions.pymathics
848+
bio = pymathics.get(definition.name)
849+
if bio is None:
850+
bio = builtins.get(definition.name)
851+
840852
if bio is not None:
841853
from mathics.doc.doc import Doc
854+
docstr = bio.builtin.__class__.__doc__
855+
if docstr is None:
856+
return None
842857
if htmlout:
843-
usagetext = Doc(bio.__class__.__doc__).text(0)
858+
usagetext = Doc(docstr).html()
844859
else:
845-
usagetext = Doc(bio.__class__.__doc__).text(0)
860+
usagetext = Doc(docstr).text(0)
846861
usagetext = re.sub(r'\$([0-9a-zA-Z]*)\$', r'\1', usagetext)
847-
# For built-in symbols, looks for a docstring.
848-
# Looks for the "usage" message. For built-in symbols, if there is an "usage" chain, overwrite the __doc__ information.
849-
for rulemsg in ruleusage:
850-
if rulemsg.pattern.expr.leaves[1].__str__() == "\"usage\"":
851-
usagetext = rulemsg.replace.value
852-
return usagetext
862+
return usagetext
863+
return None
853864

854865

855866
class Information(PrefixOperator):
@@ -861,20 +872,27 @@ class Information(PrefixOperator):
861872
'Information' does not print information for 'ReadProtected' symbols.
862873
'Information' uses 'InputForm' to format values.
863874
875+
#> a = 2;
876+
#> Information[a]
877+
| a = 2
878+
.
879+
= Null
864880
865-
>> a = 2;
866-
>> Information[a]
867-
= a = 2
868-
881+
#> f[x_] := x ^ 2;
882+
#> g[f] ^:= 2;
883+
#> f::usage = "f[x] returns the square of x";
884+
#> Information[f]
885+
| f[x] returns the square of x
886+
.
887+
. f[x_] = x ^ 2
888+
.
889+
. g[f] ^= 2
890+
.
891+
= Null
869892
870-
>> f[x_] := x ^ 2
871-
>> g[f] ^:= 2
872-
>> f::usage = "f[x] returns the square of x";
873-
X> Information[f]
874-
= f[x] returns the square of x
875893
876-
>> ? Table
877-
=
894+
#> ? Table
895+
|
878896
. 'Table[expr, {i, n}]'
879897
. evaluates expr with i ranging from 1 to n, returning
880898
. a list of the results.
@@ -885,9 +903,10 @@ class Information(PrefixOperator):
885903
. evaluates expr with i taking on the values e1, e2,
886904
. ..., ei.
887905
.
906+
= Null
888907
889-
>> Information[Table]
890-
=
908+
#> Information[Table]
909+
|
891910
. 'Table[expr, {i, n}]'
892911
. evaluates expr with i ranging from 1 to n, returning
893912
. a list of the results.
@@ -900,6 +919,7 @@ class Information(PrefixOperator):
900919
.
901920
. Attributes[Table] = {HoldAll, Protected}
902921
.
922+
= Null
903923
"""
904924

905925
operator = "??"
@@ -910,15 +930,14 @@ class Information(PrefixOperator):
910930

911931
def format_definition(self, symbol, evaluation, options, grid=True):
912932
'StandardForm,TraditionalForm,OutputForm: Information[symbol_, OptionsPattern[Information]]'
913-
from mathics.core.expression import from_python
933+
ret = SymbolNull
914934
lines = []
915935
if isinstance(symbol, String):
916936
evaluation.print_out(symbol)
917-
evaluation.evaluate(Expression('Information', Symbol('System`String')))
918-
return
937+
return ret
919938
if not isinstance(symbol, Symbol):
920939
evaluation.message('Information', 'notfound', symbol)
921-
return Symbol('Null')
940+
return ret
922941
# Print the "usage" message if available.
923942
usagetext = _get_usage_string(symbol, evaluation)
924943
if usagetext is not None:
@@ -929,17 +948,16 @@ def format_definition(self, symbol, evaluation, options, grid=True):
929948

930949
if grid:
931950
if lines:
932-
return Expression(
951+
infoshow = Expression(
933952
'Grid', Expression(
934953
'List', *(Expression('List', line) for line in lines)),
935954
Expression(
936955
'Rule', Symbol('ColumnAlignments'), Symbol('Left')))
937-
else:
938-
return Symbol('Null')
956+
evaluation.print_out(infoshow)
939957
else:
940958
for line in lines:
941959
evaluation.print_out(Expression('InputForm', line))
942-
return Symbol('Null')
960+
return ret
943961

944962
# It would be deserable to call here the routine inside Definition, but for some reason it fails...
945963
# Instead, I just copy the code from Definition
@@ -1006,7 +1024,9 @@ def rhs(expr):
10061024

10071025
def format_definition_input(self, symbol, evaluation, options):
10081026
'InputForm: Information[symbol_, OptionsPattern[Information]]'
1009-
return self.format_definition(symbol, evaluation, options, grid=False)
1027+
self.format_definition(symbol, evaluation, options, grid=False)
1028+
ret = SymbolNull
1029+
return ret
10101030

10111031

10121032
class Clear(Builtin):
@@ -1748,17 +1768,19 @@ def apply(self, module, evaluation):
17481768
except ImportError as e:
17491769
evaluation.message(self.get_name(), 'notfound', module)
17501770
return SymbolFailed
1751-
1771+
except PyMathicsLoadException as e:
1772+
evaluation.message(self.get_name(), 'notmathicslib', module)
1773+
return SymbolFailed
1774+
else:
17521775
# Add Pymathics` to $ContextPath so that when user don't
17531776
# have to qualify Pymathics variables and functions,
17541777
# as the those in the module just loaded.
17551778
# Following the example of $ContextPath in the WL
17561779
# reference manual where PackletManager appears first in
17571780
# the list, it seems to be preferable to add this PyMathics
17581781
# at the beginning.
1759-
context_path = evaluation.definitions.get_context_path()
1760-
if "Pymathics`" not in context_path:
1761-
context_path.insert(0, "Pymathics`")
1762-
evaluation.definitions.set_context_path(context_path)
1763-
1782+
context_path = evaluation.definitions.get_context_path()
1783+
if "Pymathics`" not in context_path:
1784+
context_path.insert(0, "Pymathics`")
1785+
evaluation.definitions.set_context_path(context_path)
17641786
return module

mathics/builtin/base.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,7 @@ def contextify_form_name(f):
270270
attributes=attributes,
271271
options=options,
272272
defaultvalues=defaults,
273+
builtin=self
273274
)
274275
if is_pymodule:
275276
definitions.pymathics[name] = definition

mathics/builtin/inout.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1897,6 +1897,9 @@ class Print(Builtin):
18971897
| μ
18981898
#> Print["μ"]
18991899
| μ
1900+
#> Print["-Hola\\n-Qué tal?"]
1901+
| -Hola
1902+
. -Qué tal?
19001903
"""
19011904

19021905
def apply(self, expr, evaluation):

mathics/core/definitions.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -734,7 +734,7 @@ def __init__(
734734
options=None,
735735
nvalues=None,
736736
defaultvalues=None,
737-
builtin=None,
737+
builtin=None
738738
) -> None:
739739

740740
super(Definition, self).__init__()

mathics/doc/doc.py

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1143,7 +1143,6 @@ class DocTest(object):
11431143
`|` Prints output.
11441144
"""
11451145
def __init__(self, index, testcase):
1146-
11471146
def strip_sentinal(line):
11481147
"""Remove END_LINE_SENTINAL from the end of a line if it appears.
11491148
@@ -1192,19 +1191,19 @@ def strip_sentinal(line):
11921191
if self.result is not None:
11931192
self.result += text
11941193
elif self.outs:
1195-
self.outs[-1] += text
1194+
self.outs[-1].text += text
11961195
continue
11971196

11981197
match = TESTCASE_OUT_RE.match(line)
11991198
symbol, text = match.group(1), match.group(2)
12001199
text = text.strip()
12011200
if symbol == '=':
12021201
self.result = text
1203-
elif text:
1204-
if symbol == ':':
1205-
out = Message('', '', text)
1206-
elif symbol == '|':
1207-
out = Print(text)
1202+
elif symbol == ':':
1203+
out = Message('', '', text)
1204+
self.outs.append(out)
1205+
elif symbol == '|':
1206+
out = Print(text)
12081207
self.outs.append(out)
12091208

12101209
def __str__(self):

0 commit comments

Comments
 (0)