Skip to content
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

chore(ci): drop official support for Python 3.7, add support for 3.12 #936

Merged
merged 11 commits into from
Nov 13, 2024
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.7", "3.8", "3.9", "3.10", "3.11"]
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]

steps:
- uses: actions/checkout@v4
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@

### Updates

- Drop official Python 3.7 support, add Python 3.12 support
- Updated pandas version to 2.x
- Enable automated test run as required step for release process
- Enable basic DependaBot scanning for pip packages and GitHub actions used in CI
- Address security vulnerabilities in dependencies
- Add CI support for release proces with [release.yaml](.github/workflows/release.yml) workflow
- Release documentation is updated acrodingly in [RELEASING.md](./RELEASING.md)
- Update README.md with installation methods on newer Jupyter and JupyterLab releases
Expand Down
43 changes: 24 additions & 19 deletions sparkmagic/sparkmagic/tests/test_sparkkernelbase.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ class TestSparkKernel(SparkKernelBase):
def __init__(self, user_code_parser=None):
kwargs = {"testing": True}
if user_code_parser is None:
user_code_parser = MagicMock(return_value=code)
user_code_parser = MagicMock()
user_code_parser.get_code_to_run = MagicMock(return_value=code)

super().__init__(
None, None, None, None, None, LANG_PYTHON, user_code_parser, **kwargs
Expand All @@ -26,7 +27,8 @@ def __init__(self, user_code_parser=None):
def setup_function():
global kernel, execute_cell_mock, do_shutdown_mock, ipython_display

user_code_parser = MagicMock(return_value=code)
user_code_parser = MagicMock()
user_code_parser.get_code_to_run = MagicMock(return_value=code)
kernel = TestSparkKernel(user_code_parser)

kernel._execute_cell_for_user = execute_cell_mock = MagicMock(
Expand All @@ -45,24 +47,23 @@ def test_execute_valid_code():
ret = kernel.do_execute(code, False)

kernel.user_code_parser.get_code_to_run.assert_called_once_with(code)
assert execute_cell_mock.called_once_with(ret, True)
assert execute_cell_mock.return_value is ret
assert kernel._fatal_error is None

assert execute_cell_mock.called_once_with(code, True)
execute_cell_mock.assert_called_once_with(code, False, True, None, False)
assert ret is execute_cell_mock.return_value

# no errors
assert kernel._fatal_error is None
assert ipython_display.send_error.call_count == 0


def test_execute_throws_if_fatal_error_happened():
# Verify that if a fatal error already happened, we don't run the code and show the fatal error instead.
fatal_error = "Error."
kernel._fatal_error = fatal_error
kernel.do_execute(code, False)

ret = kernel.do_execute(code, False)

assert execute_cell_mock.return_value is ret
assert kernel._fatal_error == fatal_error
assert execute_cell_mock.called_once_with("None", True)
# assert kernel._complete_cell ran after the error
execute_cell_mock.assert_called_once_with("None", False, True, None, False)
assert ipython_display.send_error.call_count == 1


Expand All @@ -72,9 +73,9 @@ def test_execute_alerts_user_if_an_unexpected_error_happens():
kernel._fatal_error = "Something bad happened before"
kernel._repeat_fatal_error = MagicMock(side_effect=ValueError)

ret = kernel.do_execute(code, False)
assert execute_cell_mock.return_value is ret
assert execute_cell_mock.called_once_with("None", True)
kernel.do_execute(code, False)
# assert kernel._complete_cell ran after the error
execute_cell_mock.assert_called_once_with("None", False, True, None, False)
assert ipython_display.send_error.call_count == 1


Expand All @@ -88,12 +89,16 @@ def test_execute_throws_if_fatal_error_happens_for_execution():

execute_cell_mock.return_value = reply_content

ret = kernel._execute_cell(
code, False, shutdown_if_error=True, log_if_error=fatal_error
)
assert execute_cell_mock.return_value is ret
kernel._execute_cell(code, False, shutdown_if_error=True, log_if_error=fatal_error)

assert kernel._fatal_error == message
assert execute_cell_mock.called_once_with("None", True)

# expect two calls, one for the code execution attempt
# and one for kernel._complete_cell after the error
assert execute_cell_mock.call_count == 2
execute_cell_mock.assert_any_call(code, False, True, None, False)
execute_cell_mock.assert_any_call("None", False, True, None, False)

assert ipython_display.send_error.call_count == 1


Expand Down
Loading