From d6a748262a44334f27008e8c90d2557f46481f5b Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Tue, 10 Oct 2023 10:33:39 -0500 Subject: [PATCH] Add python 3.12 support (#367) --- .github/workflows/test.yml | 6 ++-- jupyter_core/utils/__init__.py | 17 +++++++---- tests/test_async.py | 34 --------------------- tests/test_utils.py | 56 ++++++++++++++++++++++++++++++++++ 4 files changed, 71 insertions(+), 42 deletions(-) delete mode 100644 tests/test_async.py create mode 100644 tests/test_utils.py diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index ebb1af99..3f6e6170 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -28,12 +28,14 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest, windows-latest, macos-latest] - python-version: ["3.8", "3.11"] + python-version: ["3.8", "3.12"] include: - os: windows-latest python-version: "3.9" - os: ubuntu-latest - python-version: "pypy-3.8" + python-version: "3.11" + - os: ubuntu-latest + python-version: "pypy-3.9" - os: macos-latest python-version: "3.10" steps: diff --git a/jupyter_core/utils/__init__.py b/jupyter_core/utils/__init__.py index 0c043d4d..48cd9694 100644 --- a/jupyter_core/utils/__init__.py +++ b/jupyter_core/utils/__init__.py @@ -160,12 +160,17 @@ def wrapped(*args: Any, **kwargs: Any) -> Any: pass # Run the loop for this thread. - try: - loop = asyncio.get_event_loop() - except RuntimeError: - loop = asyncio.new_event_loop() - asyncio.set_event_loop(loop) - return loop.run_until_complete(inner) + # In Python 3.12, a deprecation warning is raised, which + # may later turn into a RuntimeError. We handle both + # cases. + with warnings.catch_warnings(): + warnings.simplefilter("ignore", DeprecationWarning) + try: + loop = asyncio.get_event_loop() + except RuntimeError: + loop = asyncio.new_event_loop() + asyncio.set_event_loop(loop) + return loop.run_until_complete(inner) wrapped.__doc__ = coro.__doc__ return wrapped diff --git a/tests/test_async.py b/tests/test_async.py deleted file mode 100644 index 924e9a40..00000000 --- a/tests/test_async.py +++ /dev/null @@ -1,34 +0,0 @@ -"""Tests for async helper functions""" - -# Copyright (c) Jupyter Development Team. -# Distributed under the terms of the Modified BSD License. - -import asyncio - -from jupyter_core.utils import ensure_async, run_sync - - -async def afunc(): - return "afunc" - - -def func(): - return "func" - - -sync_afunc = run_sync(afunc) - - -def test_ensure_async(): - async def main(): - assert await ensure_async(afunc()) == "afunc" - assert await ensure_async(func()) == "func" - - asyncio.run(main()) - - -def test_run_sync(): - async def main(): - assert sync_afunc() == "afunc" - - asyncio.run(main()) diff --git a/tests/test_utils.py b/tests/test_utils.py new file mode 100644 index 00000000..ad5cbb4f --- /dev/null +++ b/tests/test_utils.py @@ -0,0 +1,56 @@ +"""Tests for utils""" + +# Copyright (c) Jupyter Development Team. +# Distributed under the terms of the Modified BSD License. + +import asyncio +import os +import tempfile + +import pytest + +from jupyter_core.utils import deprecation, ensure_async, ensure_dir_exists, run_sync + + +def test_ensure_dir_exists(): + with tempfile.TemporaryDirectory() as td: + ensure_dir_exists(td) + ensure_dir_exists(os.path.join(str(td), "foo"), 0o777) + + +def test_deprecation(): + with pytest.deprecated_call(): + deprecation("foo") + + +async def afunc(): + return "afunc" + + +def func(): + return "func" + + +sync_afunc = run_sync(afunc) + + +def test_run_sync(): + async def foo(): + return 1 + + foo_sync = run_sync(foo) + assert foo_sync() == 1 + assert foo_sync() == 1 + + asyncio.set_event_loop(None) + assert foo_sync() == 1 + + asyncio.run(foo()) + + +def test_ensure_async(): + async def main(): + assert await ensure_async(afunc()) == "afunc" + assert await ensure_async(func()) == "func" + + asyncio.run(main())