Skip to content

Commit 4e468a8

Browse files
authored
Merge pull request #1149 from mathics/rc1
Release candidate 1
2 parents 96911dd + 6481223 commit 4e468a8

File tree

15 files changed

+312
-350
lines changed

15 files changed

+312
-350
lines changed

CHANGES.rst

Lines changed: 203 additions & 198 deletions
Large diffs are not rendered by default.

Makefile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ build:
3737
develop:
3838
$(PIP) install -e .
3939

40+
#: Make distirbution: wheels, eggs, tarball
41+
dist:
42+
./admin-tools/make-dist.sh
43+
4044
#: Install mathics
4145
install:
4246
$(PYTHON) setup.py install

README.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ Mathics is released under the GNU General Public License Version 3 (GPL3).
4646
.. |Travis| image:: https://secure.travis-ci.org/mathics/Mathics.svg?branch=master
4747
.. _Travis: https://travis-ci.org/mathics/Mathics
4848
.. _PyPI: https://pypi.org/project/Mathics/
49-
.. |mathicsscript| image:: https://mathics.org/screenshots/mathicsscript.png
50-
.. |mathicssserver| image:: https://mathics.org/screenshots/mathicsserver.png
49+
.. |mathicsscript| image:: https://github.com/Mathics3/mathicsscript/blob/master/screenshots/mathicsscript1.gif
50+
.. |mathicssserver| image:: https://mathics.org/images/mathicsserver.png
5151
.. |Latest Version| image:: https://badge.fury.io/py/Mathics3.svg
5252
:target: https://badge.fury.io/py/Mathics3
5353
.. |Pypi Installs| image:: https://pepy.tech/badge/Mathics3

admin-tools/make-dist.sh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#!/bin/bash
12
PACKAGE=mathics3
23

34
# FIXME put some of the below in a common routine
@@ -15,7 +16,7 @@ fi
1516

1617

1718
cd ..
18-
source $PACKAGE/version.py
19+
source mathics/version.py
1920
echo $__version__
2021

2122
for pyversion in $PYVERSIONS; do

mathics/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949
version_string += f", cython {version_info['cython']}"
5050

5151
license_string = """\
52-
Copyright (C) 2011-2020 The Mathics Team.
52+
Copyright (C) 2011-2021 The Mathics Team.
5353
This program comes with ABSOLUTELY NO WARRANTY.
5454
This is free software, and you are welcome to redistribute it
5555
under certain conditions.

mathics/builtin/assignment.py

Lines changed: 64 additions & 42 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-
1752-
# Add PyMathics` to $ContextPath so that when user don't
1753-
# have to qualify PyMathics variables and functions,
1771+
except PyMathicsLoadException as e:
1772+
evaluation.message(self.get_name(), 'notmathicslib', module)
1773+
return SymbolFailed
1774+
else:
1775+
# Add Pymathics` to $ContextPath so that when user don't
1776+
# 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: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ def contribute(self, definitions, is_pymodule=False):
9191
name = self.get_name()
9292
options = {}
9393
option_syntax = "Warn"
94+
9495
for option, value in self.options.items():
9596
if option == "$OptionSyntax":
9697
option_syntax = value
@@ -147,7 +148,7 @@ def check_options(options_to_check, evaluation):
147148
for pattern, function in self.get_functions(is_pymodule=is_pymodule):
148149
rules.append(
149150
BuiltinRule(
150-
name, pattern, function, check_options, system=not is_pymodule
151+
name, pattern, function, check_options, system=True
151152
)
152153
)
153154
for pattern, replace in self.rules.items():
@@ -260,6 +261,7 @@ def contextify_form_name(f):
260261
pattern = Expression("Default", Symbol(name), Integer(spec))
261262
if pattern is not None:
262263
defaults.append(Rule(pattern, value, system=True))
264+
263265
definition = Definition(
264266
name=name,
265267
rules=rules,
@@ -268,6 +270,7 @@ def contextify_form_name(f):
268270
attributes=attributes,
269271
options=options,
270272
defaultvalues=defaults,
273+
builtin=self
271274
)
272275
if is_pymodule:
273276
definitions.pymathics[name] = definition
@@ -312,11 +315,10 @@ def get_functions(self, prefix="apply", is_pymodule=False):
312315
pattern = m.group(2)
313316
else:
314317
attrs = []
315-
if is_pymodule:
316-
name = ensure_context(self.get_name(short=True), "Pymathics")
317-
else:
318-
name = self.get_name()
319-
318+
# if is_pymodule:
319+
# name = ensure_context(self.get_name(short=True), "Pymathics")
320+
# else:
321+
name = self.get_name()
320322
pattern = pattern % {"name": name}
321323
definition_class = (
322324
PyMathicsDefinitions() if is_pymodule else SystemDefinitions()
@@ -764,4 +766,3 @@ def from_expression(expr):
764766
return CountableInteger(0, upper_limit=True)
765767

766768
return None # leave original expression unevaluated
767-

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: 7 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
fully_qualified_symbol_name,
2020
strip_context,
2121
)
22-
from mathics_scanner.tokeniser import base_names_pattern, full_names_pattern
22+
from mathics_scanner.tokeniser import full_names_pattern
2323

2424
type_compiled_pattern = type(re.compile("a.a"))
2525

@@ -152,17 +152,13 @@ def load_pymathics_module(self, module, remove_on_quit=True):
152152
if not var.context:
153153
var.context = "Pymathics`"
154154
symbol_name = instance.get_name()
155-
builtins[symbol_name] = instance
156155
builtins_by_module[loaded_module.__name__].append(instance)
157156
newsymbols[symbol_name] = instance
158157

159158
for name in newsymbols:
160159
luname = self.lookup_name(name)
161160
self.user.pop(name, None)
162-
if remove_on_quit and name not in self.pymathics:
163-
self.pymathics[name] = self.builtin.get(name, None)
164-
self.builtin.update(newsymbols)
165-
161+
166162
for name, item in newsymbols.items():
167163
if name != "System`MakeBoxes":
168164
item.contribute(self, is_pymodule=True)
@@ -177,25 +173,9 @@ def clear_pymathics_modules(self):
177173
if not key.startswith("mathics."):
178174
print(f'removing module "{key}" not in mathics.')
179175
del builtins_by_module[key]
180-
# print("reloading symbols from current builtins.")
181-
for s in self.pymathics:
182-
if s in self.builtin:
183-
# If there was a true built-in definition for the symbol, restore it, else, remove he symbol.
184-
if self.pymathics[s]:
185-
self.builtin[s] = self.pymathics[s]
186-
builtins[s] = None
187-
for key, val in builtins_by_module.items():
188-
for simb in val:
189-
if simb.get_name() == s:
190-
builtins[s] = simb
191-
break
192-
if builtins[s] is not None:
193-
break
194-
if builtins[s] is None:
195-
builtins.__delitem__(s)
196-
else:
197-
self.builtin.__delitem__(s)
198-
builtins.__delitem__(s)
176+
for key in pymathics:
177+
del self.pymathics[key]
178+
199179
self.pymathics = {}
200180
# print("everything is clean")
201181
return None
@@ -447,7 +427,7 @@ def get_definition(self, name, only_if_exists=False) -> "Definition":
447427
pymathics.attributes if pymathics else
448428
(builtin.attributes if builtin else set())
449429
)
450-
upvalues = [],
430+
upvalues = [],
451431
messages = [],
452432
nvalues = [],
453433
defaultvalues = [],
@@ -754,7 +734,7 @@ def __init__(
754734
options=None,
755735
nvalues=None,
756736
defaultvalues=None,
757-
builtin=None,
737+
builtin=None
758738
) -> None:
759739

760740
super(Definition, self).__init__()

mathics/core/parser/util.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,12 +72,12 @@ def lookup_name(self, name):
7272
class PyMathicsDefinitions(object):
7373
"""
7474
Dummy Definitions object that puts every unqualified symbol in
75-
PyMathics`.
75+
Pymathics`.
7676
"""
7777

7878
def lookup_name(self, name):
7979
assert isinstance(name, str)
80-
context = "System`" if name in SYSTEM_LIST else "PyMathics`"
80+
context = "System`" if name in SYSTEM_LIST else "Pymathics`"
8181
# print("XXX", name, context)
8282
return ensure_context(name, context)
8383

0 commit comments

Comments
 (0)