Repository navigation
Fix behavior of $Line , In[...] and Out[...]. #1988
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -82,17 +82,17 @@ class In(Builtin): | |
| >> Definition[In] | ||
| = Attributes[In] = {Listable, Protected} | ||
| . | ||
| . In[6] = Definition[In] | ||
| . | ||
| . In[5] = In[-1] | ||
| . In[1] = x = 1 | ||
| . | ||
| . In[4] = x | ||
| . In[2] = x = x + 1 | ||
| . | ||
| . In[3] = Do[In[2], {3}] | ||
| . | ||
| . In[2] = x = x + 1 | ||
| . In[4] = x | ||
| . | ||
| . In[1] = x = 1 | ||
| . In[5] = In[-1] | ||
| . | ||
| . In[6] = Definition[In] | ||
| . | ||
| """ | ||
|
|
||
|
|
@@ -226,3 +226,4 @@ class Line(Builtin): | |
|
|
||
| name = "$Line" | ||
| summary_text = "current line number" | ||
| rules = {"$Line": "1"} | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This automatically sets the initial value of |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -481,7 +481,7 @@ def get_history_length(self) -> int: | |
|
|
||
| def get_line_no(self) -> int: | ||
| """Get $Line, the current input line number""" | ||
| return self.get_config_value("$Line", 0) or 0 | ||
| return self.get_config_value("$Line", 1) or 1 | ||
|
|
||
| def get_matching_names(self, pattern: Union[str, re.Pattern]) -> List[str]: | ||
| """ | ||
|
|
@@ -666,7 +666,7 @@ def increment_line_no(self, increment: int = 1) -> None: | |
| """Increment $Line, the current input line number""" | ||
| line_number = self.get_line_no() | ||
| if line_number is not None: | ||
| self.set_config_value("$Line", +increment) | ||
| self.set_config_value("$Line", line_number + increment) | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Seems we erase it by mistake at some point...
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Probably during
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I could use in Evaluation.evaluation, in the finally block. Right now, it is not used anywhere |
||
|
|
||
| def is_uncertain_final_value(self, last_evaluated_time: int, symbols: set) -> bool: | ||
| """ | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -229,8 +229,6 @@ def evaluate(self, query, timeout=None, format=None): | |
| output_forms = self.definitions.outputforms | ||
|
|
||
| line_no = self.definitions.get_line_no() | ||
| line_no += 1 | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should happend at the end of the evaluation, not before. |
||
| self.definitions.set_line_no(line_no) | ||
|
|
||
| history_length = self.definitions.get_history_length() | ||
|
|
||
|
|
@@ -242,7 +240,8 @@ def check_io_hook(hook): | |
| def evaluate(): | ||
| if history_length > 0: | ||
| self.definitions.add_rule( | ||
| "In", RewriteRule(to_expression("In", line_no), query) | ||
| "In", | ||
| RewriteRule(to_expression("In", line_no), query, evaluation=self), | ||
| ) | ||
| if check_io_hook("System`$Pre"): | ||
| self.last_eval = Expression(SymbolPre, query).evaluate(self) | ||
|
|
@@ -261,8 +260,13 @@ def evaluate(): | |
| stored_result = self.get_stored_result(out_result, output_forms) | ||
| self.definitions.add_rule( | ||
| "Out", | ||
| RewriteRule(Expression(SymbolOut, Integer(line_no)), stored_result), | ||
| RewriteRule( | ||
| Expression(SymbolOut, Integer(line_no)), | ||
| stored_result, | ||
| evaluation=self, | ||
| ), | ||
| ) | ||
|
|
||
| if self.last_eval != self.SymbolNull: | ||
| if check_io_hook("System`$PrePrint"): | ||
| self.last_eval = Expression( | ||
|
|
@@ -345,10 +349,14 @@ def evaluate(): | |
| self.out = [] | ||
| finally: | ||
| self.stop() | ||
| # $Line could have changed during the evaluation. | ||
| line_no = self.definitions.get_line_no() | ||
| line_no += 1 | ||
| self.definitions.set_line_no(line_no) | ||
|
|
||
| history_length = self.definitions.get_history_length() | ||
|
|
||
| line = line_no - history_length | ||
| line = line_no - history_length - 1 | ||
| while line > 0: | ||
| unset_in = self.definitions.unset("In", Expression(SymbolIn, Integer(line))) | ||
| unset_out = self.definitions.unset( | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -190,18 +190,22 @@ def reset(self, add_builtin=True, catch_interrupt=False): | |
| """ | ||
| reset the definitions and the evaluation objects. | ||
| """ | ||
| try: | ||
| self.definitions = Definitions(add_builtin) | ||
| except KeyError: | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This seems to have worked before I fixed the |
||
| from mathics.core.load_builtin import import_and_load_builtins | ||
| if add_builtin: | ||
| from mathics.core.load_builtin import ( | ||
| import_and_load_builtins, | ||
| mathics3_builtins_modules, | ||
| ) | ||
|
|
||
| import_and_load_builtins() | ||
| self.definitions = Definitions(add_builtin) | ||
| if not mathics3_builtins_modules: | ||
| import_and_load_builtins() | ||
|
|
||
| definitions = Definitions(add_builtin) | ||
| self.evaluation = Evaluation( | ||
| definitions=self.definitions, catch_interrupt=catch_interrupt | ||
| definitions=definitions, catch_interrupt=catch_interrupt | ||
| ) | ||
| self.last_result = None | ||
| definitions.set_line_no(1) | ||
| self.definitions = definitions | ||
|
|
||
| def evaluate(self, str_expression, timeout=None, form=None): | ||
| """Parse str_expression and evaluate using the `evaluate` method of the Expression""" | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -29,24 +29,25 @@ def test_session_evaluation(): | |
| Expression(Symbol("Global`F"), Symbol("Global`x")) | ||
| ) | ||
| assert len(session.evaluation.out) == 0 | ||
| assert session.evaluate("$Line") is Symbol("$Line") | ||
| assert session.evaluate("$Line") is Integer1 | ||
|
|
||
|
|
||
| def test_session_evaluation_as_in_cli(): | ||
| # `evaluation_as_in_cli` returns a `Result` object | ||
| session.reset() | ||
| assert session.evaluate("$Line") is Symbol("$Line") | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This change fits better with the WMA behaviour.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok. Please enlighten. In what way is it better?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As it is now in master, which is weird. Also, this is not compatible with the result using the MathicsSession object: which looks inconsistent: three ways to evaluate the same expression in the same condition, and three different results. |
||
| assert session.evaluate("$Line") is Integer1 | ||
| result = session.evaluate_as_in_cli('Print["Hola"]') | ||
| assert isinstance(result, Result) | ||
| assert len(result.out) == 1 and result.out[0].text == "Hola" | ||
| # Use session.evaluate(...) does not modify the `$Line` or | ||
| # `Out` definitions, while `evaluate_as_in_cli` does: | ||
| assert session.evaluate("$Line") is Integer1 | ||
| assert session.evaluate("$Line") is Integer2 | ||
| assert session.evaluate_as_in_cli("$Line", form="unformatted").result == Integer2 | ||
| assert session.evaluate("Out[1]") is SymbolNull | ||
| assert session.evaluate_as_in_cli("Out[1]").result is None | ||
| session.reset() | ||
| assert session.evaluate("$Line") is Symbol("$Line") | ||
| # After reset, `$Line` takes the value `1`. | ||
| assert session.evaluate("$Line") is Integer1 | ||
|
|
||
|
|
||
| def test_session_format_evaluation(): | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here, the order was wrong because the rules were not properly built in mathics.core.evaluation. Adding the
evaluationparameter when the rules are created, the rules can determine that that the patterns are literal patterns, and therefore the right precedence is used.