diff --git a/CHANGES.rst b/CHANGES.rst index d392b727d7..446311a119 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -4,26 +4,30 @@ CHANGES 1.1.1 ----- -This is the last update before some major refactoring and interface changing occurs. +This may be the last update before some major refactoring and interface changing occurs. -After this relase, Django will no longer be bundled here. See `mathics-django ` for the unbundled replacement. +In a future 2.0.0 release, Django will no longer be bundled here. See `mathics-django ` for the unbundled replacement. Some changes were made to support `Pymathics Graph `_, a new graph package bundled separately, -and to support the ability for front-ends to handle rendering on their own. +and to support the ability for front-ends to handle rendering on their own. Note that currently this doesn't integrate well into the Django interface, although it works +well in ``mathicsscript``. Package Updates -++++++++++++++++ ++++++++++++++++ - sympy 1.7.1 Mathics Packages added: -- ``DiscreteMath`CombinatoricaV0.9`` and - ``DiscreteMath`CombinatoricaV0.6``. V0.9 covers Steven Skiena's older "Implementing Discrete Mathematics: Combinatorics and Graph Theory" book. +- ``DiscreteMath`CombinatoricaV0.9`` (preferred) aand + ``DiscreteMath`CombinatoricaV0.6``. + +Both of these correspond to Steven Skiena's *older* book: "Implementing Discrete Mathematics: Combinatorics and Graph Theory" book. -If you have a package that you would like included in the distribution, and it works with Mathics, please contact us. +If you have a package that you would like included in the distribution, and it works with Mathics, please contact us +Rubi may appear in a future release, possibly in a year or so. However this might be speeded up if we can get people to help out with this. New builtins: @@ -31,23 +35,25 @@ New builtins: - ``StirlingS1``, ``StirlingS2`` (not all WL variations handled) - ``MapAt`` (not all WL variations handled) -- ``PythonForm``, ``SympyForm`` these is not in WL. It simply will show a crude translation to ``sympy`` or ``python``. Expect more and better translation later +- ``PythonForm``, ``SympyForm``: these is not in WL. It simply will show a crude translation to ``sympy`` or ``python``. Expect more and better translation later - ``Throw`` and ``Catch`` - ``With`` -- Start ``FileNameTake`` +- ``FileNameTake`` Enhancements and Bug fixes: +++++++++++++++++++++++++++ - Workaround for ``Compile`` so it accepts functions ##1026 - Add ``Trace`` option to ``Get``. ``Get["fn", Trace->True]`` will show lines as they are read. -- Add bool for ``from_python`` +- Convert to/from Boolean types properly in ``from_python``, ``to_python``. Previously they were 0, and 1. - Extend ``DeleteCases`` to accept a levelspec parameter. -- Set Evaluation#exc_result to capture ``Aborted``, ``Timeout``, ``Overflow1``, etc. -- ``ImageData`` changed to get bits {0,1} not bools. -- add tokenizer symbols for <-> and -> and the unicode versions of those. -- fix ``Needs`` +- Set ``Evaluation#exc_result`` to capture ``Aborted``, ``Timeout``, ``Overflow1``, etc. +- ``ImageData`` changed to get bits {0,1}, not booleans as previously. +- Add tokenizer symbols for <-> and -> and the unicode versions of those. +- Small corrections to ``Needs``, e.g check if already loaded, correct a typo, etc. - ``System`$InputFileName`` is now set inside ``Needs`` and ``Get`` +- Install shell scripts ``dmathicserver``, ``dmathicsscript``, and ``dmathics`` to simplify running docker +- Adjust $InputFileName inside ``Get`` and ``Needs``. 1.1.0 ----- diff --git a/mathics/builtin/arithmetic.py b/mathics/builtin/arithmetic.py index 558a1abc5d..e9bf30f11d 100644 --- a/mathics/builtin/arithmetic.py +++ b/mathics/builtin/arithmetic.py @@ -31,6 +31,7 @@ Rational, Real, Symbol, + SymbolNull, Complex, String, SymbolTrue, @@ -916,7 +917,7 @@ def apply_check(self, x, y, evaluation): return Symbol("ComplexInfinity") result = self.apply(Expression("Sequence", x, y), evaluation) - if result is None or result != Symbol("Null"): + if result is None or result != SymbolNull: return result diff --git a/mathics/builtin/attributes.py b/mathics/builtin/attributes.py index 3cbf7325f6..a6c60ee2e9 100644 --- a/mathics/builtin/attributes.py +++ b/mathics/builtin/attributes.py @@ -11,7 +11,7 @@ from mathics.builtin.base import Predefined, Builtin from mathics.builtin.evaluation import Sequence -from mathics.core.expression import Expression, Symbol, String +from mathics.core.expression import Expression, Symbol, SymbolNull, String from mathics.builtin.assignment import get_symbol_list @@ -46,16 +46,16 @@ class Attributes(Builtin): = {Listable} """ - attributes = ('HoldAll', 'Listable') + attributes = ("HoldAll", "Listable") def apply(self, expr, evaluation): - 'Attributes[expr_]' + "Attributes[expr_]" name = expr.get_lookup_name() attributes = list(evaluation.definitions.get_attributes(name)) attributes.sort() attr = [Symbol(attribute) for attribute in attributes] - return Expression('List', *attr) + return Expression("List", *attr) class SetAttributes(Builtin): @@ -75,26 +75,28 @@ class SetAttributes(Builtin): = {Flat, Orderless} """ - attributes = ('HoldFirst',) + attributes = ("HoldFirst",) def apply(self, symbols, attributes, evaluation): - 'SetAttributes[symbols_, attributes_]' + "SetAttributes[symbols_, attributes_]" - symbols = get_symbol_list(symbols, lambda item: evaluation.message( - 'SetAttributes', 'sym', item, 1)) + symbols = get_symbol_list( + symbols, lambda item: evaluation.message("SetAttributes", "sym", item, 1) + ) if symbols is None: return - values = get_symbol_list(attributes, lambda item: evaluation.message( - 'SetAttributes', 'sym', item, 2)) + values = get_symbol_list( + attributes, lambda item: evaluation.message("SetAttributes", "sym", item, 2) + ) if values is None: return for symbol in symbols: - if 'System`Locked' in evaluation.definitions.get_attributes(symbol): - evaluation.message('SetAttributes', 'locked', Symbol(symbol)) + if "System`Locked" in evaluation.definitions.get_attributes(symbol): + evaluation.message("SetAttributes", "locked", Symbol(symbol)) else: for value in values: evaluation.definitions.set_attribute(symbol, value) - return Symbol('Null') + return SymbolNull class ClearAttributes(Builtin): @@ -116,26 +118,29 @@ class ClearAttributes(Builtin): = {} """ - attributes = ('HoldFirst',) + attributes = ("HoldFirst",) def apply(self, symbols, attributes, evaluation): - 'ClearAttributes[symbols_, attributes_]' + "ClearAttributes[symbols_, attributes_]" - symbols = get_symbol_list(symbols, lambda item: evaluation.message( - 'ClearAttributes', 'sym', item, 1)) + symbols = get_symbol_list( + symbols, lambda item: evaluation.message("ClearAttributes", "sym", item, 1) + ) if symbols is None: return - values = get_symbol_list(attributes, lambda item: evaluation.message( - 'ClearAttributes', 'sym', item, 2)) + values = get_symbol_list( + attributes, + lambda item: evaluation.message("ClearAttributes", "sym", item, 2), + ) if values is None: return for symbol in symbols: - if 'System`Locked' in evaluation.definitions.get_attributes(symbol): - evaluation.message('ClearAttributes', 'locked', Symbol(symbol)) + if "System`Locked" in evaluation.definitions.get_attributes(symbol): + evaluation.message("ClearAttributes", "locked", Symbol(symbol)) else: for value in values: evaluation.definitions.clear_attribute(symbol, value) - return Symbol('Null') + return SymbolNull class Protect(Builtin): @@ -156,9 +161,9 @@ class Protect(Builtin): = {1, 2, 3} """ - attributes = ('HoldAll',) + attributes = ("HoldAll",) messages = { - 'ssym': "`1` is not a symbol or a string.", + "ssym": "`1` is not a symbol or a string.", } def apply(self, symbols, evaluation): @@ -174,16 +179,16 @@ def apply(self, symbols, evaluation): if symbols.get_head_name() in ("System`Sequence", "System`List"): symbols = symbols.get_leaves() else: - evaluation.message('Protect', 'ssym', symbols) - return Symbol("Null") - + evaluation.message("Protect", "ssym", symbols) + return SymbolNull + for symbol in symbols: if isinstance(symbol, Symbol): items.append(symbol) else: pattern = symbol.get_string_value() - if not pattern or pattern=="": - evaluation.message('Protect', 'ssym', symbol) + if not pattern or pattern == "": + evaluation.message("Protect", "ssym", symbol) continue if pattern[0] == "`": @@ -191,11 +196,15 @@ def apply(self, symbols, evaluation): names = evaluation.definitions.get_matching_names(pattern) for defn in names: symbol = Symbol(defn) - if not 'System`Locked' in evaluation.definitions.get_attributes(defn): + if not "System`Locked" in evaluation.definitions.get_attributes( + defn + ): items.append(symbol) - Expression("SetAttributes", Expression("List", *items), protected).evaluate(evaluation) - return Symbol('Null') + Expression("SetAttributes", Expression("List", *items), protected).evaluate( + evaluation + ) + return SymbolNull class Unprotect(Builtin): @@ -209,20 +218,20 @@ class Unprotect(Builtin): """ - attributes = ('HoldAll',) + attributes = ("HoldAll",) messages = { - 'ssym': "`1` is not a symbol or a string.", + "ssym": "`1` is not a symbol or a string.", } def apply(self, symbols, evaluation): "Unprotect[symbols___]" protected = Symbol("System`Protected") items = [] - if isinstance(symbols ,Symbol): + if isinstance(symbols, Symbol): symbols = [symbols] elif isinstance(symbols, Expression): symbols = symbols.get_leaves() - elif isinstance(symbols ,String): + elif isinstance(symbols, String): symbols = [symbols] else: symbols = symbols.get_sequence() @@ -232,8 +241,8 @@ def apply(self, symbols, evaluation): items.append(symbol) else: pattern = symbol.get_string_value() - if not pattern or pattern=="": - evaluation.message('Unprotect', 'ssym', symbol) + if not pattern or pattern == "": + evaluation.message("Unprotect", "ssym", symbol) continue if pattern[0] == "`": @@ -241,11 +250,15 @@ def apply(self, symbols, evaluation): names = evaluation.definitions.get_matching_names(pattern) for defn in names: symbol = Symbol(defn) - if not 'System`Locked' in evaluation.definitions.get_attributes(defn): + if not "System`Locked" in evaluation.definitions.get_attributes( + defn + ): items.append(symbol) - Expression("ClearAttributes", Expression("List", *items), protected).evaluate(evaluation) - return Symbol('Null') + Expression("ClearAttributes", Expression("List", *items), protected).evaluate( + evaluation + ) + return SymbolNull class Protected(Predefined): diff --git a/mathics/builtin/files.py b/mathics/builtin/files.py index 191383c920..2c2bf3bc07 100644 --- a/mathics/builtin/files.py +++ b/mathics/builtin/files.py @@ -4930,7 +4930,7 @@ def apply(self, context, evaluation): # Already loaded return SymbolNull - # TODO: Look why this rises the message + # TODO: Figure out why this raises the message: # "Select::normal: Nonatomic expression expected." already_loaded = Expression('MemberQ', Symbol('System`$Packages'), context) diff --git a/mathics/builtin/image.py b/mathics/builtin/image.py index b2a3c1d87a..b8aa12ea64 100644 --- a/mathics/builtin/image.py +++ b/mathics/builtin/image.py @@ -13,6 +13,7 @@ Real, MachineReal, Symbol, + SymbolNull, from_python, ) from mathics.builtin.colors import ( @@ -242,7 +243,7 @@ def apply(self, path, expr, opts, evaluation): """ImageExport[path_?StringQ, expr_, opts___]""" if isinstance(expr, Image): expr.pil().save(path.get_string_value()) - return Symbol("Null") + return SymbolNull else: return evaluation.message("ImageExport", "noimage") diff --git a/mathics/builtin/structure.py b/mathics/builtin/structure.py index 2a3c74e194..b782fe7f72 100644 --- a/mathics/builtin/structure.py +++ b/mathics/builtin/structure.py @@ -13,8 +13,9 @@ Expression, String, Symbol, - SymbolTrue, + SymbolNull, SymbolFalse, + SymbolTrue, Integer, Rational, strip_context, @@ -291,9 +292,9 @@ def apply(self, p1, p2, evaluation): "PatternsOrderedQ[p1_, p2_]" if p1.get_sort_key(True) <= p2.get_sort_key(True): - return Symbol("True") + return SymbolTrue else: - return Symbol("False") + return SymbolFalse class OrderedQ(Builtin): @@ -314,9 +315,9 @@ def apply(self, e1, e2, evaluation): "OrderedQ[e1_, e2_]" if e1 <= e2: - return Symbol("True") + return SymbolTrue else: - return Symbol("False") + return SymbolFalse class Order(Builtin): @@ -657,7 +658,7 @@ def callback(level): heads = self.get_option(options, "Heads", evaluation).is_true() result, depth = walk_levels(expr, start, stop, heads=heads, callback=callback) - return Symbol("Null") + return SymbolNull class MapIndexed(Builtin): diff --git a/mathics/version.py b/mathics/version.py index c89e7eece7..abbe89d906 100644 --- a/mathics/version.py +++ b/mathics/version.py @@ -5,4 +5,4 @@ # This file is suitable for sourcing inside POSIX shell as # well as importing into Python. That's why there is no # space around "=" below. -__version__="1.1.1dev" # noqa +__version__="1.1.1" # noqa