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
2 changes: 1 addition & 1 deletion CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ API incompatibility

* ``Matcher`` now requires an additional ``evaluation`` parameter
* ``Romberg`` removed as an ``NIntegrate[]`` method. It is depcrecated in SciPy and is to be removed by SciPy 1.15.

* `Definitions.get_ownvalue` now returns a `BaseElement` instead of a `BaseRule` object.

Bugs
----
Expand Down
4 changes: 1 addition & 3 deletions mathics/builtin/makeboxes.py
Original file line number Diff line number Diff line change
Expand Up @@ -516,9 +516,7 @@ def format_operator(operator) -> Union[String, BaseElement]:
encoding_rule = evaluation.definitions.get_ownvalue(
"$CharacterEncoding"
)
encoding = (
"UTF8" if encoding_rule is None else encoding_rule.replace.value
)
encoding = "UTF8" if encoding_rule is None else encoding_rule.value
op_str = (
operator.value
if isinstance(operator, String)
Expand Down
2 changes: 1 addition & 1 deletion mathics/core/builtin.py
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ def contribute(self, definitions: Definitions, is_pymodule=False):
# Otherwise it'll be created in Global` when it's
# used, so it won't work.
if option not in definitions.builtin:
definitions.builtin[option] = Definition(name=name)
definitions.builtin[option] = Definition(name=option)

# Check if the given options are actually supported by the
# Builtin. If not, we might issue an "optx" error and
Expand Down
58 changes: 30 additions & 28 deletions mathics/core/definitions.py
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ def is_pattern_a_kind_of(pattern: BaseElement, pattern_name: str) -> bool:
return None


def insert_rule(values: list, rule: BaseRule) -> None:
def insert_rule(values: List[BaseRule], rule: BaseRule) -> None:
"""
Add a new rule inside a list of values.
Rules are sorted in a way that the first elements
Expand Down Expand Up @@ -326,14 +326,14 @@ def __init__(
if not self.add_rule(rule):
print(f"{rule.pattern.expr} could not be associated with {self.name}")

def get_values_list(self, pos: str) -> list:
def get_values_list(self, pos: str) -> List[BaseRule]:
"""Return one of the value lists"""
assert pos.isalpha()
if pos == "messages":
return self.messages
return getattr(self, f"{pos}values")

def set_values_list(self, pos: str, rules: list) -> None:
def set_values_list(self, pos: str, rules: List[BaseRule]) -> None:
"""Set one of the value lists"""
assert pos.isalpha()
if pos == "messages":
Expand Down Expand Up @@ -847,23 +847,23 @@ def get_attributes(self, name: str) -> int:
"""
return self.get_definition(name).attributes

def get_ownvalues(self, name: str) -> list:
def get_ownvalues(self, name: str) -> List[BaseRule]:
"""Return the list of ownvalues"""
return self.get_definition(name).ownvalues

def get_downvalues(self, name: str) -> list:
def get_downvalues(self, name: str) -> List[BaseRule]:
"""Return the list of downvalues"""
return self.get_definition(name).downvalues

def get_subvalues(self, name: str) -> list:
def get_subvalues(self, name: str) -> List[BaseRule]:
"""Return the list of subvalues"""
return self.get_definition(name).subvalues

def get_upvalues(self, name: str) -> list:
def get_upvalues(self, name: str) -> List[BaseRule]:
"""Return the list of upvalues"""
return self.get_definition(name).upvalues

def get_formats(self, name: str, format_name="") -> list:
def get_formats(self, name: str, format_name="") -> List[BaseRule]:
"""
Return a list of format rules associated with `name`.
if `format_name` is given, looks to the rules associated
Expand All @@ -874,11 +874,11 @@ def get_formats(self, name: str, format_name="") -> list:
result.sort()
return result

def get_nvalues(self, name: str) -> list:
def get_nvalues(self, name: str) -> List[BaseRule]:
"""Return the list of nvalues"""
return self.get_definition(name).nvalues

def get_defaultvalues(self, name: str) -> list:
def get_defaultvalues(self, name: str) -> List[BaseRule]:
"""Return the list of defaultvalues"""
return self.get_definition(name).defaultvalues

Expand Down Expand Up @@ -1042,7 +1042,7 @@ def add_message(self, name: str, rule: BaseRule) -> None:
self.mark_changed(definition)
self.clear_definitions_cache(name)

def set_values(self, name: str, values, rules) -> None:
def set_values(self, name: str, values: str, rules: List[BaseRule]) -> None:
"""Set a list of rules associated with the Symbol `name`"""
pos = valuesname(values)
definition = self.get_user_definition(self.lookup_name(name))
Expand Down Expand Up @@ -1075,9 +1075,16 @@ def set_user_definitions(self, definitions: str) -> None:

def get_ownvalue(self, name: str) -> BaseElement:
"""Get ownvalue associated with `name`"""
ownvalues = self.get_definition(self.lookup_name(name)).ownvalues
if ownvalues:
return ownvalues[0]
lookup_name = self.lookup_name(name)
ownvalues = self.get_definition(lookup_name).ownvalues

for ownvalue in ownvalues:
if not isinstance(ownvalue.pattern.expr, Symbol):
continue
try:
return ownvalue.get_replace_value()
except ValueError:
continue
raise ValueError
# return None

Expand Down Expand Up @@ -1108,20 +1115,15 @@ def get_config_value(
self, name: str, default: Optional[int] = None
) -> Optional[int]:
"Infinity -> None, otherwise returns integer."
value = self.get_definition(name).ownvalues
if value:
try:
value = value[0].replace
except AttributeError:
return None
if value.get_name() == "System`Infinity" or value.has_form(
"DirectedInfinity", 1
):
return None

return int(value.get_int_value())

return default
try:
value = self.get_ownvalue(name)
except ValueError:
return default
if value.get_name() == "System`Infinity" or value.has_form(
"DirectedInfinity", 1
):
return None
return int(value.to_python()) # .get_int_value())

def set_config_value(self, name: str, new_value: int) -> None:
"""Set the (own)value of an integer variable"""
Expand Down
2 changes: 1 addition & 1 deletion mathics/core/element.py
Original file line number Diff line number Diff line change
Expand Up @@ -416,7 +416,7 @@ def is_free(self, form, evaluation) -> bool:
def is_inexact(self) -> bool:
return self.get_precision() is not None

def sameQ(self, rhs: "BaseElement") -> bool:
def sameQ(self, rhs) -> bool:
"""Mathics SameQ"""
return id(self) == id(rhs)

Expand Down
26 changes: 22 additions & 4 deletions mathics/core/pattern.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,17 @@

from abc import ABC
from itertools import chain
from typing import TYPE_CHECKING, Callable, Dict, Optional, Sequence, Tuple, Type, Union
from typing import (
TYPE_CHECKING,
Callable,
Dict,
Optional,
Sequence,
Tuple,
Type,
Union,
overload,
)

from mathics.core.atoms import Integer
from mathics.core.attributes import A_FLAT, A_ONE_IDENTITY, A_ORDERLESS
Expand Down Expand Up @@ -314,11 +324,19 @@ def get_match_candidates_count(
"""Return the number of candidates that match with the pattern."""
return len(self.get_match_candidates(elements, pattern_context))

@overload
def sameQ(self, other: "BasePattern") -> bool:
...

@overload
def sameQ(self, other: BaseElement) -> bool:
...

def sameQ(self, other) -> bool:
"""Mathics SameQ"""
if not isinstance(other, BasePattern):
return False
return self.expr.sameQ(other.expr)
if isinstance(other, BasePattern):
return self.expr.sameQ(other.expr)
return self.expr.sameQ(other)


class AtomPattern(BasePattern):
Expand Down
7 changes: 7 additions & 0 deletions mathics/core/rules.py
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,9 @@ def apply_function(
):
raise NotImplementedError

def get_replace_value(self) -> BaseElement:
raise ValueError

def get_sort_key(self, pattern_sort=True) -> tuple:
# FIXME: check if this makes sense:
return tuple((self.system, self.pattern.get_sort_key(pattern_sort)))
Expand Down Expand Up @@ -269,6 +272,10 @@ def apply_rule(

return new

def get_replace_value(self) -> BaseElement:
"""return the replace value"""
return self.replace

def __repr__(self) -> str:
return "<Rule: %s -> %s>" % (self.pattern, self.replace)

Expand Down
7 changes: 5 additions & 2 deletions mathics/doc/online.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,11 @@ def online_doc_string(

# First look at user definitions:
for rulemsg in ruleusage:
if rulemsg.pattern.expr.elements[1].__str__() == '"usage"':
usagetext = rulemsg.replace.value
if rulemsg.pattern.expr.get_elements()[1].__str__() == '"usage"':
# mypy complains about the plane conversion, but
# to_python() returns a string wrapped in quotes.
# So, let's get ride the quotes...
usagetext = rulemsg.get_replace_value().to_python(string_quotes=False)

if not is_long_form and usagetext:
return usagetext
Expand Down
7 changes: 4 additions & 3 deletions mathics/eval/assignments/assignment.py
Original file line number Diff line number Diff line change
Expand Up @@ -1101,12 +1101,13 @@ def eval_assign_part(
if is_protected(name, defs):
evaluation.message(self.get_name(), "wrsym", symbol)
return False
rule = defs.get_ownvalue(name)
if rule is None:
try:
rule = defs.get_ownvalue(name)
except ValueError:
evaluation.message(self.get_name(), "noval", symbol)
return False
indices = lhs.elements[1:]
return eval_Part([rule.replace], indices, evaluation, rhs)
return eval_Part([rule], indices, evaluation, rhs)


def eval_assign_random_state(
Expand Down
2 changes: 1 addition & 1 deletion mathics/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ def get_srcdir():


def show_echo(query, evaluation):
echovar = evaluation.definitions.get_ownvalue("System`$Echo").replace
echovar = evaluation.definitions.get_ownvalue("System`$Echo")
if not isinstance(echovar, Expression) or not echovar.has_form("List", None):
return

Expand Down
Loading