sopel-irc / sopel

:robot::speech_balloon: An easy-to-use and highly extensible IRC Bot framework. Formerly Willie.
https://sopel.chat
Other
950 stars 405 forks source link

tools.calculation: replace deprecated `ast.Num` with `ast.Constant` #2464

Closed dgw closed 11 months ago

dgw commented 1 year ago

ast.Num and friends have been deprecated since Python 3.8, but only started to generate warnings in Python 3.12 prereleases.

Feels like stdlib made a bad trade here, simplifying Python internals in exchange for making users write uglier, more complicated type checks such as this. But it's been so long, it's not as if they'll un-deprecate the older, more-convenient-for-the-user classes.

Compatibility

I was under the impression that ast.Constant would work as far back as Python 3.6, but apparently not. This change has to wait until we're ready to drop Python 3.7.

Checklist

dgw commented 11 months ago

Well, there are no direct tests of this module… Even though CI passes, I don't really trust it that much.

I've started work on a test/tools/test_tools_calculation.py suite. But that's out of scope of this PR, and doesn't need to be done for 8.0 specifically, so I will mark this as ready for review and just show up with the test suite later when I'm done with it.

SnoopJ commented 11 months ago

Had a go at writing a basic set of tests for tools.calculation if you'd like to add them to this PR. Also wrote some up for the calc, dice plugins, I've opened #2503 for those (but can add the test listed here to that one if you'd prefer, let me know)

click for diff ```diff diff --git a/test/tools/test_tools_calculation.py b/test/tools/test_tools_calculation.py new file mode 100644 index 00000000..9f858285 --- /dev/null +++ b/test/tools/test_tools_calculation.py @@ -0,0 +1,35 @@ +from __future__ import annotations + +import ast +import operator + +import pytest + +from sopel.tools.calculation import EquationEvaluator, ExpressionEvaluator + + +def test_expression_eval(): + OPS = { + ast.Add: operator.add, + ast.Sub: operator.sub, + } + evaluator = ExpressionEvaluator(bin_ops=OPS) + + assert evaluator("1 + 1") == 2 + assert evaluator("43 - 1") == 42 + assert evaluator("1 + 1 - 2") == 0 + + with pytest.raises(ExpressionEvaluator.Error): + evaluator("2 * 2") + + +def test_equation_eval(): + evaluator = EquationEvaluator() + + assert evaluator("1 + 1") == 2 + assert evaluator("43 - 1") == 42 + assert evaluator("(((1 + 1 + 2) * 3 / 5) ** 8 - 13) // 21 % 35") == 16.0 + assert evaluator("-42") == -42 + assert evaluator("-(-42)") == 42 + assert evaluator("+42") == 42 + assert evaluator("3 ^ 2") == 9 ```
dgw commented 11 months ago

Had a go at writing a basic set of tests for tools.calculation if you'd like to add them to this PR.

I've adopted them into my WIP branch for adding tests to this module. This PR is already double-approved, and I'd rather not kibosh that status. 😁 But I appreciate that your quick patch gets the module to 81% coverage already! I'll have a look at the helpers and error cases at my leisure, probably for submission to the 8.1 cycle (coincidence?).